Commit 02883715 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

bcrypt: Validate secret size in BCryptGenerateSymmetricKey().

Fixes online connection error in Forza Horizon 5. Signed-off-by: 's avatarPaul Gofman <pgofman@codeweavers.com> Signed-off-by: 's avatarHans Leidekker <hans@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 33bc90e6
......@@ -1521,9 +1521,10 @@ NTSTATUS WINAPI BCryptGenerateSymmetricKey( BCRYPT_ALG_HANDLE algorithm, BCRYPT_
UCHAR *object, ULONG object_len, UCHAR *secret, ULONG secret_len,
ULONG flags )
{
BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
struct algorithm *alg = algorithm;
ULONG block_size, size;
struct key *key;
ULONG block_size;
TRACE( "%p, %p, %p, %u, %p, %u, %08x\n", algorithm, handle, object, object_len, secret, secret_len, flags );
......@@ -1538,6 +1539,25 @@ NTSTATUS WINAPI BCryptGenerateSymmetricKey( BCRYPT_ALG_HANDLE algorithm, BCRYPT_
if (!(block_size = get_block_size( alg ))) return STATUS_INVALID_PARAMETER;
if (!get_alg_property( alg, BCRYPT_KEY_LENGTHS, (UCHAR*)&key_lengths, sizeof(key_lengths), &size ))
{
if (secret_len > (size = key_lengths.dwMaxLength / 8))
{
WARN( "secret_len %u exceeds key max length %u, setting to maximum.\n", secret_len, size );
secret_len = size;
}
else if (secret_len < (size = key_lengths.dwMinLength / 8))
{
WARN( "secret_len %u is less than minimum key length %u.\n", secret_len, size );
return STATUS_INVALID_PARAMETER;
}
else if (key_lengths.dwIncrement && (secret_len * 8 - key_lengths.dwMinLength) % key_lengths.dwIncrement)
{
WARN( "secret_len %u is not a valid key length.\n", secret_len );
return STATUS_INVALID_PARAMETER;
}
}
if (!(key = heap_alloc_zero( sizeof(*key) ))) return STATUS_NO_MEMORY;
InitializeCriticalSection( &key->u.s.cs );
key->hdr.magic = MAGIC_KEY;
......
......@@ -731,6 +731,17 @@ static void test_BCryptGenerateSymmetricKey(void)
key = NULL;
buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
key = (BCRYPT_KEY_HANDLE)0xdeadbeef;
ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, 1, 0);
ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
ok(key == (HANDLE)0xdeadbeef, "got unexpected key %p.\n", key);
key = (BCRYPT_KEY_HANDLE)0xdeadbeef;
ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret) + 1, 0);
ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
ok(key == (HANDLE)0xdeadbeef, "got unexpected key %p.\n", key);
ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
ok(key != NULL, "key not set\n");
......@@ -1101,8 +1112,16 @@ static void test_BCryptEncrypt(void)
/* 256 bit key */
buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret256, sizeof(secret256), 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
ret = pBCryptDestroyKey(key);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
/* Key generations succeeds if the key size exceeds maximum and uses maximum key length
* from secret. */
ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret256, sizeof(secret256) + 1, 0);
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
size = 0;
memcpy(ivbuf, iv, sizeof(iv));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment