[3/4] rsaenh: Change the way AES 128 is derived to match Windows behavior
Bruno Jesus
00cpxxx at gmail.com
Tue Jul 22 22:48:09 CDT 2014
AES 192 and 256 are working fine, but AES 128 is not. After hours of
testing I think this is a plausible solution. What I don't understand
is how this ever worked, is there anything else that would affect the
keys?
-------------- next part --------------
---
dlls/rsaenh/rsaenh.c | 26 +++++++++++++++++++++++---
dlls/rsaenh/tests/rsaenh.c | 5 -----
2 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c
index dd49618..aec203c 100644
--- a/dlls/rsaenh/rsaenh.c
+++ b/dlls/rsaenh/rsaenh.c
@@ -3926,6 +3926,8 @@ BOOL WINAPI RSAENH_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseD
switch (GET_ALG_CLASS(Algid))
{
case ALG_CLASS_DATA_ENCRYPT:
+ {
+ int need_padding;
*phKey = new_key(hProv, Algid, dwFlags, &pCryptKey);
if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE;
@@ -3936,8 +3938,26 @@ BOOL WINAPI RSAENH_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseD
*/
dwLen = RSAENH_MAX_HASH_SIZE;
RSAENH_CPGetHashParam(pCryptHash->hProv, hBaseData, HP_HASHVAL, abHashValue, &dwLen, 0);
-
- if (dwLen < pCryptKey->dwKeyLen) {
+
+ /*
+ * The usage of padding seems to vary from algorithm to algorithm.
+ * For now the only different case found was for AES with 128 bit key.
+ */
+ switch(Algid)
+ {
+ case CALG_AES_128:
+ /* To reduce the chance of regressions we will only deviate
+ * from the old behavior for the tested hash lengths */
+ if (dwLen == 16 || dwLen == 20)
+ {
+ need_padding = 1;
+ break;
+ }
+ default:
+ need_padding = dwLen < pCryptKey->dwKeyLen;
+ }
+
+ if (need_padding) {
BYTE pad1[RSAENH_HMAC_DEF_PAD_LEN], pad2[RSAENH_HMAC_DEF_PAD_LEN];
BYTE old_hashval[RSAENH_MAX_HASH_SIZE];
DWORD i;
@@ -3966,7 +3986,7 @@ BOOL WINAPI RSAENH_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseD
memcpy(pCryptKey->abKeyValue, abHashValue,
RSAENH_MIN(pCryptKey->dwKeyLen, sizeof(pCryptKey->abKeyValue)));
break;
-
+ }
case ALG_CLASS_MSG_ENCRYPT:
if (!lookup_handle(&handle_table, pCryptHash->hKey, RSAENH_MAGIC_KEY,
(OBJECTHDR**)&pMasterKey))
diff --git a/dlls/rsaenh/tests/rsaenh.c b/dlls/rsaenh/tests/rsaenh.c
index dad6a27..c49bd92 100644
--- a/dlls/rsaenh/tests/rsaenh.c
+++ b/dlls/rsaenh/tests/rsaenh.c
@@ -1140,9 +1140,6 @@ static void test_aes(int keylen)
result = CryptEncrypt(hKey, 0, TRUE, 0, pbData, &dwLen, sizeof(pbData));
ok(result, "Expected OK, got last error %d\n", GetLastError());
ok(dwLen == 48, "Expected dwLen 48, got %d\n", dwLen);
- if(i == 0) todo_wine
- ok(!memcmp(aes_cbc_enc[i], pbData, dwLen), "Expected equal data sequences\n");
- else
ok(!memcmp(aes_cbc_enc[i], pbData, dwLen), "Expected equal data sequences\n");
result = CryptDecrypt(hKey, 0, TRUE, 0, pbData, &dwLen);
@@ -3530,9 +3527,7 @@ static void test_key_derivation(const char *prov)
memset(wine_broken, 0, sizeof(wine_broken));
wine_broken[8].mode = wine_broken[8].blen = 1;
- wine_broken[9].exp_data = 1;
wine_broken[20] = wine_broken[32] = wine_broken[44] = wine_broken[8];
- wine_broken[21] = wine_broken[33] = wine_broken[45] = wine_broken[9];
for (i=0; i<sizeof(tests)/sizeof(tests[0]); i++)
{
--
1.8.3.2
More information about the wine-patches
mailing list