Skip to content

Commit 214354f

Browse files
authored
crypto: fix webcrypto HMAC "get key length" in deriveKey and generateKey
PR-URL: #44917 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent 40a0757 commit 214354f

File tree

5 files changed

+41
-26
lines changed

5 files changed

+41
-26
lines changed

lib/internal/crypto/mac.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const {
1414
} = internalBinding('crypto');
1515

1616
const {
17-
getHashLength,
17+
getBlockSize,
1818
hasAnyNotIn,
1919
jobPromise,
2020
normalizeHashName,
@@ -54,7 +54,7 @@ async function hmacGenerateKey(algorithm, extractable, keyUsages) {
5454
throw new ERR_MISSING_OPTION('algorithm.hash');
5555

5656
if (length === undefined)
57-
length = getHashLength(hash.name);
57+
length = getBlockSize(hash.name);
5858

5959
validateBitLength(length, 'algorithm.length', true);
6060

lib/internal/crypto/util.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,12 @@ function getUsagesUnion(usageSet, ...usages) {
340340
return newset;
341341
}
342342

343-
function getHashLength(name) {
343+
function getBlockSize(name) {
344344
switch (name) {
345-
case 'SHA-1': return 160;
346-
case 'SHA-256': return 256;
347-
case 'SHA-384': return 384;
348-
case 'SHA-512': return 512;
345+
case 'SHA-1': return 512;
346+
case 'SHA-256': return 512;
347+
case 'SHA-384': return 1024;
348+
case 'SHA-512': return 1024;
349349
}
350350
}
351351

@@ -430,8 +430,8 @@ module.exports = {
430430
validateMaxBufferLength,
431431
bigIntArrayToUnsignedBigInt,
432432
bigIntArrayToUnsignedInt,
433+
getBlockSize,
433434
getStringOption,
434435
getUsagesUnion,
435-
getHashLength,
436436
secureHeapUsed,
437437
};

lib/internal/crypto/webcrypto.js

+2-10
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ const {
5656

5757
const {
5858
getArrayBufferOrView,
59+
getBlockSize,
5960
hasAnyNotIn,
6061
lazyRequire,
6162
normalizeAlgorithm,
@@ -200,16 +201,7 @@ function getKeyLength({ name, length, hash }) {
200201
return length;
201202
case 'HMAC':
202203
if (length === undefined) {
203-
switch (hash?.name) {
204-
case 'SHA-1':
205-
return 160;
206-
case 'SHA-256':
207-
return 256;
208-
case 'SHA-384':
209-
return 384;
210-
case 'SHA-512':
211-
return 512;
212-
}
204+
return getBlockSize(hash?.name);
213205
}
214206

215207
if (typeof length === 'number' && length !== 0) {

test/parallel/test-webcrypto-derivekey.js

+27-4
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,11 @@ const { webcrypto: { subtle }, KeyObject } = require('crypto');
124124
const vectors = [
125125
['PBKDF2', 'deriveKey', 528],
126126
['HKDF', 'deriveKey', 528],
127-
[{ name: 'HMAC', hash: 'SHA-1' }, 'sign', 160],
128-
[{ name: 'HMAC', hash: 'SHA-256' }, 'sign', 256],
129-
[{ name: 'HMAC', hash: 'SHA-384' }, 'sign', 384],
130-
[{ name: 'HMAC', hash: 'SHA-512' }, 'sign', 512],
127+
[{ name: 'HMAC', hash: 'SHA-1' }, 'sign', 512],
128+
[{ name: 'HMAC', hash: 'SHA-256' }, 'sign', 512],
129+
// Not long enough secret generated by ECDH
130+
// [{ name: 'HMAC', hash: 'SHA-384' }, 'sign', 1024],
131+
// [{ name: 'HMAC', hash: 'SHA-512' }, 'sign', 1024],
131132
];
132133

133134
(async () => {
@@ -151,6 +152,28 @@ const { webcrypto: { subtle }, KeyObject } = require('crypto');
151152
})().then(common.mustCall());
152153
}
153154

155+
{
156+
const vectors = [
157+
[{ name: 'HMAC', hash: 'SHA-1' }, 'sign', 512],
158+
[{ name: 'HMAC', hash: 'SHA-256' }, 'sign', 512],
159+
[{ name: 'HMAC', hash: 'SHA-384' }, 'sign', 1024],
160+
[{ name: 'HMAC', hash: 'SHA-512' }, 'sign', 1024],
161+
];
162+
163+
(async () => {
164+
for (const [derivedKeyAlgorithm, usage, expected] of vectors) {
165+
const derived = await subtle.deriveKey(
166+
{ name: 'PBKDF2', salt: new Uint8Array([]), hash: 'SHA-256', iterations: 20 },
167+
await subtle.importKey('raw', new Uint8Array([]), { name: 'PBKDF2' }, false, ['deriveKey']),
168+
derivedKeyAlgorithm,
169+
false,
170+
[usage]);
171+
172+
assert.strictEqual(derived.algorithm.length, expected);
173+
}
174+
})().then(common.mustCall());
175+
}
176+
154177
// Test X25519 and X448 key derivation
155178
{
156179
async function test(name) {

test/parallel/test-webcrypto-keygen.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -551,10 +551,10 @@ const vectors = {
551551

552552
if (length === undefined) {
553553
switch (hash) {
554-
case 'SHA-1': length = 160; break;
555-
case 'SHA-256': length = 256; break;
556-
case 'SHA-384': length = 384; break;
557-
case 'SHA-512': length = 512; break;
554+
case 'SHA-1': length = 512; break;
555+
case 'SHA-256': length = 512; break;
556+
case 'SHA-384': length = 1024; break;
557+
case 'SHA-512': length = 1024; break;
558558
}
559559
}
560560

0 commit comments

Comments
 (0)