From e48e5c03a1ccc22e9629f52a43b9339ac857ab1d Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Fri, 5 Sep 2025 08:36:26 +0200 Subject: [PATCH 1/4] lib: prefer TypedArrayPrototype primordials Refs: #59699 --- lib/internal/crypto/argon2.js | 3 ++- lib/internal/crypto/diffiehellman.js | 3 ++- lib/internal/crypto/ml_dsa.js | 20 +++++++++++--------- lib/internal/crypto/ml_kem.js | 28 +++++++++++++++++----------- lib/internal/crypto/pbkdf2.js | 3 ++- lib/internal/crypto/random.js | 5 +++-- lib/internal/crypto/webcrypto.js | 5 +++-- 7 files changed, 40 insertions(+), 27 deletions(-) diff --git a/lib/internal/crypto/argon2.js b/lib/internal/crypto/argon2.js index 3ae009e04a3302..1d2b8b7cac91e9 100644 --- a/lib/internal/crypto/argon2.js +++ b/lib/internal/crypto/argon2.js @@ -4,6 +4,7 @@ const { FunctionPrototypeCall, MathPow, StringPrototypeToLowerCase, + TypedArrayPrototypeGetBuffer, Uint8Array, } = primordials; @@ -231,7 +232,7 @@ async function argon2DeriveBits(algorithm, baseKey, length) { { name: 'OperationError', cause: err }); } - return result.buffer; + return TypedArrayPrototypeGetBuffer(result); } module.exports = { diff --git a/lib/internal/crypto/diffiehellman.js b/lib/internal/crypto/diffiehellman.js index b6ba8cfc78541e..58e2bc0c91ec3c 100644 --- a/lib/internal/crypto/diffiehellman.js +++ b/lib/internal/crypto/diffiehellman.js @@ -6,6 +6,7 @@ const { MathCeil, ObjectDefineProperty, SafeSet, + TypedArrayPrototypeGetBuffer, Uint8Array, } = primordials; @@ -377,7 +378,7 @@ async function ecdhDeriveBits(algorithm, baseKey, length) { const masked = new Uint8Array(slice); masked[sliceLength - 1] = masked[sliceLength - 1] & masks[mod]; - return masked.buffer; + return TypedArrayPrototypeGetBuffer(masked); } module.exports = { diff --git a/lib/internal/crypto/ml_dsa.js b/lib/internal/crypto/ml_dsa.js index 966f5b0d222fd0..779977a12a5adb 100644 --- a/lib/internal/crypto/ml_dsa.js +++ b/lib/internal/crypto/ml_dsa.js @@ -2,6 +2,8 @@ const { SafeSet, + TypedArrayPrototypeGetBuffer, + TypedArrayPrototypeSet, Uint8Array, } = primordials; @@ -119,35 +121,35 @@ function mlDsaExportKey(key, format) { switch (format) { case kWebCryptoKeyFormatRaw: { if (key[kKeyType] === 'private') { - return key[kKeyObject][kHandle].rawSeed().buffer; + return TypedArrayPrototypeGetBuffer(key[kKeyObject][kHandle].rawSeed()); } - return key[kKeyObject][kHandle].rawPublicKey().buffer; + return TypedArrayPrototypeGetBuffer(key[kKeyObject][kHandle].rawPublicKey()); } case kWebCryptoKeyFormatSPKI: { - return key[kKeyObject][kHandle].export(kKeyFormatDER, kWebCryptoKeyFormatSPKI).buffer; + return TypedArrayPrototypeGetBuffer(key[kKeyObject][kHandle].export(kKeyFormatDER, kWebCryptoKeyFormatSPKI)); } case kWebCryptoKeyFormatPKCS8: { const seed = key[kKeyObject][kHandle].rawSeed(); const buffer = new Uint8Array(54); - buffer.set([ + TypedArrayPrototypeSet(buffer, [ 0x30, 0x34, 0x02, 0x01, 0x00, 0x30, 0x0B, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x00, 0x04, 0x22, 0x80, 0x20, ], 0); switch (key[kAlgorithm].name) { case 'ML-DSA-44': - buffer.set([0x11], 17); + TypedArrayPrototypeSet(buffer, [0x11], 17); break; case 'ML-DSA-65': - buffer.set([0x12], 17); + TypedArrayPrototypeSet(buffer, [0x12], 17); break; case 'ML-DSA-87': - buffer.set([0x13], 17); + TypedArrayPrototypeSet(buffer, [0x13], 17); break; } - buffer.set(seed, 22); - return buffer.buffer; + TypedArrayPrototypeSet(buffer, seed, 22); + return TypedArrayPrototypeGetBuffer(buffer); } default: return undefined; diff --git a/lib/internal/crypto/ml_kem.js b/lib/internal/crypto/ml_kem.js index 4dfa1fa31a0425..1eb8d931fa0a2b 100644 --- a/lib/internal/crypto/ml_kem.js +++ b/lib/internal/crypto/ml_kem.js @@ -3,6 +3,8 @@ const { PromiseWithResolvers, SafeSet, + TypedArrayPrototypeGetBuffer, + TypedArrayPrototypeSet, Uint8Array, } = primordials; @@ -90,35 +92,35 @@ function mlKemExportKey(key, format) { switch (format) { case kWebCryptoKeyFormatRaw: { if (key[kKeyType] === 'private') { - return key[kKeyObject][kHandle].rawSeed().buffer; + return TypedArrayPrototypeGetBuffer(key[kKeyObject][kHandle].rawSeed()); } - return key[kKeyObject][kHandle].rawPublicKey().buffer; + return TypedArrayPrototypeGetBuffer(key[kKeyObject][kHandle].rawPublicKey()); } case kWebCryptoKeyFormatSPKI: { - return key[kKeyObject][kHandle].export(kKeyFormatDER, kWebCryptoKeyFormatSPKI).buffer; + return TypedArrayPrototypeGetBuffer(key[kKeyObject][kHandle].export(kKeyFormatDER, kWebCryptoKeyFormatSPKI)); } case kWebCryptoKeyFormatPKCS8: { const seed = key[kKeyObject][kHandle].rawSeed(); const buffer = new Uint8Array(86); - buffer.set([ + TypedArrayPrototypeSet(buffer, [ 0x30, 0x54, 0x02, 0x01, 0x00, 0x30, 0x0B, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x04, 0x00, 0x04, 0x42, 0x80, 0x40, ], 0); switch (key[kAlgorithm].name) { case 'ML-KEM-512': - buffer.set([0x01], 17); + TypedArrayPrototypeSet(buffer, [0x01], 17); break; case 'ML-KEM-768': - buffer.set([0x02], 17); + TypedArrayPrototypeSet(buffer, [0x02], 17); break; case 'ML-KEM-1024': - buffer.set([0x03], 17); + TypedArrayPrototypeSet(buffer, [0x03], 17); break; } - buffer.set(seed, 22); - return buffer.buffer; + TypedArrayPrototypeSet(buffer, seed, 22); + return TypedArrayPrototypeGetBuffer(buffer); } default: return undefined; @@ -241,7 +243,11 @@ function mlKemEncapsulate(encapsulationKey) { { name: 'OperationError', cause: error })); } else { const { 0: sharedKey, 1: ciphertext } = result; - resolve({ sharedKey: sharedKey.buffer, ciphertext: ciphertext.buffer }); + + resolve({ + sharedKey: TypedArrayPrototypeGetBuffer(sharedKey), + ciphertext: TypedArrayPrototypeGetBuffer(ciphertext), + }); } }; job.run(); @@ -270,7 +276,7 @@ function mlKemDecapsulate(decapsulationKey, ciphertext) { 'The operation failed for an operation-specific reason', { name: 'OperationError', cause: error })); } else { - resolve(result.buffer); + resolve(TypedArrayPrototypeGetBuffer(result)); } }; job.run(); diff --git a/lib/internal/crypto/pbkdf2.js b/lib/internal/crypto/pbkdf2.js index ebdba7334f6556..2b11535edb3ec7 100644 --- a/lib/internal/crypto/pbkdf2.js +++ b/lib/internal/crypto/pbkdf2.js @@ -3,6 +3,7 @@ const { ArrayBuffer, FunctionPrototypeCall, + TypedArrayPrototypeGetBuffer, } = primordials; const { Buffer } = require('buffer'); @@ -121,7 +122,7 @@ async function pbkdf2DeriveBits(algorithm, baseKey, length) { { name: 'OperationError', cause: err }); } - return result.buffer; + return TypedArrayPrototypeGetBuffer(result); } module.exports = { diff --git a/lib/internal/crypto/random.js b/lib/internal/crypto/random.js index 84f16f4e6653ed..c9030124e7f71f 100644 --- a/lib/internal/crypto/random.js +++ b/lib/internal/crypto/random.js @@ -19,6 +19,7 @@ const { NumberPrototypeToString, StringFromCharCodeApply, StringPrototypePadStart, + TypedArrayPrototypeGetBuffer, } = primordials; const { @@ -104,12 +105,12 @@ function randomBytes(size, callback) { const buf = new FastBuffer(size); if (callback === undefined) { - randomFillSync(buf.buffer, 0, size); + randomFillSync(TypedArrayPrototypeGetBuffer(buf), 0, size); return buf; } // Keep the callback as a regular function so this is propagated. - randomFill(buf.buffer, 0, size, function(error) { + randomFill(TypedArrayPrototypeGetBuffer(buf), 0, size, function(error) { if (error) return FunctionPrototypeCall(callback, this, error); FunctionPrototypeCall(callback, this, null, buf); }); diff --git a/lib/internal/crypto/webcrypto.js b/lib/internal/crypto/webcrypto.js index 18b5253e2aa463..745c94ba10f591 100644 --- a/lib/internal/crypto/webcrypto.js +++ b/lib/internal/crypto/webcrypto.js @@ -11,6 +11,7 @@ const { StringPrototypeSlice, StringPrototypeStartsWith, SymbolToStringTag, + TypedArrayPrototypeGetBuffer, } = primordials; const { @@ -530,12 +531,12 @@ async function exportKeyRawSecret(key, format) { case 'AES-KW': // Fall through case 'HMAC': - return key[kKeyObject][kHandle].export().buffer; + return TypedArrayPrototypeGetBuffer(key[kKeyObject][kHandle].export()); case 'AES-OCB': // Fall through case 'ChaCha20-Poly1305': if (format === 'raw-secret') { - return key[kKeyObject][kHandle].export().buffer; + return TypedArrayPrototypeGetBuffer(key[kKeyObject][kHandle].export()); } return undefined; default: From fcb69788a205bf4c46c97050b97ee3d61ba9c171 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sat, 6 Sep 2025 10:56:07 +0200 Subject: [PATCH 2/4] fixup! lib: prefer TypedArrayPrototype primordials --- lib/internal/crypto/ml_dsa.js | 28 ++++++++++------------------ lib/internal/crypto/ml_kem.js | 28 ++++++++++------------------ 2 files changed, 20 insertions(+), 36 deletions(-) diff --git a/lib/internal/crypto/ml_dsa.js b/lib/internal/crypto/ml_dsa.js index 779977a12a5adb..085e2dd756a0eb 100644 --- a/lib/internal/crypto/ml_dsa.js +++ b/lib/internal/crypto/ml_dsa.js @@ -3,7 +3,6 @@ const { SafeSet, TypedArrayPrototypeGetBuffer, - TypedArrayPrototypeSet, Uint8Array, } = primordials; @@ -131,24 +130,17 @@ function mlDsaExportKey(key, format) { } case kWebCryptoKeyFormatPKCS8: { const seed = key[kKeyObject][kHandle].rawSeed(); - const buffer = new Uint8Array(54); - TypedArrayPrototypeSet(buffer, [ - 0x30, 0x34, 0x02, 0x01, 0x00, 0x30, 0x0B, 0x06, + const orc = { + __proto__: null, + 'ML-DSA-44': 0x11, + 'ML-DSA-65': 0x12, + 'ML-DSA-87': 0x13, + }[key[kAlgorithm].name]; + const buffer = new Uint8Array([ + 0x30, 0x34, 0x02, 0x01, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, - 0x03, 0x00, 0x04, 0x22, 0x80, 0x20, - ], 0); - switch (key[kAlgorithm].name) { - case 'ML-DSA-44': - TypedArrayPrototypeSet(buffer, [0x11], 17); - break; - case 'ML-DSA-65': - TypedArrayPrototypeSet(buffer, [0x12], 17); - break; - case 'ML-DSA-87': - TypedArrayPrototypeSet(buffer, [0x13], 17); - break; - } - TypedArrayPrototypeSet(buffer, seed, 22); + 0x03, orc, 0x04, 0x22, 0x80, 0x20, ...seed + ]); return TypedArrayPrototypeGetBuffer(buffer); } default: diff --git a/lib/internal/crypto/ml_kem.js b/lib/internal/crypto/ml_kem.js index 1eb8d931fa0a2b..60b7e9d6cd1a1f 100644 --- a/lib/internal/crypto/ml_kem.js +++ b/lib/internal/crypto/ml_kem.js @@ -4,7 +4,6 @@ const { PromiseWithResolvers, SafeSet, TypedArrayPrototypeGetBuffer, - TypedArrayPrototypeSet, Uint8Array, } = primordials; @@ -102,24 +101,17 @@ function mlKemExportKey(key, format) { } case kWebCryptoKeyFormatPKCS8: { const seed = key[kKeyObject][kHandle].rawSeed(); - const buffer = new Uint8Array(86); - TypedArrayPrototypeSet(buffer, [ - 0x30, 0x54, 0x02, 0x01, 0x00, 0x30, 0x0B, 0x06, + const orc = { + __proto__: null, + 'ML-KEM-512': 0x01, + 'ML-KEM-768': 0x02, + 'ML-KEM-1024': 0x03, + }[key[kAlgorithm].name]; + const buffer = new Uint8Array([ + 0x30, 0x54, 0x02, 0x01, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, - 0x04, 0x00, 0x04, 0x42, 0x80, 0x40, - ], 0); - switch (key[kAlgorithm].name) { - case 'ML-KEM-512': - TypedArrayPrototypeSet(buffer, [0x01], 17); - break; - case 'ML-KEM-768': - TypedArrayPrototypeSet(buffer, [0x02], 17); - break; - case 'ML-KEM-1024': - TypedArrayPrototypeSet(buffer, [0x03], 17); - break; - } - TypedArrayPrototypeSet(buffer, seed, 22); + 0x04, orc, 0x04, 0x42, 0x80, 0x40, ...seed + ]); return TypedArrayPrototypeGetBuffer(buffer); } default: From 58125d12876cc825a0cadfff0e332289d1226541 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sat, 6 Sep 2025 10:59:26 +0200 Subject: [PATCH 3/4] fixup! lib: prefer TypedArrayPrototype primordials --- lib/internal/crypto/ml_dsa.js | 4 ++-- lib/internal/crypto/ml_kem.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/internal/crypto/ml_dsa.js b/lib/internal/crypto/ml_dsa.js index 085e2dd756a0eb..9b97eafd16e6b1 100644 --- a/lib/internal/crypto/ml_dsa.js +++ b/lib/internal/crypto/ml_dsa.js @@ -131,7 +131,7 @@ function mlDsaExportKey(key, format) { case kWebCryptoKeyFormatPKCS8: { const seed = key[kKeyObject][kHandle].rawSeed(); const orc = { - __proto__: null, + '__proto__': null, 'ML-DSA-44': 0x11, 'ML-DSA-65': 0x12, 'ML-DSA-87': 0x13, @@ -139,7 +139,7 @@ function mlDsaExportKey(key, format) { const buffer = new Uint8Array([ 0x30, 0x34, 0x02, 0x01, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, - 0x03, orc, 0x04, 0x22, 0x80, 0x20, ...seed + 0x03, orc, 0x04, 0x22, 0x80, 0x20, ...seed, ]); return TypedArrayPrototypeGetBuffer(buffer); } diff --git a/lib/internal/crypto/ml_kem.js b/lib/internal/crypto/ml_kem.js index 60b7e9d6cd1a1f..6e4d574a58eeec 100644 --- a/lib/internal/crypto/ml_kem.js +++ b/lib/internal/crypto/ml_kem.js @@ -102,7 +102,7 @@ function mlKemExportKey(key, format) { case kWebCryptoKeyFormatPKCS8: { const seed = key[kKeyObject][kHandle].rawSeed(); const orc = { - __proto__: null, + '__proto__': null, 'ML-KEM-512': 0x01, 'ML-KEM-768': 0x02, 'ML-KEM-1024': 0x03, @@ -110,7 +110,7 @@ function mlKemExportKey(key, format) { const buffer = new Uint8Array([ 0x30, 0x54, 0x02, 0x01, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, - 0x04, orc, 0x04, 0x42, 0x80, 0x40, ...seed + 0x04, orc, 0x04, 0x42, 0x80, 0x40, ...seed, ]); return TypedArrayPrototypeGetBuffer(buffer); } From 94c21637fd2930e0dee1defde5b3660405e5545e Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sat, 6 Sep 2025 12:51:42 +0200 Subject: [PATCH 4/4] fixup! lib: prefer TypedArrayPrototype primordials --- lib/internal/crypto/ml_dsa.js | 9 ++++++--- lib/internal/crypto/ml_kem.js | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/internal/crypto/ml_dsa.js b/lib/internal/crypto/ml_dsa.js index 9b97eafd16e6b1..fd04230f29c088 100644 --- a/lib/internal/crypto/ml_dsa.js +++ b/lib/internal/crypto/ml_dsa.js @@ -3,6 +3,7 @@ const { SafeSet, TypedArrayPrototypeGetBuffer, + TypedArrayPrototypeSet, Uint8Array, } = primordials; @@ -130,17 +131,19 @@ function mlDsaExportKey(key, format) { } case kWebCryptoKeyFormatPKCS8: { const seed = key[kKeyObject][kHandle].rawSeed(); + const buffer = new Uint8Array(54); const orc = { '__proto__': null, 'ML-DSA-44': 0x11, 'ML-DSA-65': 0x12, 'ML-DSA-87': 0x13, }[key[kAlgorithm].name]; - const buffer = new Uint8Array([ + TypedArrayPrototypeSet(buffer, [ 0x30, 0x34, 0x02, 0x01, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, - 0x03, orc, 0x04, 0x22, 0x80, 0x20, ...seed, - ]); + 0x03, orc, 0x04, 0x22, 0x80, 0x20, + ], 0); + TypedArrayPrototypeSet(buffer, seed, 22); return TypedArrayPrototypeGetBuffer(buffer); } default: diff --git a/lib/internal/crypto/ml_kem.js b/lib/internal/crypto/ml_kem.js index 6e4d574a58eeec..5f6efc01125a4b 100644 --- a/lib/internal/crypto/ml_kem.js +++ b/lib/internal/crypto/ml_kem.js @@ -4,6 +4,7 @@ const { PromiseWithResolvers, SafeSet, TypedArrayPrototypeGetBuffer, + TypedArrayPrototypeSet, Uint8Array, } = primordials; @@ -101,17 +102,19 @@ function mlKemExportKey(key, format) { } case kWebCryptoKeyFormatPKCS8: { const seed = key[kKeyObject][kHandle].rawSeed(); + const buffer = new Uint8Array(86); const orc = { '__proto__': null, 'ML-KEM-512': 0x01, 'ML-KEM-768': 0x02, 'ML-KEM-1024': 0x03, }[key[kAlgorithm].name]; - const buffer = new Uint8Array([ + TypedArrayPrototypeSet(buffer, [ 0x30, 0x54, 0x02, 0x01, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, - 0x04, orc, 0x04, 0x42, 0x80, 0x40, ...seed, - ]); + 0x04, orc, 0x04, 0x42, 0x80, 0x40, + ], 0); + TypedArrayPrototypeSet(buffer, seed, 22); return TypedArrayPrototypeGetBuffer(buffer); } default: