Skip to content

Commit 72937e5

Browse files
panvatargos
authored andcommitted
crypto: require HMAC key length with SHA-3 hashes in Web Cryptography
PR-URL: #59567 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
1 parent b2b8383 commit 72937e5

File tree

5 files changed

+69
-28
lines changed

5 files changed

+69
-28
lines changed

lib/internal/crypto/util.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -629,11 +629,13 @@ function getBlockSize(name) {
629629
case 'SHA-512':
630630
return 1024;
631631
case 'SHA3-256':
632-
return 1088;
632+
// Fall through
633633
case 'SHA3-384':
634-
return 832;
634+
// Fall through
635635
case 'SHA3-512':
636-
return 576;
636+
// This interaction is not defined for now.
637+
// https://github.com/WICG/webcrypto-modern-algos/issues/23
638+
throw lazyDOMException('Explicit algorithm length member is required', 'NotSupportedError');
637639
}
638640
}
639641

lib/internal/crypto/webcrypto.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const {
99
ReflectConstruct,
1010
StringPrototypeRepeat,
1111
StringPrototypeSlice,
12+
StringPrototypeStartsWith,
1213
SymbolToStringTag,
1314
} = primordials;
1415

@@ -1235,7 +1236,6 @@ function check(op, alg, length) {
12351236
case 'sign':
12361237
case 'verify':
12371238
case 'digest':
1238-
case 'generateKey':
12391239
case 'importKey':
12401240
case 'exportKey':
12411241
case 'wrapKey':
@@ -1260,6 +1260,17 @@ function check(op, alg, length) {
12601260

12611261
return true;
12621262
}
1263+
case 'generateKey': {
1264+
if (
1265+
normalizedAlgorithm.name === 'HMAC' &&
1266+
normalizedAlgorithm.length === undefined &&
1267+
StringPrototypeStartsWith(normalizedAlgorithm.hash.name, 'SHA3-')
1268+
) {
1269+
return false;
1270+
}
1271+
1272+
return true;
1273+
}
12631274
default: {
12641275
const assert = require('internal/assert');
12651276
assert.fail('Unreachable code');

test/fixtures/webcrypto/supports-sha3.mjs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,26 @@ export const vectors = {
1919
[!boringSSL, 'SHA3-512'],
2020
],
2121
'generateKey': [
22-
[!boringSSL, { name: 'HMAC', hash: 'SHA3-256' }],
2322
[!boringSSL, { name: 'HMAC', hash: 'SHA3-256', length: 256 }],
2423
[false, { name: 'HMAC', hash: 'SHA3-256', length: 25 }],
2524
[!boringSSL, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA3-256', ...RSA_KEY_GEN }],
2625
[!boringSSL, { name: 'RSA-PSS', hash: 'SHA3-256', ...RSA_KEY_GEN }],
2726
[!boringSSL, { name: 'RSA-OAEP', hash: 'SHA3-256', ...RSA_KEY_GEN }],
28-
[!boringSSL, { name: 'HMAC', hash: 'SHA3-256' }],
2927
[!boringSSL, { name: 'HMAC', hash: 'SHA3-256', length: 256 }],
3028
[false, { name: 'HMAC', hash: 'SHA3-256', length: 25 }],
3129
[false, { name: 'HMAC', hash: 'SHA3-256', length: 0 }],
30+
31+
// This interaction is not defined for now.
32+
// https://github.com/WICG/webcrypto-modern-algos/issues/23
33+
[false, { name: 'HMAC', hash: 'SHA3-256' }],
3234
],
3335
'deriveKey': [
3436
[!boringSSL,
3537
{ name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) },
3638
{ name: 'AES-CBC', length: 128 }],
3739
[!boringSSL,
3840
{ name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) },
39-
{ name: 'HMAC', hash: 'SHA3-256' }],
41+
{ name: 'HMAC', hash: 'SHA3-256', length: 256 }],
4042
[false,
4143
{ name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) },
4244
'HKDF'],
@@ -45,14 +47,29 @@ export const vectors = {
4547
{ name: 'AES-CBC', length: 128 }],
4648
[!boringSSL,
4749
{ name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 },
48-
{ name: 'HMAC', hash: 'SHA3-256' }],
50+
{ name: 'HMAC', hash: 'SHA3-256', length: 256 }],
4951
[false,
5052
{ name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 },
5153
'HKDF'],
5254
[!boringSSL,
5355
{ name: 'X25519', public: X25519.publicKey },
54-
{ name: 'HMAC', hash: 'SHA3-256' }],
56+
{ name: 'HMAC', hash: 'SHA3-256', length: 256 }],
5557
[!boringSSL,
58+
{ name: 'ECDH', public: ECDH.publicKey },
59+
{ name: 'HMAC', hash: 'SHA3-256', length: 256 }],
60+
61+
// This interaction is not defined for now.
62+
// https://github.com/WICG/webcrypto-modern-algos/issues/23
63+
[false,
64+
{ name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) },
65+
{ name: 'HMAC', hash: 'SHA3-256' }],
66+
[false,
67+
{ name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 },
68+
{ name: 'HMAC', hash: 'SHA3-256' }],
69+
[false,
70+
{ name: 'X25519', public: X25519.publicKey },
71+
{ name: 'HMAC', hash: 'SHA3-256' }],
72+
[false,
5673
{ name: 'ECDH', public: ECDH.publicKey },
5774
{ name: 'HMAC', hash: 'SHA3-256' }],
5875
],

