rsaenh: Add implementation of Enhanced RSA AES Provider.

This commit is contained in:
Vijay Kiran Kamuju 2007-11-20 16:58:23 -06:00 committed by Alexandre Julliard
parent ea1f8c7ad8
commit 1dbaa8c619
7 changed files with 1454 additions and 35 deletions

View File

@ -8,6 +8,7 @@ IMPORTLIB = librsaenh.$(IMPLIBEXT)
IMPORTS = crypt32 advapi32 kernel32
C_SRCS = \
aes.c \
des.c \
handle.c \
implglue.c \

1333
dlls/rsaenh/aes.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
* Glueing the RSAENH specific code to the crypto library
*
* Copyright (c) 2004, 2005 Michael Jung
* Copyright (c) 2007 Vijay Kiran Kamuju
*
* based on code by Mike McCormack and David Hammerton
*
@ -194,6 +195,19 @@ BOOL setup_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
case CALG_DES:
des_setup(abKeyValue, 8, 0, &pKeyContext->des);
break;
case CALG_AES:
case CALG_AES_128:
aes_setup(abKeyValue, 16, 0, &pKeyContext->aes);
break;
case CALG_AES_192:
aes_setup(abKeyValue, 24, 0, &pKeyContext->aes);
break;
case CALG_AES_256:
aes_setup(abKeyValue, 32, 0, &pKeyContext->aes);
break;
}
return TRUE;
@ -209,6 +223,10 @@ BOOL duplicate_key_impl(ALG_ID aiAlgid, CONST KEY_CONTEXT *pSrcKeyContext,
case CALG_3DES:
case CALG_3DES_112:
case CALG_DES:
case CALG_AES:
case CALG_AES_128:
case CALG_AES_192:
case CALG_AES_256:
memcpy(pDestKeyContext, pSrcKeyContext, sizeof(KEY_CONTEXT));
break;
case CALG_RSA_KEYX:
@ -275,6 +293,17 @@ BOOL encrypt_block_impl(ALG_ID aiAlgid, DWORD dwKeySpec, KEY_CONTEXT *pKeyContex
}
break;
case CALG_AES:
case CALG_AES_128:
case CALG_AES_192:
case CALG_AES_256:
if (enc) {
aes_ecb_encrypt(in, out, &pKeyContext->aes);
} else {
aes_ecb_decrypt(in, out, &pKeyContext->aes);
}
break;
case CALG_RSA_KEYX:
case CALG_RSA_SIGN:
outlen = inlen = (mp_count_bits(&pKeyContext->rsa.N)+7)/8;

View File

@ -63,6 +63,7 @@ typedef union tagKEY_CONTEXT {
rc2_key rc2;
des_key des;
des3_key des3;
aes_key aes;
prng_state rc4;
rsa_key rsa;
} KEY_CONTEXT;

View File

@ -5,6 +5,7 @@
* Copyright 2002 TransGaming Technologies (David Hammerton)
* Copyright 2004 Mike McCormack for CodeWeavers
* Copyright 2004, 2005 Michael Jung
* Copyright 2007 Vijay Kiran Kamuju
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -111,6 +112,7 @@ typedef struct tagCRYPTKEY
#define RSAENH_PERSONALITY_STRONG 1u
#define RSAENH_PERSONALITY_ENHANCED 2u
#define RSAENH_PERSONALITY_SCHANNEL 3u
#define RSAENH_PERSONALITY_AES 4u
#define RSAENH_MAGIC_CONTAINER 0x26384993u
typedef struct tagKEYCONTAINER
@ -153,9 +155,9 @@ typedef struct tagKEYCONTAINER
/******************************************************************************
* aProvEnumAlgsEx - Defines the capabilities of the CSP personalities.
*/
#define RSAENH_MAX_ENUMALGS 20
#define RSAENH_MAX_ENUMALGS 24
#define RSAENH_PCT1_SSL2_SSL3_TLS1 (CRYPT_FLAG_PCT1|CRYPT_FLAG_SSL2|CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1)
static const PROV_ENUMALGS_EX aProvEnumAlgsEx[4][RSAENH_MAX_ENUMALGS+1] =
static const PROV_ENUMALGS_EX aProvEnumAlgsEx[5][RSAENH_MAX_ENUMALGS+1] =
{
{
{CALG_RC2, 40, 40, 56,0, 4,"RC2", 24,"RSA Data Security's RC2"},
@ -228,6 +230,27 @@ static const PROV_ENUMALGS_EX aProvEnumAlgsEx[4][RSAENH_MAX_ENUMALGS+1] =
{CALG_SCHANNEL_ENC_KEY,0,0,-1,0, 12,"SCH ENC KEY",24,"SChannel Encryption Key"},
{CALG_TLS1PRF, 0, 0, -1,0, 9,"TLS1 PRF", 28,"TLS1 Pseudo Random Function"},
{0, 0, 0, 0,0, 1,"", 1,""}
},
{
{CALG_RC2, 128, 40, 128,0, 4,"RC2", 24,"RSA Data Security's RC2"},
{CALG_RC4, 128, 40, 128,0, 4,"RC4", 24,"RSA Data Security's RC4"},
{CALG_DES, 56, 56, 56,0, 4,"DES", 31,"Data Encryption Standard (DES)"},
{CALG_3DES_112, 112,112, 112,0, 13,"3DES TWO KEY",19,"Two Key Triple DES"},
{CALG_3DES, 168,168, 168,0, 5,"3DES", 21,"Three Key Triple DES"},
{CALG_AES, 128,128, 128,0, 4,"AES", 35,"Advanced Encryption Standard (AES)"},
{CALG_AES_128, 128,128, 128,0, 8,"AES-128", 39,"Advanced Encryption Standard (AES-128)"},
{CALG_AES_192, 192,192, 192,0, 8,"AES-192", 39,"Advanced Encryption Standard (AES-192)"},
{CALG_AES_256, 256,256, 256,0, 8,"AES-256", 39,"Advanced Encryption Standard (AES-256)"},
{CALG_SHA, 160,160, 160,CRYPT_FLAG_SIGNING, 6,"SHA-1", 30,"Secure Hash Algorithm (SHA-1)"},
{CALG_MD2, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD2", 23,"Message Digest 2 (MD2)"},
{CALG_MD4, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD4", 23,"Message Digest 4 (MD4)"},
{CALG_MD5, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD5", 23,"Message Digest 5 (MD5)"},
{CALG_SSL3_SHAMD5,288,288,288,0, 12,"SSL3 SHAMD5",12,"SSL3 SHAMD5"},
{CALG_MAC, 0, 0, 0,0, 4,"MAC", 28,"Message Authentication Code"},
{CALG_RSA_SIGN,1024,384,16384,CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC,9,"RSA_SIGN",14,"RSA Signature"},
{CALG_RSA_KEYX,1024,384,16384,CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC,9,"RSA_KEYX",17,"RSA Key Exchange"},
{CALG_HMAC, 0, 0, 0,0, 5,"HMAC", 18,"Hugo's MAC (HMAC)"},
{0, 0, 0, 0,0, 1,"", 1,""}
}
};
@ -844,6 +867,14 @@ static HCRYPTKEY new_key(HCRYPTPROV hProv, ALG_ID aiAlgid, DWORD dwFlags, CRYPTK
pCryptKey->dwMode = CRYPT_MODE_CBC;
break;
case CALG_AES:
case CALG_AES_128:
case CALG_AES_192:
case CALG_AES_256:
pCryptKey->dwBlockLen = 16;
pCryptKey->dwMode = CRYPT_MODE_ECB;
break;
case CALG_RSA_KEYX:
case CALG_RSA_SIGN:
pCryptKey->dwBlockLen = dwKeyLen >> 3;
@ -1081,6 +1112,8 @@ static HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const
pKeyContainer->dwPersonality = RSAENH_PERSONALITY_ENHANCED;
} else if (!strcmp(pVTable->pszProvName, MS_DEF_RSA_SCHANNEL_PROV_A)) {
pKeyContainer->dwPersonality = RSAENH_PERSONALITY_SCHANNEL;
} else if (!strcmp(pVTable->pszProvName, MS_ENH_RSA_AES_PROV_A)) {
pKeyContainer->dwPersonality = RSAENH_PERSONALITY_AES;
} else {
pKeyContainer->dwPersonality = RSAENH_PERSONALITY_STRONG;
}
@ -2562,6 +2595,10 @@ BOOL WINAPI RSAENH_CPGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYP
case CALG_DES:
case CALG_3DES_112:
case CALG_3DES:
case CALG_AES:
case CALG_AES_128:
case CALG_AES_192:
case CALG_AES_256:
case CALG_PCT1_MASTER:
case CALG_SSL2_MASTER:
case CALG_SSL3_MASTER:
@ -3757,7 +3794,7 @@ cleanup:
return res;
}
static const WCHAR szProviderKeys[4][97] = {
static const WCHAR szProviderKeys[5][104] = {
{ 'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r',
'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v',
@ -3781,9 +3818,14 @@ static const WCHAR szProviderKeys[4][97] = {
'C','r','y','p','t','o','g','r','a','p','h','y','\\','D','e','f','a','u','l','t','s','\\',
'P','r','o','v','i','d','e','r','\\','M','i','c','r','o','s','o','f','t',' ',
'R','S','A',' ','S','C','h','a','n','n','e','l',' ',
'C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r','o','v','i','d','e','r',0 },
{ 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
'C','r','y','p','t','o','g','r','a','p','h','y','\\','D','e','f','a','u','l','t','s','\\',
'P','r','o','v','i','d','e','r','\\','M','i','c','r','o','s','o','f','t',' ',
'E','n','h','a','n','c','e','d',' ','R','S','A',' ','a','n','d',' ','A','E','S',' ',
'C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r','o','v','i','d','e','r',0 }
};
static const WCHAR szDefaultKeys[2][65] = {
static const WCHAR szDefaultKeys[3][65] = {
{ 'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r',
'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v',
@ -3791,7 +3833,11 @@ static const WCHAR szDefaultKeys[2][65] = {
{ 'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r',
'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v',
'i','d','e','r',' ','T','y','p','e','s','\\','T','y','p','e',' ','0','1','2',0 }
'i','d','e','r',' ','T','y','p','e','s','\\','T','y','p','e',' ','0','1','2',0 },
{ 'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r',
'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v',
'i','d','e','r',' ','T','y','p','e','s','\\','T','y','p','e',' ','0','2','4',0 }
};
@ -3823,7 +3869,7 @@ HRESULT WINAPI DllRegisterServer(void)
long apiRet;
int i;
for (i=0; i<4; i++) {
for (i=0; i<5; i++) {
apiRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, szProviderKeys[i], 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dp);
@ -3835,8 +3881,21 @@ HRESULT WINAPI DllRegisterServer(void)
static const WCHAR szRSABase[] = { 'r','s','a','e','n','h','.','d','l','l',0 };
static const WCHAR szType[] = { 'T','y','p','e',0 };
static const WCHAR szSignature[] = { 'S','i','g','n','a','t','u','r','e',0 };
DWORD type = (i == 3) ? PROV_RSA_SCHANNEL : PROV_RSA_FULL;
DWORD sign = 0xdeadbeef;
DWORD type, sign;
switch(i)
{
case 3:
type=PROV_RSA_SCHANNEL;
break;
case 4:
type=PROV_RSA_AES;
break;
default:
type=PROV_RSA_FULL;
break;
}
sign = 0xdeadbeef;
RegSetValueExW(key, szImagePath, 0, REG_SZ, (const BYTE *)szRSABase,
(lstrlenW(szRSABase) + 1) * sizeof(WCHAR));
RegSetValueExW(key, szType, 0, REG_DWORD, (LPBYTE)&type, sizeof(type));
@ -3846,30 +3905,35 @@ HRESULT WINAPI DllRegisterServer(void)
}
}
for (i=0; i<2; i++) {
apiRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, szDefaultKeys[i], 0, NULL,
for (i=0; i<3; i++) {
apiRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, szDefaultKeys[i], 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dp);
if (apiRet == ERROR_SUCCESS)
{
if (dp == REG_CREATED_NEW_KEY)
{
static const WCHAR szName[] = { 'N','a','m','e',0 };
static const WCHAR szRSAName[2][46] = {
static const WCHAR szRSAName[3][54] = {
{ 'M','i','c','r','o','s','o','f','t',' ', 'B','a','s','e',' ',
'C','r','y','p','t','o','g','r','a','p','h','i','c',' ',
'P','r','o','v','i','d','e','r',' ','v','1','.','0',0 },
{ 'M','i','c','r','o','s','o','f','t',' ','R','S','A',' ',
'S','C','h','a','n','n','e','l',' ',
'C','r','y','p','t','o','g','r','a','p','h','i','c',' ',
'P','r','o','v','i','d','e','r',0 },
{ 'M','i','c','r','o','s','o','f','t',' ','E','n','h','a','n','c','e','d',' ',
'R','S','A',' ','a','n','d',' ','A','E','S',' ',
'C','r','y','p','t','o','g','r','a','p','h','i','c',' ',
'P','r','o','v','i','d','e','r',0 } };
static const WCHAR szTypeName[] = { 'T','y','p','e','N','a','m','e',0 };
static const WCHAR szRSATypeName[2][38] = {
static const WCHAR szRSATypeName[3][38] = {
{ 'R','S','A',' ','F','u','l','l',' ',
'(','S','i','g','n','a','t','u','r','e',' ','a','n','d',' ',
'K','e','y',' ','E','x','c','h','a','n','g','e',')',0 },
{ 'R','S','A',' ','S','C','h','a','n','n','e','l',0 } };
{ 'R','S','A',' ','S','C','h','a','n','n','e','l',0 },
{ 'R','S','A',' ','F','u','l','l',' ','a','n','d',' ','A','E','S',0 } };
RegSetValueExW(key, szName, 0, REG_SZ,
RegSetValueExW(key, szName, 0, REG_SZ,
(const BYTE *)szRSAName[i], lstrlenW(szRSAName[i])*sizeof(WCHAR)+sizeof(WCHAR));
RegSetValueExW(key, szTypeName, 0, REG_SZ,
(const BYTE *)szRSATypeName[i], lstrlenW(szRSATypeName[i])*sizeof(WCHAR)+sizeof(WCHAR));
@ -3900,7 +3964,9 @@ HRESULT WINAPI DllUnregisterServer(void)
RegDeleteKeyW(HKEY_LOCAL_MACHINE, szProviderKeys[1]);
RegDeleteKeyW(HKEY_LOCAL_MACHINE, szProviderKeys[2]);
RegDeleteKeyW(HKEY_LOCAL_MACHINE, szProviderKeys[3]);
RegDeleteKeyW(HKEY_LOCAL_MACHINE, szProviderKeys[4]);
RegDeleteKeyW(HKEY_LOCAL_MACHINE, szDefaultKeys[0]);
RegDeleteKeyW(HKEY_LOCAL_MACHINE, szDefaultKeys[1]);
RegDeleteKeyW(HKEY_LOCAL_MACHINE, szDefaultKeys[2]);
return S_OK;
}

View File

@ -140,31 +140,21 @@ static int init_aes_environment(void)
* This provider is available on Windows XP, Windows 2003 and Vista. */
result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
todo_wine {
ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError());
}
if (!CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, 0))
{
todo_wine {
ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError());
}
if (GetLastError()!=NTE_BAD_KEYSET) return 0;
result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES,
CRYPT_NEWKEYSET);
todo_wine {
ok(result, "%08x\n", GetLastError());
}
if (!result) return 0;
result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
todo_wine {
ok(result, "%08x\n", GetLastError());
}
if (result) CryptDestroyKey(hKey);
result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
todo_wine {
ok(result, "%08x\n", GetLastError());
}
if (result) CryptDestroyKey(hKey);
}
return 1;
@ -175,7 +165,7 @@ static void clean_up_aes_environment(void)
BOOL result;
result = CryptReleaseContext(hProv, 1);
todo_wine ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", GetLastError());
CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_DELETEKEYSET);
}
@ -670,14 +660,10 @@ static void test_aes(int keylen)
dwLen = 13;
result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
todo_wine {
ok(result, "%08x\n", GetLastError());
}
result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
todo_wine {
ok(result, "%08x\n", GetLastError());
}
for (i=0; i<4; i++)
{
@ -685,13 +671,10 @@ static void test_aes(int keylen)
dwLen = cTestData[i].enclen;
result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, cTestData[i].buflen);
todo_wine {
ok(result, "%08x\n", GetLastError());
ok(dwLen==cTestData[i].buflen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].buflen);
}
result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
todo_wine {
ok(result, "%08x\n", GetLastError());
ok(dwLen==cTestData[i].enclen,"length incorrect, got %d, expected %d\n",dwLen,cTestData[i].enclen);
ok(memcmp(pbData,cTestData[i].decstr,cTestData[1].enclen)==0,"decryption incorrect %d\n",i);
@ -701,12 +684,9 @@ static void test_aes(int keylen)
printBytes("expected",cTestData[i].decstr,cTestData[i].strlen);
printBytes("got",pbData,dwLen);
}
}
}
result = CryptDestroyKey(hKey);
todo_wine {
ok(result, "%08x\n", GetLastError());
}
}
static void test_rc2(void)

View File

@ -129,6 +129,11 @@ typedef struct tag_des3_key {
ulong32 ek[3][32], dk[3][32];
} des3_key;
typedef struct tag_aes_key {
ulong32 eK[64], dK[64];
int Nr;
} aes_key;
int rc2_setup(const unsigned char *key, int keylen, int bits, int num_rounds, rc2_key *skey);
void rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, rc2_key *key);
void rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, rc2_key *key);
@ -141,6 +146,10 @@ int des3_setup(const unsigned char *key, int keylen, int num_rounds, des3_key *s
void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const des3_key *key);
void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const des3_key *key);
int aes_setup(const unsigned char *key, int keylen, int rounds, aes_key *skey);
void aes_ecb_encrypt(const unsigned char *pt, unsigned char *ct, aes_key *skey);
void aes_ecb_decrypt(const unsigned char *ct, unsigned char *pt, aes_key *skey);
typedef struct tag_md2_state {
unsigned char chksum[16], X[48], buf[16];
unsigned long curlen;