@@ -171,185 +171,230 @@ const kNamedCurveAliases = {
171171 'P-521' : 'secp521r1' ,
172172} ;
173173
174- const kSupportedAlgorithms = {
175- 'digest' : {
176- 'SHA-1' : null ,
177- 'SHA-256' : null ,
178- 'SHA-384' : null ,
179- 'SHA-512' : null ,
174+ // Algorithm definitions organized by algorithm name
175+ const kAlgorithmDefinitions = {
176+ 'AES-CBC' : {
177+ 'generateKey' : 'AesKeyGenParams' ,
178+ 'exportKey' : null ,
179+ 'importKey' : null ,
180+ 'encrypt' : 'AesCbcParams' ,
181+ 'decrypt' : 'AesCbcParams' ,
182+ 'get key length' : 'AesDerivedKeyParams' ,
183+ } ,
184+ 'AES-CTR' : {
185+ 'generateKey' : 'AesKeyGenParams' ,
186+ 'exportKey' : null ,
187+ 'importKey' : null ,
188+ 'encrypt' : 'AesCtrParams' ,
189+ 'decrypt' : 'AesCtrParams' ,
190+ 'get key length' : 'AesDerivedKeyParams' ,
180191 } ,
181- 'generateKey' : {
182- 'RSASSA-PKCS1-v1_5' : 'RsaHashedKeyGenParams' ,
183- 'RSA-PSS' : 'RsaHashedKeyGenParams' ,
184- 'RSA-OAEP' : 'RsaHashedKeyGenParams' ,
185- 'ECDSA' : 'EcKeyGenParams' ,
186- 'ECDH' : 'EcKeyGenParams' ,
187- 'AES-CTR' : 'AesKeyGenParams' ,
188- 'AES-CBC' : 'AesKeyGenParams' ,
189- 'AES-GCM' : 'AesKeyGenParams' ,
190- 'HMAC' : 'HmacKeyGenParams' ,
191- 'Ed25519' : null ,
192- 'X25519' : null ,
192+ 'AES-GCM' : {
193+ 'generateKey' : 'AesKeyGenParams' ,
194+ 'exportKey' : null ,
195+ 'importKey' : null ,
196+ 'encrypt' : 'AeadParams' ,
197+ 'decrypt' : 'AeadParams' ,
198+ 'get key length' : 'AesDerivedKeyParams' ,
193199 } ,
194- 'exportKey' : {
195- 'RSASSA-PKCS1-v1_5' : null ,
196- 'RSA-PSS' : null ,
197- 'RSA-OAEP' : null ,
198- 'ECDSA' : null ,
199- 'ECDH' : null ,
200- 'HMAC' : null ,
201- 'AES-CTR' : null ,
202- 'AES-CBC' : null ,
203- 'AES-GCM' : null ,
204- 'Ed25519' : null ,
205- 'X25519' : null ,
200+ 'AES-KW' : {
201+ 'generateKey' : 'AesKeyGenParams' ,
202+ 'exportKey' : null ,
203+ 'importKey' : null ,
204+ 'get key length' : 'AesDerivedKeyParams' ,
205+ 'wrapKey' : null ,
206+ 'unwrapKey' : null ,
206207 } ,
207- 'sign' : {
208- 'RSASSA-PKCS1-v1_5' : null ,
209- 'RSA-PSS' : 'RsaPssParams' ,
210- 'ECDSA' : 'EcdsaParams' ,
211- 'HMAC' : null ,
212- 'Ed25519' : null ,
208+ 'ChaCha20-Poly1305' : {
209+ 'generateKey' : null ,
210+ 'exportKey' : null ,
211+ 'importKey' : null ,
212+ 'encrypt' : 'AeadParams' ,
213+ 'decrypt' : 'AeadParams' ,
214+ 'get key length' : null ,
213215 } ,
214- 'verify' : {
215- 'RSASSA-PKCS1-v1_5' : null ,
216- 'RSA-PSS' : 'RsaPssParams' ,
217- 'ECDSA' : 'EcdsaParams' ,
218- 'HMAC' : null ,
219- 'Ed25519' : null ,
216+ 'cSHAKE128' : { 'digest' : 'CShakeParams' } ,
217+ 'cSHAKE256' : { 'digest' : 'CShakeParams' } ,
218+ 'ECDH' : {
219+ 'generateKey' : 'EcKeyGenParams' ,
220+ 'exportKey' : null ,
221+ 'importKey' : 'EcKeyImportParams' ,
222+ 'deriveBits' : 'EcdhKeyDeriveParams' ,
220223 } ,
221- 'importKey' : {
222- 'RSASSA-PKCS1-v1_5' : 'RsaHashedImportParams' ,
223- 'RSA-PSS' : 'RsaHashedImportParams' ,
224- 'RSA-OAEP' : 'RsaHashedImportParams' ,
225- 'ECDSA' : 'EcKeyImportParams' ,
226- 'ECDH' : 'EcKeyImportParams' ,
227- 'HMAC' : 'HmacImportParams' ,
228- 'HKDF' : null ,
229- 'PBKDF2' : null ,
230- 'AES-CTR' : null ,
231- 'AES-CBC' : null ,
232- 'AES-GCM' : null ,
233- 'Ed25519' : null ,
234- 'X25519' : null ,
224+ 'ECDSA' : {
225+ 'generateKey' : 'EcKeyGenParams' ,
226+ 'exportKey' : null ,
227+ 'importKey' : 'EcKeyImportParams' ,
228+ 'sign' : 'EcdsaParams' ,
229+ 'verify' : 'EcdsaParams' ,
235230 } ,
236- 'deriveBits' : {
237- 'HKDF' : 'HkdfParams' ,
238- 'PBKDF2' : 'Pbkdf2Params' ,
239- 'ECDH' : 'EcdhKeyDeriveParams' ,
240- 'X25519' : 'EcdhKeyDeriveParams' ,
231+ 'Ed25519' : {
232+ 'generateKey' : null ,
233+ 'exportKey' : null ,
234+ 'importKey' : null ,
235+ 'sign' : null ,
236+ 'verify' : null ,
241237 } ,
242- 'encrypt' : {
243- 'RSA-OAEP' : 'RsaOaepParams' ,
244- 'AES-CBC' : 'AesCbcParams' ,
245- 'AES-GCM' : 'AeadParams' ,
246- 'AES-CTR' : 'AesCtrParams' ,
238+ 'Ed448' : {
239+ 'generateKey' : null ,
240+ 'exportKey' : null ,
241+ 'importKey' : null ,
242+ 'sign' : 'Ed448Params' ,
243+ 'verify' : 'Ed448Params' ,
247244 } ,
248- 'decrypt' : {
249- 'RSA-OAEP' : 'RsaOaepParams' ,
250- 'AES-CBC' : 'AesCbcParams' ,
251- 'AES-GCM' : 'AeadParams' ,
252- 'AES-CTR' : 'AesCtrParams' ,
245+ 'HKDF' : {
246+ 'importKey' : null ,
247+ 'deriveBits' : 'HkdfParams' ,
248+ 'get key length' : null ,
253249 } ,
254- 'get key length ' : {
255- 'AES-CBC ' : 'AesDerivedKeyParams ' ,
256- 'AES-CTR ' : 'AesDerivedKeyParams' ,
257- 'AES-GCM ' : 'AesDerivedKeyParams ' ,
258- 'HMAC ' : 'HmacImportParams' ,
259- 'HKDF ' : null ,
260- 'PBKDF2 ' : null ,
250+ 'HMAC ' : {
251+ 'generateKey ' : 'HmacKeyGenParams ' ,
252+ 'exportKey ' : null ,
253+ 'importKey ' : 'HmacImportParams ' ,
254+ 'sign ' : null ,
255+ 'verify ' : null ,
256+ 'get key length ' : 'HmacImportParams' ,
261257 } ,
262- 'wrapKey' : { } ,
263- 'unwrapKey' : { } ,
264- } ;
265-
266- const conditionalAlgorithms = ObjectEntries ( {
267- 'AES-KW' : [ {
268- 'generateKey' : 'AesKeyGenParams' ,
258+ 'ML-DSA-44' : {
259+ 'generateKey' : null ,
269260 'exportKey' : null ,
270261 'importKey' : null ,
271- 'get key length' : 'AesDerivedKeyParams' ,
272- 'wrapKey' : null ,
273- 'unwrapKey' : null ,
274- } , ! process . features . openssl_is_boringssl ] ,
275- } ) ;
262+ 'sign' : 'ContextParams' ,
263+ 'verify' : 'ContextParams' ,
264+ } ,
265+ 'ML-DSA-65' : {
266+ 'generateKey' : null ,
267+ 'exportKey' : null ,
268+ 'importKey' : null ,
269+ 'sign' : 'ContextParams' ,
270+ 'verify' : 'ContextParams' ,
271+ } ,
272+ 'ML-DSA-87' : {
273+ 'generateKey' : null ,
274+ 'exportKey' : null ,
275+ 'importKey' : null ,
276+ 'sign' : 'ContextParams' ,
277+ 'verify' : 'ContextParams' ,
278+ } ,
279+ 'PBKDF2' : {
280+ 'importKey' : null ,
281+ 'deriveBits' : 'Pbkdf2Params' ,
282+ 'get key length' : null ,
283+ } ,
284+ 'RSA-OAEP' : {
285+ 'generateKey' : 'RsaHashedKeyGenParams' ,
286+ 'exportKey' : null ,
287+ 'importKey' : 'RsaHashedImportParams' ,
288+ 'encrypt' : 'RsaOaepParams' ,
289+ 'decrypt' : 'RsaOaepParams' ,
290+ } ,
291+ 'RSA-PSS' : {
292+ 'generateKey' : 'RsaHashedKeyGenParams' ,
293+ 'exportKey' : null ,
294+ 'importKey' : 'RsaHashedImportParams' ,
295+ 'sign' : 'RsaPssParams' ,
296+ 'verify' : 'RsaPssParams' ,
297+ } ,
298+ 'RSASSA-PKCS1-v1_5' : {
299+ 'generateKey' : 'RsaHashedKeyGenParams' ,
300+ 'exportKey' : null ,
301+ 'importKey' : 'RsaHashedImportParams' ,
302+ 'sign' : null ,
303+ 'verify' : null ,
304+ } ,
305+ 'SHA-1' : { 'digest' : null } ,
306+ 'SHA-256' : { 'digest' : null } ,
307+ 'SHA-384' : { 'digest' : null } ,
308+ 'SHA-512' : { 'digest' : null } ,
309+ 'SHA3-256' : { 'digest' : null } ,
310+ 'SHA3-384' : { 'digest' : null } ,
311+ 'SHA3-512' : { 'digest' : null } ,
312+ 'X25519' : {
313+ 'generateKey' : null ,
314+ 'exportKey' : null ,
315+ 'importKey' : null ,
316+ 'deriveBits' : 'EcdhKeyDeriveParams' ,
317+ } ,
318+ 'X448' : {
319+ 'generateKey' : null ,
320+ 'exportKey' : null ,
321+ 'importKey' : null ,
322+ 'deriveBits' : 'EcdhKeyDeriveParams' ,
323+ } ,
324+ } ;
276325
277- for ( let i = 0 ; i < conditionalAlgorithms . length ; i ++ ) {
278- if ( conditionalAlgorithms [ i ] [ 1 ] [ 1 ] ) {
279- const name = conditionalAlgorithms [ i ] [ 0 ] ;
280- const ops = ObjectEntries ( conditionalAlgorithms [ i ] [ 1 ] [ 0 ] ) ;
281- for ( let j = 0 ; j < ops . length ; j ++ ) {
282- const { 0 : op , 1 : dict } = ops [ j ] ;
283- kSupportedAlgorithms [ op ] [ name ] = dict ;
284- }
285- }
286- }
326+ // Conditionally supported algorithms
327+ const conditionalAlgorithms = {
328+ 'AES-KW' : ! process . features . openssl_is_boringssl ,
329+ 'ChaCha20-Poly1305' : ! process . features . openssl_is_boringssl ||
330+ ArrayPrototypeIncludes ( getCiphers ( ) , 'chacha20-poly1305' ) ,
331+ 'cSHAKE128' : ! process . features . openssl_is_boringssl ||
332+ ArrayPrototypeIncludes ( getHashes ( ) , 'shake128' ) ,
333+ 'cSHAKE256' : ! process . features . openssl_is_boringssl ||
334+ ArrayPrototypeIncludes ( getHashes ( ) , 'shake256' ) ,
335+ 'Ed448' : ! process . features . openssl_is_boringssl ,
336+ 'ML-DSA-44' : ! ! EVP_PKEY_ML_DSA_44 ,
337+ 'ML-DSA-65' : ! ! EVP_PKEY_ML_DSA_65 ,
338+ 'ML-DSA-87' : ! ! EVP_PKEY_ML_DSA_87 ,
339+ 'SHA3-256' : ! process . features . openssl_is_boringssl ||
340+ ArrayPrototypeIncludes ( getHashes ( ) , 'sha3-256' ) ,
341+ 'SHA3-384' : ! process . features . openssl_is_boringssl ||
342+ ArrayPrototypeIncludes ( getHashes ( ) , 'sha3-384' ) ,
343+ 'SHA3-512' : ! process . features . openssl_is_boringssl ||
344+ ArrayPrototypeIncludes ( getHashes ( ) , 'sha3-512' ) ,
345+ 'X448' : ! process . features . openssl_is_boringssl ,
346+ } ;
287347
288- const experimentalAlgorithms = ObjectEntries ( { } ) ;
289-
290- if ( ! process . features . openssl_is_boringssl ) {
291- ArrayPrototypePush ( experimentalAlgorithms ,
292- [ 'Ed448' , {
293- generateKey : null ,
294- sign : 'Ed448Params' ,
295- verify : 'Ed448Params' ,
296- importKey : null ,
297- exportKey : null ,
298- } ] ,
299- [ 'X448' , {
300- generateKey : null ,
301- importKey : null ,
302- deriveBits : 'EcdhKeyDeriveParams' ,
303- exportKey : null ,
304- } ] ,
305- [ 'cSHAKE128' , { digest : 'CShakeParams' } ] ,
306- [ 'cSHAKE256' , { digest : 'CShakeParams' } ] ,
307- [ 'ChaCha20-Poly1305' , {
308- 'encrypt' : 'AeadParams' ,
309- 'decrypt' : 'AeadParams' ,
310- 'generateKey' : null ,
311- 'importKey' : null ,
312- 'exportKey' : null ,
313- 'get key length' : null ,
314- } ] ,
315- [ 'SHA3-256' , { digest : null } ] ,
316- [ 'SHA3-384' , { digest : null } ] ,
317- [ 'SHA3-512' , { digest : null } ] ,
318- ) ;
319- }
348+ // Experimental algorithms
349+ const experimentalAlgorithms = [
350+ 'ChaCha20-Poly1305' ,
351+ 'cSHAKE128' ,
352+ 'cSHAKE256' ,
353+ 'Ed448' ,
354+ 'ML-DSA-44' ,
355+ 'ML-DSA-65' ,
356+ 'ML-DSA-87' ,
357+ 'SHA3-256' ,
358+ 'SHA3-384' ,
359+ 'SHA3-512' ,
360+ 'X448' ,
361+ ] ;
362+
363+ // Transform the algorithm definitions into the operation-keyed structure
364+ function createSupportedAlgorithms ( algorithmDefs ) {
365+ const result = { } ;
366+
367+ for ( const { 0 : algorithmName , 1 : operations } of ObjectEntries ( algorithmDefs ) ) {
368+ // Skip algorithms that are conditionally not supported
369+ if ( ObjectPrototypeHasOwnProperty ( conditionalAlgorithms , algorithmName ) &&
370+ ! conditionalAlgorithms [ algorithmName ] ) {
371+ continue ;
372+ }
320373
321- for ( const { 0 : algorithm , 1 : nid } of [
322- [ 'ML-DSA-44' , EVP_PKEY_ML_DSA_44 ] ,
323- [ 'ML-DSA-65' , EVP_PKEY_ML_DSA_65 ] ,
324- [ 'ML-DSA-87' , EVP_PKEY_ML_DSA_87 ] ,
325- ] ) {
326- if ( nid ) {
327- ArrayPrototypePush ( experimentalAlgorithms , [ algorithm , {
328- generateKey : null ,
329- sign : 'ContextParams' ,
330- verify : 'ContextParams' ,
331- importKey : null ,
332- exportKey : null ,
333- } ] ) ;
374+ for ( const { 0 : operation , 1 : dict } of ObjectEntries ( operations ) ) {
375+ result [ operation ] ||= { } ;
376+
377+ // Add experimental warnings for experimental algorithms
378+ if ( ArrayPrototypeIncludes ( experimentalAlgorithms , algorithmName ) ) {
379+ ObjectDefineProperty ( result [ operation ] , algorithmName , {
380+ get ( ) {
381+ emitExperimentalWarning ( `The ${ algorithmName } Web Crypto API algorithm` ) ;
382+ return dict ;
383+ } ,
384+ __proto__ : null ,
385+ enumerable : true ,
386+ } ) ;
387+ } else {
388+ result [ operation ] [ algorithmName ] = dict ;
389+ }
390+ }
334391 }
335- }
336392
337- for ( let i = 0 ; i < experimentalAlgorithms . length ; i ++ ) {
338- const name = experimentalAlgorithms [ i ] [ 0 ] ;
339- const ops = ObjectEntries ( experimentalAlgorithms [ i ] [ 1 ] ) ;
340- for ( let j = 0 ; j < ops . length ; j ++ ) {
341- const { 0 : op , 1 : dict } = ops [ j ] ;
342- ObjectDefineProperty ( kSupportedAlgorithms [ op ] , name , {
343- get ( ) {
344- emitExperimentalWarning ( `The ${ name } Web Crypto API algorithm` ) ;
345- return dict ;
346- } ,
347- __proto__ : null ,
348- enumerable : true ,
349- } ) ;
350- }
393+ return result ;
351394}
352395
396+ const kSupportedAlgorithms = createSupportedAlgorithms ( kAlgorithmDefinitions ) ;
397+
353398const simpleAlgorithmDictionaries = {
354399 AeadParams : { iv : 'BufferSource' , additionalData : 'BufferSource' } ,
355400 RsaHashedKeyGenParams : { hash : 'HashAlgorithmIdentifier' } ,
0 commit comments