bcrypt: Validate secret size in BCryptGenerateSymmetricKey().
Fixes online connection error in Forza Horizon 5. Signed-off-by: Paul Gofman <pgofman@codeweavers.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
33bc90e687
commit
028837158a
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue