Skip to content

Commit b5690e7

Browse files
committed
crypto: fix SHAKE128/256 breaking change introduced with OpenSSL 3.4
Update doc/api/deprecations.md Update doc/api/deprecations.md
1 parent ecc4ab1 commit b5690e7

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed

doc/api/deprecations.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4061,6 +4061,19 @@ Type: Documentation-only
40614061

40624062
The [`util.types.isNativeError`][] API is deprecated. Please use [`Error.isError`][] instead.
40634063

4064+
### DEP0198: Creating SHAKE-128 and SHAKE-256 digests without an explicit `options.outputLength`
4065+
4066+
<!-- YAML
4067+
changes:
4068+
- version: REPLACEME
4069+
pr-url: https://github.com/nodejs/node/pull/58942
4070+
description: Documentation-only deprecation with support for `--pending-deprecation`.
4071+
-->
4072+
4073+
Type: Documentation-only (supports [`--pending-deprecation`][])
4074+
4075+
Creating SHAKE-128 and SHAKE-256 digests without an explicit `options.outputLength` is deprecated.
4076+
40644077
[DEP0142]: #dep0142-repl_builtinlibs
40654078
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
40664079
[RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3

lib/internal/crypto/hash.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,24 @@ const {
5858
isArrayBufferView,
5959
} = require('internal/util/types');
6060

61+
const { getOptionValue } = require('internal/options');
62+
6163
const LazyTransform = require('internal/streams/lazy_transform');
6264

6365
const kState = Symbol('kState');
6466
const kFinalized = Symbol('kFinalized');
6567

68+
/**
69+
* @param {string} name
70+
*/
71+
function normalizeAlgorithm(name) {
72+
return name.toLowerCase().replace('-', '');
73+
}
74+
75+
const pendingDeprecation = getOptionValue('--pending-deprecation');
76+
let shakeWarningEmitted = false;
77+
const shakeWarning = 'Creating SHAKE-128 and SHAKE-256 digests without an explicit options.outputLength is deprecated.';
78+
6679
function Hash(algorithm, options) {
6780
if (!new.target)
6881
return new Hash(algorithm, options);
@@ -80,6 +93,13 @@ function Hash(algorithm, options) {
8093
this[kState] = {
8194
[kFinalized]: false,
8295
};
96+
if (pendingDeprecation && !shakeWarningEmitted && !isCopy && xofLen === undefined) {
97+
const normalized = normalizeAlgorithm(algorithm);
98+
if (normalized === 'shake128' || normalized === 'shake256') {
99+
process.emitWarning(shakeWarning, 'DeprecationWarning', 'DEP0198');
100+
shakeWarningEmitted = true;
101+
}
102+
}
83103
ReflectApply(LazyTransform, this, [options]);
84104
}
85105

@@ -213,6 +233,12 @@ function hash(algorithm, input, outputEncoding = 'hex') {
213233
}
214234
}
215235
}
236+
// TODO: ideally we have to ship https://github.com/nodejs/node/pull/58121 so
237+
// that a proper DEP0198 deprecation can be done here as well.
238+
const normalizedAlgorithm = normalizeAlgorithm(algorithm);
239+
if (normalizedAlgorithm === 'shake128' || normalizedAlgorithm === 'shake256') {
240+
return new Hash(algorithm).update(input).digest(outputEncoding);
241+
}
216242
return oneShotDigest(algorithm, getCachedHashId(algorithm), getHashCache(),
217243
input, normalized, encodingsMap[normalized]);
218244
}

src/crypto/crypto_hash.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,18 @@ bool Hash::HashInit(const EVP_MD* md, Maybe<unsigned int> xof_md_len) {
331331
}
332332

333333
md_len_ = mdctx_.getDigestSize();
334+
// TODO(@panva): remove this behaviour when DEP0198 is End-Of-Life
335+
if (mdctx_.hasXofFlag() && !xof_md_len.IsJust() && md_len_ == 0) {
336+
const char* name = OBJ_nid2sn(EVP_MD_type(md));
337+
if (name != nullptr) {
338+
if (strcmp(name, "SHAKE128") == 0) {
339+
md_len_ = 16;
340+
} else if (strcmp(name, "SHAKE256") == 0) {
341+
md_len_ = 32;
342+
}
343+
}
344+
}
345+
334346
if (xof_md_len.IsJust() && xof_md_len.FromJust() != md_len_) {
335347
// This is a little hack to cause createHash to fail when an incorrect
336348
// hashSize option was passed for a non-XOF hash function.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Flags: --pending-deprecation
2+
'use strict';
3+
4+
const common = require('../common');
5+
if (!common.hasCrypto)
6+
common.skip('missing crypto');
7+
8+
const { createHash } = require('crypto');
9+
10+
common.expectWarning({
11+
DeprecationWarning: {
12+
DEP0198: 'Creating SHAKE-128 and SHAKE-256 digests without an explicit options.outputLength is deprecated.',
13+
}
14+
});
15+
16+
{
17+
createHash('shake128').update('test').digest();
18+
}

0 commit comments

Comments
 (0)