mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 04:39:45 +00:00
rsaenh: Add support for CRYPT_IPSEC_HMAC_KEY.
This commit is contained in:
parent
5ccf2bd998
commit
c91afb9733
@ -993,7 +993,6 @@ static void test_rc2_keylen(void)
|
||||
sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
|
||||
0, CRYPT_IPSEC_HMAC_KEY, &hkey);
|
||||
/* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
|
||||
todo_wine
|
||||
ok(ret ||
|
||||
broken(!ret && GetLastError() == NTE_BAD_FLAGS),
|
||||
"CryptImportKey error %08x\n", GetLastError());
|
||||
@ -1041,7 +1040,6 @@ static void test_rc2_keylen(void)
|
||||
sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
|
||||
0, CRYPT_IPSEC_HMAC_KEY, &hkey);
|
||||
/* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
|
||||
todo_wine
|
||||
ok(ret ||
|
||||
broken(!ret && GetLastError() == NTE_BAD_FLAGS),
|
||||
"CryptImportKey error %08x\n", GetLastError());
|
||||
@ -1066,7 +1064,6 @@ static void test_rc2_keylen(void)
|
||||
ret = pCryptImportKey(provider, (BYTE*)&key_blob,
|
||||
sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
|
||||
0, CRYPT_IPSEC_HMAC_KEY, &hkey);
|
||||
todo_wine
|
||||
ok(ret ||
|
||||
broken(!ret && GetLastError() == NTE_BAD_FLAGS),
|
||||
"CryptImportKey error %08x\n", GetLastError());
|
||||
@ -1081,7 +1078,6 @@ static void test_rc2_keylen(void)
|
||||
ret = pCryptImportKey(provider, (BYTE*)&key_blob,
|
||||
sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
|
||||
0, CRYPT_IPSEC_HMAC_KEY, &hkey);
|
||||
todo_wine
|
||||
ok(ret ||
|
||||
broken(!ret && GetLastError() == NTE_BAD_FLAGS),
|
||||
"CryptImportKey error %08x\n", GetLastError());
|
||||
|
@ -74,7 +74,7 @@ typedef struct tagCRYPTHASH
|
||||
* CRYPTKEY - key objects
|
||||
*/
|
||||
#define RSAENH_MAGIC_KEY 0x73620457u
|
||||
#define RSAENH_MAX_KEY_SIZE 48
|
||||
#define RSAENH_MAX_KEY_SIZE 64
|
||||
#define RSAENH_MAX_BLOCK_SIZE 24
|
||||
#define RSAENH_KEYSTATE_IDLE 0
|
||||
#define RSAENH_KEYSTATE_ENCRYPTING 1
|
||||
@ -105,6 +105,7 @@ typedef struct tagCRYPTKEY
|
||||
BYTE abInitVector[RSAENH_MAX_BLOCK_SIZE];
|
||||
BYTE abChainVector[RSAENH_MAX_BLOCK_SIZE];
|
||||
RSAENH_SCHANNEL_INFO siSChannelInfo;
|
||||
CRYPT_DATA_BLOB blobHmacKey;
|
||||
} CRYPTKEY;
|
||||
|
||||
/******************************************************************************
|
||||
@ -732,6 +733,7 @@ static void destroy_key(OBJECTHDR *pObject)
|
||||
free_key_impl(pCryptKey->aiAlgid, &pCryptKey->context);
|
||||
free_data_blob(&pCryptKey->siSChannelInfo.blobClientRandom);
|
||||
free_data_blob(&pCryptKey->siSChannelInfo.blobServerRandom);
|
||||
free_data_blob(&pCryptKey->blobHmacKey);
|
||||
HeapFree(GetProcessHeap(), 0, pCryptKey);
|
||||
}
|
||||
|
||||
@ -825,7 +827,13 @@ static HCRYPTKEY new_key(HCRYPTPROV hProv, ALG_ID aiAlgid, DWORD dwFlags, CRYPTK
|
||||
return (HCRYPTKEY)INVALID_HANDLE_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CALG_HMAC:
|
||||
/* Avoid the key length check for HMAC keys, which have unlimited
|
||||
* length.
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
if (dwKeyLen % 8 ||
|
||||
dwKeyLen > peaAlgidInfo->dwMaxLen ||
|
||||
@ -859,6 +867,7 @@ static HCRYPTKEY new_key(HCRYPTPROV hProv, ALG_ID aiAlgid, DWORD dwFlags, CRYPTK
|
||||
memset(pCryptKey->abInitVector, 0, sizeof(pCryptKey->abInitVector));
|
||||
init_data_blob(&pCryptKey->siSChannelInfo.blobClientRandom);
|
||||
init_data_blob(&pCryptKey->siSChannelInfo.blobServerRandom);
|
||||
init_data_blob(&pCryptKey->blobHmacKey);
|
||||
|
||||
switch(aiAlgid)
|
||||
{
|
||||
@ -892,6 +901,11 @@ static HCRYPTKEY new_key(HCRYPTPROV hProv, ALG_ID aiAlgid, DWORD dwFlags, CRYPTK
|
||||
pCryptKey->dwBlockLen = dwKeyLen >> 3;
|
||||
pCryptKey->dwMode = 0;
|
||||
break;
|
||||
|
||||
case CALG_HMAC:
|
||||
pCryptKey->dwBlockLen = 0;
|
||||
pCryptKey->dwMode = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
*ppCryptKey = pCryptKey;
|
||||
@ -2931,25 +2945,53 @@ static BOOL import_plaintext_key(HCRYPTPROV hProv, CONST BYTE *pbData,
|
||||
CONST DWORD *pKeyLen = (CONST DWORD *)(pBlobHeader + 1);
|
||||
CONST BYTE *pbKeyStream = (CONST BYTE*)(pKeyLen + 1);
|
||||
|
||||
if (dwFlags & CRYPT_IPSEC_HMAC_KEY)
|
||||
{
|
||||
FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n");
|
||||
SetLastError(NTE_BAD_FLAGS);
|
||||
return FALSE;
|
||||
}
|
||||
if (dwDataLen < sizeof(BLOBHEADER)+sizeof(DWORD)+*pKeyLen)
|
||||
{
|
||||
SetLastError(NTE_BAD_DATA); /* FIXME: error code */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*phKey = new_key(hProv, pBlobHeader->aiKeyAlg, *pKeyLen<<19, &pCryptKey);
|
||||
if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
memcpy(pCryptKey->abKeyValue, pbKeyStream, *pKeyLen);
|
||||
setup_key(pCryptKey);
|
||||
if (dwFlags & CRYPT_EXPORTABLE)
|
||||
pCryptKey->dwPermissions |= CRYPT_EXPORT;
|
||||
if (dwFlags & CRYPT_IPSEC_HMAC_KEY)
|
||||
{
|
||||
*phKey = new_key(hProv, CALG_HMAC, 0, &pCryptKey);
|
||||
if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
if (*pKeyLen <= sizeof(pCryptKey->abKeyValue))
|
||||
{
|
||||
memcpy(pCryptKey->abKeyValue, pbKeyStream, *pKeyLen);
|
||||
pCryptKey->dwKeyLen = *pKeyLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
CRYPT_DATA_BLOB blobHmacKey = { *pKeyLen, (BYTE *)pbKeyStream };
|
||||
|
||||
/* In order to initialize an HMAC key, the key material is hashed,
|
||||
* and the output of the hash function is used as the key material.
|
||||
* Unfortunately, the way the Crypto API is designed, we don't know
|
||||
* the hash algorithm yet, so we have to copy the entire key
|
||||
* material.
|
||||
*/
|
||||
if (!copy_data_blob(&pCryptKey->blobHmacKey, &blobHmacKey))
|
||||
{
|
||||
release_handle(&handle_table, *phKey, RSAENH_MAGIC_KEY);
|
||||
*phKey = (HCRYPTKEY)INVALID_HANDLE_VALUE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
setup_key(pCryptKey);
|
||||
if (dwFlags & CRYPT_EXPORTABLE)
|
||||
pCryptKey->dwPermissions |= CRYPT_EXPORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
*phKey = new_key(hProv, pBlobHeader->aiKeyAlg, *pKeyLen<<19, &pCryptKey);
|
||||
if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
memcpy(pCryptKey->abKeyValue, pbKeyStream, *pKeyLen);
|
||||
setup_key(pCryptKey);
|
||||
if (dwFlags & CRYPT_EXPORTABLE)
|
||||
pCryptKey->dwPermissions |= CRYPT_EXPORT;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -4172,6 +4214,27 @@ BOOL WINAPI RSAENH_CPSetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwPa
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pCryptKey->aiAlgid == CALG_HMAC && !pCryptKey->dwKeyLen) {
|
||||
HCRYPTHASH hKeyHash;
|
||||
|
||||
if (!RSAENH_CPCreateHash(hProv, ((PHMAC_INFO)pbData)->HashAlgid, 0, 0,
|
||||
&hKeyHash))
|
||||
return FALSE;
|
||||
if (!RSAENH_CPHashData(hProv, hKeyHash, pCryptKey->blobHmacKey.pbData,
|
||||
pCryptKey->blobHmacKey.cbData, 0))
|
||||
{
|
||||
RSAENH_CPDestroyHash(hProv, hKeyHash);
|
||||
return FALSE;
|
||||
}
|
||||
pCryptKey->dwKeyLen = sizeof(pCryptKey->abKeyValue);
|
||||
if (!RSAENH_CPGetHashParam(hProv, hKeyHash, HP_HASHVAL, pCryptKey->abKeyValue,
|
||||
&pCryptKey->dwKeyLen, 0))
|
||||
{
|
||||
RSAENH_CPDestroyHash(hProv, hKeyHash);
|
||||
return FALSE;
|
||||
}
|
||||
RSAENH_CPDestroyHash(hProv, hKeyHash);
|
||||
}
|
||||
for (i=0; i<RSAENH_MIN(pCryptKey->dwKeyLen,pCryptHash->pHMACInfo->cbInnerString); i++) {
|
||||
pCryptHash->pHMACInfo->pbInnerString[i] ^= pCryptKey->abKeyValue[i];
|
||||
}
|
||||
|
@ -2235,7 +2235,6 @@ static void test_import_hmac(void)
|
||||
*key_len = test_case->key_len;
|
||||
memcpy(key_bytes, test_case->key, *key_len);
|
||||
result = CryptImportKey(hProv, blob, size, 0, CRYPT_IPSEC_HMAC_KEY, &key);
|
||||
todo_wine
|
||||
ok(result || broken(GetLastError() == NTE_BAD_FLAGS /* Win2k */), "CryptImportKey failed on test case %d: %08x\n", i, GetLastError());
|
||||
if (result)
|
||||
{
|
||||
@ -2253,7 +2252,7 @@ static void test_import_hmac(void)
|
||||
digest_size = sizeof(digest);
|
||||
result = CryptGetHashParam(hash, HP_HASHVAL, digest, &digest_size, 0);
|
||||
ok(result, "CryptGetHashParam failed on test case %d: %08x\n", i, GetLastError());
|
||||
ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected valued on test case %d\n", i);
|
||||
ok(!memcmp(digest, test_case->digest, sizeof(digest)), "Unexpected value on test case %d\n", i);
|
||||
CryptDestroyHash(hash);
|
||||
CryptDestroyKey(key);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user