crypto: allocate more memory for cipher.update()
For key wrapping algorithms, calling EVP_CipherUpdate() with null output could obtain the size for the ciphertext. Then use the returned size to allocate output buffer. Also add a test case to verify des3-wrap. Signed-off-by: Yihong Wang <yh.wang@ibm.com> PR-URL: https://github.com/nodejs/node/pull/20370 Fixes: https://github.com/nodejs/node/issues/19655 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
cd8ed1c447
commit
f7cdeba548
@ -3023,14 +3023,28 @@ CipherBase::UpdateResult CipherBase::Update(const char* data,
|
||||
auth_tag_set_ = true;
|
||||
}
|
||||
|
||||
*out_len = len + EVP_CIPHER_CTX_block_size(ctx_);
|
||||
*out = Malloc<unsigned char>(static_cast<size_t>(*out_len));
|
||||
*out_len = 0;
|
||||
int buff_len = len + EVP_CIPHER_CTX_block_size(ctx_);
|
||||
// For key wrapping algorithms, get output size by calling
|
||||
// EVP_CipherUpdate() with null output.
|
||||
if (mode == EVP_CIPH_WRAP_MODE &&
|
||||
EVP_CipherUpdate(ctx_,
|
||||
nullptr,
|
||||
&buff_len,
|
||||
reinterpret_cast<const unsigned char*>(data),
|
||||
len) != 1) {
|
||||
return kErrorState;
|
||||
}
|
||||
|
||||
*out = Malloc<unsigned char>(buff_len);
|
||||
int r = EVP_CipherUpdate(ctx_,
|
||||
*out,
|
||||
out_len,
|
||||
reinterpret_cast<const unsigned char*>(data),
|
||||
len);
|
||||
|
||||
CHECK_LE(*out_len, buff_len);
|
||||
|
||||
// When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is
|
||||
// invalid. In that case, remember the error and throw in final().
|
||||
if (!r && kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
|
||||
|
25
test/parallel/test-crypto-des3-wrap.js
Normal file
25
test/parallel/test-crypto-des3-wrap.js
Normal file
@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
if (!common.hasCrypto)
|
||||
common.skip('missing crypto');
|
||||
|
||||
const assert = require('assert');
|
||||
const crypto = require('crypto');
|
||||
|
||||
// Test case for des-ede3 wrap/unwrap. des3-wrap needs extra 2x blocksize
|
||||
// then plaintext to store ciphertext.
|
||||
const test = {
|
||||
key: Buffer.from('3c08e25be22352910671cfe4ba3652b1220a8a7769b490ba', 'hex'),
|
||||
iv: Buffer.alloc(0),
|
||||
plaintext: '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBG' +
|
||||
'WWELweCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZU' +
|
||||
'JjAfaFg**'
|
||||
};
|
||||
|
||||
const cipher = crypto.createCipheriv('des3-wrap', test.key, test.iv);
|
||||
const ciphertext = cipher.update(test.plaintext, 'utf8');
|
||||
|
||||
const decipher = crypto.createDecipheriv('des3-wrap', test.key, test.iv);
|
||||
const msg = decipher.update(ciphertext, 'buffer', 'utf8');
|
||||
|
||||
assert.strictEqual(msg, test.plaintext);
|
Loading…
x
Reference in New Issue
Block a user