From 2e4d37e3f0d9c49306e9403462465ba445bee727 Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Fri, 9 Dec 2022 12:24:51 +0100 Subject: [PATCH] crypto: fix CipherBase Update int32 overflow PR-URL: https://github.com/nodejs/node/pull/45769 Fixes: https://github.com/nodejs/node/issues/45757 Reviewed-By: Anna Henningsen Reviewed-By: Filip Skokan Reviewed-By: Luigi Pinca Reviewed-By: Ben Noordhuis Reviewed-By: Paolo Insogna --- src/crypto/crypto_cipher.cc | 6 +++++- test/parallel/test-crypto-cipheriv-decipheriv.js | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index b907e9e9cdc4e4..81ba818a2dc7d3 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -803,7 +803,11 @@ CipherBase::UpdateResult CipherBase::Update( if (kind_ == kDecipher && IsAuthenticatedMode()) CHECK(MaybePassAuthTagToOpenSSL()); - int buf_len = len + EVP_CIPHER_CTX_block_size(ctx_.get()); + const int block_size = EVP_CIPHER_CTX_block_size(ctx_.get()); + CHECK_GT(block_size, 0); + if (len + block_size > INT_MAX) return kErrorState; + int buf_len = len + block_size; + // For key wrapping algorithms, get output size by calling // EVP_CipherUpdate() with null output. if (kind_ == kCipher && mode == EVP_CIPH_WRAP_MODE && diff --git a/test/parallel/test-crypto-cipheriv-decipheriv.js b/test/parallel/test-crypto-cipheriv-decipheriv.js index 87f3641fb188bd..3e3632203af72c 100644 --- a/test/parallel/test-crypto-cipheriv-decipheriv.js +++ b/test/parallel/test-crypto-cipheriv-decipheriv.js @@ -215,3 +215,11 @@ for (let n = minIvLength; n < maxIvLength; n += 1) { () => crypto.createCipheriv('aes-128-ecb', Buffer.alloc(17), null), /Invalid key length/); } + +{ + // https://github.com/nodejs/node/issues/45757 + // eslint-disable-next-line no-restricted-syntax + assert.throws(() => + crypto.createCipheriv('aes-128-gcm', Buffer.alloc(16), Buffer.alloc(12)) + .update(Buffer.allocUnsafeSlow(2 ** 31 - 1))); +}