test/parallel/test-webcrypto-derivekey.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,14 @@ const { KeyObject } = require('crypto');
157157
// Not long enough secret generated by ECDH
158158
[{ name: 'HMAC', hash: 'SHA-384' }, 'sign', 1024],
159159
[{ name: 'HMAC', hash: 'SHA-512' }, 'sign', 1024],
160-
[{ name: 'HMAC', hash: 'SHA3-256' }, 'sign', 1088],
161-
[{ name: 'HMAC', hash: 'SHA3-384' }, 'sign', 832],
162-
[{ name: 'HMAC', hash: 'SHA3-512' }, 'sign', 576],
160+
[{ name: 'HMAC', hash: 'SHA3-256', length: 256 }, 'sign', 256],
161+
[{ name: 'HMAC', hash: 'SHA3-384', length: 384 }, 'sign', 384],
162+
[{ name: 'HMAC', hash: 'SHA3-512', length: 512 }, 'sign', 512],
163+
// This interaction is not defined for now.
164+
// https://github.com/WICG/webcrypto-modern-algos/issues/23
165+
// [{ name: 'HMAC', hash: 'SHA3-256' }, 'sign', 256],
166+
// [{ name: 'HMAC', hash: 'SHA3-384' }, 'sign', 384],
167+
// [{ name: 'HMAC', hash: 'SHA3-512' }, 'sign', 512],
163168
];
164169

165170
(async () => {
@@ -196,9 +201,14 @@ const { KeyObject } = require('crypto');
196201
[{ name: 'HMAC', hash: 'SHA-256' }, 'sign', 512],
197202
[{ name: 'HMAC', hash: 'SHA-384' }, 'sign', 1024],
198203
[{ name: 'HMAC', hash: 'SHA-512' }, 'sign', 1024],
199-
[{ name: 'HMAC', hash: 'SHA3-256' }, 'sign', 1088],
200-
[{ name: 'HMAC', hash: 'SHA3-384' }, 'sign', 832],
201-
[{ name: 'HMAC', hash: 'SHA3-512' }, 'sign', 576],
204+
[{ name: 'HMAC', hash: 'SHA3-256', length: 256 }, 'sign', 256],
205+
[{ name: 'HMAC', hash: 'SHA3-384', length: 384 }, 'sign', 384],
206+
[{ name: 'HMAC', hash: 'SHA3-512', length: 512 }, 'sign', 512],
207+
// This interaction is not defined for now.
208+
// https://github.com/WICG/webcrypto-modern-algos/issues/23
209+
// [{ name: 'HMAC', hash: 'SHA3-256' }, 'sign', 256],
210+
// [{ name: 'HMAC', hash: 'SHA3-384' }, 'sign', 384],
211+
// [{ name: 'HMAC', hash: 'SHA3-512' }, 'sign', 512],
202212
];
203213

204214
(async () => {

test/parallel/test-webcrypto-keygen.js

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -614,9 +614,6 @@ if (hasOpenSSL(3, 5)) {
614614
case 'SHA-256': length = 512; break;
615615
case 'SHA-384': length = 1024; break;
616616
case 'SHA-512': length = 1024; break;
617-
case 'SHA3-256': length = 1088; break;
618-
case 'SHA3-384': length = 832; break;
619-
case 'SHA3-512': length = 576; break;
620617
}
621618
}
622619

@@ -642,20 +639,24 @@ if (hasOpenSSL(3, 5)) {
642639
}
643640

644641
const kTests = [
645-
[ undefined, 'SHA-1', ['sign', 'verify']],
646-
[ undefined, 'SHA-256', ['sign', 'verify']],
647-
[ undefined, 'SHA-384', ['sign', 'verify']],
648-
[ undefined, 'SHA-512', ['sign', 'verify']],
649-
[ 128, 'SHA-256', ['sign', 'verify']],
650-
[ 1024, 'SHA-512', ['sign', 'verify']],
642+
[undefined, 'SHA-1', ['sign', 'verify']],
643+
[undefined, 'SHA-256', ['sign', 'verify']],
644+
[undefined, 'SHA-384', ['sign', 'verify']],
645+
[undefined, 'SHA-512', ['sign', 'verify']],
646+
[128, 'SHA-256', ['sign', 'verify']],
647+
[1024, 'SHA-512', ['sign', 'verify']],
651648
];
652649

653650
if (!process.features.openssl_is_boringssl) {
654651
kTests.push(
655-
656-
[ undefined, 'SHA3-256', ['sign', 'verify']],
657-
[ undefined, 'SHA3-384', ['sign', 'verify']],
658-
[ undefined, 'SHA3-512', ['sign', 'verify']],
652+
[256, 'SHA3-256', ['sign', 'verify']],
653+
[384, 'SHA3-384', ['sign', 'verify']],
654+
[512, 'SHA3-512', ['sign', 'verify']],
655+
// This interaction is not defined for now.
656+
// https://github.com/WICG/webcrypto-modern-algos/issues/23
657+
// [undefined, 'SHA3-256', ['sign', 'verify']],
658+
// [undefined, 'SHA3-384', ['sign', 'verify']],
659+
// [undefined, 'SHA3-512', ['sign', 'verify']],
659660
);
660661
} else {
661662
common.printSkipMessage('Skipping unsupported SHA-3 test cases');

0 commit comments

Comments
 (0)