Add support for Dell E7A8 generator
This commit is contained in:
1 parent
6a67b69d22
commit
ee5f3a8d0d
10 files changed
+674
-497
No files matched your search
@@ -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
@@ -21,7 +21,7 @@ module.exports = function(config) {
|
||||
base: "SauceLabs",
|
||||
browserName: 'MicrosoftEdge',
|
||||
platform: 'Windows 10',
|
||||
version: '13.10586'
|
||||
version: '18.17763'
|
||||
},
|
||||
ChromeHeadlessTravis: {
|
||||
base: "ChromeHeadless",
|
||||
|
||||
@@ -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");
|
||||
});
|
||||
});
|
||||
@@ -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
@@ -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
@@ -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[] {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ export enum DellTag {
|
||||
Tag6FF1 = "6FF1",
|
||||
Tag1F66 = "1F66",
|
||||
Tag1F5A = "1F5A",
|
||||
TagBF97 = "BF97"
|
||||
TagBF97 = "BF97",
|
||||
TagE7A8 = "E7A8"
|
||||
}
|
||||
|
||||
export const enum SuffixType {
|
||||
|
||||
@@ -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
@@ -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");
|
||||
|
||||
Reference in new issue
Block a user