mirror of
https://github.com/bacher09/pwgen-for-bios.git
synced 2024-09-18 14:58:53 -04:00
Switch insyde module to typed arrays
This commit is contained in:
parent
da4eb4318f
commit
38aa1e6351
3 changed files with 72 additions and 69 deletions
|
@ -1,5 +1,4 @@
|
|||
import { insydeSolver } from "./insyde";
|
||||
import { acerInsyde10Solver, AES128, Crc64, Sha256 } from "./insyde";
|
||||
import { acerInsyde10Solver, AES128, Crc64, insydeSolver, Sha256} from "./insyde";
|
||||
|
||||
describe("Insyde BIOS", () => {
|
||||
it("Insyde key for 03133610 is 12891236", () => {
|
||||
|
@ -40,7 +39,7 @@ describe("Acer Insyde 10 BIOS", () => {
|
|||
|
||||
describe("Utils", () => {
|
||||
it("sha256", () => {
|
||||
expect(new Sha256([]).hexdigest())
|
||||
expect(new Sha256(Uint8Array.from([])).hexdigest())
|
||||
.toEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
|
||||
|
||||
expect(new Sha256([1]).hexdigest())
|
||||
|
@ -59,13 +58,13 @@ describe("Utils", () => {
|
|||
.toEqual("bd03ac1428f0ea86f4b83a731ffc7967bb82866d8545322f888d2f6e857ffc18");
|
||||
});
|
||||
it("AES128", () => {
|
||||
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
|
||||
const numbers = Uint8Array.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
|
||||
const myaes = new AES128(numbers);
|
||||
expect(myaes.encryptBlock(numbers))
|
||||
.toEqual([52, 195, 59, 127, 20, 253, 83, 220, 234, 37, 224, 26, 2, 225, 103, 39]);
|
||||
.toEqual(Uint8Array.from([52, 195, 59, 127, 20, 253, 83, 220, 234, 37, 224, 26, 2, 225, 103, 39]));
|
||||
|
||||
expect(myaes.encryptBlock("123456789abcdefg".split("").map((v) => v.charCodeAt(0))))
|
||||
.toEqual([111, 52, 225, 193, 98, 40, 19, 168, 122, 34, 93, 3, 146, 166, 202, 100]);
|
||||
expect(myaes.encryptBlock(Uint8Array.from("123456789abcdefg".split("").map((v) => v.charCodeAt(0)))))
|
||||
.toEqual(Uint8Array.from([111, 52, 225, 193, 98, 40, 19, 168, 122, 34, 93, 3, 146, 166, 202, 100]));
|
||||
});
|
||||
it("crc64", () => {
|
||||
let mycrc = new Crc64(Crc64.ECMA_POLYNOMIAL);
|
||||
|
@ -75,7 +74,7 @@ describe("Utils", () => {
|
|||
mycrc.update([0x80]);
|
||||
expect(mycrc.hexdigest()).toEqual("c96c5795d7870f42");
|
||||
mycrc.reset();
|
||||
mycrc.update([0xde, 0xad, 0xbe, 0xef]);
|
||||
mycrc.update(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
|
||||
expect(mycrc.hexdigest()).toEqual("fc232c18806871af");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -28,8 +28,10 @@ export class Crc64 {
|
|||
this.crc = JSBI.BigInt(0);
|
||||
}
|
||||
|
||||
public update(input: number[]) {
|
||||
for (let b of input) {
|
||||
public update(input: Uint8Array | number[]) {
|
||||
/* tslint:disable-next-line:prefer-for-of */
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const b = input[i] & 0xFF;
|
||||
const index = JSBI.toNumber(JSBI.asUintN(8, JSBI.bitwiseXor(this.crc, JSBI.BigInt(b))));
|
||||
const temp = JSBI.bitwiseXor(this.table[index], JSBI.signedRightShift(this.crc, JSBI.BigInt(8)));
|
||||
this.crc = JSBI.asUintN(64, temp);
|
||||
|
@ -76,7 +78,7 @@ export class Crc64 {
|
|||
|
||||
/* tslint:disable:no-shadowed-variable */
|
||||
export class Sha256 {
|
||||
private static readonly SHA256_CONSTANTS: number[] = [
|
||||
private static readonly SHA256_CONSTANTS: Uint32Array = Uint32Array.from([
|
||||
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
|
||||
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
|
||||
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
|
||||
|
@ -93,32 +95,31 @@ export class Sha256 {
|
|||
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
|
||||
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
|
||||
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
|
||||
];
|
||||
]);
|
||||
|
||||
private static readonly SHA256_IV: number[] = [
|
||||
private static readonly SHA256_IV: Uint32Array = Uint32Array.from([
|
||||
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
|
||||
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
|
||||
];
|
||||
]);
|
||||
|
||||
private state: number[];
|
||||
private data: number[];
|
||||
private state: Uint32Array;
|
||||
private data: Uint8Array;
|
||||
private bitlen: JSBI;
|
||||
private datalen: number;
|
||||
|
||||
constructor(input?: number[]) {
|
||||
constructor(input?: Uint8Array | number[]) {
|
||||
this.bitlen = JSBI.BigInt(0);
|
||||
this.datalen = 0;
|
||||
this.data = new Array(64);
|
||||
this.data = new Uint8Array(64);
|
||||
this.state = Sha256.SHA256_IV.slice();
|
||||
|
||||
if (input && Array.isArray(input)) {
|
||||
if (input && (input instanceof Uint8Array || Array.isArray(input))) {
|
||||
this.update(input);
|
||||
}
|
||||
}
|
||||
|
||||
private transform() {
|
||||
// Maybe Uint8Array ?
|
||||
let m: number[] = new Array(64);
|
||||
let m: Uint32Array = new Uint32Array(64);
|
||||
|
||||
function ROTRIGHT(a: number, b: number): number {
|
||||
return (a >>> b) | (a << (32 - b));
|
||||
|
@ -169,13 +170,9 @@ export class Sha256 {
|
|||
this.state[5] += f;
|
||||
this.state[6] += g;
|
||||
this.state[7] += h;
|
||||
|
||||
this.state.forEach((val, index) => {
|
||||
this.state[index] = val >>> 0;
|
||||
});
|
||||
}
|
||||
|
||||
private final(): number[] {
|
||||
private final(): Uint8Array {
|
||||
let i = this.datalen & 63;
|
||||
if (this.datalen < 56) {
|
||||
this.data[i++] = 0x80;
|
||||
|
@ -199,7 +196,7 @@ export class Sha256 {
|
|||
this.data[i] = JSBI.toNumber(val);
|
||||
}
|
||||
this.transform();
|
||||
let hash: number[] = new Array(32);
|
||||
let hash = new Uint8Array(32);
|
||||
for (let i = 0; i < 4; i++) {
|
||||
for (let j = 0; j < 8; j++) {
|
||||
hash[i + j * 4] = (this.state[j] >>> (24 - i * 8)) & 0xFF;
|
||||
|
@ -217,8 +214,10 @@ export class Sha256 {
|
|||
return item;
|
||||
}
|
||||
|
||||
public update(input: number[]) {
|
||||
for (let b of input) {
|
||||
public update(input: Uint8Array | number[]) {
|
||||
/* tslint:disable-next-line:prefer-for-of */
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const b = input[i];
|
||||
this.data[this.datalen] = b;
|
||||
this.datalen++;
|
||||
|
||||
|
@ -230,13 +229,13 @@ export class Sha256 {
|
|||
}
|
||||
}
|
||||
|
||||
public digest(): number[] {
|
||||
public digest(): Uint8Array {
|
||||
let item = this.copy();
|
||||
return item.final();
|
||||
}
|
||||
|
||||
public hexdigest() {
|
||||
return this.digest().map((x) => {
|
||||
return Array.from(this.digest()).map((x) => {
|
||||
x = x & 0xFF;
|
||||
return (x < 0xf) ? "0" + x.toString(16) : x.toString(16);
|
||||
}).join("");
|
||||
|
@ -249,7 +248,7 @@ export class AES128 {
|
|||
private static readonly NK = 4;
|
||||
private static readonly NR = 10;
|
||||
|
||||
private static readonly sbox: number[] = [
|
||||
private static readonly sbox: Uint8Array = Uint8Array.from([
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
|
@ -266,19 +265,19 @@ export class AES128 {
|
|||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
||||
];
|
||||
]);
|
||||
|
||||
private static readonly rcon: number[] = [
|
||||
private static readonly rcon: Uint8Array = Uint8Array.from([
|
||||
0x8D, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A
|
||||
];
|
||||
]);
|
||||
|
||||
private roundKey: number[];
|
||||
private roundKey: Uint8Array;
|
||||
|
||||
constructor(key: number[]) {
|
||||
constructor(key: Uint8Array) {
|
||||
this.roundKey = AES128.keyExpansion(key);
|
||||
}
|
||||
|
||||
public encryptBlock(input: number[]): number[] {
|
||||
public encryptBlock(input: Uint8Array): Uint8Array {
|
||||
if (input.length !== 16) {
|
||||
throw new Error("Invalid block length");
|
||||
}
|
||||
|
@ -297,17 +296,17 @@ export class AES128 {
|
|||
return state;
|
||||
}
|
||||
|
||||
private static keyExpansion(key: number[]): number[] {
|
||||
private static keyExpansion(key: Uint8Array): Uint8Array {
|
||||
if (key.length !== 16) {
|
||||
throw new Error("Key should be 16 bytes");
|
||||
}
|
||||
|
||||
let roundKey = new Array(176);
|
||||
let roundKey = new Uint8Array(176);
|
||||
// first round key is the key itself
|
||||
for (let i = 0; i < AES128.NK * 4; i++) {
|
||||
roundKey[i] = key[i];
|
||||
}
|
||||
let temp: number[] = new Array(4);
|
||||
let temp = new Uint8Array(4);
|
||||
// all other round keys generated from previous ones
|
||||
for (let i = AES128.NK; i < AES128.NB * (AES128.NR + 1); i++) {
|
||||
const k = (i - 1) * 4;
|
||||
|
@ -347,7 +346,7 @@ export class AES128 {
|
|||
return roundKey;
|
||||
}
|
||||
|
||||
private static addRoundKey(round: number, state: number[], roundKey: number[]) {
|
||||
private static addRoundKey(round: number, state: Uint8Array, roundKey: Uint8Array) {
|
||||
for (let i = 0; i < 4; i++) {
|
||||
for (let j = 0; j < 4; j++) {
|
||||
state[i * 4 + j] ^= roundKey[(round * AES128.NB * 4) + (i * AES128.NB) + j];
|
||||
|
@ -356,7 +355,7 @@ export class AES128 {
|
|||
}
|
||||
}
|
||||
|
||||
private static subBytes(state: number[]) {
|
||||
private static subBytes(state: Uint8Array) {
|
||||
for (let i = 0; i < 4; i++) {
|
||||
for (let j = 0; j < 4; j++) {
|
||||
state[j * 4 + i] = AES128.sbox[state[j * 4 + i]];
|
||||
|
@ -364,7 +363,7 @@ export class AES128 {
|
|||
}
|
||||
}
|
||||
|
||||
private static shiftRows(state: number[]) {
|
||||
private static shiftRows(state: Uint8Array) {
|
||||
// rotate first row 1 columns to left
|
||||
let temp: number = state[0 * 4 + 1];
|
||||
state[0 * 4 + 1] = state[1 * 4 + 1];
|
||||
|
@ -386,7 +385,7 @@ export class AES128 {
|
|||
state[1 * 4 + 3] = temp;
|
||||
}
|
||||
|
||||
private static mixColumns(state: number[]) {
|
||||
private static mixColumns(state: Uint8Array) {
|
||||
let tmp1: number;
|
||||
let tmp2: number;
|
||||
|
||||
|
@ -409,40 +408,44 @@ export class AES128 {
|
|||
}
|
||||
}
|
||||
|
||||
export function insydeAcerSwitch(arr: number[]): number[] {
|
||||
export function insydeAcerSwitch(arr: Uint8Array): Uint8Array {
|
||||
if (arr.length !== 32) {
|
||||
throw new Error("Input array should have 32 length");
|
||||
}
|
||||
|
||||
function fun0(arr: number[]): number[] {
|
||||
let output: number[] = [];
|
||||
function fun0(arr: Uint8Array): Uint8Array {
|
||||
let output = new Uint8Array(16);
|
||||
let k = 0;
|
||||
for (let i = 3; i >= 0; i--) {
|
||||
for (let j = 0; j < 16; j += 4 ) {
|
||||
output.push(arr[i + j]);
|
||||
output[k++] = arr[i + j];
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function fun1(arr: number[]): number[] {
|
||||
let output: number[] = [];
|
||||
function fun1(arr: Uint8Array): Uint8Array {
|
||||
let output = new Uint8Array(16);
|
||||
let k = 0;
|
||||
for (let i = 0; i < 4; i++) {
|
||||
for (let j = 12; j >= 0; j -= 4) {
|
||||
output.push(arr[i + j]);
|
||||
output[k++] = arr[i + j];
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function fun2(arr: number[]): number[] {
|
||||
let output: number[] = [];
|
||||
function fun2(arr: Uint8Array): Uint8Array {
|
||||
let output = new Uint8Array(16);
|
||||
let k = 0;
|
||||
for (let i = 0; i < 4; i++) {
|
||||
for (let j = 0; j < 4; j++) {
|
||||
output.push((arr[((j + i) & 3) + i * 4] + i) & 0xFF);
|
||||
output[k++] = (arr[((j + i) & 3) + i * 4] + i) & 0xFF;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function fun3(arr: number[]): number[] {
|
||||
let output: number[] = [];
|
||||
function fun3(arr: Uint8Array): Uint8Array {
|
||||
let output = new Uint8Array(16);
|
||||
let k = 0;
|
||||
let acc1 = 0;
|
||||
let acc2 = 0;
|
||||
for (let i = 0; i < 4; i++) {
|
||||
|
@ -451,22 +454,23 @@ export function insydeAcerSwitch(arr: number[]): number[] {
|
|||
}
|
||||
for (let i = 0; i < 16; i++) {
|
||||
const pivot = ((i & 1) === 0) ? acc1 : acc2;
|
||||
output.push(arr[i] ^ pivot);
|
||||
output[k++] = arr[i] ^ pivot;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function fun4(arr: number[]): number[] {
|
||||
let output: number[] = [];
|
||||
function fun4(arr: Uint8Array): Uint8Array {
|
||||
let output = new Uint8Array(16);
|
||||
let k = 0;
|
||||
for (let i = 0; i < 16; i++) {
|
||||
const temp1 = arr[i];
|
||||
const temp2 = arr[(i + 1) & 0xF]; // arr[(i + 1) % 15];
|
||||
const pivot = (temp2 < temp1) ? temp2 : 0xFF;
|
||||
output.push(temp1 ^ pivot);
|
||||
output[k++] = temp1 ^ pivot;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function fun5(arr: number[]): number[] {
|
||||
let output: number[] = new Array(16);
|
||||
function fun5(arr: Uint8Array): Uint8Array {
|
||||
let output = new Uint8Array(16);
|
||||
for (let i = 0; i < 4; i++) {
|
||||
let acc: number = 0;
|
||||
for (let j = 0; j < 16; j += 4) {
|
||||
|
@ -479,8 +483,8 @@ export function insydeAcerSwitch(arr: number[]): number[] {
|
|||
}
|
||||
return output;
|
||||
}
|
||||
function keyProcess(arr: number[]): number[] {
|
||||
let output: number[] = new Array(16);
|
||||
function keyProcess(arr: Uint8Array): Uint8Array {
|
||||
let output = new Uint8Array(16);
|
||||
for (let i = 0; i < 16; i++) {
|
||||
let acc: number = 0;
|
||||
for (let j = 0; j < 8; j++) {
|
||||
|
@ -510,17 +514,16 @@ export function insydeAcerSwitch(arr: number[]): number[] {
|
|||
|
||||
// 10 digits acer key
|
||||
export function acerInsydeKeygen(serial: string): string[] {
|
||||
// TODO: Uint8Array
|
||||
function rotatefun(arr: number[]): number[] {
|
||||
function rotatefun(arr: Uint8Array): Uint8Array {
|
||||
const idx = arr[9] & 0xF;
|
||||
let output: number[] = new Array(16);
|
||||
let output = new Uint8Array(16);
|
||||
for (let i = 0; i < output.length; i++) {
|
||||
output[i] = arr[((idx * 2 + 1) * i) % arr.length];
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
const inputBytes: number[] = serial.split("").map((c) => c.charCodeAt(0));
|
||||
const inputBytes = Uint8Array.from(serial.split("").map((c) => c.charCodeAt(0) & 0xFF));
|
||||
const digest = (new Sha256(inputBytes)).digest();
|
||||
const key = insydeAcerSwitch(digest);
|
||||
const blockData = rotatefun(digest);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"moduleResolution": "node",
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"downlevelIteration": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"strictNullChecks": true,
|
||||
|
|
Loading…
Reference in a new issue