Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2b2ccae

Browse filesBrowse files
tniessenaddaleax
authored andcommitted
crypto: support authTagLength in GCM encryption
The authTagLength option can now be used to produce GCM authentication tags with a specific length. Backport-PR-URL: #20706 PR-URL: #20235 Refs: #20039 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Yihong Wang <yh.wang@ibm.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
1 parent 1e5de6f commit 2b2ccae
Copy full SHA for 2b2ccae

File tree

Expand file treeCollapse file tree

3 files changed

+48
-5
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+48
-5
lines changed
Open diff view settings
Collapse file

‎doc/api/crypto.md‎

Copy file name to clipboardExpand all lines: doc/api/crypto.md
+15-2Lines changed: 15 additions & 2 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,11 @@ This property is deprecated. Please use `crypto.setFips()` and
13161316
<!-- YAML
13171317
added: v0.1.94
13181318
deprecated: v10.0.0
1319+
changes:
1320+
- version: REPLACEME
1321+
pr-url: https://github.com/nodejs/node/pull/20235
1322+
description: The `authTagLength` option can now be used to produce shorter
1323+
authentication tags in GCM mode and defaults to 16 bytes.
13191324
-->
13201325

13211326
> Stability: 0 - Deprecated: Use [`crypto.createCipheriv()`][] instead.
@@ -1331,7 +1336,9 @@ Creates and returns a `Cipher` object that uses the given `algorithm` and
13311336
The `options` argument controls stream behavior and is optional except when a
13321337
cipher in CCM mode is used (e.g. `'aes-128-ccm'`). In that case, the
13331338
`authTagLength` option is required and specifies the length of the
1334-
authentication tag in bytes, see [CCM mode][].
1339+
authentication tag in bytes, see [CCM mode][]. In GCM mode, the `authTagLength`
1340+
option is not required but can be used to set the length of the authentication
1341+
tag that will be returned by `getAuthTag()` and defaults to 16 bytes.
13351342

13361343
The `algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc. On
13371344
recent OpenSSL releases, `openssl list -cipher-algorithms`
@@ -1362,6 +1369,10 @@ Adversaries][] for details.
13621369
<!-- YAML
13631370
added: v0.1.94
13641371
changes:
1372+
- version: REPLACEME
1373+
pr-url: https://github.com/nodejs/node/pull/20235
1374+
description: The `authTagLength` option can now be used to produce shorter
1375+
authentication tags in GCM mode and defaults to 16 bytes.
13651376
- version: v9.9.0
13661377
pr-url: https://github.com/nodejs/node/pull/18644
13671378
description: The `iv` parameter may now be `null` for ciphers which do not
@@ -1379,7 +1390,9 @@ initialization vector (`iv`).
13791390
The `options` argument controls stream behavior and is optional except when a
13801391
cipher in CCM mode is used (e.g. `'aes-128-ccm'`). In that case, the
13811392
`authTagLength` option is required and specifies the length of the
1382-
authentication tag in bytes, see [CCM mode][].
1393+
authentication tag in bytes, see [CCM mode][]. In GCM mode, the `authTagLength`
1394+
option is not required but can be used to set the length of the authentication
1395+
tag that will be returned by `getAuthTag()` and defaults to 16 bytes.
13831396

13841397
The `algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc. On
13851398
recent OpenSSL releases, `openssl list -cipher-algorithms`
Collapse file

‎src/node_crypto.cc‎

Copy file name to clipboardExpand all lines: src/node_crypto.cc
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3123,9 +3123,10 @@ bool CipherBase::Final(unsigned char** out, int *out_len) {
31233123
ok = EVP_CipherFinal_ex(ctx_, *out, out_len) == 1;
31243124

31253125
if (ok && kind_ == kCipher && IsAuthenticatedMode()) {
3126-
// For GCM, the tag length is static (16 bytes), while the CCM tag length
3127-
// must be specified in advance.
3128-
if (mode == EVP_CIPH_GCM_MODE)
3126+
// In GCM mode, the authentication tag length can be specified in advance,
3127+
// but defaults to 16 bytes when encrypting. In CCM mode, it must always
3128+
// be given by the user.
3129+
if (mode == EVP_CIPH_GCM_MODE && auth_tag_len_ == kNoAuthTagLength)
31293130
auth_tag_len_ = sizeof(auth_tag_);
31303131
CHECK_EQ(1, EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_AEAD_GET_TAG,
31313132
auth_tag_len_,
Collapse file

‎test/parallel/test-crypto-authenticated.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-crypto-authenticated.js
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,18 @@ for (const test of TEST_CASES) {
730730

731731
// Explicitely passing invalid lengths should throw.
732732
for (const length of [0, 1, 2, 6, 9, 10, 11, 17]) {
733+
common.expectsError(() => {
734+
crypto.createCipheriv('aes-256-gcm',
735+
'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',
736+
'qkuZpJWCewa6Szih',
737+
{
738+
authTagLength: length
739+
});
740+
}, {
741+
type: Error,
742+
message: `Invalid GCM authentication tag length: ${length}`
743+
});
744+
733745
common.expectsError(() => {
734746
crypto.createDecipheriv('aes-256-gcm',
735747
'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',
@@ -744,6 +756,23 @@ for (const test of TEST_CASES) {
744756
}
745757
}
746758

759+
// Test that GCM can produce shorter authentication tags than 16 bytes.
760+
{
761+
const fullTag = '1debb47b2c91ba2cea16fad021703070';
762+
for (const [authTagLength, e] of [[undefined, 16], [12, 12], [4, 4]]) {
763+
const cipher = crypto.createCipheriv('aes-256-gcm',
764+
'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',
765+
'qkuZpJWCewa6Szih', {
766+
authTagLength
767+
});
768+
cipher.setAAD(Buffer.from('abcd'));
769+
cipher.update('01234567', 'hex');
770+
cipher.final();
771+
const tag = cipher.getAuthTag();
772+
assert.strictEqual(tag.toString('hex'), fullTag.substr(0, 2 * e));
773+
}
774+
}
775+
747776
// Test that users can manually restrict the GCM tag length to a single value.
748777
{
749778
const decipher = crypto.createDecipheriv('aes-256-gcm',

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.