Add support for Dell E7A8 generator

This commit is contained in:
Slava Bacherikov committed 2021-12-15 14:53:41 +02:00
1 parent 6a67b69d22
commit ee5f3a8d0d
10 files changed
+674 -497

No files matched your search

+1 -1
View File
@@ -14,7 +14,7 @@ Latest released version available [here][bios-pw] and latest testing version (*s
* Asus — current BIOS date. For example: ``01-02-2013``
* Compaq — 5 decimal digits (*e.g*. ``12345``)
* Dell — supports such series: ``595B``, ``D35B``, ``2A7B``, ``A95B``, ``1D3B``, ``6FF1``, ``1F66``, ``1F5A`` and ``BF97``. *e.g*: ``1234567-2A7B`` or ``1234567890A-D35B`` for HDD.
* Dell — supports such series: ``595B``, ``D35B``, ``2A7B``, ``A95B``, ``1D3B``, ``6FF1``, ``1F66``, ``1F5A`` and ``BF97``, ``E7A8``. *e.g*: ``1234567-2A7B`` or ``1234567890A-D35B`` for HDD.
* Dell Insyde BIOS (Latitude 3540) — *e.g.* ``5F3988D5E0ACE4BF-7QH8602`` (``7QH8602`` — service tag).
* Fujitsu-Siemens — 5 decimal digits, 8 hexadecimal digits, 5x4 hexadecimal digits, 5x4 decimal digits
* Hewlett-Packard — 5 decimal digits, 10 characters
+1 -1
View File
@@ -21,7 +21,7 @@ module.exports = function(config) {
base: "SauceLabs",
browserName: 'MicrosoftEdge',
platform: 'Windows 10',
version: '13.10586'
version: '18.17763'
},
ChromeHeadlessTravis: {
base: "ChromeHeadless",
+43
View File
@@ -0,0 +1,43 @@
import { AES128, Crc64, Sha256 } from "./cryptoUtils";
describe("Crypto utils", () => {
it("sha256", () => {
expect(new Sha256(Uint8Array.from([])).hexdigest())
.toEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
expect(new Sha256(Uint8Array.from([1])).hexdigest())
.toEqual("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a");
expect(new Sha256(Uint8Array.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])).hexdigest())
.toEqual("c848e1013f9f04a9d63fa43ce7fd4af035152c7c669a4a404b67107cee5f2e4e");
expect(new Sha256(Uint8Array.from("test".split("").map((v) => v.charCodeAt(0)))).hexdigest())
.toEqual("9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08");
expect(new Sha256(Uint8Array.from("0".repeat(256).split("").map((v) => v.charCodeAt(0)))).hexdigest())
.toEqual("67f022195ee405142968ca1b53ae2513a8bab0404d70577785316fa95218e8ba");
expect(new Sha256(Uint8Array.from("0".repeat(56).split("").map((v) => v.charCodeAt(0)))).hexdigest())
.toEqual("bd03ac1428f0ea86f4b83a731ffc7967bb82866d8545322f888d2f6e857ffc18");
});
it("AES128", () => {
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(Uint8Array.from([52, 195, 59, 127, 20, 253, 83, 220, 234, 37, 224, 26, 2, 225, 103, 39]));
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);
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(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
expect(mycrc.hexdigest()).toEqual("fc232c18806871af");
});
});
+405
View File
@@ -0,0 +1,405 @@
/* tslint:disable:no-bitwise */
import JSBI from "jsbi";
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: 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);
}
}
public digest(): JSBI {
return this.crc;
}
public hexdigest(): string {
return ("0".repeat(16) + this.digest().toString(16)).slice(-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: Uint32Array = Uint32Array.from([
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: Uint32Array = Uint32Array.from([
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
]);
private state: Uint32Array;
private data: Uint8Array;
private bitlen: JSBI;
private datalen: number;
constructor(input?: Uint8Array) {
this.bitlen = JSBI.BigInt(0);
this.datalen = 0;
this.data = new Uint8Array(64);
this.state = Sha256.SHA256_IV.slice();
if (input && (input instanceof Uint8Array || Array.isArray(input))) {
this.update(input);
}
}
private transform() {
let m: Uint32Array = new Uint32Array(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;
}
private final(): Uint8Array {
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 = 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;
}
}
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: Uint8Array) {
/* 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++;
if (this.datalen >= 64) {
this.transform();
this.bitlen = JSBI.add(this.bitlen, JSBI.BigInt(512));
this.datalen = 0;
}
}
}
public digest(): Uint8Array {
let item = this.copy();
return item.final();
}
public hexdigest() {
return Array.from(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: 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,
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: Uint8Array = Uint8Array.from([
0x8D, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A
]);
private roundKey: Uint8Array;
constructor(key: Uint8Array) {
this.roundKey = AES128.keyExpansion(key);
}
public encryptBlock(input: Uint8Array): Uint8Array {
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: Uint8Array): Uint8Array {
if (key.length !== 16) {
throw new Error("Key should be 16 bytes");
}
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 = 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;
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: 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];
state[i * 4 + j] &= 0xFF;
}
}
}
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]];
}
}
}
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];
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: Uint8Array) {
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;
}
}
}
+69 -33
View File
@@ -123,143 +123,179 @@ describe("Test calculateSuffix", () => {
describe("Test keygenDell", () => {
it("Dell password for: 1234567-595B", () => {
expect(keygenDell("1234567", DellTag.Tag595B, SuffixType.ServiceTag))
.toEqual("46rg65ky");
.toEqual(["46rg65ky"]);
});
it("Dell password for: 1234567-D35B", () => {
expect(keygenDell("1234567", DellTag.TagD35B, SuffixType.ServiceTag))
.toEqual("5tc8q9re");
.toEqual(["5tc8q9re"]);
});
it("Dell password for: 1234567-2A7B", () => {
expect(keygenDell("1234567", DellTag.Tag2A7B, SuffixType.ServiceTag))
.toEqual("J1KuwWpSUgnDarfi");
.toEqual(["J1KuwWpSUgnDarfi"]);
});
it("Dell password for: 1234567-A95B", () => {
expect(keygenDell("1234567", DellTag.TagA95B, SuffixType.ServiceTag))
.toEqual("46rg65ky");
.toEqual(["46rg65ky"]);
});
it("Dell password for: 1234567-1D3B", () => {
expect(keygenDell("1234567", DellTag.Tag1D3B, SuffixType.ServiceTag))
.toEqual("Sn4fkF8bS57NymZl");
.toEqual(["Sn4fkF8bS57NymZl"]);
});
it("Dell password for: 1234567-1F66", () => {
expect(keygenDell("1234567", DellTag.Tag1F66, SuffixType.ServiceTag))
.toEqual("kIpTBzx0m3s10JDR");
.toEqual(["kIpTBzx0m3s10JDR"]);
});
it("Dell password for: 1234567-6FF1", () => {
expect(keygenDell("1234567", DellTag.Tag6FF1, SuffixType.ServiceTag))
.toEqual("Rzn1wGe555H5bM2r");
.toEqual(["Rzn1wGe555H5bM2r"]);
});
it("Dell password for: OPENSRC-1D3B", () => {
expect(keygenDell("OPENSRC", DellTag.Tag1D3B, SuffixType.ServiceTag))
.toEqual("S3yJ91q0Gar3O72I");
.toEqual(["S3yJ91q0Gar3O72I"]);
});
it("Dell password for: ABCDEFG-1D3B", () => {
expect(keygenDell("ABCDEFG", DellTag.Tag1D3B, SuffixType.ServiceTag))
.toEqual("xvn0qEeftqyrkG52");
.toEqual(["xvn0qEeftqyrkG52"]);
});
it("Dell password for: 7G9C0G2-6FF1", () => {
expect(keygenDell("7G9C0G2", DellTag.Tag6FF1, SuffixType.ServiceTag))
.toEqual("35c0b0tVb32Z6ivD");
.toEqual(["35c0b0tVb32Z6ivD"]);
});
it("Dell password for: DELLSUX-1F66", () => {
expect(keygenDell("DELLSUX", DellTag.Tag1F66, SuffixType.ServiceTag))
.toEqual("qHXaL0ntli6Gu4c0");
.toEqual(["qHXaL0ntli6Gu4c0"]);
});
it("Dell password for: CRPP562-1F66", () => {
expect(keygenDell("CRPP562", DellTag.Tag1F66, SuffixType.ServiceTag))
.toEqual("8i5qLGa9woA919Ys");
.toEqual(["8i5qLGa9woA919Ys"]);
});
it("Dell password for: CDG8T32-1F66", () => {
expect(keygenDell("CDG8T32", DellTag.Tag1F66, SuffixType.ServiceTag))
.toEqual("4Ke3y2L3kTP2f6Vo");
.toEqual(["4Ke3y2L3kTP2f6Vo"]);
});
it("Dell password for: 8M5RQ32-1F66", () => {
expect(keygenDell("8M5RQ32", DellTag.Tag1F66, SuffixType.ServiceTag))
.toEqual("3rlrbaSj46Iw221g"); });
.toEqual(["3rlrbaSj46Iw221g"]); });
it("Dell password for: 1234567-1F5A", () => {
expect(keygenDell("1234567", DellTag.Tag1F5A, SuffixType.ServiceTag))
.toEqual("2ls2b8GiP9H032kx");
.toEqual(["2ls2b8GiP9H032kx"]);
});
it("Dell password for: OPENSRC-1F5A", () => {
expect(keygenDell("OPENSRC", DellTag.Tag1F5A, SuffixType.ServiceTag))
.toEqual("ZC3j2t56eIe4Thgi");
.toEqual(["ZC3j2t56eIe4Thgi"]);
});
it("Dell password for: ABCDEFG-1F5A", () => {
expect(keygenDell("ABCDEFG", DellTag.Tag1F5A, SuffixType.ServiceTag))
.toEqual("x2zL5n7jj2Gl2TIh");
.toEqual(["x2zL5n7jj2Gl2TIh"]);
});
it("Dell password for: 1234567-BF97", () => {
expect(keygenDell("1234567", DellTag.TagBF97, SuffixType.ServiceTag))
.toEqual("2r09GZhU[r0kW2zr");
.toEqual(["2r09GZhU[r0kW2zr"]);
});
it("Dell password for: OPENSRC-BF97", () => {
expect(keygenDell("OPENSRC", DellTag.TagBF97, SuffixType.ServiceTag))
.toEqual("Dp29XkbyMrkBrp6Z");
.toEqual(["Dp29XkbyMrkBrp6Z"]);
});
it("Dell password for: ABCDEFG-BF97", () => {
expect(keygenDell("ABCDEFG", DellTag.TagBF97, SuffixType.ServiceTag))
.toEqual("kr9Z1cmPpahGzsQ[");
.toEqual(["kr9Z1cmPpahGzsQ["]);
});
it("Dell password for: DELLSUX-BF97", () => {
expect(keygenDell("DELLSUX", DellTag.TagBF97, SuffixType.ServiceTag))
.toEqual("rrNM2LrbD8nGsd2P");
.toEqual(["rrNM2LrbD8nGsd2P"]);
});
it("Dell password for: 1234567-E7A8", () => {
expect(keygenDell("1234567", DellTag.TagE7A8, SuffixType.ServiceTag).sort())
.toEqual(["Qk3LkU22kPeyq2jd", "rLIqjUy59IG2JU2R"].sort());
});
it("Dell password for: D875TG2-E7A8", () => {
expect(keygenDell("D875TG2", DellTag.TagE7A8, SuffixType.ServiceTag).sort())
.toEqual(["rLZc96rMZyGQ2GMG", "1Q6rxIWMGUznXZNy"].sort());
});
it("Dell password for: 2XSX273-E7A8", () => {
expect(keygenDell("2XSX273", DellTag.TagE7A8, SuffixType.ServiceTag).sort())
.toEqual(["rPQ0DGLdqckG2kUZ", "0ZaP6RzW9qk73rmq"].sort());
});
it("Dell password for: CZXKYX2-E7A8", () => {
expect(keygenDell("CZXKYX2", DellTag.TagE7A8, SuffixType.ServiceTag).sort())
.toEqual(["RGWD2BIR9UB9ZdIy", "38Gr7brmRGBPPIkz"].sort());
});
it("Dell password for: 6651WZ2-E7A8", () => {
expect(keygenDell("6651WZ2", DellTag.TagE7A8, SuffixType.ServiceTag).sort())
.toEqual(["PBjMMMsZUQR2MhmR", "Q1N6k2sLRkGGGrEN"].sort());
});
it("Dell password for: 9M2JTG2-E7A8", () => {
expect(keygenDell("9M2JTG2", DellTag.TagE7A8, SuffixType.ServiceTag))
.toContain("J2yR66N1kdn2N17m");
});
it("Dell password for: 1219P73-E7A8", () => {
expect(keygenDell("1219P73", DellTag.TagE7A8, SuffixType.ServiceTag))
.toContain("ksM02GskJ341hnDx");
});
// HDD
it("Dell HDD password for: 1234567890A-595B", () => {
expect(keygenDell("1234567890A", DellTag.Tag595B, SuffixType.HDD))
.toEqual("nyoap4lq");
.toEqual(["nyoap4lq"]);
});
it("Dell HDD password for: 1234567890A-D35B", () => {
expect(keygenDell("1234567890A", DellTag.TagD35B, SuffixType.HDD))
.toEqual("dc14blrd");
.toEqual(["dc14blrd"]);
});
it("Dell HDD password for: 1234567890A-2A7B", () => {
expect(keygenDell("1234567890A", DellTag.Tag2A7B, SuffixType.HDD))
.toEqual("h6lwdi91qluUyt3u");
.toEqual(["h6lwdi91qluUyt3u"]);
});
it("Dell HDD password for: 1234567890A-A95B", () => {
expect(keygenDell("1234567890A", DellTag.TagA95B, SuffixType.HDD))
.toEqual("qr0s6x4n");
.toEqual(["qr0s6x4n"]);
});
it("Dell HDD password for: 1234567890A-1D3B", () => {
expect(keygenDell("1234567890A", DellTag.Tag1D3B, SuffixType.HDD))
.toEqual("6JQ1WacHNNR0Taia");
.toEqual(["6JQ1WacHNNR0Taia"]);
});
it("Dell HDD password for: 1234567890A-1F66", () => {
expect(keygenDell("1234567890A", DellTag.Tag1F66, SuffixType.HDD))
.toEqual("vP0M31x066Z7Rq9p");
.toEqual(["vP0M31x066Z7Rq9p"]);
});
it("Dell HDD password for: 1234567890A-6FF1", () => {
expect(keygenDell("1234567890A", DellTag.Tag6FF1, SuffixType.HDD))
.toEqual("5enLLpM3Immfb8CK");
.toEqual(["5enLLpM3Immfb8CK"]);
});
it("Dell HDD password for: 1234567890A-1F5A", () => {
expect(keygenDell("1234567890A", DellTag.Tag1F5A, SuffixType.HDD))
.toEqual("L9IJjYoUIXeY5wOy");
.toEqual(["L9IJjYoUIXeY5wOy"]);
});
it("Dell HDD password for: 12345678901-1F5A", () => {
expect(keygenDell("12345678901", DellTag.Tag1F5A, SuffixType.HDD))
.toEqual("QwO5Dki1zeR1n1t2");
.toEqual(["QwO5Dki1zeR1n1t2"]);
});
it("Dell HDD password for: 12345678901-BF97", () => {
expect(keygenDell("12345678901", DellTag.TagBF97, SuffixType.HDD))
.toEqual("nDrmUU6U5DI9ZLMI");
.toEqual(["nDrmUU6U5DI9ZLMI"]);
});
it("Dell HDD password for: 1234567890A-BF97", () => {
expect(keygenDell("1234567890A", DellTag.TagBF97, SuffixType.HDD))
.toEqual("pRrky3r9ryEPNNJz");
.toEqual(["pRrky3r9ryEPNNJz"]);
});
it("Dell HDD password for: 234567890AB-BF97", () => {
expect(keygenDell("234567890AB", DellTag.TagBF97, SuffixType.HDD))
.toEqual("h2RDrReN37I1NLmr");
.toEqual(["h2RDrReN37I1NLmr"]);
});
it("Dell HDD password for: 1234567890A-E7A8", () => {
expect(keygenDell("1234567890A", DellTag.TagE7A8, SuffixType.HDD).sort())
.toEqual(["rN2rE2RBQh[X00yr", "G1bFzRGzjXIGzr22"].sort());
});
it("Dell HDD password for: 1234567890B-E7A8", () => {
expect(keygenDell("1234567890B", DellTag.TagE7A8, SuffixType.HDD).sort())
.toEqual(["Ic18yqyXXZI5Qj22", "kzzMazZrz53sRZJm"].sort());
});
});
+110 -8
View File
@@ -1,7 +1,7 @@
/* tslint:disable:no-bitwise */
import { DellTag } from "./types";
const md5magic = [
const md5magic = Uint32Array.from([
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
@@ -18,9 +18,9 @@ const md5magic = [
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
].map((v) => v | 0);
]);
const md5magic2 = [
const md5magic2 = Uint32Array.from([
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
@@ -37,7 +37,7 @@ const md5magic2 = [
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039
].map((v) => v | 0);
]);
const rotationTable = [
[7, 12, 17, 22],
@@ -115,17 +115,21 @@ class Tag595BEncoder {
protected f3: EncFunction = encF3;
protected f4: EncFunction = encF4N;
protected f5: EncFunction = encF5N;
protected md5table: number[] = md5magic;
protected readonly md5table: Uint32Array = md5magic;
constructor(encBlock: number[]) {
this.encBlock = encBlock;
this.encData = initialData.slice();
this.encData = this.initialData();
this.A = this.encData[0];
this.B = this.encData[1];
this.C = this.encData[2];
this.D = this.encData[3];
}
protected initialData(): number[] {
return initialData.slice();
}
protected calculate(func: EncFunction, key1: number, key2: number): number {
let temp = func(this.B, this.C, this.D);
return this.A + this.f1(temp, this.md5table[key2] + this.encBlock[key1]) | 0;
@@ -344,7 +348,7 @@ class Tag6FF1Encoder extends Tag595BEncoder {
}
class Tag1F5AEncoder extends Tag595BEncoder {
protected md5table = md5magic2;
protected readonly md5table = md5magic2;
protected incrementData() {
this.encData[0] += this.B;
@@ -396,6 +400,103 @@ class TagBF97Encoder extends Tag6FF1Encoder {
protected counter1 = 31;
}
export class TagE7A8Encoder extends Tag595BEncoder {
protected readonly md5table = md5magic2;
protected readonly loopParams = [17, 13, 12, 8];
protected readonly encodeParams = Uint32Array.from([
0x50501010, 0xA010908, 0xA08097, 0x60606161,
0x60606161, 0xA0008, 0x100097, 0x50501010
]);
protected initialData(): number[] {
return [0, 0, 0, 0];
}
private shortcut(fun: EncFunction, j: number, md5_index: number, rot_index: number, indexes: number[]): void {
for (let i = 0; i < 4; i++) {
const t = this.calculate(fun, (j + indexes[i]) & 7, i + md5_index);
this.A = this.D;
this.D = this.C;
this.C = this.B;
this.B = rol(t, rotationTable[rot_index][i]) + this.B | 0;
}
}
public makeEncode(): void {
for (let p = 0; p < this.loopParams[0]; p++) {
this.A |= this.encodeParams[0];
this.B ^= this.encodeParams[1];
this.C |= this.encodeParams[2] - p;
this.D ^= this.encodeParams[3] + p;
for (let j = 0; j < this.loopParams[2]; j += 4) {
this.shortcut(this.f2, j, j + 32, 0, [0, 1, 2, 3]);
}
for (let j = 0; j < this.loopParams[2]; j += 4) {
this.shortcut(this.f3, j, j, 1, [1, -2, -1, 0]);
}
for (let j = this.loopParams[3]; j > 3; j -= 4) {
this.shortcut(this.f4, j, j + 16, 2, [-3, -4, -1, 2]);
}
for (let j = this.loopParams[3]; j > 3 ; j -= 4) {
this.shortcut(this.f5, j, j + 48, 3, [2, 3, 2, -3]);
}
this.incrementData();
}
for (let p = 0; p < this.loopParams[1]; p++) {
this.A |= this.encodeParams[4];
this.B ^= this.encodeParams[5];
this.C |= this.encodeParams[6] - p;
this.D ^= this.encodeParams[7] + p;
for (let j = this.loopParams[3]; j > 3 ; j -= 4) {
this.shortcut(this.f4, j, j + 16, 2, [-3, -4, -1, 2]);
}
for (let j = 0; j < this.loopParams[2]; j += 4) {
this.shortcut(this.f5, j, j + 32, 3, [2, 3, 2, -3]);
}
for (let j = this.loopParams[3]; j > 0 ; j -= 4) {
this.shortcut(this.f2, j, j, 0, [0, 1, 2, 3]);
}
for (let j = 0; j < this.loopParams[2]; j += 4) {
this.shortcut(this.f3, j, j + 48, 1, [1, -2, 3, 0]);
}
this.incrementData();
}
}
}
export class TagE7A8EncoderSecond extends TagE7A8Encoder {
// this model has bug and it goes over the array limit
protected readonly md5table = (() => {
const overfillArr = [
0xa0008 ^ 0x6d2f93a5, 0xa08097 ^ 0x6d2f93a5, 0xa010908 ^ 0x6d2f93a5, 0x60606161 ^ 0x6d2f93a5
];
let arr = new Uint32Array(md5magic2.length + overfillArr.length);
arr.set(md5magic2);
arr.set(overfillArr, md5magic2.length);
return arr;
})()
protected readonly loopParams = [17, 13, 12, 16];
}
const encoders: {readonly [P in DellTag]: Encoder} = {
"595B": Tag595BEncoder,
"2A7B": Tag595BEncoder, // same as 595B
@@ -405,7 +506,8 @@ const encoders: {readonly [P in DellTag]: Encoder} = {
"1F66": Tag1F66Encoder,
"6FF1": Tag6FF1Encoder,
"1F5A": Tag1F5AEncoder,
"BF97": TagBF97Encoder
"BF97": TagBF97Encoder,
"E7A8": TagE7A8Encoder
};
export function blockEncode(encBlock: number[], tag: DellTag): number[] {
+40 -6
View File
@@ -1,9 +1,10 @@
/* tslint:disable:no-bitwise */
import { makeSolver } from "../utils";
import { blockEncode } from "./encode";
import { blockEncode, TagE7A8Encoder, TagE7A8EncoderSecond } from "./encode";
import { DES, latitude3540Keygen } from "./latitude";
import { DellTag, SuffixType } from "./types";
export { DellTag, SuffixType, DES, latitude3540Keygen };
import { Sha256 } from "../cryptoUtils";
const scanCodes: string =
"\0\x1B1234567890-=\x08\x09qwertyuiop[]\x0D\xFFasdfghjkl;'`\xFF\\zxcvbnm,./";
@@ -112,7 +113,7 @@ export function calculateSuffix(serial: number[], tag: DellTag, type: SuffixType
return suffix;
}
function resultToString(arr: number[], tag: DellTag): string {
function resultToString(arr: number[] | Uint8Array, tag: DellTag): string {
let r = arr[0] % 9;
let result = "";
let table = extraCharacters[tag];
@@ -130,7 +131,7 @@ function resultToString(arr: number[], tag: DellTag): string {
* serial -- serial number without tag, 7 symbols for ServiceTag, 11 symbols for HDD
* tag -- tag string
*/
export function keygenDell(serial: string, tag: DellTag, type: SuffixType): string {
export function keygenDell(serial: string, tag: DellTag, type: SuffixType): string[] {
let fullSerial: string;
function byteArrayToInt(arr: number[]): number[] {
@@ -157,6 +158,19 @@ export function keygenDell(serial: string, tag: DellTag, type: SuffixType): stri
return result;
}
function calculate_e7a8(block: number[], klass: any): string {
// TODO: refactor this
const table = "Q92G0drk9y63r5DG1hLqJGW1EnRk[QxrFMNZ328I6myLr4MsPNeZR2z72czpzUJBGXbaIjkZ";
const res = intArrayToByte(klass.encode(block));
const digest = new Sha256(Uint8Array.from(res));
const out = digest.digest();
let out_str = "";
for (let i = 0; i < 16; i++) {
out_str += table[(out[i + 16] + out[i]) % table.length];
}
return out_str;
}
if (tag === DellTag.TagA95B) {
if (type === SuffixType.ServiceTag) {
@@ -175,6 +189,25 @@ export function keygenDell(serial: string, tag: DellTag, type: SuffixType): stri
// Maybe protect against unicode symbols with: charCode & 0xFF ?
fullSerialArray.push(fullSerial.charCodeAt(i));
}
if (tag == DellTag.TagE7A8) {
// TODO: refactor all this
let encBlock = byteArrayToInt(fullSerialArray);
for (let i = 0; i < 16; i++) {
if (encBlock[i] === undefined) {
encBlock[i] = 0;
}
}
const out_str1 = calculate_e7a8(encBlock, TagE7A8Encoder);
const out_str2 = calculate_e7a8(encBlock, TagE7A8EncoderSecond);
let result = [];
if (out_str1) {
result.push(out_str1);
}
if (out_str2) {
result.push(out_str2);
}
return result;
}
fullSerialArray = fullSerialArray.concat(calculateSuffix(fullSerialArray, tag, type));
const cnt = 23;
@@ -189,7 +222,8 @@ export function keygenDell(serial: string, tag: DellTag, type: SuffixType): stri
}
encBlock[14] = cnt << 3;
let decodedBytes = intArrayToByte(blockEncode(encBlock, tag));
return resultToString(decodedBytes, tag);
const result = resultToString(decodedBytes, tag);
return (result) ? [result] : [];
}
function checkDellTag(tag: string): boolean {
@@ -223,7 +257,7 @@ export let dellSolver = makeSolver({
},
fun: (password: string) => {
let suffix = password.slice(7, 11).toUpperCase();
return [keygenDell(password.slice(0, 7), suffix as DellTag, SuffixType.ServiceTag)];
return keygenDell(password.slice(0, 7), suffix as DellTag, SuffixType.ServiceTag);
}
});
@@ -240,7 +274,7 @@ export let dellHddSolver = makeSolver({
},
fun: (password: string) => {
let suffix = password.slice(11, 15).toUpperCase();
return [keygenDell(password.slice(0, 11), suffix as DellTag, SuffixType.HDD)];
return keygenDell(password.slice(0, 11), suffix as DellTag, SuffixType.HDD);
}
});
+2 -1
View File
@@ -8,7 +8,8 @@ export enum DellTag {
Tag6FF1 = "6FF1",
Tag1F66 = "1F66",
Tag1F5A = "1F5A",
TagBF97 = "BF97"
TagBF97 = "BF97",
TagE7A8 = "E7A8"
}
export const enum SuffixType {
+1 -43
View File
@@ -1,4 +1,4 @@
import { acerInsyde10Solver, AES128, Crc64, hpInsydeSolver, insydeSolver, Sha256} from "./insyde";
import { acerInsyde10Solver, hpInsydeSolver, insydeSolver } from "./insyde";
describe("Insyde BIOS", () => {
it("Insyde key for 03133610 is 12891236", () => {
@@ -75,45 +75,3 @@ describe("HP Insyde [i \d{8}] codes", () => {
expect(hpInsydeSolver("i 511")).toEqual([]);
});
});
describe("Utils", () => {
it("sha256", () => {
expect(new Sha256(Uint8Array.from([])).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 = 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(Uint8Array.from([52, 195, 59, 127, 20, 253, 83, 220, 234, 37, 224, 26, 2, 225, 103, 39]));
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);
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(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
expect(mycrc.hexdigest()).toEqual("fc232c18806871af");
});
});
+2 -404
View File
@@ -1,415 +1,13 @@
/* tslint:disable:no-bitwise */
/* tslint:disable:no-var-requires */
/* tslint:disable:no-shadowed-variable */
/* Maybe need fixing for browsers where numbers is 32-bits */
/* Some Acer, HP laptops. 8 digit */
import JSBI from "jsbi";
import { makeSolver } from "./utils";
import { Crc64, Sha256, AES128 } from "./cryptoUtils";
const INSYDE_SALT = "Insyde Software Corp.";
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: 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);
}
}
public digest(): JSBI {
return this.crc;
}
public hexdigest(): string {
return ("0".repeat(16) + this.digest().toString(16)).slice(-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: Uint32Array = Uint32Array.from([
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: Uint32Array = Uint32Array.from([
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
]);
private state: Uint32Array;
private data: Uint8Array;
private bitlen: JSBI;
private datalen: number;
constructor(input?: Uint8Array | number[]) {
this.bitlen = JSBI.BigInt(0);
this.datalen = 0;
this.data = new Uint8Array(64);
this.state = Sha256.SHA256_IV.slice();
if (input && (input instanceof Uint8Array || Array.isArray(input))) {
this.update(input);
}
}
private transform() {
let m: Uint32Array = new Uint32Array(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;
}
private final(): Uint8Array {
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 = 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;
}
}
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: 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++;
if (this.datalen >= 64) {
this.transform();
this.bitlen = JSBI.add(this.bitlen, JSBI.BigInt(512));
this.datalen = 0;
}
}
}
public digest(): Uint8Array {
let item = this.copy();
return item.final();
}
public hexdigest() {
return Array.from(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: 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,
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: Uint8Array = Uint8Array.from([
0x8D, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A
]);
private roundKey: Uint8Array;
constructor(key: Uint8Array) {
this.roundKey = AES128.keyExpansion(key);
}
public encryptBlock(input: Uint8Array): Uint8Array {
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: Uint8Array): Uint8Array {
if (key.length !== 16) {
throw new Error("Key should be 16 bytes");
}
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 = 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;
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: 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];
state[i * 4 + j] &= 0xFF;
}
}
}
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]];
}
}
}
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];
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: Uint8Array) {
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: Uint8Array): Uint8Array {
if (arr.length !== 32) {
throw new Error("Input array should have 32 length");