Skip to content

Commit dfe3f95

Browse files
committed
crypto: fix crash in CCM mode without data
Fixes: #38035 PR-URL: #38102 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 8930eba commit dfe3f95

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

Diff for: doc/api/crypto.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -5218,7 +5218,7 @@ mode must adhere to certain restrictions when using the cipher API:
52185218
`plaintextLength + authTagLength`. Node.js does not include the authentication
52195219
tag, so the ciphertext length is always `plaintextLength`.
52205220
This is not necessary if no AAD is used.
5221-
* As CCM processes the whole message at once, `update()` can only be called
5221+
* As CCM processes the whole message at once, `update()` must be called exactly
52225222
once.
52235223
* Even though calling `update()` is sufficient to encrypt/decrypt the message,
52245224
applications *must* call `final()` to compute or verify the

Diff for: src/crypto/crypto_cipher.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -844,9 +844,9 @@ bool CipherBase::Final(AllocatedBuffer* out) {
844844
CHECK(mode == EVP_CIPH_GCM_MODE);
845845
auth_tag_len_ = sizeof(auth_tag_);
846846
}
847-
CHECK_EQ(1, EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG,
848-
auth_tag_len_,
849-
reinterpret_cast<unsigned char*>(auth_tag_)));
847+
ok = (1 == EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG,
848+
auth_tag_len_,
849+
reinterpret_cast<unsigned char*>(auth_tag_)));
850850
}
851851
}
852852

Diff for: test/parallel/test-crypto-authenticated.js

+22
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ const expectedWarnings = common.hasFipsCrypto ?
7070
['Use Cipheriv for counter mode of aes-256-ccm'],
7171
['Use Cipheriv for counter mode of aes-256-ccm'],
7272
['Use Cipheriv for counter mode of aes-256-ccm'],
73+
['Use Cipheriv for counter mode of aes-128-ccm'],
7374
];
7475

7576
const expectedDeprecationWarnings = [
@@ -665,3 +666,24 @@ for (const test of TEST_CASES) {
665666
function H(length) { return '00'.repeat(length); }
666667
}
667668
}
669+
670+
{
671+
// CCM cipher without data should not crash, see https://github.com/nodejs/node/issues/38035.
672+
const algo = 'aes-128-ccm';
673+
const key = Buffer.alloc(16);
674+
const iv = Buffer.alloc(12);
675+
const opts = { authTagLength: 10 };
676+
677+
for (const cipher of [
678+
crypto.createCipher(algo, 'foo', opts),
679+
crypto.createCipheriv(algo, key, iv, opts),
680+
]) {
681+
assert.throws(() => {
682+
cipher.final();
683+
}, common.hasOpenSSL3 ? {
684+
code: 'ERR_OSSL_TAG_NOT_SET'
685+
} : {
686+
message: /Unsupported state/
687+
});
688+
}
689+
}

0 commit comments

Comments
 (0)