From: Bruno Jesus <00cpxxx@gmail.com> Subject: [PATCH 5/7] bcrypt: Beginnings of the AES provider Message-Id: <20161207010621.23230-5-00cpxxx@gmail.com> Date: Tue, 6 Dec 2016 23:06:19 -0200 In-Reply-To: <20161207010621.23230-1-00cpxxx@gmail.com> References: <20161207010621.23230-1-00cpxxx@gmail.com> From: Hans Leidekker Signed-off-by: Bruno Jesus <00cpxxx@gmail.com> --- dlls/bcrypt/bcrypt_main.c | 40 +++++++++++++++++++++++++++++++++++++++- dlls/bcrypt/tests/bcrypt.c | 27 +++++++-------------------- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 5657264..21df85d 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -149,8 +149,10 @@ struct object ULONG magic; }; +/* Sorted by name, next struct must be completed too */ enum alg_id { + ALG_ID_AES, ALG_ID_MD5, ALG_ID_RNG, ALG_ID_SHA1, @@ -163,6 +165,7 @@ static const struct { ULONG hash_length; const WCHAR *alg_name; } alg_props[] = { + /* ALG_ID_AES */ { 16, BCRYPT_AES_ALGORITHM }, /* ALG_ID_MD5 */ { 16, BCRYPT_MD5_ALGORITHM }, /* ALG_ID_RNG */ { 0, BCRYPT_RNG_ALGORITHM }, /* ALG_ID_SHA1 */ { 20, BCRYPT_SHA1_ALGORITHM }, @@ -237,9 +240,10 @@ NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR return STATUS_NOT_IMPLEMENTED; } - if (!strcmpW( id, BCRYPT_SHA1_ALGORITHM )) alg_id = ALG_ID_SHA1; + if (!strcmpW( id, BCRYPT_AES_ALGORITHM )) alg_id = ALG_ID_AES; else if (!strcmpW( id, BCRYPT_MD5_ALGORITHM )) alg_id = ALG_ID_MD5; else if (!strcmpW( id, BCRYPT_RNG_ALGORITHM )) alg_id = ALG_ID_RNG; + else if (!strcmpW( id, BCRYPT_SHA1_ALGORITHM )) alg_id = ALG_ID_SHA1; else if (!strcmpW( id, BCRYPT_SHA256_ALGORITHM )) alg_id = ALG_ID_SHA256; else if (!strcmpW( id, BCRYPT_SHA384_ALGORITHM )) alg_id = ALG_ID_SHA384; else if (!strcmpW( id, BCRYPT_SHA512_ALGORITHM )) alg_id = ALG_ID_SHA512; @@ -566,6 +570,9 @@ static NTSTATUS key_init( struct key *key, enum alg_id id, UCHAR *secret, ULONG switch (id) { + case ALG_ID_AES: + break; + default: FIXME( "algorithm %u not supported\n", id ); return STATUS_NOT_SUPPORTED; @@ -650,12 +657,15 @@ static NTSTATUS key_destroy( struct key *key ) } #endif +#define OBJECT_LENGTH_AES 618 /* FIXME: This is the 32 bits value */ #define OBJECT_LENGTH_MD5 274 #define OBJECT_LENGTH_SHA1 278 #define OBJECT_LENGTH_SHA256 286 #define OBJECT_LENGTH_SHA384 382 #define OBJECT_LENGTH_SHA512 382 +#define BLOCK_LENGTH_AES 16 + static NTSTATUS generic_alg_property( enum alg_id id, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) { if (!strcmpW( prop, BCRYPT_HASH_LENGTH )) @@ -692,6 +702,34 @@ static NTSTATUS get_alg_property( enum alg_id id, const WCHAR *prop, UCHAR *buf, switch (id) { + case ALG_ID_AES: + if (!strcmpW( prop, BCRYPT_BLOCK_LENGTH )) + { + value = BLOCK_LENGTH_AES; + break; + } + if (!strcmpW( prop, BCRYPT_OBJECT_LENGTH )) + { + value = OBJECT_LENGTH_AES; + break; + } + if (!strcmpW( prop, BCRYPT_CHAINING_MODE )) + { + if (size >= sizeof(BCRYPT_CHAIN_MODE_CBC)) + { + memcpy(buf, BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC)); + *ret_size = sizeof(BCRYPT_CHAIN_MODE_CBC) * sizeof(WCHAR); + return STATUS_SUCCESS; + } + else + { + *ret_size = sizeof(BCRYPT_CHAIN_MODE_CBC) * sizeof(WCHAR); + return STATUS_BUFFER_TOO_SMALL; + } + } + FIXME( "unsupported AES algorithm property %s\n", debugstr_w(prop) ); + return STATUS_NOT_IMPLEMENTED; + case ALG_ID_MD5: if (!strcmpW( prop, BCRYPT_OBJECT_LENGTH )) { diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 3e41335..723b58e 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -780,7 +780,7 @@ static void test_aes(void) ULONG size, len; UCHAR mode[64]; NTSTATUS ret; -todo_wine { + alg = NULL; ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); @@ -828,7 +828,6 @@ todo_wine { ret = pBCryptCloseAlgorithmProvider(alg, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); } -} static void test_BCryptGenerateSymmetricKey(void) { @@ -847,11 +846,6 @@ static void test_BCryptGenerateSymmetricKey(void) NTSTATUS ret; ret = pBCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0); - if (ret != STATUS_SUCCESS) /* remove whole IF when Wine is fixed */ - { - todo_wine ok(0, "AES provider not available\n"); - return; - } ok(ret == STATUS_SUCCESS, "got %08x\n", ret); len = size = 0xdeadbeef; @@ -868,6 +862,7 @@ static void test_BCryptGenerateSymmetricKey(void) sizeof(BCRYPT_CHAIN_MODE_CBC), 0); todo_wine ok(ret == STATUS_SUCCESS, "got %08x\n", ret); +todo_wine { size = 0xdeadbeef; ret = pBCryptEncrypt(key, NULL, 0, NULL, NULL, 0, NULL, 0, &size, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); @@ -907,7 +902,7 @@ static void test_BCryptGenerateSymmetricKey(void) ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(size == 16, "got %u\n", size); ok(!memcmp(plaintext, data, sizeof(data)), "wrong data\n"); - +} ret = pBCryptDestroyKey(key); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); HeapFree(GetProcessHeap(), 0, buf); @@ -936,11 +931,6 @@ static void test_BCryptEncrypt(void) NTSTATUS ret; ret = pBCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0); - if (ret != STATUS_SUCCESS) /* remove whole IF when Wine is fixed */ - { - todo_wine ok(0, "AES provider not available\n"); - return; - } ok(ret == STATUS_SUCCESS, "got %08x\n", ret); len = 0xdeadbeef; @@ -953,6 +943,7 @@ static void test_BCryptEncrypt(void) ok(ret == STATUS_SUCCESS, "got %08x\n", ret); /* input size is a multiple of block size */ +todo_wine { size = 0; memcpy(ivbuf, iv, sizeof(iv)); ret = pBCryptEncrypt(key, data, 16, NULL, ivbuf, 16, NULL, 0, &size, 0); @@ -1000,7 +991,7 @@ static void test_BCryptEncrypt(void) ret = pBCryptEncrypt(key, data, 17, NULL, ivbuf, 16, ciphertext, 31, &size, BCRYPT_BLOCK_PADDING); ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret); ok(size == 32, "got %u\n", size); - +} ret = pBCryptDestroyKey(key); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); HeapFree(GetProcessHeap(), 0, buf); @@ -1027,11 +1018,6 @@ static void test_BCryptDecrypt(void) NTSTATUS ret; ret = pBCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0); - if (ret != STATUS_SUCCESS) /* remove whole IF when Wine is fixed */ - { - todo_wine ok(0, "AES provider not available\n"); - return; - } ok(ret == STATUS_SUCCESS, "got %08x\n", ret); len = 0xdeadbeef; @@ -1043,6 +1029,7 @@ static void test_BCryptDecrypt(void) ret = pBCryptGenerateSymmetricKey(aes, &key, buf, len, secret, sizeof(secret), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); +todo_wine { /* input size is a multiple of block size */ size = 0; memcpy(ivbuf, iv, sizeof(iv)); @@ -1078,7 +1065,7 @@ static void test_BCryptDecrypt(void) ret = pBCryptDecrypt(key, ciphertext, 17, NULL, ivbuf, 16, NULL, 0, &size, BCRYPT_BLOCK_PADDING); ok(ret == STATUS_INVALID_BUFFER_SIZE, "got %08x\n", ret); ok(size == 17 || broken(size == 0 /* Win < 7 */), "got %u\n", size); - +} ret = pBCryptDestroyKey(key); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); HeapFree(GetProcessHeap(), 0, buf); -- 2.9.3