summaryrefslogtreecommitdiff
path: root/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes
diff options
context:
space:
mode:
authorBartek Iwańczuk <biwanczuk@gmail.com>2023-02-14 17:38:45 +0100
committerGitHub <noreply@github.com>2023-02-14 17:38:45 +0100
commitd47147fb6ad229b1c039aff9d0959b6e281f4df5 (patch)
tree6e9e790f2b9bc71b5f0c9c7e64b95cae31579d58 /ext/node/polyfills/_crypto/crypto_browserify/browserify_aes
parent1d00bbe47e2ca14e2d2151518e02b2324461a065 (diff)
feat(ext/node): embed std/node into the snapshot (#17724)
This commit moves "deno_std/node" in "ext/node" crate. The code is transpiled and snapshotted during the build process. During the first pass a minimal amount of work was done to create the snapshot, a lot of code in "ext/node" depends on presence of "Deno" global. This code will be gradually fixed in the follow up PRs to migrate it to import relevant APIs from "internal:" modules. Currently the code from snapshot is not used in any way, and all Node/npm compatibility still uses code from "https://deno.land/std/node" (or from the location specified by "DENO_NODE_COMPAT_URL"). This will also be handled in a follow up PRs. --------- Co-authored-by: crowlkats <crowlkats@toaxl.com> Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com> Co-authored-by: Yoshiya Hinosawa <stibium121@gmail.com>
Diffstat (limited to 'ext/node/polyfills/_crypto/crypto_browserify/browserify_aes')
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/aes.js244
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/auth_cipher.js146
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/decrypter.js138
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/encrypter.js128
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/ghash.js96
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/incr32.js19
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/mod.js13
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cbc.js22
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb.js41
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb1.js47
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb8.js30
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ctr.js35
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ecb.js12
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/mod.js221
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ofb.js22
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/stream_cipher.js40
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/xor.ts17
17 files changed, 1271 insertions, 0 deletions
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/aes.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/aes.js
new file mode 100644
index 000000000..991b238fe
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/aes.js
@@ -0,0 +1,244 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+// based on the aes implimentation in triple sec
+// https://github.com/keybase/triplesec
+// which is in turn based on the one from crypto-js
+// https://code.google.com/p/crypto-js/
+
+// deno-lint-ignore-file no-var no-inner-declarations
+
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+
+function asUInt32Array(buf) {
+ if (!Buffer.isBuffer(buf)) buf = Buffer.from(buf);
+
+ var len = (buf.length / 4) | 0;
+ var out = new Array(len);
+
+ for (var i = 0; i < len; i++) {
+ out[i] = buf.readUInt32BE(i * 4);
+ }
+
+ return out;
+}
+
+function scrubVec(v) {
+ for (var i = 0; i < v.length; v++) {
+ v[i] = 0;
+ }
+}
+
+function cryptBlock(M, keySchedule, SUB_MIX, SBOX, nRounds) {
+ var SUB_MIX0 = SUB_MIX[0];
+ var SUB_MIX1 = SUB_MIX[1];
+ var SUB_MIX2 = SUB_MIX[2];
+ var SUB_MIX3 = SUB_MIX[3];
+
+ var s0 = M[0] ^ keySchedule[0];
+ var s1 = M[1] ^ keySchedule[1];
+ var s2 = M[2] ^ keySchedule[2];
+ var s3 = M[3] ^ keySchedule[3];
+ var t0, t1, t2, t3;
+ var ksRow = 4;
+
+ for (var round = 1; round < nRounds; round++) {
+ t0 = SUB_MIX0[s0 >>> 24] ^ SUB_MIX1[(s1 >>> 16) & 0xff] ^
+ SUB_MIX2[(s2 >>> 8) & 0xff] ^ SUB_MIX3[s3 & 0xff] ^ keySchedule[ksRow++];
+ t1 = SUB_MIX0[s1 >>> 24] ^ SUB_MIX1[(s2 >>> 16) & 0xff] ^
+ SUB_MIX2[(s3 >>> 8) & 0xff] ^ SUB_MIX3[s0 & 0xff] ^ keySchedule[ksRow++];
+ t2 = SUB_MIX0[s2 >>> 24] ^ SUB_MIX1[(s3 >>> 16) & 0xff] ^
+ SUB_MIX2[(s0 >>> 8) & 0xff] ^ SUB_MIX3[s1 & 0xff] ^ keySchedule[ksRow++];
+ t3 = SUB_MIX0[s3 >>> 24] ^ SUB_MIX1[(s0 >>> 16) & 0xff] ^
+ SUB_MIX2[(s1 >>> 8) & 0xff] ^ SUB_MIX3[s2 & 0xff] ^ keySchedule[ksRow++];
+ s0 = t0;
+ s1 = t1;
+ s2 = t2;
+ s3 = t3;
+ }
+
+ t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) |
+ (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++];
+ t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) |
+ (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++];
+ t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) |
+ (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++];
+ t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) |
+ (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++];
+ t0 = t0 >>> 0;
+ t1 = t1 >>> 0;
+ t2 = t2 >>> 0;
+ t3 = t3 >>> 0;
+
+ return [t0, t1, t2, t3];
+}
+
+// AES constants
+var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
+var G = (function () {
+ // Compute double table
+ var d = new Array(256);
+ for (var j = 0; j < 256; j++) {
+ if (j < 128) {
+ d[j] = j << 1;
+ } else {
+ d[j] = (j << 1) ^ 0x11b;
+ }
+ }
+
+ var SBOX = [];
+ var INV_SBOX = [];
+ var SUB_MIX = [[], [], [], []];
+ var INV_SUB_MIX = [[], [], [], []];
+
+ // Walk GF(2^8)
+ var x = 0;
+ var xi = 0;
+ for (var i = 0; i < 256; ++i) {
+ // Compute sbox
+ var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);
+ sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;
+ SBOX[x] = sx;
+ INV_SBOX[sx] = x;
+
+ // Compute multiplication
+ var x2 = d[x];
+ var x4 = d[x2];
+ var x8 = d[x4];
+
+ // Compute sub bytes, mix columns tables
+ var t = (d[sx] * 0x101) ^ (sx * 0x1010100);
+ SUB_MIX[0][x] = (t << 24) | (t >>> 8);
+ SUB_MIX[1][x] = (t << 16) | (t >>> 16);
+ SUB_MIX[2][x] = (t << 8) | (t >>> 24);
+ SUB_MIX[3][x] = t;
+
+ // Compute inv sub bytes, inv mix columns tables
+ t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);
+ INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8);
+ INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16);
+ INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24);
+ INV_SUB_MIX[3][sx] = t;
+
+ if (x === 0) {
+ x = xi = 1;
+ } else {
+ x = x2 ^ d[d[d[x8 ^ x2]]];
+ xi ^= d[d[xi]];
+ }
+ }
+
+ return {
+ SBOX: SBOX,
+ INV_SBOX: INV_SBOX,
+ SUB_MIX: SUB_MIX,
+ INV_SUB_MIX: INV_SUB_MIX,
+ };
+})();
+
+export function AES(key) {
+ this._key = asUInt32Array(key);
+ this._reset();
+}
+
+AES.blockSize = 4 * 4;
+AES.keySize = 256 / 8;
+AES.prototype.blockSize = AES.blockSize;
+AES.prototype.keySize = AES.keySize;
+AES.prototype._reset = function () {
+ var keyWords = this._key;
+ var keySize = keyWords.length;
+ var nRounds = keySize + 6;
+ var ksRows = (nRounds + 1) * 4;
+
+ var keySchedule = [];
+ for (var k = 0; k < keySize; k++) {
+ keySchedule[k] = keyWords[k];
+ }
+
+ for (k = keySize; k < ksRows; k++) {
+ var t = keySchedule[k - 1];
+
+ if (k % keySize === 0) {
+ t = (t << 8) | (t >>> 24);
+ t = (G.SBOX[t >>> 24] << 24) |
+ (G.SBOX[(t >>> 16) & 0xff] << 16) |
+ (G.SBOX[(t >>> 8) & 0xff] << 8) |
+ (G.SBOX[t & 0xff]);
+
+ t ^= RCON[(k / keySize) | 0] << 24;
+ } else if (keySize > 6 && k % keySize === 4) {
+ t = (G.SBOX[t >>> 24] << 24) |
+ (G.SBOX[(t >>> 16) & 0xff] << 16) |
+ (G.SBOX[(t >>> 8) & 0xff] << 8) |
+ (G.SBOX[t & 0xff]);
+ }
+
+ keySchedule[k] = keySchedule[k - keySize] ^ t;
+ }
+
+ var invKeySchedule = [];
+ for (var ik = 0; ik < ksRows; ik++) {
+ var ksR = ksRows - ik;
+ var tt = keySchedule[ksR - (ik % 4 ? 0 : 4)];
+
+ if (ik < 4 || ksR <= 4) {
+ invKeySchedule[ik] = tt;
+ } else {
+ invKeySchedule[ik] = G.INV_SUB_MIX[0][G.SBOX[tt >>> 24]] ^
+ G.INV_SUB_MIX[1][G.SBOX[(tt >>> 16) & 0xff]] ^
+ G.INV_SUB_MIX[2][G.SBOX[(tt >>> 8) & 0xff]] ^
+ G.INV_SUB_MIX[3][G.SBOX[tt & 0xff]];
+ }
+ }
+
+ this._nRounds = nRounds;
+ this._keySchedule = keySchedule;
+ this._invKeySchedule = invKeySchedule;
+};
+
+AES.prototype.encryptBlockRaw = function (M) {
+ M = asUInt32Array(M);
+ return cryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX, this._nRounds);
+};
+
+AES.prototype.encryptBlock = function (M) {
+ var out = this.encryptBlockRaw(M);
+ var buf = Buffer.allocUnsafe(16);
+ buf.writeUInt32BE(out[0], 0);
+ buf.writeUInt32BE(out[1], 4);
+ buf.writeUInt32BE(out[2], 8);
+ buf.writeUInt32BE(out[3], 12);
+ return buf;
+};
+
+AES.prototype.decryptBlock = function (M) {
+ M = asUInt32Array(M);
+
+ // swap
+ var m1 = M[1];
+ M[1] = M[3];
+ M[3] = m1;
+
+ var out = cryptBlock(
+ M,
+ this._invKeySchedule,
+ G.INV_SUB_MIX,
+ G.INV_SBOX,
+ this._nRounds,
+ );
+ var buf = Buffer.allocUnsafe(16);
+ buf.writeUInt32BE(out[0], 0);
+ buf.writeUInt32BE(out[3], 4);
+ buf.writeUInt32BE(out[2], 8);
+ buf.writeUInt32BE(out[1], 12);
+ return buf;
+};
+
+AES.prototype.scrub = function () {
+ scrubVec(this._keySchedule);
+ scrubVec(this._invKeySchedule);
+ scrubVec(this._key);
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/auth_cipher.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/auth_cipher.js
new file mode 100644
index 000000000..c4bd5ebe4
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/auth_cipher.js
@@ -0,0 +1,146 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+// deno-lint-ignore-file no-var no-inner-declarations
+
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+import * as aes from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/aes.js";
+import Transform from "internal:deno_node/polyfills/_crypto/crypto_browserify/cipher_base.js";
+import { GHASH } from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/ghash.js";
+import { xor } from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/xor.ts";
+import { incr32 } from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/incr32.js";
+
+function xorTest(a, b) {
+ var out = 0;
+ if (a.length !== b.length) out++;
+
+ var len = Math.min(a.length, b.length);
+ for (var i = 0; i < len; ++i) {
+ out += a[i] ^ b[i];
+ }
+
+ return out;
+}
+
+function calcIv(self, iv, ck) {
+ if (iv.length === 12) {
+ self._finID = Buffer.concat([iv, Buffer.from([0, 0, 0, 1])]);
+ return Buffer.concat([iv, Buffer.from([0, 0, 0, 2])]);
+ }
+ var ghash = new GHASH(ck);
+ var len = iv.length;
+ var toPad = len % 16;
+ ghash.update(iv);
+ if (toPad) {
+ toPad = 16 - toPad;
+ ghash.update(Buffer.alloc(toPad, 0));
+ }
+ ghash.update(Buffer.alloc(8, 0));
+ var ivBits = len * 8;
+ var tail = Buffer.alloc(8);
+ // Fixed from the original
+ // https://github.com/crypto-browserify/browserify-aes/issues/58#issuecomment-451778917
+ tail.writeUIntBE(ivBits, 2, 6);
+ ghash.update(tail);
+ self._finID = ghash.state;
+ var out = Buffer.from(self._finID);
+ incr32(out);
+ return out;
+}
+export function StreamCipher(mode, key, iv, decrypt) {
+ Transform.call(this);
+
+ var h = Buffer.alloc(4, 0);
+
+ this._cipher = new aes.AES(key);
+ var ck = this._cipher.encryptBlock(h);
+ this._ghash = new GHASH(ck);
+ iv = calcIv(this, iv, ck);
+
+ this._prev = Buffer.from(iv);
+ this._cache = Buffer.allocUnsafe(0);
+ this._secCache = Buffer.allocUnsafe(0);
+ this._decrypt = decrypt;
+ this._alen = 0;
+ this._len = 0;
+ this._mode = mode;
+
+ this._authTag = null;
+ this._called = false;
+}
+
+// StreamCipher inherts Transform
+StreamCipher.prototype = Object.create(Transform.prototype, {
+ constructor: {
+ value: StreamCipher,
+ enumerable: false,
+ writable: true,
+ configurable: true,
+ },
+});
+
+StreamCipher.prototype._update = function (chunk) {
+ if (!this._called && this._alen) {
+ var rump = 16 - (this._alen % 16);
+ if (rump < 16) {
+ rump = Buffer.alloc(rump, 0);
+ this._ghash.update(rump);
+ }
+ }
+
+ this._called = true;
+ var out = this._mode.encrypt(this, chunk);
+ if (this._decrypt) {
+ this._ghash.update(chunk);
+ } else {
+ this._ghash.update(out);
+ }
+ this._len += chunk.length;
+ return out;
+};
+
+StreamCipher.prototype._final = function () {
+ if (this._decrypt && !this._authTag) {
+ throw new Error("Unsupported state or unable to authenticate data");
+ }
+
+ var tag = xor(
+ this._ghash.final(this._alen * 8, this._len * 8),
+ this._cipher.encryptBlock(this._finID),
+ );
+ if (this._decrypt && xorTest(tag, this._authTag)) {
+ throw new Error("Unsupported state or unable to authenticate data");
+ }
+
+ this._authTag = tag;
+ this._cipher.scrub();
+};
+
+StreamCipher.prototype.getAuthTag = function getAuthTag() {
+ if (this._decrypt || !Buffer.isBuffer(this._authTag)) {
+ throw new Error("Attempting to get auth tag in unsupported state");
+ }
+
+ return this._authTag;
+};
+
+StreamCipher.prototype.setAuthTag = function setAuthTag(tag) {
+ if (!this._decrypt) {
+ throw new Error("Attempting to set auth tag in unsupported state");
+ }
+
+ this._authTag = tag;
+};
+
+StreamCipher.prototype.setAAD = function setAAD(buf) {
+ if (this._called) {
+ throw new Error("Attempting to set AAD in unsupported state");
+ }
+
+ this._ghash.update(buf);
+ this._alen += buf.length;
+};
+
+export default StreamCipher;
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/decrypter.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/decrypter.js
new file mode 100644
index 000000000..6a92a4574
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/decrypter.js
@@ -0,0 +1,138 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+// deno-lint-ignore-file no-var
+
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+import AuthCipher from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/auth_cipher.js";
+import StreamCipher from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/stream_cipher.js";
+import Transform from "internal:deno_node/polyfills/_crypto/crypto_browserify/cipher_base.js";
+import * as aes from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/aes.js";
+import ebtk from "internal:deno_node/polyfills/_crypto/crypto_browserify/evp_bytes_to_key.ts";
+import { MODES } from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/mod.js";
+
+function Decipher(mode, key, iv) {
+ Transform.call(this);
+
+ this._cache = new Splitter();
+ this._last = void 0;
+ this._cipher = new aes.AES(key);
+ this._prev = Buffer.from(iv);
+ this._mode = mode;
+ this._autopadding = true;
+}
+
+Decipher.prototype = Object.create(Transform.prototype, {
+ constructor: {
+ value: Decipher,
+ enumerable: false,
+ writable: true,
+ configurable: true,
+ },
+});
+
+Decipher.prototype._update = function (data) {
+ this._cache.add(data);
+ var chunk;
+ var thing;
+ var out = [];
+ while ((chunk = this._cache.get(this._autopadding))) {
+ thing = this._mode.decrypt(this, chunk);
+ out.push(thing);
+ }
+ return Buffer.concat(out);
+};
+
+Decipher.prototype._final = function () {
+ var chunk = this._cache.flush();
+ if (this._autopadding) {
+ return unpad(this._mode.decrypt(this, chunk));
+ } else if (chunk) {
+ throw new Error("data not multiple of block length");
+ }
+};
+
+Decipher.prototype.setAutoPadding = function (setTo) {
+ this._autopadding = !!setTo;
+ return this;
+};
+
+function Splitter() {
+ this.cache = Buffer.allocUnsafe(0);
+}
+
+Splitter.prototype.add = function (data) {
+ this.cache = Buffer.concat([this.cache, data]);
+};
+
+Splitter.prototype.get = function (autoPadding) {
+ var out;
+ if (autoPadding) {
+ if (this.cache.length > 16) {
+ out = this.cache.slice(0, 16);
+ this.cache = this.cache.slice(16);
+ return out;
+ }
+ } else {
+ if (this.cache.length >= 16) {
+ out = this.cache.slice(0, 16);
+ this.cache = this.cache.slice(16);
+ return out;
+ }
+ }
+
+ return null;
+};
+
+Splitter.prototype.flush = function () {
+ if (this.cache.length) return this.cache;
+};
+
+function unpad(last) {
+ var padded = last[15];
+ if (padded < 1 || padded > 16) {
+ throw new Error("unable to decrypt data");
+ }
+ var i = -1;
+ while (++i < padded) {
+ if (last[i + (16 - padded)] !== padded) {
+ throw new Error("unable to decrypt data");
+ }
+ }
+ if (padded === 16) return;
+
+ return last.slice(0, 16 - padded);
+}
+
+export function createDecipheriv(suite, password, iv) {
+ var config = MODES[suite.toLowerCase()];
+ if (!config) throw new TypeError("invalid suite type");
+
+ if (typeof iv === "string") iv = Buffer.from(iv);
+ if (config.mode !== "GCM" && iv.length !== config.iv) {
+ throw new TypeError("invalid iv length " + iv.length);
+ }
+
+ if (typeof password === "string") password = Buffer.from(password);
+ if (password.length !== config.key / 8) {
+ throw new TypeError("invalid key length " + password.length);
+ }
+
+ if (config.type === "stream") {
+ return new StreamCipher(config.module, password, iv, true);
+ } else if (config.type === "auth") {
+ return new AuthCipher(config.module, password, iv, true);
+ }
+
+ return new Decipher(config.module, password, iv);
+}
+
+export function createDecipher(suite, password) {
+ var config = MODES[suite.toLowerCase()];
+ if (!config) throw new TypeError("invalid suite type");
+
+ var keys = ebtk(password, false, config.key, config.iv);
+ return createDecipheriv(suite, keys.key, keys.iv);
+}
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/encrypter.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/encrypter.js
new file mode 100644
index 000000000..6a95a719c
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/encrypter.js
@@ -0,0 +1,128 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+// deno-lint-ignore-file no-var
+
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+import AuthCipher from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/auth_cipher.js";
+import StreamCipher from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/stream_cipher.js";
+import Transform from "internal:deno_node/polyfills/_crypto/crypto_browserify/cipher_base.js";
+import * as aes from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/aes.js";
+import ebtk from "internal:deno_node/polyfills/_crypto/crypto_browserify/evp_bytes_to_key.ts";
+import { MODES } from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/mod.js";
+
+function Cipher(mode, key, iv) {
+ Transform.call(this);
+
+ this._cache = new Splitter();
+ this._cipher = new aes.AES(key);
+ this._prev = Buffer.from(iv);
+ this._mode = mode;
+ this._autopadding = true;
+}
+
+Cipher.prototype = Object.create(Transform.prototype, {
+ constructor: {
+ value: Cipher,
+ enumerable: false,
+ writable: true,
+ configurable: true,
+ },
+});
+
+Cipher.prototype._update = function (data) {
+ this._cache.add(data);
+ var chunk;
+ var thing;
+ var out = [];
+
+ while ((chunk = this._cache.get())) {
+ thing = this._mode.encrypt(this, chunk);
+ out.push(thing);
+ }
+
+ return Buffer.concat(out);
+};
+
+var PADDING = Buffer.alloc(16, 0x10);
+
+Cipher.prototype._final = function () {
+ var chunk = this._cache.flush();
+ if (this._autopadding) {
+ chunk = this._mode.encrypt(this, chunk);
+ this._cipher.scrub();
+ return chunk;
+ }
+
+ if (!chunk.equals(PADDING)) {
+ this._cipher.scrub();
+ throw new Error("data not multiple of block length");
+ }
+};
+
+Cipher.prototype.setAutoPadding = function (setTo) {
+ this._autopadding = !!setTo;
+ return this;
+};
+
+function Splitter() {
+ this.cache = Buffer.allocUnsafe(0);
+}
+
+Splitter.prototype.add = function (data) {
+ this.cache = Buffer.concat([this.cache, data]);
+};
+
+Splitter.prototype.get = function () {
+ if (this.cache.length > 15) {
+ const out = this.cache.slice(0, 16);
+ this.cache = this.cache.slice(16);
+ return out;
+ }
+ return null;
+};
+
+Splitter.prototype.flush = function () {
+ var len = 16 - this.cache.length;
+ var padBuff = Buffer.allocUnsafe(len);
+
+ var i = -1;
+ while (++i < len) {
+ padBuff.writeUInt8(len, i);
+ }
+
+ return Buffer.concat([this.cache, padBuff]);
+};
+
+export function createCipheriv(suite, password, iv) {
+ var config = MODES[suite.toLowerCase()];
+ if (!config) throw new TypeError("invalid suite type");
+
+ if (typeof password === "string") password = Buffer.from(password);
+ if (password.length !== config.key / 8) {
+ throw new TypeError("invalid key length " + password.length);
+ }
+
+ if (typeof iv === "string") iv = Buffer.from(iv);
+ if (config.mode !== "GCM" && iv.length !== config.iv) {
+ throw new TypeError("invalid iv length " + iv.length);
+ }
+
+ if (config.type === "stream") {
+ return new StreamCipher(config.module, password, iv);
+ } else if (config.type === "auth") {
+ return new AuthCipher(config.module, password, iv);
+ }
+
+ return new Cipher(config.module, password, iv);
+}
+
+export function createCipher(suite, password) {
+ var config = MODES[suite.toLowerCase()];
+ if (!config) throw new TypeError("invalid suite type");
+
+ var keys = ebtk(password, false, config.key, config.iv);
+ return createCipheriv(suite, keys.key, keys.iv);
+}
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/ghash.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/ghash.js
new file mode 100644
index 000000000..ac896f921
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/ghash.js
@@ -0,0 +1,96 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+// Copyright 2009-2015, Emily Stark, Mike Hamburg and Dan Boneh at Stanford University. All rights reserved.
+
+// deno-lint-ignore-file no-var
+
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+
+var ZEROES = Buffer.alloc(16, 0);
+
+function toArray(buf) {
+ return [
+ buf.readUInt32BE(0),
+ buf.readUInt32BE(4),
+ buf.readUInt32BE(8),
+ buf.readUInt32BE(12),
+ ];
+}
+
+function fromArray(out) {
+ var buf = Buffer.allocUnsafe(16);
+ buf.writeUInt32BE(out[0] >>> 0, 0);
+ buf.writeUInt32BE(out[1] >>> 0, 4);
+ buf.writeUInt32BE(out[2] >>> 0, 8);
+ buf.writeUInt32BE(out[3] >>> 0, 12);
+ return buf;
+}
+
+export function GHASH(key) {
+ this.h = key;
+ this.state = Buffer.alloc(16, 0);
+ this.cache = Buffer.allocUnsafe(0);
+}
+
+// from http://bitwiseshiftleft.github.io/sjcl/doc/symbols/src/core_gcm.js.html
+// by Juho Vähä-Herttua
+GHASH.prototype.ghash = function (block) {
+ var i = -1;
+ while (++i < block.length) {
+ this.state[i] ^= block[i];
+ }
+ this._multiply();
+};
+
+GHASH.prototype._multiply = function () {
+ var Vi = toArray(this.h);
+ var Zi = [0, 0, 0, 0];
+ var j, xi, lsbVi;
+ var i = -1;
+ while (++i < 128) {
+ xi = (this.state[~~(i / 8)] & (1 << (7 - (i % 8)))) !== 0;
+ if (xi) {
+ // Z_i+1 = Z_i ^ V_i
+ Zi[0] ^= Vi[0];
+ Zi[1] ^= Vi[1];
+ Zi[2] ^= Vi[2];
+ Zi[3] ^= Vi[3];
+ }
+
+ // Store the value of LSB(V_i)
+ lsbVi = (Vi[3] & 1) !== 0;
+
+ // V_i+1 = V_i >> 1
+ for (j = 3; j > 0; j--) {
+ Vi[j] = (Vi[j] >>> 1) | ((Vi[j - 1] & 1) << 31);
+ }
+ Vi[0] = Vi[0] >>> 1;
+
+ // If LSB(V_i) is 1, V_i+1 = (V_i >> 1) ^ R
+ if (lsbVi) {
+ Vi[0] = Vi[0] ^ (0xe1 << 24);
+ }
+ }
+ this.state = fromArray(Zi);
+};
+
+GHASH.prototype.update = function (buf) {
+ this.cache = Buffer.concat([this.cache, buf]);
+ var chunk;
+ while (this.cache.length >= 16) {
+ chunk = this.cache.slice(0, 16);
+ this.cache = this.cache.slice(16);
+ this.ghash(chunk);
+ }
+};
+
+GHASH.prototype.final = function (abl, bl) {
+ if (this.cache.length) {
+ this.ghash(Buffer.concat([this.cache, ZEROES], 16));
+ }
+
+ this.ghash(fromArray([0, abl, 0, bl]));
+ return this.state;
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/incr32.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/incr32.js
new file mode 100644
index 000000000..65172eefb
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/incr32.js
@@ -0,0 +1,19 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+export function incr32(iv) {
+ let len = iv.length;
+ let item;
+ while (len--) {
+ item = iv.readUInt8(len);
+ if (item === 255) {
+ iv.writeUInt8(0, len);
+ } else {
+ item++;
+ iv.writeUInt8(item, len);
+ break;
+ }
+ }
+}
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/mod.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/mod.js
new file mode 100644
index 000000000..abf5bde5f
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/mod.js
@@ -0,0 +1,13 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+import { MODES } from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/mod.js";
+
+export * from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/encrypter.js";
+export * from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/decrypter.js";
+
+export function getCiphers() {
+ return Object.keys(MODES);
+}
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cbc.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cbc.js
new file mode 100644
index 000000000..837adf32f
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cbc.js
@@ -0,0 +1,22 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+import { xor } from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/xor.ts";
+
+export const encrypt = function (self, block) {
+ const data = xor(block, self._prev);
+
+ self._prev = self._cipher.encryptBlock(data);
+ return self._prev;
+};
+
+export const decrypt = function (self, block) {
+ const pad = self._prev;
+
+ self._prev = block;
+ const out = self._cipher.decryptBlock(block);
+
+ return xor(out, pad);
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb.js
new file mode 100644
index 000000000..8bfd81463
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb.js
@@ -0,0 +1,41 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+import { xor } from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/xor.ts";
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+
+function encryptStart(self, data, decrypt) {
+ const len = data.length;
+ const out = xor(data, self._cache);
+ self._cache = self._cache.slice(len);
+ self._prev = Buffer.concat([self._prev, decrypt ? data : out]);
+ return out;
+}
+
+export const encrypt = function (self, data, decrypt) {
+ let out = Buffer.allocUnsafe(0);
+ let len;
+
+ while (data.length) {
+ if (self._cache.length === 0) {
+ self._cache = self._cipher.encryptBlock(self._prev);
+ self._prev = Buffer.allocUnsafe(0);
+ }
+
+ if (self._cache.length <= data.length) {
+ len = self._cache.length;
+ out = Buffer.concat([
+ out,
+ encryptStart(self, data.slice(0, len), decrypt),
+ ]);
+ data = data.slice(len);
+ } else {
+ out = Buffer.concat([out, encryptStart(self, data, decrypt)]);
+ break;
+ }
+ }
+
+ return out;
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb1.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb1.js
new file mode 100644
index 000000000..2af8824f0
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb1.js
@@ -0,0 +1,47 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+
+function encryptByte(self, byteParam, decrypt) {
+ let pad;
+ let i = -1;
+ const len = 8;
+ let out = 0;
+ let bit, value;
+ while (++i < len) {
+ pad = self._cipher.encryptBlock(self._prev);
+ bit = (byteParam & (1 << (7 - i))) ? 0x80 : 0;
+ value = pad[0] ^ bit;
+ out += (value & 0x80) >> (i % 8);
+ self._prev = shiftIn(self._prev, decrypt ? bit : value);
+ }
+ return out;
+}
+
+function shiftIn(buffer, value) {
+ const len = buffer.length;
+ let i = -1;
+ const out = Buffer.allocUnsafe(buffer.length);
+ buffer = Buffer.concat([buffer, Buffer.from([value])]);
+
+ while (++i < len) {
+ out[i] = buffer[i] << 1 | buffer[i + 1] >> (7);
+ }
+
+ return out;
+}
+
+export const encrypt = function (self, chunk, decrypt) {
+ const len = chunk.length;
+ const out = Buffer.allocUnsafe(len);
+ let i = -1;
+
+ while (++i < len) {
+ out[i] = encryptByte(self, chunk[i], decrypt);
+ }
+
+ return out;
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb8.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb8.js
new file mode 100644
index 000000000..262494a81
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb8.js
@@ -0,0 +1,30 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+
+function encryptByte(self, byteParam, decrypt) {
+ const pad = self._cipher.encryptBlock(self._prev);
+ const out = pad[0] ^ byteParam;
+
+ self._prev = Buffer.concat([
+ self._prev.slice(1),
+ Buffer.from([decrypt ? byteParam : out]),
+ ]);
+
+ return out;
+}
+
+export const encrypt = function (self, chunk, decrypt) {
+ const len = chunk.length;
+ const out = Buffer.allocUnsafe(len);
+ let i = -1;
+
+ while (++i < len) {
+ out[i] = encryptByte(self, chunk[i], decrypt);
+ }
+
+ return out;
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ctr.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ctr.js
new file mode 100644
index 000000000..fd1781ab2
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ctr.js
@@ -0,0 +1,35 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+import { xor } from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/xor.ts";
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+import { incr32 } from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/incr32.js";
+
+function getBlock(self) {
+ const out = self._cipher.encryptBlockRaw(self._prev);
+ incr32(self._prev);
+ return out;
+}
+
+const blockSize = 16;
+export const encrypt = function (self, chunk) {
+ const chunkNum = Math.ceil(chunk.length / blockSize);
+ const start = self._cache.length;
+ self._cache = Buffer.concat([
+ self._cache,
+ Buffer.allocUnsafe(chunkNum * blockSize),
+ ]);
+ for (let i = 0; i < chunkNum; i++) {
+ const out = getBlock(self);
+ const offset = start + i * blockSize;
+ self._cache.writeUInt32BE(out[0], offset + 0);
+ self._cache.writeUInt32BE(out[1], offset + 4);
+ self._cache.writeUInt32BE(out[2], offset + 8);
+ self._cache.writeUInt32BE(out[3], offset + 12);
+ }
+ const pad = self._cache.slice(0, chunk.length);
+ self._cache = self._cache.slice(chunk.length);
+ return xor(chunk, pad);
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ecb.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ecb.js
new file mode 100644
index 000000000..b4f99cffb
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ecb.js
@@ -0,0 +1,12 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+export const encrypt = function (self, block) {
+ return self._cipher.encryptBlock(block);
+};
+
+export const decrypt = function (self, block) {
+ return self._cipher.decryptBlock(block);
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/mod.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/mod.js
new file mode 100644
index 000000000..b30ed0b25
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/mod.js
@@ -0,0 +1,221 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+import * as ECB from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ecb.js";
+import * as CBC from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cbc.js";
+import * as CFB from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb.js";
+import * as CFB8 from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb8.js";
+import * as CFB1 from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/cfb1.js";
+import * as OFB from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ofb.js";
+import * as CTR from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ctr.js";
+
+const GCM = CTR;
+
+const modeModules = {
+ ECB,
+ CBC,
+ CFB,
+ CFB8,
+ CFB1,
+ OFB,
+ CTR,
+ GCM,
+};
+
+export const MODES = {
+ "aes-128-ecb": {
+ "cipher": "AES",
+ "key": 128,
+ "iv": 0,
+ "mode": "ECB",
+ "type": "block",
+ },
+ "aes-192-ecb": {
+ "cipher": "AES",
+ "key": 192,
+ "iv": 0,
+ "mode": "ECB",
+ "type": "block",
+ },
+ "aes-256-ecb": {
+ "cipher": "AES",
+ "key": 256,
+ "iv": 0,
+ "mode": "ECB",
+ "type": "block",
+ },
+ "aes-128-cbc": {
+ "cipher": "AES",
+ "key": 128,
+ "iv": 16,
+ "mode": "CBC",
+ "type": "block",
+ },
+ "aes-192-cbc": {
+ "cipher": "AES",
+ "key": 192,
+ "iv": 16,
+ "mode": "CBC",
+ "type": "block",
+ },
+ "aes-256-cbc": {
+ "cipher": "AES",
+ "key": 256,
+ "iv": 16,
+ "mode": "CBC",
+ "type": "block",
+ },
+ "aes128": {
+ "cipher": "AES",
+ "key": 128,
+ "iv": 16,
+ "mode": "CBC",
+ "type": "block",
+ },
+ "aes192": {
+ "cipher": "AES",
+ "key": 192,
+ "iv": 16,
+ "mode": "CBC",
+ "type": "block",
+ },
+ "aes256": {
+ "cipher": "AES",
+ "key": 256,
+ "iv": 16,
+ "mode": "CBC",
+ "type": "block",
+ },
+ "aes-128-cfb": {
+ "cipher": "AES",
+ "key": 128,
+ "iv": 16,
+ "mode": "CFB",
+ "type": "stream",
+ },
+ "aes-192-cfb": {
+ "cipher": "AES",
+ "key": 192,
+ "iv": 16,
+ "mode": "CFB",
+ "type": "stream",
+ },
+ "aes-256-cfb": {
+ "cipher": "AES",
+ "key": 256,
+ "iv": 16,
+ "mode": "CFB",
+ "type": "stream",
+ },
+ "aes-128-cfb8": {
+ "cipher": "AES",
+ "key": 128,
+ "iv": 16,
+ "mode": "CFB8",
+ "type": "stream",
+ },
+ "aes-192-cfb8": {
+ "cipher": "AES",
+ "key": 192,
+ "iv": 16,
+ "mode": "CFB8",
+ "type": "stream",
+ },
+ "aes-256-cfb8": {
+ "cipher": "AES",
+ "key": 256,
+ "iv": 16,
+ "mode": "CFB8",
+ "type": "stream",
+ },
+ "aes-128-cfb1": {
+ "cipher": "AES",
+ "key": 128,
+ "iv": 16,
+ "mode": "CFB1",
+ "type": "stream",
+ },
+ "aes-192-cfb1": {
+ "cipher": "AES",
+ "key": 192,
+ "iv": 16,
+ "mode": "CFB1",
+ "type": "stream",
+ },
+ "aes-256-cfb1": {
+ "cipher": "AES",
+ "key": 256,
+ "iv": 16,
+ "mode": "CFB1",
+ "type": "stream",
+ },
+ "aes-128-ofb": {
+ "cipher": "AES",
+ "key": 128,
+ "iv": 16,
+ "mode": "OFB",
+ "type": "stream",
+ },
+ "aes-192-ofb": {
+ "cipher": "AES",
+ "key": 192,
+ "iv": 16,
+ "mode": "OFB",
+ "type": "stream",
+ },
+ "aes-256-ofb": {
+ "cipher": "AES",
+ "key": 256,
+ "iv": 16,
+ "mode": "OFB",
+ "type": "stream",
+ },
+ "aes-128-ctr": {
+ "cipher": "AES",
+ "key": 128,
+ "iv": 16,
+ "mode": "CTR",
+ "type": "stream",
+ },
+ "aes-192-ctr": {
+ "cipher": "AES",
+ "key": 192,
+ "iv": 16,
+ "mode": "CTR",
+ "type": "stream",
+ },
+ "aes-256-ctr": {
+ "cipher": "AES",
+ "key": 256,
+ "iv": 16,
+ "mode": "CTR",
+ "type": "stream",
+ },
+ "aes-128-gcm": {
+ "cipher": "AES",
+ "key": 128,
+ "iv": 12,
+ "mode": "GCM",
+ "type": "auth",
+ },
+ "aes-192-gcm": {
+ "cipher": "AES",
+ "key": 192,
+ "iv": 12,
+ "mode": "GCM",
+ "type": "auth",
+ },
+ "aes-256-gcm": {
+ "cipher": "AES",
+ "key": 256,
+ "iv": 12,
+ "mode": "GCM",
+ "type": "auth",
+ },
+};
+
+for (const mode of Object.values(MODES)) {
+ mode.module = modeModules[mode.mode];
+}
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ofb.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ofb.js
new file mode 100644
index 000000000..20ccdf015
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/modes/ofb.js
@@ -0,0 +1,22 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+import { xor } from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/xor.ts";
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+
+function getBlock(self) {
+ self._prev = self._cipher.encryptBlock(self._prev);
+ return self._prev;
+}
+
+export const encrypt = function (self, chunk) {
+ while (self._cache.length < chunk.length) {
+ self._cache = Buffer.concat([self._cache, getBlock(self)]);
+ }
+
+ const pad = self._cache.slice(0, chunk.length);
+ self._cache = self._cache.slice(chunk.length);
+ return xor(chunk, pad);
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/stream_cipher.js b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/stream_cipher.js
new file mode 100644
index 000000000..432730f91
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/stream_cipher.js
@@ -0,0 +1,40 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+
+import * as aes from "internal:deno_node/polyfills/_crypto/crypto_browserify/browserify_aes/aes.js";
+import Transform from "internal:deno_node/polyfills/_crypto/crypto_browserify/cipher_base.js";
+
+export function StreamCipher(mode, key, iv, decrypt) {
+ Transform.call(this);
+
+ this._cipher = new aes.AES(key);
+ this._prev = Buffer.from(iv);
+ this._cache = Buffer.allocUnsafe(0);
+ this._secCache = Buffer.allocUnsafe(0);
+ this._decrypt = decrypt;
+ this._mode = mode;
+}
+
+// StreamCipher inherits Transform
+StreamCipher.prototype = Object.create(Transform.prototype, {
+ constructor: {
+ value: StreamCipher,
+ enumerable: false,
+ writable: true,
+ configurable: true,
+ },
+});
+
+StreamCipher.prototype._update = function (chunk) {
+ return this._mode.encrypt(this, chunk, this._decrypt);
+};
+
+StreamCipher.prototype._final = function () {
+ this._cipher.scrub();
+};
+
+export default StreamCipher;
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/xor.ts b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/xor.ts
new file mode 100644
index 000000000..6b9327ebc
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/browserify_aes/xor.ts
@@ -0,0 +1,17 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2014-2017 browserify-aes contributors. All rights reserved. MIT license.
+// Copyright 2013 Maxwell Krohn. All rights reserved. MIT license.
+// Copyright 2009-2013 Jeff Mott. All rights reserved. MIT license.
+
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+
+export function xor(a: Buffer, b: Buffer): Buffer {
+ const length = Math.min(a.length, b.length);
+ const buffer = Buffer.allocUnsafe(length);
+
+ for (let i = 0; i < length; ++i) {
+ buffer[i] = a[i] ^ b[i];
+ }
+
+ return buffer;
+}