PHP WebShell
Текущая директория: /opt/BitGoJS/node_modules/asmcrypto.js/src/aes/gcm
Просмотр файла: gcm.js
/**
* Galois/Counter mode
*/
import { IllegalArgumentError, IllegalStateError, SecurityError } from '../../errors';
import { _heap_write, is_bytes, is_number } from '../../utils';
import { AES } from '../aes';
import { AES_asm } from '../aes.asm';
var _AES_GCM_data_maxLength = 68719476704; // 2^36 - 2^5
export class AES_GCM extends AES {
constructor(key, nonce, adata, tagSize, heap, asm) {
super(key, undefined, false, heap, asm);
this.nonce = null;
this.adata = null;
this.iv = null;
this.counter = 1;
this.tagSize = 16;
this.mode = 'GCM';
this.BLOCK_SIZE = 16;
this.reset(key, tagSize, nonce, adata);
}
reset(key, tagSize, nonce, adata) {
return this.AES_GCM_reset(key, tagSize, nonce, adata);
}
encrypt(data) {
return this.AES_GCM_encrypt(data);
}
decrypt(data) {
return this.AES_GCM_decrypt(data);
}
AES_GCM_Encrypt_process(data) {
if (!is_bytes(data)) throw new TypeError("data isn't of expected type");
var dpos = 0,
dlen = data.length || 0,
asm = this.asm,
heap = this.heap,
counter = this.counter,
pos = this.pos,
len = this.len,
rpos = 0,
rlen = (len + dlen) & -16,
wlen = 0;
if (((counter - 1) << 4) + len + dlen > _AES_GCM_data_maxLength) throw new RangeError('counter overflow');
var result = new Uint8Array(rlen);
while (dlen > 0) {
wlen = _heap_write(heap, pos + len, data, dpos, dlen);
len += wlen;
dpos += wlen;
dlen -= wlen;
wlen = asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA + pos, len);
wlen = asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, wlen);
if (wlen) result.set(heap.subarray(pos, pos + wlen), rpos);
counter += wlen >>> 4;
rpos += wlen;
if (wlen < len) {
pos += wlen;
len -= wlen;
} else {
pos = 0;
len = 0;
}
}
this.result = result;
this.counter = counter;
this.pos = pos;
this.len = len;
return this;
}
AES_GCM_Encrypt_finish() {
var asm = this.asm,
heap = this.heap,
counter = this.counter,
tagSize = this.tagSize,
adata = this.adata,
pos = this.pos,
len = this.len;
var result = new Uint8Array(len + tagSize);
asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA + pos, (len + 15) & -16);
if (len) result.set(heap.subarray(pos, pos + len));
for (var i = len; i & 15; i++) heap[pos + i] = 0;
asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, i);
var alen = adata !== null ? adata.length : 0,
clen = ((counter - 1) << 4) + len;
(heap[0] = heap[1] = heap[2] = 0),
(heap[3] = alen >>> 29),
(heap[4] = alen >>> 21),
(heap[5] = (alen >>> 13) & 255),
(heap[6] = (alen >>> 5) & 255),
(heap[7] = (alen << 3) & 255),
(heap[8] = heap[9] = heap[10] = 0),
(heap[11] = clen >>> 29),
(heap[12] = (clen >>> 21) & 255),
(heap[13] = (clen >>> 13) & 255),
(heap[14] = (clen >>> 5) & 255),
(heap[15] = (clen << 3) & 255);
asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16);
asm.get_iv(AES_asm.HEAP_DATA);
asm.set_counter(0, 0, 0, this.gamma0);
asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA, 16);
result.set(heap.subarray(0, tagSize), len);
this.result = result;
this.counter = 1;
this.pos = 0;
this.len = 0;
return this;
}
AES_GCM_Decrypt_process(data) {
if (!is_bytes(data)) throw new TypeError("data isn't of expected type");
var dpos = 0,
dlen = data.length || 0,
asm = this.asm,
heap = this.heap,
counter = this.counter,
tagSize = this.tagSize,
pos = this.pos,
len = this.len,
rpos = 0,
rlen = len + dlen > tagSize ? (len + dlen - tagSize) & -16 : 0,
tlen = len + dlen - rlen,
wlen = 0;
if (((counter - 1) << 4) + len + dlen > _AES_GCM_data_maxLength) throw new RangeError('counter overflow');
var result = new Uint8Array(rlen);
while (dlen > tlen) {
wlen = _heap_write(heap, pos + len, data, dpos, dlen - tlen);
len += wlen;
dpos += wlen;
dlen -= wlen;
wlen = asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, wlen);
wlen = asm.cipher(AES_asm.DEC.CTR, AES_asm.HEAP_DATA + pos, wlen);
if (wlen) result.set(heap.subarray(pos, pos + wlen), rpos);
counter += wlen >>> 4;
rpos += wlen;
pos = 0;
len = 0;
}
if (dlen > 0) {
len += _heap_write(heap, 0, data, dpos, dlen);
}
this.result = result;
this.counter = counter;
this.pos = pos;
this.len = len;
return this;
}
AES_GCM_Decrypt_finish() {
var asm = this.asm,
heap = this.heap,
tagSize = this.tagSize,
adata = this.adata,
counter = this.counter,
pos = this.pos,
len = this.len,
rlen = len - tagSize,
wlen = 0;
if (len < tagSize) throw new IllegalStateError('authentication tag not found');
var result = new Uint8Array(rlen),
atag = new Uint8Array(heap.subarray(pos + rlen, pos + len));
for (var i = rlen; i & 15; i++) heap[pos + i] = 0;
wlen = asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, i);
wlen = asm.cipher(AES_asm.DEC.CTR, AES_asm.HEAP_DATA + pos, i);
if (rlen) result.set(heap.subarray(pos, pos + rlen));
var alen = adata !== null ? adata.length : 0,
clen = ((counter - 1) << 4) + len - tagSize;
(heap[0] = heap[1] = heap[2] = 0),
(heap[3] = alen >>> 29),
(heap[4] = alen >>> 21),
(heap[5] = (alen >>> 13) & 255),
(heap[6] = (alen >>> 5) & 255),
(heap[7] = (alen << 3) & 255),
(heap[8] = heap[9] = heap[10] = 0),
(heap[11] = clen >>> 29),
(heap[12] = (clen >>> 21) & 255),
(heap[13] = (clen >>> 13) & 255),
(heap[14] = (clen >>> 5) & 255),
(heap[15] = (clen << 3) & 255);
asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16);
asm.get_iv(AES_asm.HEAP_DATA);
asm.set_counter(0, 0, 0, this.gamma0);
asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA, 16);
var acheck = 0;
for (var i = 0; i < tagSize; ++i) acheck |= atag[i] ^ heap[i];
if (acheck) throw new SecurityError('data integrity check failed');
this.result = result;
this.counter = 1;
this.pos = 0;
this.len = 0;
return this;
}
AES_GCM_decrypt(data) {
var result1 = this.AES_GCM_Decrypt_process(data).result;
var result2 = this.AES_GCM_Decrypt_finish().result;
var result = new Uint8Array(result1.length + result2.length);
if (result1.length) result.set(result1);
if (result2.length) result.set(result2, result1.length);
this.result = result;
return this;
}
AES_GCM_encrypt(data) {
var result1 = this.AES_GCM_Encrypt_process(data).result;
var result2 = this.AES_GCM_Encrypt_finish().result;
var result = new Uint8Array(result1.length + result2.length);
if (result1.length) result.set(result1);
if (result2.length) result.set(result2, result1.length);
this.result = result;
return this;
}
AES_GCM_reset(key, tagSize, nonce, adata, counter, iv) {
this.AES_reset(key, undefined, false);
var asm = this.asm;
var heap = this.heap;
asm.gcm_init();
var tagSize = tagSize;
if (tagSize !== undefined) {
if (!is_number(tagSize)) throw new TypeError('tagSize must be a number');
if (tagSize < 4 || tagSize > 16) throw new IllegalArgumentError('illegal tagSize value');
this.tagSize = tagSize;
} else {
this.tagSize = 16;
}
if (nonce !== undefined) {
if (!is_bytes(nonce)) {
throw new TypeError('unexpected nonce type');
}
this.nonce = nonce;
var noncelen = nonce.length || 0,
noncebuf = new Uint8Array(16);
if (noncelen !== 12) {
this._gcm_mac_process(nonce);
(heap[0] = heap[1] = heap[2] = heap[3] = heap[4] = heap[5] = heap[6] = heap[7] = heap[8] = heap[9] = heap[10] = 0),
(heap[11] = noncelen >>> 29),
(heap[12] = (noncelen >>> 21) & 255),
(heap[13] = (noncelen >>> 13) & 255),
(heap[14] = (noncelen >>> 5) & 255),
(heap[15] = (noncelen << 3) & 255);
asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16);
asm.get_iv(AES_asm.HEAP_DATA);
asm.set_iv();
noncebuf.set(heap.subarray(0, 16));
} else {
noncebuf.set(nonce);
noncebuf[15] = 1;
}
var nonceview = new DataView(noncebuf.buffer);
this.gamma0 = nonceview.getUint32(12);
asm.set_nonce(nonceview.getUint32(0), nonceview.getUint32(4), nonceview.getUint32(8), 0);
asm.set_mask(0, 0, 0, 0xffffffff);
} else {
throw new Error('nonce is required');
}
if (adata !== undefined && adata !== null) {
if (!is_bytes(adata)) {
throw new TypeError('unexpected adata type');
}
if (adata.length > _AES_GCM_data_maxLength) throw new IllegalArgumentError('illegal adata length');
if (adata.length) {
this.adata = adata;
this._gcm_mac_process(adata);
} else {
this.adata = null;
}
} else {
this.adata = null;
}
if (counter !== undefined) {
if (!is_number(counter)) throw new TypeError('counter must be a number');
if (counter < 1 || counter > 0xffffffff) throw new RangeError('counter must be a positive 32-bit integer');
this.counter = counter;
asm.set_counter(0, 0, 0, (this.gamma0 + counter) | 0);
} else {
this.counter = 1;
asm.set_counter(0, 0, 0, (this.gamma0 + 1) | 0);
}
if (iv !== undefined) {
if (!is_number(iv)) throw new TypeError('iv must be a number');
this.iv = iv;
this.AES_set_iv(iv);
}
return this;
}
_gcm_mac_process(data) {
var heap = this.heap,
asm = this.asm,
dpos = 0,
dlen = data.length || 0,
wlen = 0;
while (dlen > 0) {
wlen = _heap_write(heap, 0, data, dpos, dlen);
dpos += wlen;
dlen -= wlen;
while (wlen & 15) heap[wlen++] = 0;
asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, wlen);
}
}
}
export class AES_GCM_Encrypt extends AES_GCM {
constructor(key, nonce, adata, tagSize, heap, asm) {
super(key, nonce, adata, tagSize, heap, asm);
}
process(data) {
return this.AES_GCM_Encrypt_process(data);
}
finish() {
return this.AES_GCM_Encrypt_finish();
}
}
export class AES_GCM_Decrypt extends AES_GCM {
constructor(key, nonce, adata, tagSize, heap, asm) {
super(key, nonce, adata, tagSize, heap, asm);
}
process(data) {
return this.AES_GCM_Decrypt_process(data);
}
finish() {
return this.AES_GCM_Decrypt_finish();
}
}
Выполнить команду
Для локальной разработки. Не используйте в интернете!