forked from Mirrors/wine-wine
bcrypt: Implement BCryptDecrypt for AES GCM mode.
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair@hotmail.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>oldstable
parent
7c9291ce07
commit
8d2b1d276d
|
@ -1361,17 +1361,35 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
|
||||||
padding, iv, iv_len, output, output_len, ret_len, flags );
|
padding, iv, iv_len, output, output_len, ret_len, flags );
|
||||||
|
|
||||||
if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
|
if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
|
||||||
if (padding)
|
|
||||||
{
|
|
||||||
FIXME( "padding info not implemented\n" );
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
if (flags & ~BCRYPT_BLOCK_PADDING)
|
if (flags & ~BCRYPT_BLOCK_PADDING)
|
||||||
{
|
{
|
||||||
FIXME( "flags %08x not supported\n", flags );
|
FIXME( "flags %08x not supported\n", flags );
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key->mode == MODE_ID_GCM)
|
||||||
|
{
|
||||||
|
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO *auth_info = padding;
|
||||||
|
|
||||||
|
if (!auth_info) return STATUS_INVALID_PARAMETER;
|
||||||
|
if (!auth_info->pbNonce) return STATUS_INVALID_PARAMETER;
|
||||||
|
if (!auth_info->pbTag) return STATUS_INVALID_PARAMETER;
|
||||||
|
if (auth_info->cbTag < 12 || auth_info->cbTag > 16) return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if ((status = key_set_params( key, auth_info->pbNonce, auth_info->cbNonce )))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
*ret_len = input_len;
|
||||||
|
if (flags & BCRYPT_BLOCK_PADDING) return STATUS_INVALID_PARAMETER;
|
||||||
|
if (!output) return STATUS_SUCCESS;
|
||||||
|
if (output_len < *ret_len) return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
if ((status = key_decrypt( key, input, input_len, output, output_len )))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if ((status = key_set_params( key, iv, iv_len ))) return status;
|
if ((status = key_set_params( key, iv, iv_len ))) return status;
|
||||||
|
|
||||||
*ret_len = input_len;
|
*ret_len = input_len;
|
||||||
|
|
|
@ -969,16 +969,16 @@ static void test_BCryptDecrypt(void)
|
||||||
memcpy(ivbuf, iv, sizeof(iv));
|
memcpy(ivbuf, iv, sizeof(iv));
|
||||||
memset(plaintext, 0, sizeof(plaintext));
|
memset(plaintext, 0, sizeof(plaintext));
|
||||||
ret = pBCryptDecrypt(key, ciphertext4, 32, &auth_info, ivbuf, 16, plaintext, 32, &size, 0);
|
ret = pBCryptDecrypt(key, ciphertext4, 32, &auth_info, ivbuf, 16, plaintext, 32, &size, 0);
|
||||||
todo_wine ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||||
todo_wine ok(size == 32, "got %u\n", size);
|
ok(size == 32, "got %u\n", size);
|
||||||
todo_wine ok(!memcmp(plaintext, expected3, sizeof(expected3)), "wrong data\n");
|
ok(!memcmp(plaintext, expected3, sizeof(expected3)), "wrong data\n");
|
||||||
|
|
||||||
/* test with wrong tag */
|
/* test with wrong tag */
|
||||||
memcpy(ivbuf, iv, sizeof(iv));
|
memcpy(ivbuf, iv, sizeof(iv));
|
||||||
auth_info.pbTag = iv; /* wrong tag */
|
auth_info.pbTag = iv; /* wrong tag */
|
||||||
ret = pBCryptDecrypt(key, ciphertext4, 32, &auth_info, ivbuf, 16, plaintext, 32, &size, 0);
|
ret = pBCryptDecrypt(key, ciphertext4, 32, &auth_info, ivbuf, 16, plaintext, 32, &size, 0);
|
||||||
todo_wine ok(ret == STATUS_AUTH_TAG_MISMATCH, "got %08x\n", ret);
|
todo_wine ok(ret == STATUS_AUTH_TAG_MISMATCH, "got %08x\n", ret);
|
||||||
todo_wine ok(size == 32, "got %u\n", size);
|
ok(size == 32, "got %u\n", size);
|
||||||
|
|
||||||
ret = pBCryptDestroyKey(key);
|
ret = pBCryptDestroyKey(key);
|
||||||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||||
|
|
Loading…
Reference in New Issue