forked from Mirrors/wine-wine
bcrypt: Add support for computing/comparing cipher tag.
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
8d2b1d276d
commit
c7b46e8e3c
|
@ -50,6 +50,9 @@ static HINSTANCE instance;
|
|||
#if defined(HAVE_GNUTLS_CIPHER_INIT) && !defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H)
|
||||
WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
||||
|
||||
/* Not present in gnutls version < 3.0 */
|
||||
static int (*pgnutls_cipher_tag)(gnutls_cipher_hd_t handle, void * tag, size_t tag_size);
|
||||
|
||||
static void *libgnutls_handle;
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
MAKE_FUNCPTR(gnutls_cipher_decrypt2);
|
||||
|
@ -69,6 +72,11 @@ MAKE_FUNCPTR(gnutls_perror);
|
|||
#define GNUTLS_CIPHER_AES_256_GCM 94
|
||||
#endif
|
||||
|
||||
static int compat_gnutls_cipher_tag(gnutls_cipher_hd_t handle, void * tag, size_t tag_size)
|
||||
{
|
||||
return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
|
||||
}
|
||||
|
||||
static void gnutls_log( int level, const char *msg )
|
||||
{
|
||||
TRACE( "<%d> %s", level, msg );
|
||||
|
@ -102,6 +110,12 @@ static BOOL gnutls_initialize(void)
|
|||
LOAD_FUNCPTR(gnutls_perror)
|
||||
#undef LOAD_FUNCPTR
|
||||
|
||||
if (!(pgnutls_cipher_tag = wine_dlsym( libgnutls_handle, "gnutls_cipher_tag", NULL, 0 )))
|
||||
{
|
||||
WARN("gnutls_cipher_tag not found\n");
|
||||
pgnutls_cipher_tag = compat_gnutls_cipher_tag;
|
||||
}
|
||||
|
||||
if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS)
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
|
@ -1018,6 +1032,19 @@ static NTSTATUS key_decrypt( struct key *key, const UCHAR *input, ULONG input_le
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS key_get_tag( struct key *key, UCHAR *tag, ULONG len )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = pgnutls_cipher_tag( key->handle, tag, len )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS key_destroy( struct key *key )
|
||||
{
|
||||
if (key->handle) pgnutls_cipher_deinit( key->handle );
|
||||
|
@ -1123,6 +1150,12 @@ static NTSTATUS key_decrypt( struct key *key, const UCHAR *input, ULONG input_le
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS key_get_tag( struct key *key, UCHAR *tag, ULONG len )
|
||||
{
|
||||
FIXME( "not implemented on Mac\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS key_destroy( struct key *key )
|
||||
{
|
||||
if (key->ref_encrypt) CCCryptorRelease( key->ref_encrypt );
|
||||
|
@ -1158,6 +1191,12 @@ static NTSTATUS key_decrypt( struct key *key, const UCHAR *input, ULONG input_le
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS key_get_tag( struct key *key, UCHAR *tag, ULONG len )
|
||||
{
|
||||
ERR( "support for keys not available at build time\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS key_destroy( struct key *key )
|
||||
{
|
||||
ERR( "support for keys not available at build time\n" );
|
||||
|
@ -1311,7 +1350,7 @@ NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
|
|||
if ((status = key_encrypt( key, input, input_len, output, output_len )))
|
||||
return status;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return key_get_tag( key, auth_info->pbTag, auth_info->cbTag );
|
||||
}
|
||||
|
||||
if ((status = key_set_params( key, iv, iv_len ))) return status;
|
||||
|
@ -1370,6 +1409,7 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
|
|||
if (key->mode == MODE_ID_GCM)
|
||||
{
|
||||
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO *auth_info = padding;
|
||||
UCHAR tag[16];
|
||||
|
||||
if (!auth_info) return STATUS_INVALID_PARAMETER;
|
||||
if (!auth_info->pbNonce) return STATUS_INVALID_PARAMETER;
|
||||
|
@ -1387,6 +1427,11 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
|
|||
if ((status = key_decrypt( key, input, input_len, output, output_len )))
|
||||
return status;
|
||||
|
||||
if ((status = key_get_tag( key, tag, sizeof(tag) )))
|
||||
return status;
|
||||
if (memcmp( tag, auth_info->pbTag, auth_info->cbTag ))
|
||||
return STATUS_AUTH_TAG_MISMATCH;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -754,11 +754,11 @@ static void test_BCryptEncrypt(void)
|
|||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
ok(size == 32, "got %u\n", size);
|
||||
ok(!memcmp(ciphertext, expected4, sizeof(expected4)), "wrong data\n");
|
||||
todo_wine ok(!memcmp(tag, expected_tag, sizeof(expected_tag)), "wrong tag\n");
|
||||
ok(!memcmp(tag, expected_tag, sizeof(expected_tag)), "wrong tag\n");
|
||||
for (i = 0; i < 32; i++)
|
||||
ok(ciphertext[i] == expected4[i], "%u: %02x != %02x\n", i, ciphertext[i], expected4[i]);
|
||||
for (i = 0; i < 16; i++)
|
||||
todo_wine ok(tag[i] == expected_tag[i], "%u: %02x != %02x\n", i, tag[i], expected_tag[i]);
|
||||
ok(tag[i] == expected_tag[i], "%u: %02x != %02x\n", i, tag[i], expected_tag[i]);
|
||||
|
||||
/* input size is not multiple of block size */
|
||||
size = 0;
|
||||
|
@ -769,11 +769,11 @@ static void test_BCryptEncrypt(void)
|
|||
ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
|
||||
ok(size == 24, "got %u\n", size);
|
||||
ok(!memcmp(ciphertext, expected4, 24), "wrong data\n");
|
||||
todo_wine ok(!memcmp(tag, expected_tag2, sizeof(expected_tag2)), "wrong tag\n");
|
||||
ok(!memcmp(tag, expected_tag2, sizeof(expected_tag2)), "wrong tag\n");
|
||||
for (i = 0; i < 24; i++)
|
||||
ok(ciphertext[i] == expected4[i], "%u: %02x != %02x\n", i, ciphertext[i], expected4[i]);
|
||||
for (i = 0; i < 16; i++)
|
||||
todo_wine ok(tag[i] == expected_tag2[i], "%u: %02x != %02x\n", i, tag[i], expected_tag2[i]);
|
||||
ok(tag[i] == expected_tag2[i], "%u: %02x != %02x\n", i, tag[i], expected_tag2[i]);
|
||||
|
||||
/* test with padding */
|
||||
memcpy(ivbuf, iv, sizeof(iv));
|
||||
|
@ -977,7 +977,7 @@ static void test_BCryptDecrypt(void)
|
|||
memcpy(ivbuf, iv, sizeof(iv));
|
||||
auth_info.pbTag = iv; /* wrong tag */
|
||||
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);
|
||||
ok(ret == STATUS_AUTH_TAG_MISMATCH, "got %08x\n", ret);
|
||||
ok(size == 32, "got %u\n", size);
|
||||
|
||||
ret = pBCryptDestroyKey(key);
|
||||
|
|
Loading…
Reference in New Issue