Add support for Acer Insyde 10 digits
Based on let-def ocaml code: https://github.com/let-def/insydious/blob/master/deriv.ml
This commit is contained in:
1 parent
b99bdd7c81
commit
327fa5f815
8 files changed
+736
-158
No files matched your search
+2
-1
@@ -3,7 +3,7 @@ import { asusSolver } from "./asus";
|
||||
import { dellHddSolver, dellSolver, hddOldSolver } from "./dell";
|
||||
import { fsi20DecNewSolver, fsi20DecOldSolver, fsi24DecSolver, fsiHexSolver } from "./fsi";
|
||||
import { hpMiniSolver } from "./hpmini";
|
||||
import { insydeSolver } from "./insyde";
|
||||
import { acerInsyde10Solver, insydeSolver } from "./insyde";
|
||||
import {
|
||||
phoenixFsiLSolver, phoenixFsiPSolver, phoenixFsiSolver,
|
||||
phoenixFsiSSolver, phoenixFsiXSolver, phoenixHPCompaqSolver, phoenixSolver
|
||||
@@ -17,6 +17,7 @@ export type KeygenResult = [Solver, string[], number];
|
||||
|
||||
export const solvers: Solver[] = [
|
||||
asusSolver,
|
||||
acerInsyde10Solver,
|
||||
sonySolver,
|
||||
sony4x4Solver,
|
||||
samsungSolver,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { insydeSolver } from "./insyde";
|
||||
import { acerInsyde10Solver, AES128, Crc64, Sha256 } from "./insyde";
|
||||
|
||||
describe("Insyde BIOS", () => {
|
||||
it("Insyde key for 03133610 is 12891236", () => {
|
||||
@@ -13,3 +14,64 @@ describe("Insyde BIOS", () => {
|
||||
expect(insydeSolver("1234567")).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Acer Insyde 10 BIOS", () => {
|
||||
it("Check Acer solver", () => {
|
||||
expect(acerInsyde10Solver("0173549286")).toEqual(["e0eac38fdfcfd74a"]);
|
||||
expect(acerInsyde10Solver("1014206418")).toEqual(["3c0a50907bc2c604"]);
|
||||
expect(acerInsyde10Solver("1765418418")).toEqual(["5f54e355b83e969c"]);
|
||||
expect(acerInsyde10Solver("1858408509")).toEqual(["c4791532114cfbab"]);
|
||||
expect(acerInsyde10Solver("1925715998")).toEqual(["f21cce78c0987233"]);
|
||||
expect(acerInsyde10Solver("2051611322")).toEqual(["1c648cb56e8a64bb"]);
|
||||
expect(acerInsyde10Solver("2036529205")).toEqual(["f2e874332b6f50b1"]);
|
||||
expect(acerInsyde10Solver("1768688657")).toEqual(["80774329818c3312"]);
|
||||
expect(acerInsyde10Solver("1746144265")).toEqual(["c3d46da5f6f3c75b"]);
|
||||
expect(acerInsyde10Solver("1611926546")).toEqual(["f61c86479a8a6b20"]);
|
||||
expect(acerInsyde10Solver("1355047683")).toEqual(["7fe913d78ffc5ed1"]);
|
||||
expect(acerInsyde10Solver("1373072054")).toEqual(["aebeae5c425684cd"]);
|
||||
expect(acerInsyde10Solver("1373899792")).toEqual(["a26970a4ffb62d49"]);
|
||||
expect(acerInsyde10Solver("1395185025")).toEqual(["a763280d9f7396ec"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Utils", () => {
|
||||
it("sha256", () => {
|
||||
expect(new Sha256([]).hexdigest())
|
||||
.toEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
|
||||
|
||||
expect(new Sha256([1]).hexdigest())
|
||||
.toEqual("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a");
|
||||
|
||||
expect(new Sha256([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).hexdigest())
|
||||
.toEqual("c848e1013f9f04a9d63fa43ce7fd4af035152c7c669a4a404b67107cee5f2e4e");
|
||||
|
||||
expect(new Sha256("test".split("").map((v) => v.charCodeAt(0))).hexdigest())
|
||||
.toEqual("9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08");
|
||||
|
||||
expect(new Sha256("0".repeat(256).split("").map((v) => v.charCodeAt(0))).hexdigest())
|
||||
.toEqual("67f022195ee405142968ca1b53ae2513a8bab0404d70577785316fa95218e8ba");
|
||||
|
||||
expect(new Sha256("0".repeat(56).split("").map((v) => v.charCodeAt(0))).hexdigest())
|
||||
.toEqual("bd03ac1428f0ea86f4b83a731ffc7967bb82866d8545322f888d2f6e857ffc18");
|
||||
});
|
||||
it("AES128", () => {
|
||||
const numbers = [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]);
|
||||
|
||||
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]);
|
||||
});
|
||||
it("crc64", () => {
|
||||
let mycrc = new Crc64(Crc64.ECMA_POLYNOMIAL);
|
||||
mycrc.update([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
|
||||
expect(mycrc.hexdigest()).toEqual("335a089168033fbe");
|
||||
mycrc.reset();
|
||||
mycrc.update([0x80]);
|
||||
expect(mycrc.hexdigest()).toEqual("c96c5795d7870f42");
|
||||
mycrc.reset();
|
||||
mycrc.update([0xde, 0xad, 0xbe, 0xef]);
|
||||
expect(mycrc.hexdigest()).toEqual("fc232c18806871af");
|
||||
});
|
||||
});
|
||||
+538
-1
@@ -1,8 +1,537 @@
|
||||
/* tslint:disable:no-bitwise */
|
||||
/* tslint:disable:no-var-requires */
|
||||
/* Maybe need fixing for browsers where numbers is 32-bits */
|
||||
/* Some Acer, HP laptops. 8 digit */
|
||||
import type JSBIT from "jsbi";
|
||||
import { makeSolver } from "./utils";
|
||||
const JSBI = require("jsbi");
|
||||
type JSBI = JSBIT;
|
||||
|
||||
export class Crc64 {
|
||||
private static tableCache: {[key: string]: JSBI[]} = {};
|
||||
// ECMA 182 0xC96C5795D7870F42
|
||||
public static readonly ECMA_POLYNOMIAL = JSBI.BigInt("14514072000185962306");
|
||||
|
||||
private table: JSBI[];
|
||||
private crc: JSBI;
|
||||
public readonly polynom: JSBI;
|
||||
|
||||
constructor(poly: JSBI, table?: JSBI[]) {
|
||||
this.polynom = poly;
|
||||
if (table && Array.isArray(table)) {
|
||||
this.table = table;
|
||||
} else {
|
||||
this.table = Crc64.getCRC64Table(poly);
|
||||
}
|
||||
this.crc = JSBI.BigInt(0);
|
||||
}
|
||||
|
||||
public reset() {
|
||||
this.crc = JSBI.BigInt(0);
|
||||
}
|
||||
|
||||
public update(input: number[]) {
|
||||
for (let b of input) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public digest(): JSBI {
|
||||
return this.crc;
|
||||
}
|
||||
|
||||
public hexdigest(): string {
|
||||
return this.digest().toString(16);
|
||||
}
|
||||
private static makeTable(poly: JSBI): JSBI[] {
|
||||
let table: JSBI[] = [];
|
||||
for (let i = 0; i < 256; i++) {
|
||||
let crc: JSBI = JSBI.BigInt(i);
|
||||
for (let j = 0; j < 8; j++) {
|
||||
if (JSBI.EQ(JSBI.bitwiseAnd(crc, JSBI.BigInt(1)), 1)) {
|
||||
crc = JSBI.bitwiseXor(JSBI.signedRightShift(crc, JSBI.BigInt(1)), poly);
|
||||
} else {
|
||||
crc = JSBI.signedRightShift(crc, JSBI.BigInt(1));
|
||||
}
|
||||
}
|
||||
table.push(JSBI.asUintN(64, crc));
|
||||
}
|
||||
return table;
|
||||
}
|
||||
private static getCRC64Table(poly: JSBI) {
|
||||
const key = poly.toString(10);
|
||||
const val = Crc64.tableCache[key];
|
||||
if (val !== undefined && Array.isArray(val)) {
|
||||
return val;
|
||||
} else {
|
||||
const table = Crc64.makeTable(poly);
|
||||
// save only ECMA table
|
||||
if (JSBI.EQ(poly, Crc64.ECMA_POLYNOMIAL)) {
|
||||
Crc64.tableCache[key] = table;
|
||||
}
|
||||
return table;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* tslint:disable:no-shadowed-variable */
|
||||
export class Sha256 {
|
||||
private static readonly SHA256_CONSTANTS: number[] = [
|
||||
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
|
||||
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
|
||||
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
|
||||
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
|
||||
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
|
||||
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
|
||||
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
|
||||
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
|
||||
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
|
||||
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
|
||||
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
|
||||
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
|
||||
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
|
||||
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
|
||||
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
|
||||
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
|
||||
];
|
||||
|
||||
private static readonly SHA256_IV: number[] = [
|
||||
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
|
||||
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
|
||||
];
|
||||
|
||||
private state: number[];
|
||||
private data: number[];
|
||||
private bitlen: JSBI;
|
||||
private datalen: number;
|
||||
|
||||
constructor(input?: number[]) {
|
||||
this.bitlen = JSBI.BigInt(0);
|
||||
this.datalen = 0;
|
||||
this.data = new Array(64);
|
||||
this.state = Sha256.SHA256_IV.slice();
|
||||
|
||||
if (input && Array.isArray(input)) {
|
||||
this.update(input);
|
||||
}
|
||||
}
|
||||
|
||||
private transform() {
|
||||
// Maybe Uint8Array ?
|
||||
let m: number[] = new Array(64);
|
||||
|
||||
function ROTRIGHT(a: number, b: number): number {
|
||||
return (a >>> b) | (a << (32 - b));
|
||||
}
|
||||
function CH(a: number, b: number, c: number): number {
|
||||
return (a & b) ^ (~a & c);
|
||||
}
|
||||
function MAJ(a: number, b: number, c: number): number {
|
||||
return (a & b) ^ (a & c) ^ (b & c);
|
||||
}
|
||||
function EP0(a: number) {
|
||||
return ROTRIGHT(a, 2) ^ ROTRIGHT(a, 13) ^ ROTRIGHT(a, 22);
|
||||
}
|
||||
function EP1(a: number) {
|
||||
return ROTRIGHT(a, 6) ^ ROTRIGHT(a, 11) ^ ROTRIGHT(a, 25);
|
||||
}
|
||||
function SIG0(a: number): number {
|
||||
return ROTRIGHT(a, 7) ^ ROTRIGHT(a, 18) ^ (a >>> 3);
|
||||
}
|
||||
function SIG1(a: number): number {
|
||||
return ROTRIGHT(a, 17) ^ ROTRIGHT(a, 19) ^ (a >>> 10);
|
||||
}
|
||||
for (let i = 0, j = 0; i < 16; i++, j += 4) {
|
||||
m[i] = (this.data[j] << 24) | (this.data[j + 1] << 16) | (this.data[j + 2] << 8) |
|
||||
(this.data[j + 3]);
|
||||
}
|
||||
for (let i = 16; i < 64; i++) {
|
||||
m[i] = (SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]) >>> 0;
|
||||
}
|
||||
let [a, b, c, d, e, f, g, h] = this.state;
|
||||
for (let i = 0; i < 64; i++) {
|
||||
const t1 = h + EP1(e) + CH(e, f, g) + Sha256.SHA256_CONSTANTS[i] + m[i];
|
||||
const t2 = EP0(a) + MAJ(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = (d + t1) >>> 0;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = (t1 + t2) >>> 0;
|
||||
}
|
||||
this.state[0] += a;
|
||||
this.state[1] += b;
|
||||
this.state[2] += c;
|
||||
this.state[3] += d;
|
||||
this.state[4] += e;
|
||||
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[] {
|
||||
let i = this.datalen & 63;
|
||||
if (this.datalen < 56) {
|
||||
this.data[i++] = 0x80;
|
||||
while (i < 56) {
|
||||
this.data[i++] = 0;
|
||||
}
|
||||
} else {
|
||||
this.data[i++] = 0x80;
|
||||
while (i < 64) {
|
||||
this.data[i++] = 0;
|
||||
}
|
||||
this.transform();
|
||||
for (let i = 0; i < 56; i++) {
|
||||
this.data[i] = 0;
|
||||
}
|
||||
}
|
||||
this.bitlen = JSBI.add(this.bitlen, JSBI.BigInt(this.datalen * 8));
|
||||
for (let i = 63, j = 0; i >= 56; i--, j += 8) {
|
||||
// val = (this.bitlen >> j) & 0xFF
|
||||
const val = JSBI.asUintN(8, JSBI.signedRightShift(this.bitlen, JSBI.BigInt(j)));
|
||||
this.data[i] = JSBI.toNumber(val);
|
||||
}
|
||||
this.transform();
|
||||
let hash: number[] = new Array(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;
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
private copy(): Sha256 {
|
||||
let item = new Sha256();
|
||||
item.state = this.state.slice();
|
||||
item.data = this.data.slice();
|
||||
item.bitlen = this.bitlen;
|
||||
item.datalen = this.datalen;
|
||||
return item;
|
||||
}
|
||||
|
||||
public update(input: number[]) {
|
||||
for (let b of input) {
|
||||
this.data[this.datalen] = b;
|
||||
this.datalen++;
|
||||
|
||||
if (this.datalen >= 64) {
|
||||
this.transform();
|
||||
this.bitlen = JSBI.add(this.bitlen, JSBI.BigInt(512));
|
||||
this.datalen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public digest(): number[] {
|
||||
let item = this.copy();
|
||||
return item.final();
|
||||
}
|
||||
|
||||
public hexdigest() {
|
||||
return this.digest().map((x) => {
|
||||
x = x & 0xFF;
|
||||
return (x < 0xf) ? "0" + x.toString(16) : x.toString(16);
|
||||
}).join("");
|
||||
}
|
||||
}
|
||||
|
||||
export class AES128 {
|
||||
// AES128 ECB mode
|
||||
private static readonly NB = 4;
|
||||
private static readonly NK = 4;
|
||||
private static readonly NR = 10;
|
||||
|
||||
private static readonly sbox: number[] = [
|
||||
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,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
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[] = [
|
||||
0x8D, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A
|
||||
];
|
||||
|
||||
private roundKey: number[];
|
||||
|
||||
constructor(key: number[]) {
|
||||
this.roundKey = AES128.keyExpansion(key);
|
||||
}
|
||||
|
||||
public encryptBlock(input: number[]): number[] {
|
||||
if (input.length !== 16) {
|
||||
throw new Error("Invalid block length");
|
||||
}
|
||||
let state = input.slice();
|
||||
AES128.addRoundKey(0, state, this.roundKey);
|
||||
for (let round = 1; ; round++) {
|
||||
AES128.subBytes(state);
|
||||
AES128.shiftRows(state);
|
||||
if (round === 10) {
|
||||
break;
|
||||
}
|
||||
AES128.mixColumns(state);
|
||||
AES128.addRoundKey(round, state, this.roundKey);
|
||||
}
|
||||
AES128.addRoundKey(AES128.NR, state, this.roundKey);
|
||||
return state;
|
||||
}
|
||||
|
||||
private static keyExpansion(key: number[]): number[] {
|
||||
if (key.length !== 16) {
|
||||
throw new Error("Key should be 16 bytes");
|
||||
}
|
||||
|
||||
let roundKey = new Array(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);
|
||||
// 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;
|
||||
temp[0] = roundKey[k + 0];
|
||||
temp[1] = roundKey[k + 1];
|
||||
temp[2] = roundKey[k + 2];
|
||||
temp[3] = roundKey[k + 3];
|
||||
|
||||
if (i % AES128.NK === 0) {
|
||||
// AES RotWord()
|
||||
{
|
||||
const first = temp[0];
|
||||
temp[0] = temp[1];
|
||||
temp[1] = temp[2];
|
||||
temp[2] = temp[3];
|
||||
temp[3] = first;
|
||||
}
|
||||
// AES SubWord()
|
||||
{
|
||||
temp[0] = AES128.sbox[temp[0]];
|
||||
temp[1] = AES128.sbox[temp[1]];
|
||||
temp[2] = AES128.sbox[temp[2]];
|
||||
temp[3] = AES128.sbox[temp[3]];
|
||||
}
|
||||
|
||||
temp[0] ^= AES128.rcon[i / AES128.NK];
|
||||
}
|
||||
{
|
||||
const j = i * 4;
|
||||
const k = (i - AES128.NK) * 4;
|
||||
roundKey[j + 0] = roundKey[k + 0] ^ temp[0];
|
||||
roundKey[j + 1] = roundKey[k + 1] ^ temp[1];
|
||||
roundKey[j + 2] = roundKey[k + 2] ^ temp[2];
|
||||
roundKey[j + 3] = roundKey[k + 3] ^ temp[3];
|
||||
}
|
||||
}
|
||||
return roundKey;
|
||||
}
|
||||
|
||||
private static addRoundKey(round: number, state: number[], roundKey: number[]) {
|
||||
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];
|
||||
state[i * 4 + j] &= 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static subBytes(state: number[]) {
|
||||
for (let i = 0; i < 4; i++) {
|
||||
for (let j = 0; j < 4; j++) {
|
||||
state[j * 4 + i] = AES128.sbox[state[j * 4 + i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static shiftRows(state: number[]) {
|
||||
// rotate first row 1 columns to left
|
||||
let temp: number = state[0 * 4 + 1];
|
||||
state[0 * 4 + 1] = state[1 * 4 + 1];
|
||||
state[1 * 4 + 1] = state[2 * 4 + 1];
|
||||
state[2 * 4 + 1] = state[3 * 4 + 1];
|
||||
state[3 * 4 + 1] = temp;
|
||||
// rotate second row 2 columns to left
|
||||
temp = state[0 * 4 + 2];
|
||||
state[0 * 4 + 2] = state[2 * 4 + 2];
|
||||
state[2 * 4 + 2] = temp;
|
||||
temp = state[1 * 4 + 2];
|
||||
state[1 * 4 + 2] = state[3 * 4 + 2];
|
||||
state[3 * 4 + 2] = temp;
|
||||
// rotate thirdd row 3 columns to left
|
||||
temp = state[0 * 4 + 3];
|
||||
state[0 * 4 + 3] = state[3 * 4 + 3];
|
||||
state[3 * 4 + 3] = state[2 * 4 + 3];
|
||||
state[2 * 4 + 3] = state[1 * 4 + 3];
|
||||
state[1 * 4 + 3] = temp;
|
||||
}
|
||||
|
||||
private static mixColumns(state: number[]) {
|
||||
let tmp1: number;
|
||||
let tmp2: number;
|
||||
|
||||
function xtime(x: number): number {
|
||||
return (x << 1) ^ (((x >>> 7) & 1) * 0x1B);
|
||||
}
|
||||
|
||||
for (let i = 0; i < 4; i++) {
|
||||
const t = state[i * 4 + 0];
|
||||
tmp1 = state[i * 4 + 0] ^ state[i * 4 + 1] ^ state[i * 4 + 2] ^ state[i * 4 + 3];
|
||||
tmp2 = xtime(state[i * 4 + 0] ^ state[i * 4 + 1]);
|
||||
state[i * 4 + 0] ^= tmp2 ^ tmp1;
|
||||
tmp2 = xtime(state[i * 4 + 1] ^ state[i * 4 + 2]);
|
||||
state[i * 4 + 1] ^= tmp2 ^ tmp1;
|
||||
tmp2 = xtime(state[i * 4 + 2] ^ state[i * 4 + 3]);
|
||||
state[i * 4 + 2] ^= tmp2 ^ tmp1;
|
||||
tmp2 = xtime(state[i * 4 + 3] ^ t);
|
||||
state[i * 4 + 3] ^= tmp2 ^ tmp1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function insydeAcerSwitch(arr: number[]): number[] {
|
||||
if (arr.length !== 32) {
|
||||
throw new Error("Input array should have 32 length");
|
||||
}
|
||||
|
||||
function fun0(arr: number[]): number[] {
|
||||
let output: number[] = [];
|
||||
for (let i = 3; i >= 0; i--) {
|
||||
for (let j = 0; j < 16; j += 4 ) {
|
||||
output.push(arr[i + j]);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function fun1(arr: number[]): number[] {
|
||||
let output: number[] = [];
|
||||
for (let i = 0; i < 4; i++) {
|
||||
for (let j = 12; j >= 0; j -= 4) {
|
||||
output.push(arr[i + j]);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function fun2(arr: number[]): number[] {
|
||||
let output: number[] = [];
|
||||
for (let i = 0; i < 4; i++) {
|
||||
for (let j = 0; j < 4; j++) {
|
||||
output.push((arr[((j + i) & 3) + i * 4] + i) & 0xFF);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function fun3(arr: number[]): number[] {
|
||||
let output: number[] = [];
|
||||
let acc1 = 0;
|
||||
let acc2 = 0;
|
||||
for (let i = 0; i < 4; i++) {
|
||||
acc1 ^= arr[i * 5];
|
||||
acc2 ^= arr[i * 3 + 3];
|
||||
}
|
||||
for (let i = 0; i < 16; i++) {
|
||||
const pivot = ((i & 1) === 0) ? acc1 : acc2;
|
||||
output.push(arr[i] ^ pivot);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function fun4(arr: number[]): number[] {
|
||||
let output: number[] = [];
|
||||
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);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function fun5(arr: number[]): number[] {
|
||||
let output: number[] = new Array(16);
|
||||
for (let i = 0; i < 4; i++) {
|
||||
let acc: number = 0;
|
||||
for (let j = 0; j < 16; j += 4) {
|
||||
acc ^= arr[j + i];
|
||||
}
|
||||
for (let j = 0; j < 16; j += 4) {
|
||||
const temp = i + j;
|
||||
output[temp] = (arr[temp] * acc) & 0xFF;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function keyProcess(arr: number[]): number[] {
|
||||
let output: number[] = new Array(16);
|
||||
for (let i = 0; i < 16; i++) {
|
||||
let acc: number = 0;
|
||||
for (let j = 0; j < 8; j++) {
|
||||
acc += arr[((i >> 2) << 3) + j] * arr[j * 4 + (i & 3)];
|
||||
}
|
||||
output[i] = acc & 0xFF;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
const temp = keyProcess(arr);
|
||||
switch (arr[8] % 6) {
|
||||
case 0:
|
||||
return fun0(temp);
|
||||
case 1:
|
||||
return fun1(temp);
|
||||
case 2:
|
||||
return fun2(temp);
|
||||
case 3:
|
||||
return fun3(temp);
|
||||
case 4:
|
||||
return fun4(temp);
|
||||
default:
|
||||
return fun5(temp);
|
||||
}
|
||||
}
|
||||
|
||||
// 10 digits acer key
|
||||
export function acerInsydeKeygen(serial: string): string[] {
|
||||
// TODO: Uint8Array
|
||||
function rotatefun(arr: number[]): number[] {
|
||||
const idx = arr[9] & 0xF;
|
||||
let output: number[] = new Array(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 digest = (new Sha256(inputBytes)).digest();
|
||||
const key = insydeAcerSwitch(digest);
|
||||
const blockData = rotatefun(digest);
|
||||
const data = (new AES128(key)).encryptBlock(blockData);
|
||||
let crc = new Crc64(Crc64.ECMA_POLYNOMIAL);
|
||||
crc.update(data);
|
||||
return [crc.hexdigest()];
|
||||
}
|
||||
|
||||
/* tslint:disable:no-bitwise */
|
||||
function insydeKeygen(serial: string): string[] {
|
||||
const salt = "Iou|hj&Z";
|
||||
let password = "";
|
||||
@@ -31,3 +560,11 @@ export let insydeSolver = makeSolver({
|
||||
inputValidator: (s) => /^\d{8}$/i.test(s),
|
||||
fun: insydeKeygen
|
||||
});
|
||||
|
||||
export let acerInsyde10Solver = makeSolver({
|
||||
name: "acerInsyde10",
|
||||
description: "Acer Insyde 10 digits",
|
||||
examples: ["0173549286"],
|
||||
inputValidator: (s) => /^\d{10}$/i.test(s),
|
||||
fun: acerInsydeKeygen
|
||||
});
|
||||
@@ -1,3 +1,4 @@
|
||||
/* tslint:disable:no-var-requires */
|
||||
const JSBI = require("jsbi");
|
||||
import { modularPow, sony4x4Keygen, sony4x4Solver } from "./sony_4x4";
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// based on dogbert's pwgen-sony-4x4.py
|
||||
/* tslint:disable:no-bitwise */
|
||||
/* tslint:disable:no-var-requires */
|
||||
import type JSBIT from "jsbi";
|
||||
const JSBI = require("jsbi");
|
||||
type JSBI = JSBIT;
|
||||
|
||||
Reference in new issue
Block a user