From: Hans Leidekker <hans@codeweavers.com> --- dlls/rsaenh/Makefile.in | 4 +- dlls/rsaenh/implglue.c | 723 ++++++++++++++++++++++++---------------- dlls/rsaenh/implglue.h | 53 ++- dlls/rsaenh/rsaenh.c | 234 ++++++------- 4 files changed, 567 insertions(+), 447 deletions(-) diff --git a/dlls/rsaenh/Makefile.in b/dlls/rsaenh/Makefile.in index 7a7be6679a5..6f3480c4509 100644 --- a/dlls/rsaenh/Makefile.in +++ b/dlls/rsaenh/Makefile.in @@ -1,7 +1,7 @@ MODULE = rsaenh.dll IMPORTLIB = rsaenh -IMPORTS = $(TOMCRYPT_PE_LIBS) $(SYMCRYPT_PE_LIBS) crypt32 advapi32 -EXTRAINCL = $(TOMCRYPT_PE_CFLAGS) $(SYMCRYPT_PE_CFLAGS) +IMPORTS = $(SYMCRYPT_PE_LIBS) crypt32 advapi32 +EXTRAINCL = $(SYMCRYPT_PE_CFLAGS) VER_PRODUCTVERSION = 5,1,2600,2180 diff --git a/dlls/rsaenh/implglue.c b/dlls/rsaenh/implglue.c index f81c038cdc0..26f2057b8d4 100644 --- a/dlls/rsaenh/implglue.c +++ b/dlls/rsaenh/implglue.c @@ -27,14 +27,38 @@ #include <stdio.h> #include "windef.h" #include "winbase.h" +#include "ntsecapi.h" #include "wincrypt.h" #include "implglue.h" SYMCRYPT_ENVIRONMENT_DEFS( WindowsUsermodeWin8_1nLater ); -prng_state prng = { 0 }; -int wprng = 0; +void * SYMCRYPT_CALL SymCryptCallbackAlloc( SIZE_T size ) +{ + return malloc( size ); +} + +void SYMCRYPT_CALL SymCryptCallbackFree( void *ptr ) +{ + free( ptr ); +} + +void SYMCRYPT_CALL SymCryptRsaSelftest( void ) +{ +} + +SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsaSignVerifyPct( const SYMCRYPT_RSAKEY *key ) +{ + return SYMCRYPT_NO_ERROR; +} + +SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptCallbackRandom( BYTE *buf, SIZE_T size ) +{ + return RtlGenRandom( buf, size ) ? SYMCRYPT_NO_ERROR : SYMCRYPT_EXTERNAL_FAILURE; +} + +UINT32 g_SymCryptFipsSelftestsPerformed; BOOL init_hash_impl( ALG_ID algid, struct hash *hash ) { @@ -57,370 +81,479 @@ BOOL init_hash_impl( ALG_ID algid, struct hash *hash ) return TRUE; } -BOOL new_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen) +static SYMCRYPT_RSAKEY *alloc_rsa_key( DWORD bitlen, BOOL private ) { - switch (aiAlgid) + SYMCRYPT_RSA_PARAMS params; + + params.version = 1; + params.nBitsOfModulus = bitlen; + params.nPrimes = private ? 2 : 0; + params.nPubExp = 1; + return SymCryptRsakeyAllocate( ¶ms, 0 ); +} + +BOOL new_key_impl( ALG_ID algid, KEY_CONTEXT *ctx, DWORD keylen ) +{ + switch (algid) { - case CALG_RSA_KEYX: - case CALG_RSA_SIGN: - if (rsa_make_key( &prng, wprng, dwKeyLen, 65537, &pKeyContext->rsa ) != CRYPT_OK) { - SetLastError(NTE_FAIL); - return FALSE; - } - return TRUE; + case CALG_RSA_KEYX: + case CALG_RSA_SIGN: + { + UINT64 pubexp = 65537; + + ctx->rsa.flags = SYMCRYPT_FLAG_KEY_NO_FIPS; + if (algid == CALG_RSA_KEYX) ctx->rsa.flags |= SYMCRYPT_FLAG_RSAKEY_ENCRYPT; + else ctx->rsa.flags |= SYMCRYPT_FLAG_RSAKEY_SIGN; + + if (!(ctx->rsa.key = alloc_rsa_key( keylen * 8, TRUE ))) + { + SetLastError( NTE_FAIL ); + return FALSE; + } + if (SymCryptRsakeyGenerate( ctx->rsa.key, &pubexp, 1, ctx->rsa.flags )) + { + SymCryptRsakeyFree( ctx->rsa.key ); + ctx->rsa.key = NULL; + SetLastError( NTE_FAIL ); + return FALSE; + } + break; + } + default: + SetLastError( NTE_BAD_ALGID ); + return FALSE; } + return TRUE; +} +BOOL free_key_impl( ALG_ID algid, KEY_CONTEXT *ctx ) +{ + switch (algid) + { + case CALG_RSA_KEYX: + case CALG_RSA_SIGN: + if (ctx->rsa.key) + { + SymCryptRsakeyFree( ctx->rsa.key ); + ctx->rsa.key = NULL; + } + break; + default: + break; + } return TRUE; } -BOOL free_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext) +BOOL setup_key_impl( ALG_ID algid, KEY_CONTEXT *ctx, DWORD keylen, DWORD effective_keylen, DWORD saltlen, + const BYTE *secret ) { - switch (aiAlgid) + switch (algid) { - case CALG_RSA_KEYX: - case CALG_RSA_SIGN: - rsa_free(&pKeyContext->rsa); + case CALG_RC4: + SymCryptRc4Init( &ctx->rc4, secret, keylen + saltlen ); + break; + case CALG_RC2: + SymCryptRc2ExpandKeyEx( &ctx->rc2, secret, keylen + saltlen, + effective_keylen ? effective_keylen : keylen << 3 ); + break; + case CALG_3DES: + SymCrypt3DesExpandKey( &ctx->des3, secret, 24 ); + break; + case CALG_3DES_112: + SymCrypt3DesExpandKey( &ctx->des3, secret, 16 ); + break; + case CALG_DES: + SymCryptDesExpandKey( &ctx->des, secret, 8 ); + break; + case CALG_AES: + case CALG_AES_128: + SymCryptAesExpandKey( &ctx->aes, secret, 16 ); + break; + case CALG_AES_192: + SymCryptAesExpandKey( &ctx->aes, secret, 24 ); + break; + case CALG_AES_256: + SymCryptAesExpandKey( &ctx->aes, secret, 32 ); + break; } return TRUE; } -BOOL setup_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, - DWORD dwEffectiveKeyLen, DWORD dwSaltLen, BYTE *abKeyValue) +BOOL duplicate_key_impl( ALG_ID algid, const KEY_CONTEXT *src, KEY_CONTEXT *dst ) { - switch (aiAlgid) + switch (algid) { - case CALG_RC4: - rc4_start(&pKeyContext->prng); - rc4_add_entropy(abKeyValue, dwKeyLen + dwSaltLen, &pKeyContext->prng); - /* bypass rc4_ready() to avoid the workaround for the Fluhrer, Mantin and Shamir attack, - * since Windows doesn't do that */ - /* rc4_ready(&pKeyContext->prng); */ - { - unsigned char buf[256]; - ULONG len = MIN(pKeyContext->prng.rc4.s.x, sizeof(buf)); + case CALG_RC4: + case CALG_RC2: + 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: + *dst = *src; + break; + case CALG_RSA_KEYX: + case CALG_RSA_SIGN: + { + BYTE *blob; + DWORD pubexp, keylen = SymCryptRsakeySizeofModulus( src->rsa.key ); + BOOLEAN private = SymCryptRsakeyHasPrivateKey( src->rsa.key ); - memcpy(buf, pKeyContext->prng.rc4.s.buf, sizeof(buf)); - rc4_stream_setup(&pKeyContext->prng.rc4.s, buf, len); - pKeyContext->prng.ready = 1; + if (!(dst->rsa.key = alloc_rsa_key( keylen * 8, private )) || !(blob = malloc( keylen * 2 ))) + { + SetLastError( NTE_FAIL ); + return FALSE; + } + if (private) + { + if (!export_private_key_impl( src, blob, &pubexp ) || + !import_private_key_impl( algid, blob, keylen, pubexp, dst )) + { + free( blob ); + return FALSE; } - break; - - case CALG_RC2: - SymCryptRc2ExpandKeyEx( &pKeyContext->rc2, abKeyValue, dwKeyLen + dwSaltLen, - dwEffectiveKeyLen ? dwEffectiveKeyLen : dwKeyLen << 3 ); - break; - case CALG_3DES: - SymCrypt3DesExpandKey( &pKeyContext->des3, abKeyValue, 24 ); - break; - case CALG_3DES_112: - SymCrypt3DesExpandKey( &pKeyContext->des3, abKeyValue, 16 ); - break; - case CALG_DES: - SymCryptDesExpandKey( &pKeyContext->des, abKeyValue, 8 ); - break; - case CALG_AES: - case CALG_AES_128: - SymCryptAesExpandKey( &pKeyContext->aes, abKeyValue, 16 ); - break; - case CALG_AES_192: - SymCryptAesExpandKey( &pKeyContext->aes, abKeyValue, 24 ); - break; - case CALG_AES_256: - SymCryptAesExpandKey( &pKeyContext->aes, abKeyValue, 32 ); - break; + } + else + { + if (!export_public_key_impl( src, blob, &pubexp ) || + !import_public_key_impl( algid, blob, keylen, pubexp, dst )) + { + free( blob ); + return FALSE; + } + } + dst->rsa.flags = src->rsa.flags; + free( blob ); + break; + } + default: + SetLastError( NTE_BAD_ALGID ); + return FALSE; } - return TRUE; } -BOOL duplicate_key_impl(ALG_ID aiAlgid, const KEY_CONTEXT *pSrcKeyContext, - KEY_CONTEXT *pDestKeyContext) +static BOOL verify_input( const SYMCRYPT_RSAKEY *key, const BYTE *src, SIZE_T src_size, SYMCRYPT_NUMBER_FORMAT format, + BYTE *scratch, SIZE_T scratch_size ) { - switch (aiAlgid) + SYMCRYPT_INT *tmp; + UINT32 tmp_size; + + if (src_size > SymCryptRsakeySizeofModulus( key )) return FALSE; + if (src_size == SymCryptRsakeySizeofModulus( key )) { - case CALG_RC4: - case CALG_RC2: - 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: - *pDestKeyContext = *pSrcKeyContext; - break; - case CALG_RSA_KEYX: - case CALG_RSA_SIGN: - pDestKeyContext->rsa.type = pSrcKeyContext->rsa.type; - mp_init_copy(&pDestKeyContext->rsa.e, pSrcKeyContext->rsa.e); - mp_init_copy(&pDestKeyContext->rsa.d, pSrcKeyContext->rsa.d); - mp_init_copy(&pDestKeyContext->rsa.N, pSrcKeyContext->rsa.N); - mp_init_copy(&pDestKeyContext->rsa.p, pSrcKeyContext->rsa.p); - mp_init_copy(&pDestKeyContext->rsa.q, pSrcKeyContext->rsa.q); - mp_init_copy(&pDestKeyContext->rsa.qP, pSrcKeyContext->rsa.qP); - mp_init_copy(&pDestKeyContext->rsa.dP, pSrcKeyContext->rsa.dP); - mp_init_copy(&pDestKeyContext->rsa.dQ, pSrcKeyContext->rsa.dQ); - break; - - default: - SetLastError(NTE_BAD_ALGID); - return FALSE; + tmp_size = SymCryptSizeofIntFromDigits( key->nDigitsOfModulus ); + SYMCRYPT_ASSERT( scratch_size >= tmp_size ); + tmp = SymCryptIntCreate( scratch, tmp_size, key->nDigitsOfModulus ); + + if (SymCryptIntSetValue( src, src_size, format, tmp )) return FALSE; + if (!SymCryptIntIsLessThan( tmp, SymCryptIntFromModulus( key->pmModulus ))) return FALSE; + return TRUE; } + return FALSE; +} +static BOOL rsa_encrypt( const SYMCRYPT_RSAKEY *key, const BYTE *in, SYMCRYPT_NUMBER_FORMAT in_format, + BYTE *out, SYMCRYPT_NUMBER_FORMAT out_format ) +{ + BYTE buf[SYMCRYPT_SIZEOF_INT_FROM_BITS(64) + SYMCRYPT_ASYM_ALIGN_VALUE]; + SYMCRYPT_MODELEMENT *result; + SIZE_T scratch_size, mod_size = SymCryptSizeofModElementFromModulus( key->pmModulus ); + SIZE_T key_size = SymCryptRsakeySizeofModulus( key ); + SYMCRYPT_INT *exp; + BYTE *scratch; + + scratch_size = SymCryptSizeofModElementFromModulus( key->pmModulus ) + + SYMCRYPT_MAX( SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( key->nDigitsOfModulus ), + SYMCRYPT_SCRATCH_BYTES_FOR_MODEXP( key->nDigitsOfModulus ) ); + + if (!(scratch = malloc( scratch_size ))) return FALSE; + if (!verify_input( key, in, key_size, in_format, scratch, scratch_size )) + { + free( scratch ); + return FALSE; + } + + result = SymCryptModElementCreate( scratch, mod_size, key->pmModulus ); + + SymCryptModElementSetValue( in, key_size, in_format, key->pmModulus, result, scratch + mod_size, + scratch_size - mod_size ); + + exp = SymCryptIntCreate( SYMCRYPT_ASYM_ALIGN_UP(buf), sizeof(buf) - SYMCRYPT_ASYM_ALIGN_VALUE, 1 ); + SymCryptIntSetValueUint64( key->au64PubExp[0], exp ); + + SymCryptModExp( key->pmModulus, result, exp, SymCryptIntBitsizeOfValue(exp), SYMCRYPT_FLAG_DATA_PUBLIC, + result, scratch + mod_size, scratch_size - mod_size ); + + SymCryptModElementGetValue( key->pmModulus, result, out, key_size, out_format, scratch + mod_size, + scratch_size - mod_size ); + free( scratch ); return TRUE; } -static inline void reverse_bytes(BYTE *pbData, DWORD dwLen) { - BYTE swap; - DWORD i; - - for (i=0; i<dwLen/2; i++) { - swap = pbData[i]; - pbData[i] = pbData[dwLen-i-1]; - pbData[dwLen-i-1] = swap; +BOOL encrypt_block_impl( ALG_ID algid, KEY_CONTEXT *ctx, const BYTE *in, BYTE *out ) +{ + switch (algid) + { + case CALG_RC2: + SymCryptRc2Encrypt( &ctx->rc2, in, out ); + break; + case CALG_3DES: + case CALG_3DES_112: + SymCrypt3DesEncrypt( &ctx->des3, in, out ); + break; + case CALG_DES: + SymCryptDesEncrypt( &ctx->des, in, out ); + break; + case CALG_AES: + case CALG_AES_128: + case CALG_AES_192: + case CALG_AES_256: + SymCryptAesEncrypt( &ctx->aes, in, out ); + break; + case CALG_RSA_KEYX: + case CALG_RSA_SIGN: + case CALG_SSL3_SHAMD5: + return rsa_encrypt( ctx->rsa.key, in, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, out, SYMCRYPT_NUMBER_FORMAT_LSB_FIRST ); + default: + SetLastError( NTE_BAD_ALGID ); + return FALSE; } + return TRUE; } -BOOL encrypt_block_impl(ALG_ID aiAlgid, DWORD dwKeySpec, KEY_CONTEXT *pKeyContext, const BYTE *in, - BYTE *out) +static BOOL rsa_decrypt( const SYMCRYPT_RSAKEY *key, const BYTE *in, SYMCRYPT_NUMBER_FORMAT in_format, + BYTE *out, SYMCRYPT_NUMBER_FORMAT out_format ) { - unsigned long inlen, outlen; - - switch (aiAlgid) { - case CALG_RC2: - SymCryptRc2Encrypt( &pKeyContext->rc2, in, out ); - break; - case CALG_3DES: - case CALG_3DES_112: - SymCrypt3DesEncrypt( &pKeyContext->des3, in, out ); - break; - case CALG_DES: - SymCryptDesEncrypt( &pKeyContext->des, in, out ); - break; - case CALG_AES: - case CALG_AES_128: - case CALG_AES_192: - case CALG_AES_256: - SymCryptAesEncrypt( &pKeyContext->aes, in, out ); - break; - - case CALG_RSA_KEYX: - case CALG_RSA_SIGN: - case CALG_SSL3_SHAMD5: - outlen = inlen = (mp_count_bits(pKeyContext->rsa.N)+7)/8; - if (rsa_exptmod(in, inlen, out, &outlen, dwKeySpec, &pKeyContext->rsa) != CRYPT_OK) { - SetLastError(NTE_FAIL); - return FALSE; - } - reverse_bytes(out, outlen); - break; + SIZE_T scratch_size, offset = 0, int_size, tmp_size, key_size = SymCryptRsakeySizeofModulus( key ); + SYMCRYPT_INT *ciphertext, *plaintext, *tmp; + SYMCRYPT_MODELEMENT *crt_elements[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES]; + BYTE *scratch; + UINT32 i, crt_element_total = 0, crt_elements_size[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES]; - default: - SetLastError(NTE_BAD_ALGID); - return FALSE; + int_size = SymCryptSizeofIntFromDigits( key->nDigitsOfModulus ); + tmp_size = SymCryptSizeofIntFromDigits( key->nMaxDigitsOfPrimes ); + + for (i = 0; i < key->nPrimes; i++) + { + crt_elements_size[i] = SYMCRYPT_SIZEOF_MODELEMENT_FROM_BITS( key->nBitsOfPrimes[i] ); + crt_element_total += crt_elements_size[i]; + } + + scratch_size = 3 * int_size + tmp_size + crt_element_total + + SYMCRYPT_MAX( SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( key->nDigitsOfModulus ), + SYMCRYPT_MAX( SYMCRYPT_SCRATCH_BYTES_FOR_MODEXP( key->nDigitsOfModulus ), + SYMCRYPT_MAX( SYMCRYPT_SCRATCH_BYTES_FOR_INT_DIVMOD( key->nDigitsOfModulus, key->nMaxDigitsOfPrimes ), + SYMCRYPT_SCRATCH_BYTES_FOR_CRT_SOLUTION( key->nMaxDigitsOfPrimes ) ) ) ); + + if (!(scratch = malloc( scratch_size ))) return FALSE; + + ciphertext = SymCryptIntCreate( scratch, scratch_size, key->nDigitsOfModulus ); + offset += int_size; + + plaintext = SymCryptIntCreate( scratch + offset, scratch_size - offset, key->nDigitsOfModulus ); + offset += int_size; + + tmp = SymCryptIntCreate( scratch + offset, scratch_size - offset, key->nMaxDigitsOfPrimes ); + offset += tmp_size; + + for (i = 0; i < key->nPrimes; i++) + { + crt_elements[i] = SymCryptModElementCreate( scratch + offset, scratch_size - offset, key->pmPrimes[i] ); + offset += crt_elements_size[i]; } + SymCryptIntSetValue( in, key_size, in_format, ciphertext ); + + for (i = 0; i < key->nPrimes; i++) + { + SymCryptIntDivMod( ciphertext, SymCryptDivisorFromModulus(key->pmPrimes[i]), NULL, tmp, scratch + offset, + scratch_size - offset ); + + SymCryptIntToModElement( tmp, key->pmPrimes[i], crt_elements[i], scratch + offset, scratch_size - offset ); + + SymCryptModExp( key->pmPrimes[i], crt_elements[i], key->piCrtPrivExps[i], key->nBitsOfPrimes[i], 0, + crt_elements[i], scratch + offset, scratch_size - offset ); + } + + SymCryptCrtSolve( key->nPrimes, (const SYMCRYPT_MODULUS **)key->pmPrimes, + (SYMCRYPT_MODELEMENT **)key->peCrtInverses, crt_elements, 0, plaintext, scratch + offset, + scratch_size - offset ); + + SymCryptIntGetValue( plaintext, out, key_size, out_format ); + free( scratch ); return TRUE; } -BOOL decrypt_block_impl(ALG_ID aiAlgid, DWORD dwKeySpec, KEY_CONTEXT *pKeyContext, const BYTE *in, - BYTE *out) +BOOL decrypt_block_impl( ALG_ID algid, KEY_CONTEXT *ctx, const BYTE *in, BYTE *out ) { - unsigned long inlen, outlen; - BYTE *in_reversed; - - switch (aiAlgid) { - case CALG_RC2: - SymCryptRc2Decrypt( &pKeyContext->rc2, in, out ); - break; - case CALG_3DES: - case CALG_3DES_112: - SymCrypt3DesDecrypt( &pKeyContext->des3, in, out ); - break; - case CALG_DES: - SymCryptDesDecrypt( &pKeyContext->des, in, out ); - break; - case CALG_AES: - case CALG_AES_128: - case CALG_AES_192: - case CALG_AES_256: - SymCryptAesDecrypt( &pKeyContext->aes, in, out ); - break; - - case CALG_RSA_KEYX: - case CALG_RSA_SIGN: - case CALG_SSL3_SHAMD5: - outlen = inlen = (mp_count_bits(pKeyContext->rsa.N)+7)/8; - in_reversed = malloc(inlen); - if (!in_reversed) { - SetLastError(NTE_NO_MEMORY); - return FALSE; - } - memcpy(in_reversed, in, inlen); - reverse_bytes(in_reversed, inlen); - if (rsa_exptmod(in_reversed, inlen, out, &outlen, dwKeySpec, &pKeyContext->rsa) != CRYPT_OK) { - free(in_reversed); - SetLastError(NTE_FAIL); - return FALSE; - } - free(in_reversed); - break; - - default: - SetLastError(NTE_BAD_ALGID); - return FALSE; + switch (algid) + { + case CALG_RC2: + SymCryptRc2Decrypt( &ctx->rc2, in, out ); + break; + case CALG_3DES: + case CALG_3DES_112: + SymCrypt3DesDecrypt( &ctx->des3, in, out ); + break; + case CALG_DES: + SymCryptDesDecrypt( &ctx->des, in, out ); + break; + case CALG_AES: + case CALG_AES_128: + case CALG_AES_192: + case CALG_AES_256: + SymCryptAesDecrypt( &ctx->aes, in, out ); + break; + case CALG_RSA_KEYX: + case CALG_RSA_SIGN: + case CALG_SSL3_SHAMD5: + return rsa_decrypt( ctx->rsa.key, in, SYMCRYPT_NUMBER_FORMAT_LSB_FIRST, out, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST ); + default: + SetLastError( NTE_BAD_ALGID ); + return FALSE; } - return TRUE; } -BOOL encrypt_stream_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, BYTE *stream, DWORD dwLen) +BOOL sign_hash_impl( KEY_CONTEXT *ctx, const BYTE *in, BYTE *out ) { - switch (aiAlgid) { - case CALG_RC4: - rc4_stream_crypt(&pKeyContext->prng.rc4.s, stream, dwLen, stream); - break; + return rsa_decrypt( ctx->rsa.key, in, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, out, SYMCRYPT_NUMBER_FORMAT_LSB_FIRST ); +} - default: - SetLastError(NTE_BAD_ALGID); - return FALSE; - } +BOOL verify_signature_impl( KEY_CONTEXT *ctx, const BYTE *in, BYTE *out ) +{ + return rsa_encrypt( ctx->rsa.key, in, SYMCRYPT_NUMBER_FORMAT_LSB_FIRST, out, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST ); +} +BOOL encrypt_stream_impl( ALG_ID algid, KEY_CONTEXT *ctx, BYTE *stream, DWORD len ) +{ + switch (algid) + { + case CALG_RC4: + SymCryptRc4Crypt( &ctx->rc4, stream, stream, len ); + break; + default: + SetLastError( NTE_BAD_ALGID ); + return FALSE; + } return TRUE; } -BOOL export_public_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,DWORD *pdwPubExp) +BOOL export_public_key_impl( const KEY_CONTEXT *ctx, BYTE *dst, DWORD *pubexp ) { - mp_to_unsigned_bin(pKeyContext->rsa.N, pbDest); - reverse_bytes(pbDest, mp_unsigned_bin_size(pKeyContext->rsa.N)); - if (mp_unsigned_bin_size(pKeyContext->rsa.N) < dwKeyLen) - memset(pbDest + mp_unsigned_bin_size(pKeyContext->rsa.N), 0, - dwKeyLen - mp_unsigned_bin_size(pKeyContext->rsa.N)); - *pdwPubExp = (DWORD)mp_get_int(pKeyContext->rsa.e); + BYTE *modulus = dst; + SIZE_T modulus_size; + UINT64 pubexp64; + + if (!ctx->rsa.key) return FALSE; + + modulus_size = SymCryptRsakeySizeofModulus( ctx->rsa.key ); + + if (SymCryptRsakeyGetValue( ctx->rsa.key, modulus, modulus_size, &pubexp64, 1, NULL, NULL, 0, + SYMCRYPT_NUMBER_FORMAT_LSB_FIRST, 0 )) + { + return FALSE; + SetLastError( NTE_FAIL ); + } + *pubexp = pubexp64; return TRUE; } -BOOL import_public_key_impl(const BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, - DWORD dwPubExp) +BOOL import_public_key_impl( ALG_ID algid, const BYTE *src, DWORD keylen, DWORD pubexp, KEY_CONTEXT *ctx ) { - BYTE *pbTemp; + const BYTE *modulus = src; + UINT64 exp64 = pubexp; - if (mp_init_multi(&pKeyContext->rsa.e, &pKeyContext->rsa.d, &pKeyContext->rsa.N, - &pKeyContext->rsa.dQ,&pKeyContext->rsa.dP,&pKeyContext->rsa.qP, - &pKeyContext->rsa.p, &pKeyContext->rsa.q, NULL)) + ctx->rsa.flags = SYMCRYPT_FLAG_KEY_NO_FIPS; + if (algid == CALG_RSA_KEYX) ctx->rsa.flags |= SYMCRYPT_FLAG_RSAKEY_ENCRYPT; + else ctx->rsa.flags |= SYMCRYPT_FLAG_RSAKEY_SIGN | SYMCRYPT_FLAG_RSAKEY_ENCRYPT; + + if (!(ctx->rsa.key = alloc_rsa_key( keylen * 8, FALSE ))) { - SetLastError(NTE_FAIL); + SetLastError( NTE_FAIL ); return FALSE; } - - pbTemp = malloc(dwKeyLen); - if (!pbTemp) return FALSE; - memcpy(pbTemp, pbSrc, dwKeyLen); - - pKeyContext->rsa.type = PK_PUBLIC; - reverse_bytes(pbTemp, dwKeyLen); - mp_read_unsigned_bin(pKeyContext->rsa.N, pbTemp, dwKeyLen); - free(pbTemp); - mp_set_int(pKeyContext->rsa.e, dwPubExp); - - return TRUE; + if (SymCryptRsakeySetValue( modulus, keylen, &exp64, 1, NULL, NULL, 0, SYMCRYPT_NUMBER_FORMAT_LSB_FIRST, + ctx->rsa.flags, ctx->rsa.key )) + { + SetLastError( NTE_FAIL ); + return FALSE; + } + return TRUE; } -BOOL export_private_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, - DWORD *pdwPubExp) +BOOL export_private_key_impl( const KEY_CONTEXT *ctx, BYTE *dst, DWORD *pubexp ) { - mp_to_unsigned_bin(pKeyContext->rsa.N, pbDest); - reverse_bytes(pbDest, mp_unsigned_bin_size(pKeyContext->rsa.N)); - if (mp_unsigned_bin_size(pKeyContext->rsa.N) < dwKeyLen) - memset(pbDest + mp_unsigned_bin_size(pKeyContext->rsa.N), 0, - dwKeyLen - mp_unsigned_bin_size(pKeyContext->rsa.N)); - pbDest += dwKeyLen; - mp_to_unsigned_bin(pKeyContext->rsa.p, pbDest); - reverse_bytes(pbDest, mp_unsigned_bin_size(pKeyContext->rsa.p)); - if (mp_unsigned_bin_size(pKeyContext->rsa.p) < (dwKeyLen+1)>>1) - memset(pbDest + mp_unsigned_bin_size(pKeyContext->rsa.p), 0, - ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(pKeyContext->rsa.p)); - pbDest += (dwKeyLen+1)>>1; - mp_to_unsigned_bin(pKeyContext->rsa.q, pbDest); - reverse_bytes(pbDest, mp_unsigned_bin_size(pKeyContext->rsa.q)); - if (mp_unsigned_bin_size(pKeyContext->rsa.q) < (dwKeyLen+1)>>1) - memset(pbDest + mp_unsigned_bin_size(pKeyContext->rsa.q), 0, - ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(pKeyContext->rsa.q)); - pbDest += (dwKeyLen+1)>>1; - mp_to_unsigned_bin(pKeyContext->rsa.dP, pbDest); - reverse_bytes(pbDest, mp_unsigned_bin_size(pKeyContext->rsa.dP)); - if (mp_unsigned_bin_size(pKeyContext->rsa.dP) < (dwKeyLen+1)>>1) - memset(pbDest + mp_unsigned_bin_size(pKeyContext->rsa.dP), 0, - ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(pKeyContext->rsa.dP)); - pbDest += (dwKeyLen+1)>>1; - mp_to_unsigned_bin(pKeyContext->rsa.dQ, pbDest); - reverse_bytes(pbDest, mp_unsigned_bin_size(pKeyContext->rsa.dQ)); - if (mp_unsigned_bin_size(pKeyContext->rsa.dQ) < (dwKeyLen+1)>>1) - memset(pbDest + mp_unsigned_bin_size(pKeyContext->rsa.dQ), 0, - ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(pKeyContext->rsa.dQ)); - pbDest += (dwKeyLen+1)>>1; - mp_to_unsigned_bin(pKeyContext->rsa.qP, pbDest); - reverse_bytes(pbDest, mp_unsigned_bin_size(pKeyContext->rsa.qP)); - if (mp_unsigned_bin_size(pKeyContext->rsa.qP) < (dwKeyLen+1)>>1) - memset(pbDest + mp_unsigned_bin_size(pKeyContext->rsa.qP), 0, - ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(pKeyContext->rsa.qP)); - pbDest += (dwKeyLen+1)>>1; - mp_to_unsigned_bin(pKeyContext->rsa.d, pbDest); - reverse_bytes(pbDest, mp_unsigned_bin_size(pKeyContext->rsa.d)); - if (mp_unsigned_bin_size(pKeyContext->rsa.d) < dwKeyLen) - memset(pbDest + mp_unsigned_bin_size(pKeyContext->rsa.d), 0, - dwKeyLen - mp_unsigned_bin_size(pKeyContext->rsa.d)); - *pdwPubExp = (DWORD)mp_get_int(pKeyContext->rsa.e); + BYTE *modulus, *primes[2], *exponents[2], *coefficient, *private_exp; + SIZE_T modulus_size, primes_sizes[2]; + UINT64 pubexp64; + + if (!ctx->rsa.key) return FALSE; + + modulus_size = SymCryptRsakeySizeofModulus( ctx->rsa.key ); + + primes_sizes[0] = SymCryptRsakeySizeofPrime( ctx->rsa.key, 0 ); + primes_sizes[1] = SymCryptRsakeySizeofPrime( ctx->rsa.key, 1 ); + + modulus = dst; + primes[0] = modulus + modulus_size; + primes[1] = modulus + modulus_size + primes_sizes[0]; + if (SymCryptRsakeyGetValue( ctx->rsa.key, modulus, modulus_size, &pubexp64, 1, primes, primes_sizes, 2, + SYMCRYPT_NUMBER_FORMAT_LSB_FIRST, 0 )) + { + return FALSE; + SetLastError( NTE_FAIL ); + } + + exponents[0] = primes[1] + primes_sizes[1]; + exponents[1] = exponents[0] + primes_sizes[0]; + coefficient = exponents[1] + primes_sizes[1]; + private_exp = coefficient + primes_sizes[0]; + + if (SymCryptRsakeyGetCrtValue( ctx->rsa.key, exponents, primes_sizes, 2, coefficient, primes_sizes[0], + private_exp, modulus_size, SYMCRYPT_NUMBER_FORMAT_LSB_FIRST, 0 )) + { + return FALSE; + SetLastError( NTE_FAIL ); + } + + *pubexp = pubexp64; return TRUE; } -BOOL import_private_key_impl(const BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, - DWORD dwDataLen, DWORD dwPubExp) +BOOL import_private_key_impl( ALG_ID algid, const BYTE *src, DWORD keylen, DWORD pubexp, KEY_CONTEXT *ctx ) { - BYTE *pbTemp, *pbBigNum; + const BYTE *modulus = src, *primes[2]; + SIZE_T primes_sizes[2]; + UINT64 exp64 = pubexp; + + ctx->rsa.flags = SYMCRYPT_FLAG_KEY_NO_FIPS; + if (algid == CALG_RSA_KEYX) ctx->rsa.flags |= SYMCRYPT_FLAG_RSAKEY_ENCRYPT; + else ctx->rsa.flags |= SYMCRYPT_FLAG_RSAKEY_SIGN | SYMCRYPT_FLAG_RSAKEY_ENCRYPT; + + if (!(ctx->rsa.key = alloc_rsa_key( keylen * 8, TRUE ))) + { + SetLastError( NTE_FAIL ); + return FALSE; + } + + primes[0] = modulus + keylen; + primes[1] = primes[0] + keylen / 2; + + primes_sizes[0] = keylen / 2; + primes_sizes[1] = keylen / 2; - if (mp_init_multi(&pKeyContext->rsa.e, &pKeyContext->rsa.d, &pKeyContext->rsa.N, - &pKeyContext->rsa.dQ,&pKeyContext->rsa.dP,&pKeyContext->rsa.qP, - &pKeyContext->rsa.p, &pKeyContext->rsa.q, NULL)) + if (SymCryptRsakeySetValue( modulus, keylen, &exp64, 1, primes, primes_sizes, 2, + SYMCRYPT_NUMBER_FORMAT_LSB_FIRST, ctx->rsa.flags, ctx->rsa.key )) { - SetLastError(NTE_FAIL); + SetLastError( NTE_FAIL ); return FALSE; } - pbTemp = malloc(2*dwKeyLen+5*((dwKeyLen+1)>>1)); - if (!pbTemp) return FALSE; - memcpy(pbTemp, pbSrc, min(dwDataLen, 2*dwKeyLen+5*((dwKeyLen+1)>>1))); - pbBigNum = pbTemp; - - pKeyContext->rsa.type = PK_PRIVATE; - reverse_bytes(pbBigNum, dwKeyLen); - mp_read_unsigned_bin(pKeyContext->rsa.N, pbBigNum, dwKeyLen); - pbBigNum += dwKeyLen; - reverse_bytes(pbBigNum, (dwKeyLen+1)>>1); - mp_read_unsigned_bin(pKeyContext->rsa.p, pbBigNum, (dwKeyLen+1)>>1); - pbBigNum += (dwKeyLen+1)>>1; - reverse_bytes(pbBigNum, (dwKeyLen+1)>>1); - mp_read_unsigned_bin(pKeyContext->rsa.q, pbBigNum, (dwKeyLen+1)>>1); - pbBigNum += (dwKeyLen+1)>>1; - reverse_bytes(pbBigNum, (dwKeyLen+1)>>1); - mp_read_unsigned_bin(pKeyContext->rsa.dP, pbBigNum, (dwKeyLen+1)>>1); - pbBigNum += (dwKeyLen+1)>>1; - reverse_bytes(pbBigNum, (dwKeyLen+1)>>1); - mp_read_unsigned_bin(pKeyContext->rsa.dQ, pbBigNum, (dwKeyLen+1)>>1); - pbBigNum += (dwKeyLen+1)>>1; - reverse_bytes(pbBigNum, (dwKeyLen+1)>>1); - mp_read_unsigned_bin(pKeyContext->rsa.qP, pbBigNum, (dwKeyLen+1)>>1); - pbBigNum += (dwKeyLen+1)>>1; - /* The size of the private exponent d is inferred from the remaining - * data length. - */ - dwKeyLen = min(dwKeyLen, dwDataLen - (pbBigNum - pbTemp)); - reverse_bytes(pbBigNum, dwKeyLen); - mp_read_unsigned_bin(pKeyContext->rsa.d, pbBigNum, dwKeyLen); - mp_set_int(pKeyContext->rsa.e, dwPubExp); - - free(pbTemp); return TRUE; } diff --git a/dlls/rsaenh/implglue.h b/dlls/rsaenh/implglue.h index 4ea65e3a973..f9eb9ab6c8e 100644 --- a/dlls/rsaenh/implglue.h +++ b/dlls/rsaenh/implglue.h @@ -24,23 +24,27 @@ #ifndef __WINE_IMPLGLUE_H #define __WINE_IMPLGLUE_H -#include "tomcrypt.h" #include "symcrypt.h" +#include "symcrypt_low_level.h" #define RSAENH_MAX_HASH_SIZE 104 -typedef union tagKEY_CONTEXT { +struct rsa_key +{ + SYMCRYPT_RSAKEY *key; + UINT32 flags; +}; + +typedef union tagKEY_CONTEXT +{ SYMCRYPT_DES_EXPANDED_KEY des; SYMCRYPT_3DES_EXPANDED_KEY des3; SYMCRYPT_RC2_EXPANDED_KEY rc2; + SYMCRYPT_RC4_STATE rc4; SYMCRYPT_AES_EXPANDED_KEY aes; - prng_state prng; - rsa_key rsa; + struct rsa_key rsa; } KEY_CONTEXT; -extern prng_state prng; -extern int wprng; - struct hash { const SYMCRYPT_HASH *desc; @@ -59,27 +63,22 @@ static inline void finalize_hash_impl(struct hash *hash, BYTE *hash_value, DWORD SymCryptHashResult( hash->desc, &hash->state, hash_value, hash_size ); } -BOOL new_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen); -BOOL free_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext); -BOOL setup_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, - DWORD dwEffectiveKeyLen, DWORD dwSaltLen, BYTE *abKeyValue); -BOOL duplicate_key_impl(ALG_ID aiAlgid, const KEY_CONTEXT *pSrcKeyContext, - KEY_CONTEXT *pDestKeyContext); +BOOL new_key_impl(ALG_ID algid, KEY_CONTEXT *ctx, DWORD keylen); +BOOL free_key_impl(ALG_ID algid, KEY_CONTEXT *ctx); +BOOL setup_key_impl(ALG_ID algid, KEY_CONTEXT *ctx, DWORD keylen, DWORD effective_keylen, DWORD saltlen, + const BYTE *keyvalue); +BOOL duplicate_key_impl(ALG_ID algid, const KEY_CONTEXT *src, KEY_CONTEXT *dst); + +BOOL encrypt_block_impl(ALG_ID algid, KEY_CONTEXT *ctx, const BYTE *in, BYTE *out); +BOOL decrypt_block_impl(ALG_ID algid, KEY_CONTEXT *ctx, const BYTE *in, BYTE *out); +BOOL encrypt_stream_impl(ALG_ID algid, KEY_CONTEXT *ctx, BYTE *inout, DWORD len); -/* dwKeySpec is optional for symmetric key algorithms */ -BOOL encrypt_block_impl(ALG_ID aiAlgid, DWORD dwKeySpec, KEY_CONTEXT *pKeyContext, const BYTE *pbIn, - BYTE *pbOut); -BOOL decrypt_block_impl(ALG_ID aiAlgid, DWORD dwKeySpec, KEY_CONTEXT *pKeyContext, const BYTE *pbIn, - BYTE *pbOut); -BOOL encrypt_stream_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, BYTE *pbInOut, DWORD dwLen); +BOOL sign_hash_impl(KEY_CONTEXT *ctx, const BYTE *in, BYTE *out); +BOOL verify_signature_impl(KEY_CONTEXT *ctx, const BYTE *in, BYTE *out); -BOOL export_public_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, - DWORD *pdwPubExp); -BOOL import_public_key_impl(const BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, - DWORD dwPubExp); -BOOL export_private_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, - DWORD *pdwPubExp); -BOOL import_private_key_impl(const BYTE* pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, - DWORD dwDataLen, DWORD dwPubExp); +BOOL export_public_key_impl(const KEY_CONTEXT *ctx, BYTE *dst, DWORD *pubexp); +BOOL import_public_key_impl(ALG_ID algid, const BYTE *src, DWORD keylen, DWORD pubexp, KEY_CONTEXT *ctx); +BOOL export_private_key_impl(const KEY_CONTEXT *ctx, BYTE *dst, DWORD *pubexp); +BOOL import_private_key_impl(ALG_ID algid, const BYTE *src, DWORD keylen, DWORD pubexp, KEY_CONTEXT *ctx); #endif /* __WINE_IMPLGLUE_H */ diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c index 4eca3a6d9eb..4de6a2d0617 100644 --- a/dlls/rsaenh/rsaenh.c +++ b/dlls/rsaenh/rsaenh.c @@ -355,10 +355,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID reserved) DisableThreadLibraryCalls(hInstance); init_handle_table(&handle_table); SymCryptInit(); - /* tomcrypt initialization */ - init_LTM(); - wprng = register_prng( &rc4_desc ); - rng_make_prng( 1024, wprng, &prng, NULL ); break; case DLL_PROCESS_DETACH: @@ -560,18 +556,18 @@ BOOL block_encrypt(CRYPTKEY *key, BYTE *data, DWORD *data_len, DWORD buf_len, { switch (key->dwMode) { case CRYPT_MODE_ECB: - encrypt_block_impl(key->aiAlgid, 0, context, in, out); + encrypt_block_impl(key->aiAlgid, context, in, out); break; case CRYPT_MODE_CBC: for (j = 0; j < key->dwBlockLen; j++) in[j] ^= chain_vector[j]; - encrypt_block_impl(key->aiAlgid, 0, context, in, out); + encrypt_block_impl(key->aiAlgid, context, in, out); memcpy(chain_vector, out, key->dwBlockLen); break; case CRYPT_MODE_CFB: for (j = 0; j < key->dwBlockLen; j++) { - encrypt_block_impl(key->aiAlgid, 0, context, chain_vector, o); + encrypt_block_impl(key->aiAlgid, context, chain_vector, o); out[j] = in[j] ^ o[0]; for (k = 0; k < key->dwBlockLen - 1; k++) chain_vector[k] = chain_vector[k+1]; @@ -682,13 +678,13 @@ static void destroy_hash(OBJECTHDR *pObject) */ static inline BOOL init_hash(CRYPTHASH *pCryptHash) { DWORD dwLen; - + switch (pCryptHash->aiAlgid) { case CALG_HMAC: if (pCryptHash->pHMACInfo) { const PROV_ENUMALGS_EX *pAlgInfo; - + pAlgInfo = get_algid_info(pCryptHash->hProv, pCryptHash->pHMACInfo->HashAlgid); if (!pAlgInfo) { @@ -703,7 +699,7 @@ static inline BOOL init_hash(CRYPTHASH *pCryptHash) { pCryptHash->pHMACInfo->cbInnerString); } return TRUE; - + case CALG_MAC: dwLen = sizeof(DWORD); RSAENH_CPGetKeyParam(pCryptHash->hProv, pCryptHash->hKey, KP_BLOCKLEN, @@ -808,7 +804,7 @@ static inline void finalize_hash(CRYPTHASH *pCryptHash) { DWORD dwDataLen; CRYPTKEY *key; - + switch (pCryptHash->aiAlgid) { case CALG_HMAC: @@ -856,7 +852,7 @@ static inline void finalize_hash(CRYPTHASH *pCryptHash) static void destroy_key(OBJECTHDR *pObject) { CRYPTKEY *pCryptKey = (CRYPTKEY*)pObject; - + free_key_impl(pCryptKey->aiAlgid, &pCryptKey->context); free_data_blob(&pCryptKey->siSChannelInfo.blobClientRandom); free_data_blob(&pCryptKey->siSChannelInfo.blobServerRandom); @@ -990,7 +986,7 @@ static HCRYPTKEY new_key(HCRYPTPROV hProv, ALG_ID aiAlgid, DWORD dwFlags, CRYPTK const PROV_ENUMALGS_EX *peaAlgidInfo; *ppCryptKey = NULL; - + /* * Retrieve the CSP's capabilities for the given ALG_ID value */ @@ -1003,7 +999,7 @@ static HCRYPTKEY new_key(HCRYPTPROV hProv, ALG_ID aiAlgid, DWORD dwFlags, CRYPTK * Assume the default key length, if none is specified explicitly */ if (dwKeyLen == 0) dwKeyLen = peaAlgidInfo->dwDefaultLen; - + /* * Check if the requested key length is supported by the current CSP. * Adjust key length's for DES algorithms. @@ -1534,7 +1530,7 @@ static HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD dwFlags, cons if (!lookup_handle(&handle_table, hKeyContainer, RSAENH_MAGIC_CONTAINER, (OBJECTHDR**)&pKeyContainer)) return (HCRYPTPROV)INVALID_HANDLE_VALUE; - + /* read_key_value calls import_key, which calls import_private_key, * which implicitly installs the key value into the appropriate key * container key. Thus the ref count is incremented twice, once for @@ -1604,7 +1600,7 @@ static BOOL build_hash_signature(BYTE *pbSignature, DWORD dwLen, ALG_ID aiAlgid, for (dwIdxOID = 0; aOIDDescriptor[dwIdxOID].aiAlgid; dwIdxOID++) { if (aOIDDescriptor[dwIdxOID].aiAlgid == aiAlgid) break; } - + if (!aOIDDescriptor[dwIdxOID].aiAlgid) { SetLastError(NTE_BAD_ALGID); return FALSE; @@ -1643,7 +1639,7 @@ static BOOL build_hash_signature(BYTE *pbSignature, DWORD dwLen, ALG_ID aiAlgid, pbSignature[i++] = abHashValue[j]; } } - + return TRUE; } @@ -1676,7 +1672,7 @@ static BOOL tls1_p(HCRYPTHASH hHMAC, const PCRYPT_DATA_BLOB pblobSeed, BYTE *pbB SetLastError(NTE_BAD_HASH); return FALSE; } - + /* compute A_1 = HMAC(seed) */ init_hash(pHMAC); update_hash(pHMAC, pblobSeed->pbData, pblobSeed->cbData); @@ -1744,13 +1740,13 @@ static BOOL tls1_prf(HCRYPTPROV hProv, HCRYPTPROV hSecret, const PCRYPT_DATA_BLO } dwHalfSecretLen = (pSecret->dwKeyLen+1)/2; - + /* concatenation of the label and the seed */ if (!concat_data_blobs(&blobLabelSeed, pblobLabel, pblobSeed)) goto exit; - + /* zero out the buffer, since two random streams will be xor'ed into it. */ memset(pbBuffer, 0, dwBufferLen); - + /* build a 'fake' key, to hold the secret. CALG_SSL2_MASTER is used since it provides * the biggest range of valid key lengths. */ hHalfSecret = new_key(hProv, CALG_SSL2_MASTER, MAKELONG(0,dwHalfSecretLen*8), &pHalfSecret); @@ -1768,7 +1764,7 @@ static BOOL tls1_prf(HCRYPTPROV hProv, HCRYPTPROV hSecret, const PCRYPT_DATA_BLO hmacInfo.HashAlgid = CALG_SHA; if (!RSAENH_CPSetHashParam(hProv, hHMAC, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0)) goto exit; if (!tls1_p(hHMAC, &blobLabelSeed, pbBuffer, dwBufferLen)) goto exit; - + result = TRUE; exit: release_handle(&handle_table, hHalfSecret, RSAENH_MAGIC_KEY); @@ -1796,7 +1792,7 @@ exit: static BOOL pad_data_pkcs1(const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD dwBufferLen, DWORD dwFlags) { DWORD i; - + /* Ensure there is enough space for PKCS1 #2 padding */ if (dwDataLen > dwBufferLen-11) { SetLastError(NTE_BAD_LEN); @@ -1804,7 +1800,7 @@ static BOOL pad_data_pkcs1(const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, } memmove(abBuffer + dwBufferLen - dwDataLen, abData, dwDataLen); - + abBuffer[0] = 0x00; abBuffer[1] = RSAENH_PKC_BLOCKTYPE; for (i=2; i < dwBufferLen - dwDataLen - 1; i++) @@ -1813,7 +1809,7 @@ static BOOL pad_data_pkcs1(const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, for (i-=8; i < dwBufferLen - dwDataLen - 1; i++) abBuffer[i] = 0x03; abBuffer[i] = 0x00; - + return TRUE; } @@ -2021,7 +2017,7 @@ static BOOL pad_data(HCRYPTPROV hProv, const BYTE *abData, DWORD dwDataLen, BYTE static BOOL unpad_data_pkcs1(const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD *dwBufferLen, DWORD dwFlags) { DWORD i; - + if (dwDataLen < 3) { SetLastError(NTE_BAD_DATA); @@ -2245,13 +2241,13 @@ BOOL WINAPI RSAENH_CPAcquireContext(HCRYPTPROV *phProv, LPSTR pszContainer, } *phProv = new_key_container("", dwFlags, pVTable); break; - + default: *phProv = (HCRYPTPROV)INVALID_HANDLE_VALUE; SetLastError(NTE_BAD_FLAGS); return FALSE; } - + if (*phProv != (HCRYPTPROV)INVALID_HANDLE_VALUE) { SetLastError(ERROR_SUCCESS); return TRUE; @@ -2286,7 +2282,7 @@ BOOL WINAPI RSAENH_CPCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, CRYPTKEY *pCryptKey = NULL; CRYPTHASH *pCryptHash; const PROV_ENUMALGS_EX *peaAlgidInfo; - + TRACE("(hProv=%08Ix, Algid=%08x, hKey=%08Ix, dwFlags=%08lx, phHash=%p)\n", hProv, Algid, hKey, dwFlags, phHash); @@ -2360,7 +2356,7 @@ BOOL WINAPI RSAENH_CPCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, CRYPT_DATA_BLOB blobRandom, blobKeyExpansion = { 13, key_expansion }; memcpy( key_expansion, keyex, sizeof keyex ); - + if (pCryptKey->dwState != RSAENH_KEYSTATE_MASTERKEY) { static const char msec[] = "master secret"; BYTE master_secret[sizeof msec]; @@ -2368,7 +2364,7 @@ BOOL WINAPI RSAENH_CPCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, BYTE abKeyValue[48]; memcpy( master_secret, msec, sizeof msec ); - + /* See RFC 2246, chapter 8.1 */ if (!concat_data_blobs(&blobRandom, &pCryptKey->siSChannelInfo.blobClientRandom, @@ -2414,19 +2410,19 @@ BOOL WINAPI RSAENH_CPCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, BOOL WINAPI RSAENH_CPDestroyHash(HCRYPTPROV hProv, HCRYPTHASH hHash) { TRACE("(hProv=%08Ix, hHash=%08Ix)\n", hProv, hHash); - + if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) { SetLastError(NTE_BAD_UID); return FALSE; } - + if (!release_handle(&handle_table, hHash, RSAENH_MAGIC_HASH)) { SetLastError(NTE_BAD_HASH); return FALSE; } - + return TRUE; } @@ -2447,19 +2443,19 @@ BOOL WINAPI RSAENH_CPDestroyHash(HCRYPTPROV hProv, HCRYPTHASH hHash) BOOL WINAPI RSAENH_CPDestroyKey(HCRYPTPROV hProv, HCRYPTKEY hKey) { TRACE("(hProv=%08Ix, hKey=%08Ix)\n", hProv, hKey); - + if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) { SetLastError(NTE_BAD_UID); return FALSE; } - + if (!release_handle(&handle_table, hKey, RSAENH_MAGIC_KEY)) { SetLastError(NTE_BAD_KEY); return FALSE; } - + return TRUE; } @@ -2483,7 +2479,7 @@ BOOL WINAPI RSAENH_CPDuplicateHash(HCRYPTPROV hUID, HCRYPTHASH hHash, DWORD *pdw DWORD dwFlags, HCRYPTHASH *phHash) { CRYPTHASH *pSrcHash, *pDestHash; - + TRACE("(hUID=%08Ix, hHash=%08Ix, pdwReserved=%p, dwFlags=%08lx, phHash=%p)\n", hUID, hHash, pdwReserved, dwFlags, phHash); @@ -2538,7 +2534,7 @@ BOOL WINAPI RSAENH_CPDuplicateKey(HCRYPTPROV hUID, HCRYPTKEY hKey, DWORD *pdwRes DWORD dwFlags, HCRYPTKEY *phKey) { CRYPTKEY *pSrcKey, *pDestKey; - + TRACE("(hUID=%08Ix, hKey=%08Ix, pdwReserved=%p, dwFlags=%08lx, phKey=%p)\n", hUID, hKey, pdwReserved, dwFlags, phKey); @@ -2603,15 +2599,15 @@ BOOL WINAPI RSAENH_CPDuplicateKey(HCRYPTPROV hUID, HCRYPTKEY hKey, DWORD *pdwRes * * This function uses the standard WINAPI protocol for querying data of dynamic length. */ -BOOL WINAPI RSAENH_CPEncrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, - DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen) +BOOL WINAPI RSAENH_CPEncrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, + BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen) { CRYPTKEY *pCryptKey; - + TRACE("(hProv=%08Ix, hKey=%08Ix, hHash=%08Ix, Final=%d, dwFlags=%08lx, pbData=%p, " "pdwDataLen=%p, dwBufLen=%ld)\n", hProv, hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen); - + if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) { SetLastError(NTE_BAD_UID); @@ -2685,7 +2681,7 @@ BOOL WINAPI RSAENH_CPEncrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, return FALSE; } if (!pad_data(hProv, pbData, *pdwDataLen, pbData, pCryptKey->dwBlockLen, dwFlags)) return FALSE; - encrypt_block_impl(pCryptKey->aiAlgid, PK_PUBLIC, &pCryptKey->context, pbData, pbData); + encrypt_block_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, pbData); *pdwDataLen = pCryptKey->dwBlockLen; Final = TRUE; } else { @@ -2732,7 +2728,7 @@ BOOL WINAPI RSAENH_CPDecrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, TRACE("(hProv=%08Ix, hKey=%08Ix, hHash=%08Ix, Final=%d, dwFlags=%08lx, pbData=%p, " "pdwDataLen=%p)\n", hProv, hKey, hHash, Final, dwFlags, pbData, pdwDataLen); - + if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) { SetLastError(NTE_BAD_UID); @@ -2772,25 +2768,25 @@ BOOL WINAPI RSAENH_CPDecrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, for (i=0, in=pbData; i<*pdwDataLen; i+=pCryptKey->dwBlockLen, in+=pCryptKey->dwBlockLen) { switch (pCryptKey->dwMode) { case CRYPT_MODE_ECB: - decrypt_block_impl(pCryptKey->aiAlgid, 0, &pCryptKey->context, in, out); + decrypt_block_impl(pCryptKey->aiAlgid, &pCryptKey->context, in, out); break; - + case CRYPT_MODE_CBC: - decrypt_block_impl(pCryptKey->aiAlgid, 0, &pCryptKey->context, in, out); + decrypt_block_impl(pCryptKey->aiAlgid, &pCryptKey->context, in, out); for (j=0; j<pCryptKey->dwBlockLen; j++) out[j] ^= pCryptKey->abChainVector[j]; memcpy(pCryptKey->abChainVector, in, pCryptKey->dwBlockLen); break; case CRYPT_MODE_CFB: for (j=0; j<pCryptKey->dwBlockLen; j++) { - encrypt_block_impl(pCryptKey->aiAlgid, 0, &pCryptKey->context, pCryptKey->abChainVector, o); + encrypt_block_impl(pCryptKey->aiAlgid, &pCryptKey->context, pCryptKey->abChainVector, o); out[j] = in[j] ^ o[0]; for (k=0; k<pCryptKey->dwBlockLen-1; k++) pCryptKey->abChainVector[k] = pCryptKey->abChainVector[k+1]; pCryptKey->abChainVector[k] = in[j]; } break; - + default: SetLastError(NTE_BAD_ALGID); return FALSE; @@ -2829,21 +2825,21 @@ BOOL WINAPI RSAENH_CPDecrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, SetLastError(NTE_BAD_KEY); return FALSE; } - decrypt_block_impl(pCryptKey->aiAlgid, PK_PRIVATE, &pCryptKey->context, pbData, pbData); + decrypt_block_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, pbData); if (!unpad_data(hProv, pbData, pCryptKey->dwBlockLen, pbData, pdwDataLen, dwFlags)) return FALSE; Final = TRUE; } else { SetLastError(NTE_BAD_TYPE); return FALSE; } - + if (Final) setup_key(pCryptKey); if (is_valid_handle(&handle_table, hHash, RSAENH_MAGIC_HASH)) { if (*pdwDataLen>dwMax || !RSAENH_CPHashData(hProv, hHash, pbData, *pdwDataLen, 0)) return FALSE; } - + return TRUE; } @@ -2880,7 +2876,7 @@ static BOOL crypt_export_simple(CRYPTKEY *pCryptKey, CRYPTKEY *pPubKey, return FALSE; } - encrypt_block_impl(pPubKey->aiAlgid, PK_PUBLIC, &pPubKey->context, (BYTE*)(pAlgid+1), (BYTE*)(pAlgid+1)); + encrypt_block_impl(pPubKey->aiAlgid, &pPubKey->context, (BYTE *)(pAlgid + 1), (BYTE *)(pAlgid + 1)); } *pdwDataLen = dwDataLen; return TRUE; @@ -2914,8 +2910,7 @@ static BOOL crypt_export_public_key(CRYPTKEY *pCryptKey, BYTE *pbData, pRSAPubKey->magic = RSAENH_MAGIC_RSA1; pRSAPubKey->bitlen = pCryptKey->dwKeyLen << 3; - export_public_key_impl((BYTE*)(pRSAPubKey+1), &pCryptKey->context, - pCryptKey->dwKeyLen, &pRSAPubKey->pubexp); + export_public_key_impl(&pCryptKey->context, (BYTE *)(pRSAPubKey + 1), &pRSAPubKey->pubexp); } *pdwDataLen = dwDataLen; return TRUE; @@ -2954,9 +2949,7 @@ static BOOL crypt_export_private_key(CRYPTKEY *pCryptKey, BOOL force, pRSAPubKey->magic = RSAENH_MAGIC_RSA2; pRSAPubKey->bitlen = pCryptKey->dwKeyLen << 3; - - export_private_key_impl((BYTE*)(pRSAPubKey+1), &pCryptKey->context, - pCryptKey->dwKeyLen, &pRSAPubKey->pubexp); + export_private_key_impl(&pCryptKey->context, (BYTE *)(pRSAPubKey + 1), &pRSAPubKey->pubexp); } *pdwDataLen = dwDataLen; return TRUE; @@ -3015,14 +3008,14 @@ static BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey, BYTE *pbData, DWORD *pdwDataLen) { CRYPTKEY *pPubKey; - + if (dwFlags & CRYPT_SSL2_FALLBACK) { if (pCryptKey->aiAlgid != CALG_SSL2_MASTER) { SetLastError(NTE_BAD_KEY); return FALSE; } } - + switch ((BYTE)dwBlobType) { case SIMPLEBLOB: @@ -3032,7 +3025,7 @@ static BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey, } return crypt_export_simple(pCryptKey, pPubKey, dwFlags, pbData, pdwDataLen); - + case PUBLICKEYBLOB: if (is_valid_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY)) { SetLastError(NTE_BAD_KEY); /* FIXME: error code? */ @@ -3046,7 +3039,7 @@ static BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey, case PLAINTEXTKEYBLOB: return crypt_export_plaintext_key(pCryptKey, pbData, pdwDataLen); - + default: SetLastError(NTE_BAD_TYPE); /* FIXME: error code? */ return FALSE; @@ -3192,8 +3185,8 @@ static BOOL import_private_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDat *phKey = new_key(hProv, pBlobHeader->aiKeyAlg, MAKELONG(0,pRSAPubKey->bitlen), &pCryptKey); if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE; setup_key(pCryptKey); - ret = import_private_key_impl((const BYTE*)(pRSAPubKey+1), &pCryptKey->context, - pRSAPubKey->bitlen/8, dwDataLen, pRSAPubKey->pubexp); + ret = import_private_key_impl(pBlobHeader->aiKeyAlg, (const BYTE *)(pRSAPubKey + 1), + pRSAPubKey->bitlen / 8, pRSAPubKey->pubexp, &pCryptKey->context); if (ret) { if (dwFlags & CRYPT_EXPORTABLE) pCryptKey->dwPermissions |= CRYPT_EXPORT; @@ -3269,8 +3262,8 @@ static BOOL import_public_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwData *phKey = new_key(hProv, algID, MAKELONG(0,pRSAPubKey->bitlen), &pCryptKey); if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE; setup_key(pCryptKey); - ret = import_public_key_impl((const BYTE*)(pRSAPubKey+1), &pCryptKey->context, - pRSAPubKey->bitlen >> 3, pRSAPubKey->pubexp); + ret = import_public_key_impl(algID, (const BYTE *)(pRSAPubKey + 1), pRSAPubKey->bitlen / 8, + pRSAPubKey->pubexp, &pCryptKey->context); if (ret) { if (dwFlags & CRYPT_EXPORTABLE) pCryptKey->dwPermissions |= CRYPT_EXPORT; @@ -3332,7 +3325,7 @@ static BOOL import_symmetric_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwD pbDecrypted = malloc(pPubKey->dwBlockLen); if (!pbDecrypted) return FALSE; - decrypt_block_impl(pPubKey->aiAlgid, PK_PRIVATE, &pPubKey->context, pbKeyStream, pbDecrypted); + decrypt_block_impl(pPubKey->aiAlgid, &pPubKey->context, pbKeyStream, pbDecrypted); dwKeyLen = RSAENH_MAX_KEY_SIZE; if (!unpad_data(hProv, pbDecrypted, pPubKey->dwBlockLen, pbDecrypted, &dwKeyLen, dwFlags)) { @@ -3506,11 +3499,11 @@ static BOOL import_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HC case PRIVATEKEYBLOB: return import_private_key(hProv, pbData, dwDataLen, dwFlags, fStoreKey, phKey); - + case PUBLICKEYBLOB: return import_public_key(hProv, pbData, dwDataLen, dwFlags, phKey); - + case SIMPLEBLOB: return import_symmetric_key(hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey); @@ -3586,7 +3579,7 @@ BOOL WINAPI RSAENH_CPGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYP /* MSDN: hProv not containing valid context handle */ return FALSE; } - + switch (Algid) { case AT_SIGNATURE: @@ -3612,7 +3605,7 @@ BOOL WINAPI RSAENH_CPGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYP FALSE); } break; - + case CALG_RC2: case CALG_RC4: case CALG_DES: @@ -3646,13 +3639,13 @@ BOOL WINAPI RSAENH_CPGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYP setup_key(pCryptKey); } break; - + default: /* MSDN: Algorithm not supported specified by Algid */ SetLastError(NTE_BAD_ALGID); return FALSE; } - + return *phKey != (HCRYPTKEY)INVALID_HANDLE_VALUE; } @@ -3673,7 +3666,7 @@ BOOL WINAPI RSAENH_CPGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYP BOOL WINAPI RSAENH_CPGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer) { TRACE("(hProv=%08Ix, dwLen=%ld, pbBuffer=%p)\n", hProv, dwLen, pbBuffer); - + if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) { /* MSDN: hProv not containing valid context handle */ @@ -3709,10 +3702,10 @@ BOOL WINAPI RSAENH_CPGetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwPa DWORD *pdwDataLen, DWORD dwFlags) { CRYPTHASH *pCryptHash; - + TRACE("(hProv=%08Ix, hHash=%08Ix, dwParam=%08lx, pbData=%p, pdwDataLen=%p, dwFlags=%08lx)\n", hProv, hHash, dwParam, pbData, pdwDataLen, dwFlags); - + if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) { SetLastError(NTE_BAD_UID); @@ -3724,7 +3717,7 @@ BOOL WINAPI RSAENH_CPGetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwPa SetLastError(NTE_BAD_FLAGS); return FALSE; } - + if (!lookup_handle(&handle_table, hHash, RSAENH_MAGIC_HASH, (OBJECTHDR**)&pCryptHash)) { @@ -3737,7 +3730,7 @@ BOOL WINAPI RSAENH_CPGetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwPa SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - + switch (dwParam) { case HP_ALGID: @@ -3983,7 +3976,7 @@ BOOL WINAPI RSAENH_CPSetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam case KP_CLIENT_RANDOM: return copy_data_blob(&pCryptKey->siSChannelInfo.blobClientRandom, (PCRYPT_DATA_BLOB)pbData); - + case KP_SERVER_RANDOM: return copy_data_blob(&pCryptKey->siSChannelInfo.blobServerRandom, (PCRYPT_DATA_BLOB)pbData); @@ -4027,7 +4020,7 @@ BOOL WINAPI RSAENH_CPGetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam { CRYPTKEY *pCryptKey; DWORD dwValue; - + TRACE("(hProv=%08Ix, hKey=%08Ix, dwParam=%08lx, pbData=%p, pdwDataLen=%p dwFlags=%08lx)\n", hProv, hKey, dwParam, pbData, pdwDataLen, dwFlags); @@ -4053,7 +4046,7 @@ BOOL WINAPI RSAENH_CPGetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam case KP_IV: return copy_param(pbData, pdwDataLen, pCryptKey->abInitVector, pCryptKey->dwBlockLen); - + case KP_SALT: switch (pCryptKey->aiAlgid) { case CALG_RC2: @@ -4104,7 +4097,7 @@ BOOL WINAPI RSAENH_CPGetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam return FALSE; } } - + /****************************************************************************** * CPGetProvParam (RSAENH.@) * @@ -4136,7 +4129,7 @@ BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, PROV_ENUMALGS provEnumalgs; DWORD dwTemp; HKEY hKey; - + /* This is for dwParam PP_CRYPT_COUNT_KEY_USE. * IE6 SP1 asks for it in the 'About' dialog. * Returning this BLOB seems to satisfy IE. The marked 0x00 seem @@ -4164,7 +4157,7 @@ BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - + if (!(pKeyContainer = get_key_container(hProv))) { /* MSDN: hProv not containing valid context handle */ @@ -4218,7 +4211,7 @@ BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, *pdwDataLen = (DWORD)MAX_PATH + 1; return TRUE; } - + if (!open_container_key("", dwFlags, KEY_READ, &hKey)) { SetLastError(ERROR_NO_MORE_ITEMS); @@ -4231,7 +4224,7 @@ BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, { case ERROR_MORE_DATA: *pdwDataLen = (DWORD)MAX_PATH + 1; - + case ERROR_SUCCESS: pKeyContainer->dwEnumContainersCtr++; RegCloseKey(hKey); @@ -4243,7 +4236,7 @@ BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, RegCloseKey(hKey); return FALSE; } - + case PP_ENUMALGS: case PP_ENUMALGS_EX: if (((pKeyContainer->dwEnumAlgsCtr >= RSAENH_MAX_ENUMALGS-1) || @@ -4259,7 +4252,7 @@ BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, if (pbData && (*pdwDataLen >= sizeof(PROV_ENUMALGS))) pKeyContainer->dwEnumAlgsCtr = ((dwFlags & CRYPT_FIRST) == CRYPT_FIRST) ? 0 : pKeyContainer->dwEnumAlgsCtr+1; - + provEnumalgs.aiAlgid = aProvEnumAlgsEx [pKeyContainer->dwPersonality][pKeyContainer->dwEnumAlgsCtr].aiAlgid; provEnumalgs.dwBitLen = aProvEnumAlgsEx @@ -4350,10 +4343,10 @@ BOOL WINAPI RSAENH_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseD CRYPTHASH *pCryptHash; BYTE abHashValue[RSAENH_MAX_HASH_SIZE*2]; DWORD dwLen; - + TRACE("(hProv=%08Ix, Algid=%d, hBaseData=%08Ix, dwFlags=%08lx phKey=%p)\n", hProv, Algid, hBaseData, dwFlags, phKey); - + if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) { SetLastError(NTE_BAD_UID); @@ -4415,12 +4408,12 @@ BOOL WINAPI RSAENH_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseD DWORD i; memcpy(old_hashval, pCryptHash->abHashValue, RSAENH_MAX_HASH_SIZE); - + for (i=0; i<RSAENH_HMAC_DEF_PAD_LEN; i++) { pad1[i] = RSAENH_HMAC_DEF_IPAD_CHAR ^ (i<dwLen ? abHashValue[i] : 0); pad2[i] = RSAENH_HMAC_DEF_OPAD_CHAR ^ (i<dwLen ? abHashValue[i] : 0); } - + init_hash(pCryptHash); update_hash(pCryptHash, pad1, RSAENH_HMAC_DEF_PAD_LEN); finalize_hash(pCryptHash); @@ -4443,7 +4436,7 @@ BOOL WINAPI RSAENH_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseD { copy_len += pCryptKey->dwSaltLen; } - + memcpy(pCryptKey->abKeyValue, abHashValue, RSAENH_MIN(copy_len, sizeof(pCryptKey->abKeyValue))); break; @@ -4455,7 +4448,7 @@ BOOL WINAPI RSAENH_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseD SetLastError(NTE_FAIL); /* FIXME error code */ return FALSE; } - + switch (Algid) { /* See RFC 2246, chapter 6.3 Key calculation */ @@ -4483,7 +4476,7 @@ BOOL WINAPI RSAENH_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseD ((dwFlags & CRYPT_SERVER) ? pCryptKey->dwBlockLen : 0)), pCryptKey->dwBlockLen); break; - + case CALG_SCHANNEL_MAC_KEY: *phKey = new_key(hProv, Algid, MAKELONG(LOWORD(dwFlags),pMasterKey->siSChannelInfo.saMACAlg.cBits), @@ -4494,7 +4487,7 @@ BOOL WINAPI RSAENH_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseD pMasterKey->siSChannelInfo.saMACAlg.cBits / 8 : 0), pMasterKey->siSChannelInfo.saMACAlg.cBits / 8); break; - + default: SetLastError(NTE_BAD_ALGID); return FALSE; @@ -4532,7 +4525,7 @@ BOOL WINAPI RSAENH_CPGetUserKey(HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *ph KEYCONTAINER *pKeyContainer; TRACE("(hProv=%08Ix, dwKeySpec=%08lx, phUserKey=%p)\n", hProv, dwKeySpec, phUserKey); - + if (!(pKeyContainer = get_key_container(hProv))) { /* MSDN: hProv not containing valid context handle */ @@ -4589,7 +4582,7 @@ BOOL WINAPI RSAENH_CPHashData(HCRYPTPROV hProv, HCRYPTHASH hHash, const BYTE *pb DWORD dwDataLen, DWORD dwFlags) { CRYPTHASH *pCryptHash; - + TRACE("(hProv=%08Ix, hHash=%08Ix, pbData=%p, dwDataLen=%ld, dwFlags=%08lx)\n", hProv, hHash, pbData, dwDataLen, dwFlags); @@ -4611,7 +4604,7 @@ BOOL WINAPI RSAENH_CPHashData(HCRYPTPROV hProv, HCRYPTHASH hHash, const BYTE *pb SetLastError(NTE_BAD_ALGID); return FALSE; } - + if (pCryptHash->dwState != RSAENH_HASHSTATE_HASHING) { SetLastError(NTE_BAD_HASH_STATE); @@ -4698,7 +4691,7 @@ BOOL WINAPI RSAENH_CPReleaseContext(HCRYPTPROV hProv, DWORD dwFlags) SetLastError(NTE_BAD_FLAGS); return FALSE; } - + return TRUE; } @@ -4743,14 +4736,14 @@ BOOL WINAPI RSAENH_CPSetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwPa SetLastError(NTE_BAD_FLAGS); return FALSE; } - + if (!lookup_handle(&handle_table, hHash, RSAENH_MAGIC_HASH, (OBJECTHDR**)&pCryptHash)) { SetLastError(NTE_BAD_HASH); return FALSE; } - + switch (dwParam) { case HP_HMAC_INFO: free_hmac_info(pCryptHash->pHMACInfo); @@ -4792,7 +4785,7 @@ BOOL WINAPI RSAENH_CPSetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwPa for (i=0; i<RSAENH_MIN(pCryptKey->dwKeyLen,pCryptHash->pHMACInfo->cbOuterString); i++) { pCryptHash->pHMACInfo->pbOuterString[i] ^= pCryptKey->abKeyValue[i]; } - + init_hash(pCryptHash); return TRUE; @@ -4800,13 +4793,13 @@ BOOL WINAPI RSAENH_CPSetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwPa memcpy(pCryptHash->abHashValue, pbData, pCryptHash->dwHashSize); pCryptHash->dwState = RSAENH_HASHSTATE_FINISHED; return TRUE; - + case HP_TLS1PRF_SEED: return copy_data_blob(&pCryptHash->tpPRFParams.blobSeed, (PCRYPT_DATA_BLOB)pbData); case HP_TLS1PRF_LABEL: return copy_data_blob(&pCryptHash->tpPRFParams.blobLabel, (PCRYPT_DATA_BLOB)pbData); - + default: SetLastError(NTE_BAD_TYPE); return FALSE; @@ -4904,9 +4897,9 @@ BOOL WINAPI RSAENH_CPSignHash(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwKeySpe SetLastError(NTE_BAD_FLAGS); return FALSE; } - + if (!RSAENH_CPGetUserKey(hProv, dwKeySpec, &hCryptKey)) return FALSE; - + if (!lookup_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey)) { @@ -4934,19 +4927,18 @@ BOOL WINAPI RSAENH_CPSignHash(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwKeySpe goto out; } } - + dwHashLen = sizeof(DWORD); if (!RSAENH_CPGetHashParam(hProv, hHash, HP_ALGID, (BYTE*)&aiAlgid, &dwHashLen, 0)) goto out; - + dwHashLen = RSAENH_MAX_HASH_SIZE; if (!RSAENH_CPGetHashParam(hProv, hHash, HP_HASHVAL, abHashValue, &dwHashLen, 0)) goto out; - if (!build_hash_signature(pbSignature, *pdwSigLen, aiAlgid, abHashValue, dwHashLen, dwFlags)) { goto out; } - ret = encrypt_block_impl(pCryptKey->aiAlgid, PK_PRIVATE, &pCryptKey->context, pbSignature, pbSignature); + ret = sign_hash_impl(&pCryptKey->context, pbSignature, pbSignature); out: RSAENH_CPDestroyKey(hProv, hCryptKey); return ret; @@ -4971,8 +4963,7 @@ out: * Failure: FALSE (GetLastError() == NTE_BAD_SIGNATURE, if signature is invalid) */ BOOL WINAPI RSAENH_CPVerifySignature(HCRYPTPROV hProv, HCRYPTHASH hHash, const BYTE *pbSignature, - DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, - DWORD dwFlags) + DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags) { BYTE *pbConstructed = NULL, *pbDecrypted = NULL; CRYPTKEY *pCryptKey; @@ -4984,18 +4975,18 @@ BOOL WINAPI RSAENH_CPVerifySignature(HCRYPTPROV hProv, HCRYPTHASH hHash, const B TRACE("(hProv=%08Ix, hHash=%08Ix, pbSignature=%p, dwSigLen=%ld, hPubKey=%08Ix, sDescription=%s, " "dwFlags=%08lx)\n", hProv, hHash, pbSignature, dwSigLen, hPubKey, debugstr_w(sDescription), dwFlags); - + if (dwFlags & ~(CRYPT_NOHASHOID|CRYPT_X931_FORMAT)) { SetLastError(NTE_BAD_FLAGS); return FALSE; } - + if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) { SetLastError(NTE_BAD_UID); return FALSE; } - + if (!lookup_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey)) { @@ -5025,10 +5016,10 @@ BOOL WINAPI RSAENH_CPVerifySignature(HCRYPTPROV hProv, HCRYPTHASH hHash, const B return FALSE; } } - + dwHashLen = sizeof(DWORD); if (!RSAENH_CPGetHashParam(hProv, hHash, HP_ALGID, (BYTE*)&aiAlgid, &dwHashLen, 0)) return FALSE; - + dwHashLen = RSAENH_MAX_HASH_SIZE; if (!RSAENH_CPGetHashParam(hProv, hHash, HP_HASHVAL, abHashValue, &dwHashLen, 0)) return FALSE; @@ -5044,10 +5035,7 @@ BOOL WINAPI RSAENH_CPVerifySignature(HCRYPTPROV hProv, HCRYPTHASH hHash, const B goto cleanup; } - if (!decrypt_block_impl(pCryptKey->aiAlgid, PK_PUBLIC, &pCryptKey->context, pbSignature, pbDecrypted)) - { - goto cleanup; - } + if (!verify_signature_impl(&pCryptKey->context, pbSignature, pbDecrypted)) goto cleanup; if (build_hash_signature(pbConstructed, dwSigLen, aiAlgid, abHashValue, dwHashLen, dwFlags) && !memcmp(pbDecrypted, pbConstructed, dwSigLen)) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11053