From: Hans Leidekker <hans@codeweavers.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59870 --- dlls/bcrypt/bcrypt_main.c | 14 ++++++++++---- dlls/bcrypt/tests/bcrypt.c | 13 +++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 3ca369538b2..f3ebedfa09d 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -1676,7 +1676,8 @@ static NTSTATUS decrypt_aes_ecb( const struct key *key, const UCHAR *input, ULON } static NTSTATUS decrypt_aes_gcm( struct key *key, const UCHAR *input, ULONG input_len, - const BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO *info, UCHAR *output ) + const BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO *info, UCHAR *output, ULONG output_len, + ULONG *ret_len ) { SYMCRYPT_ERROR error; @@ -1684,6 +1685,9 @@ static NTSTATUS decrypt_aes_gcm( struct key *key, const UCHAR *input, ULONG inpu return STATUS_INVALID_PARAMETER; if (info->dwFlags & BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG) FIXME( "call chaining not implemented\n" ); + if (!output) return STATUS_SUCCESS; + if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL; + EnterCriticalSection( &key->s.cs ); SymCryptGcmInit( &key->s.gcm.state, &key->s.gcm.handle, info->pbNonce, info->cbNonce ); @@ -1774,7 +1778,7 @@ static NTSTATUS decrypt_symmetric( struct key *key, const UCHAR *input, ULONG in return decrypt_aes_ecb( key, input, input_len, output, output_len, ret_len, flags ); case CHAIN_MODE_GCM: - return decrypt_aes_gcm( key, input, input_len, info, output ); + return decrypt_aes_gcm( key, input, input_len, info, output, output_len, ret_len ); default: if (iv && iv_len != key->s.block_size) return STATUS_INVALID_PARAMETER; @@ -2031,13 +2035,15 @@ static NTSTATUS encrypt_aes_ecb( const struct key *key, const UCHAR *input, ULON } static NTSTATUS encrypt_aes_gcm( struct key *key, const UCHAR *input, ULONG input_len, - const BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO *info, UCHAR *output ) + const BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO *info, UCHAR *output, ULONG output_len, + ULONG *ret_len ) { if (!info || !info->pbNonce || !info->pbTag || info->cbTag < 12 || info->cbTag > 16) return STATUS_INVALID_PARAMETER; if (info->dwFlags & BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG) FIXME( "call chaining not implemented\n" ); if (input && !input_len) return STATUS_SUCCESS; + if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL; EnterCriticalSection( &key->s.cs ); @@ -2116,7 +2122,7 @@ static NTSTATUS encrypt_symmetric( struct key *key, const UCHAR *input, ULONG in return encrypt_aes_ecb( key, input, input_len, output, output_len, ret_len, flags ); case CHAIN_MODE_GCM: - return encrypt_aes_gcm( key, input, input_len, info, output ); + return encrypt_aes_gcm( key, input, input_len, info, output, output_len, ret_len ); default: if (iv && iv_len != key->s.block_size) return STATUS_INVALID_PARAMETER; diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index e7905f32145..2ad64492b8a 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -1316,6 +1316,9 @@ static void test_BCryptEncrypt(void) ok(tag[i] == expected_tag[i], "%lu: %02x != %02x\n", i, tag[i], expected_tag[i]); ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv data.\n"); + ret = BCryptEncrypt(key, data2, 32, &auth_info, ivbuf, 16, ciphertext, 31, &size, 0); + ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret); + /* NULL initialization vector */ size = 0; memset(ciphertext, 0xff, sizeof(ciphertext)); @@ -1916,6 +1919,16 @@ static void test_BCryptDecrypt(void) ok(!memcmp(plaintext, expected3, sizeof(expected3)), "wrong data\n"); ok(!memcmp(ivbuf, iv, sizeof(iv)), "wrong iv.\n"); + size = 0; + ret = BCryptDecrypt(key, ciphertext4, 32, &auth_info, ivbuf, 16, NULL, 0, &size, 0); + ok(ret == STATUS_SUCCESS, "got %#lx\n", ret); + ok(size == 32, "got %lu\n", size); + + size = 0; + ret = BCryptDecrypt(key, ciphertext4, 32, &auth_info, ivbuf, 16, plaintext, 31, &size, 0); + ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", ret); + ok(size == 32, "got %lu\n", size); + size = 0; memset(plaintext, 0, sizeof(plaintext)); ret = BCryptDecrypt(key, ciphertext4, 32, &auth_info, NULL, 0, plaintext, 32, &size, 0); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11170