1 /* 2 * dlls/rsaenh/implglue.c 3 * Glueing the RSAENH specific code to the crypto library 4 * 5 * Copyright (c) 2004, 2005 Michael Jung 6 * Copyright (c) 2007 Vijay Kiran Kamuju 7 * 8 * based on code by Mike McCormack and David Hammerton 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 23 */ 24 #define WIN32_NO_STATUS 25 #define WIN32_LEAN_AND_MEAN 26 27 #include <config.h> 28 29 //#include "wine/port.h" 30 #include <wine/library.h> 31 32 //#include "windef.h" 33 #include <wincrypt.h> 34 35 #include "implglue.h" 36 37 //#include <stdio.h> 38 39 /* Function prototypes copied from dlls/advapi32/crypt_md4.c */ 40 VOID WINAPI MD4Init( MD4_CTX *ctx ); 41 VOID WINAPI MD4Update( MD4_CTX *ctx, const unsigned char *buf, unsigned int len ); 42 VOID WINAPI MD4Final( MD4_CTX *ctx ); 43 /* Function prototypes copied from dlls/advapi32/crypt_md5.c */ 44 VOID WINAPI MD5Init( MD5_CTX *ctx ); 45 VOID WINAPI MD5Update( MD5_CTX *ctx, const unsigned char *buf, unsigned int len ); 46 VOID WINAPI MD5Final( MD5_CTX *ctx ); 47 /* Function prototypes copied from dlls/advapi32/crypt_sha.c */ 48 VOID WINAPI A_SHAInit(PSHA_CTX Context); 49 VOID WINAPI A_SHAUpdate(PSHA_CTX Context, const unsigned char *Buffer, UINT BufferSize); 50 VOID WINAPI A_SHAFinal(PSHA_CTX Context, PULONG Result); 51 /* Function prototype copied from dlls/advapi32/crypt.c */ 52 BOOL WINAPI SystemFunction036(PVOID pbBuffer, ULONG dwLen); 53 54 BOOL init_hash_impl(ALG_ID aiAlgid, HASH_CONTEXT *pHashContext) 55 { 56 switch (aiAlgid) 57 { 58 case CALG_MD2: 59 md2_init(&pHashContext->md2); 60 break; 61 62 case CALG_MD4: 63 MD4Init(&pHashContext->md4); 64 break; 65 66 case CALG_MD5: 67 MD5Init(&pHashContext->md5); 68 break; 69 70 case CALG_SHA: 71 A_SHAInit(&pHashContext->sha); 72 break; 73 74 case CALG_SHA_256: 75 SHA256_Init(&pHashContext->sha256); 76 break; 77 78 case CALG_SHA_384: 79 SHA384_Init(&pHashContext->sha384); 80 break; 81 82 case CALG_SHA_512: 83 SHA512_Init(&pHashContext->sha512); 84 break; 85 } 86 87 return TRUE; 88 } 89 90 BOOL update_hash_impl(ALG_ID aiAlgid, HASH_CONTEXT *pHashContext, const BYTE *pbData, 91 DWORD dwDataLen) 92 { 93 switch (aiAlgid) 94 { 95 case CALG_MD2: 96 md2_process(&pHashContext->md2, pbData, dwDataLen); 97 break; 98 99 case CALG_MD4: 100 MD4Update(&pHashContext->md4, pbData, dwDataLen); 101 break; 102 103 case CALG_MD5: 104 MD5Update(&pHashContext->md5, pbData, dwDataLen); 105 break; 106 107 case CALG_SHA: 108 A_SHAUpdate(&pHashContext->sha, pbData, dwDataLen); 109 break; 110 111 case CALG_SHA_256: 112 SHA256_Update(&pHashContext->sha256, pbData, dwDataLen); 113 break; 114 115 case CALG_SHA_384: 116 SHA384_Update(&pHashContext->sha384, pbData, dwDataLen); 117 break; 118 119 case CALG_SHA_512: 120 SHA512_Update(&pHashContext->sha512, pbData, dwDataLen); 121 break; 122 123 default: 124 SetLastError(NTE_BAD_ALGID); 125 return FALSE; 126 } 127 128 return TRUE; 129 } 130 131 BOOL finalize_hash_impl(ALG_ID aiAlgid, HASH_CONTEXT *pHashContext, BYTE *pbHashValue) 132 { 133 switch (aiAlgid) 134 { 135 case CALG_MD2: 136 md2_done(&pHashContext->md2, pbHashValue); 137 break; 138 139 case CALG_MD4: 140 MD4Final(&pHashContext->md4); 141 memcpy(pbHashValue, pHashContext->md4.digest, 16); 142 break; 143 144 case CALG_MD5: 145 MD5Final(&pHashContext->md5); 146 memcpy(pbHashValue, pHashContext->md5.digest, 16); 147 break; 148 149 case CALG_SHA: 150 A_SHAFinal(&pHashContext->sha, (PULONG)pbHashValue); 151 break; 152 153 case CALG_SHA_256: 154 SHA256_Final(pbHashValue, &pHashContext->sha256); 155 break; 156 157 case CALG_SHA_384: 158 SHA384_Final(pbHashValue, &pHashContext->sha384); 159 break; 160 161 case CALG_SHA_512: 162 SHA512_Final(pbHashValue, &pHashContext->sha512); 163 break; 164 165 default: 166 SetLastError(NTE_BAD_ALGID); 167 return FALSE; 168 } 169 170 return TRUE; 171 } 172 173 BOOL duplicate_hash_impl(ALG_ID aiAlgid, const HASH_CONTEXT *pSrcHashContext, 174 HASH_CONTEXT *pDestHashContext) 175 { 176 *pDestHashContext = *pSrcHashContext; 177 178 return TRUE; 179 } 180 181 BOOL new_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen) 182 { 183 switch (aiAlgid) 184 { 185 case CALG_RSA_KEYX: 186 case CALG_RSA_SIGN: 187 if (rsa_make_key((int)dwKeyLen, 65537, &pKeyContext->rsa) != CRYPT_OK) { 188 SetLastError(NTE_FAIL); 189 return FALSE; 190 } 191 return TRUE; 192 } 193 194 return TRUE; 195 } 196 197 BOOL free_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext) 198 { 199 switch (aiAlgid) 200 { 201 case CALG_RSA_KEYX: 202 case CALG_RSA_SIGN: 203 rsa_free(&pKeyContext->rsa); 204 } 205 206 return TRUE; 207 } 208 209 BOOL setup_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, 210 DWORD dwEffectiveKeyLen, DWORD dwSaltLen, BYTE *abKeyValue) 211 { 212 switch (aiAlgid) 213 { 214 case CALG_RC4: 215 rc4_start(&pKeyContext->rc4); 216 rc4_add_entropy(abKeyValue, dwKeyLen + dwSaltLen, &pKeyContext->rc4); 217 rc4_ready(&pKeyContext->rc4); 218 break; 219 220 case CALG_RC2: 221 rc2_setup(abKeyValue, dwKeyLen + dwSaltLen, dwEffectiveKeyLen ? 222 dwEffectiveKeyLen : dwKeyLen << 3, 0, &pKeyContext->rc2); 223 break; 224 225 case CALG_3DES: 226 des3_setup(abKeyValue, 24, 0, &pKeyContext->des3); 227 break; 228 229 case CALG_3DES_112: 230 memcpy(abKeyValue+16, abKeyValue, 8); 231 des3_setup(abKeyValue, 24, 0, &pKeyContext->des3); 232 break; 233 234 case CALG_DES: 235 des_setup(abKeyValue, 8, 0, &pKeyContext->des); 236 break; 237 238 case CALG_AES: 239 case CALG_AES_128: 240 aes_setup(abKeyValue, 16, 0, &pKeyContext->aes); 241 break; 242 243 case CALG_AES_192: 244 aes_setup(abKeyValue, 24, 0, &pKeyContext->aes); 245 break; 246 247 case CALG_AES_256: 248 aes_setup(abKeyValue, 32, 0, &pKeyContext->aes); 249 break; 250 } 251 252 return TRUE; 253 } 254 255 BOOL duplicate_key_impl(ALG_ID aiAlgid, const KEY_CONTEXT *pSrcKeyContext, 256 KEY_CONTEXT *pDestKeyContext) 257 { 258 switch (aiAlgid) 259 { 260 case CALG_RC4: 261 case CALG_RC2: 262 case CALG_3DES: 263 case CALG_3DES_112: 264 case CALG_DES: 265 case CALG_AES: 266 case CALG_AES_128: 267 case CALG_AES_192: 268 case CALG_AES_256: 269 *pDestKeyContext = *pSrcKeyContext; 270 break; 271 case CALG_RSA_KEYX: 272 case CALG_RSA_SIGN: 273 pDestKeyContext->rsa.type = pSrcKeyContext->rsa.type; 274 mp_init_copy(&pDestKeyContext->rsa.e, &pSrcKeyContext->rsa.e); 275 mp_init_copy(&pDestKeyContext->rsa.d, &pSrcKeyContext->rsa.d); 276 mp_init_copy(&pDestKeyContext->rsa.N, &pSrcKeyContext->rsa.N); 277 mp_init_copy(&pDestKeyContext->rsa.p, &pSrcKeyContext->rsa.p); 278 mp_init_copy(&pDestKeyContext->rsa.q, &pSrcKeyContext->rsa.q); 279 mp_init_copy(&pDestKeyContext->rsa.qP, &pSrcKeyContext->rsa.qP); 280 mp_init_copy(&pDestKeyContext->rsa.dP, &pSrcKeyContext->rsa.dP); 281 mp_init_copy(&pDestKeyContext->rsa.dQ, &pSrcKeyContext->rsa.dQ); 282 break; 283 284 default: 285 SetLastError(NTE_BAD_ALGID); 286 return FALSE; 287 } 288 289 return TRUE; 290 } 291 292 static inline void reverse_bytes(BYTE *pbData, DWORD dwLen) { 293 BYTE swap; 294 DWORD i; 295 296 for (i=0; i<dwLen/2; i++) { 297 swap = pbData[i]; 298 pbData[i] = pbData[dwLen-i-1]; 299 pbData[dwLen-i-1] = swap; 300 } 301 } 302 303 BOOL encrypt_block_impl(ALG_ID aiAlgid, DWORD dwKeySpec, KEY_CONTEXT *pKeyContext, const BYTE *in, 304 BYTE *out, DWORD enc) 305 { 306 unsigned long inlen, outlen; 307 BYTE *in_reversed = NULL; 308 309 switch (aiAlgid) { 310 case CALG_RC2: 311 if (enc) { 312 rc2_ecb_encrypt(in, out, &pKeyContext->rc2); 313 } else { 314 rc2_ecb_decrypt(in, out, &pKeyContext->rc2); 315 } 316 break; 317 318 case CALG_3DES: 319 case CALG_3DES_112: 320 if (enc) { 321 des3_ecb_encrypt(in, out, &pKeyContext->des3); 322 } else { 323 des3_ecb_decrypt(in, out, &pKeyContext->des3); 324 } 325 break; 326 327 case CALG_DES: 328 if (enc) { 329 des_ecb_encrypt(in, out, &pKeyContext->des); 330 } else { 331 des_ecb_decrypt(in, out, &pKeyContext->des); 332 } 333 break; 334 335 case CALG_AES: 336 case CALG_AES_128: 337 case CALG_AES_192: 338 case CALG_AES_256: 339 if (enc) { 340 aes_ecb_encrypt(in, out, &pKeyContext->aes); 341 } else { 342 aes_ecb_decrypt(in, out, &pKeyContext->aes); 343 } 344 break; 345 346 case CALG_RSA_KEYX: 347 case CALG_RSA_SIGN: 348 case CALG_SSL3_SHAMD5: 349 outlen = inlen = (mp_count_bits(&pKeyContext->rsa.N)+7)/8; 350 if (enc) { 351 if (rsa_exptmod(in, inlen, out, &outlen, dwKeySpec, &pKeyContext->rsa) != CRYPT_OK) { 352 SetLastError(NTE_FAIL); 353 return FALSE; 354 } 355 reverse_bytes(out, outlen); 356 } else { 357 in_reversed = HeapAlloc(GetProcessHeap(), 0, inlen); 358 if (!in_reversed) { 359 SetLastError(NTE_NO_MEMORY); 360 return FALSE; 361 } 362 memcpy(in_reversed, in, inlen); 363 reverse_bytes(in_reversed, inlen); 364 if (rsa_exptmod(in_reversed, inlen, out, &outlen, dwKeySpec, &pKeyContext->rsa) != CRYPT_OK) { 365 HeapFree(GetProcessHeap(), 0, in_reversed); 366 SetLastError(NTE_FAIL); 367 return FALSE; 368 } 369 HeapFree(GetProcessHeap(), 0, in_reversed); 370 } 371 break; 372 373 default: 374 SetLastError(NTE_BAD_ALGID); 375 return FALSE; 376 } 377 378 return TRUE; 379 } 380 381 BOOL encrypt_stream_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, BYTE *stream, DWORD dwLen) 382 { 383 switch (aiAlgid) { 384 case CALG_RC4: 385 rc4_read(stream, dwLen, &pKeyContext->rc4); 386 break; 387 388 default: 389 SetLastError(NTE_BAD_ALGID); 390 return FALSE; 391 } 392 393 return TRUE; 394 } 395 396 BOOL gen_rand_impl(BYTE *pbBuffer, DWORD dwLen) 397 { 398 return SystemFunction036(pbBuffer, dwLen); 399 } 400 401 BOOL export_public_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,DWORD *pdwPubExp) 402 { 403 mp_to_unsigned_bin(&pKeyContext->rsa.N, pbDest); 404 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.N)); 405 if (mp_unsigned_bin_size(&pKeyContext->rsa.N) < dwKeyLen) 406 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.N), 0, 407 dwKeyLen - mp_unsigned_bin_size(&pKeyContext->rsa.N)); 408 *pdwPubExp = (DWORD)mp_get_int(&pKeyContext->rsa.e); 409 return TRUE; 410 } 411 412 BOOL import_public_key_impl(const BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, 413 DWORD dwPubExp) 414 { 415 BYTE *pbTemp; 416 417 if (mp_init_multi(&pKeyContext->rsa.e, &pKeyContext->rsa.d, &pKeyContext->rsa.N, 418 &pKeyContext->rsa.dQ,&pKeyContext->rsa.dP,&pKeyContext->rsa.qP, 419 &pKeyContext->rsa.p, &pKeyContext->rsa.q, NULL) != MP_OKAY) 420 { 421 SetLastError(NTE_FAIL); 422 return FALSE; 423 } 424 425 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwKeyLen); 426 if (!pbTemp) return FALSE; 427 memcpy(pbTemp, pbSrc, dwKeyLen); 428 429 pKeyContext->rsa.type = PK_PUBLIC; 430 reverse_bytes(pbTemp, dwKeyLen); 431 mp_read_unsigned_bin(&pKeyContext->rsa.N, pbTemp, dwKeyLen); 432 HeapFree(GetProcessHeap(), 0, pbTemp); 433 mp_set_int(&pKeyContext->rsa.e, dwPubExp); 434 435 return TRUE; 436 } 437 438 BOOL export_private_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, 439 DWORD *pdwPubExp) 440 { 441 mp_to_unsigned_bin(&pKeyContext->rsa.N, pbDest); 442 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.N)); 443 if (mp_unsigned_bin_size(&pKeyContext->rsa.N) < dwKeyLen) 444 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.N), 0, 445 dwKeyLen - mp_unsigned_bin_size(&pKeyContext->rsa.N)); 446 pbDest += dwKeyLen; 447 mp_to_unsigned_bin(&pKeyContext->rsa.p, pbDest); 448 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.p)); 449 if (mp_unsigned_bin_size(&pKeyContext->rsa.p) < (dwKeyLen+1)>>1) 450 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.p), 0, 451 ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.p)); 452 pbDest += (dwKeyLen+1)>>1; 453 mp_to_unsigned_bin(&pKeyContext->rsa.q, pbDest); 454 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.q)); 455 if (mp_unsigned_bin_size(&pKeyContext->rsa.q) < (dwKeyLen+1)>>1) 456 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.q), 0, 457 ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.q)); 458 pbDest += (dwKeyLen+1)>>1; 459 mp_to_unsigned_bin(&pKeyContext->rsa.dP, pbDest); 460 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.dP)); 461 if (mp_unsigned_bin_size(&pKeyContext->rsa.dP) < (dwKeyLen+1)>>1) 462 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.dP), 0, 463 ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.dP)); 464 pbDest += (dwKeyLen+1)>>1; 465 mp_to_unsigned_bin(&pKeyContext->rsa.dQ, pbDest); 466 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.dQ)); 467 if (mp_unsigned_bin_size(&pKeyContext->rsa.dQ) < (dwKeyLen+1)>>1) 468 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.dQ), 0, 469 ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.dQ)); 470 pbDest += (dwKeyLen+1)>>1; 471 mp_to_unsigned_bin(&pKeyContext->rsa.qP, pbDest); 472 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.qP)); 473 if (mp_unsigned_bin_size(&pKeyContext->rsa.qP) < (dwKeyLen+1)>>1) 474 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.qP), 0, 475 ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.qP)); 476 pbDest += (dwKeyLen+1)>>1; 477 mp_to_unsigned_bin(&pKeyContext->rsa.d, pbDest); 478 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.d)); 479 if (mp_unsigned_bin_size(&pKeyContext->rsa.d) < dwKeyLen) 480 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.d), 0, 481 dwKeyLen - mp_unsigned_bin_size(&pKeyContext->rsa.d)); 482 *pdwPubExp = (DWORD)mp_get_int(&pKeyContext->rsa.e); 483 484 return TRUE; 485 } 486 487 BOOL import_private_key_impl(const BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, 488 DWORD dwDataLen, DWORD dwPubExp) 489 { 490 BYTE *pbTemp, *pbBigNum; 491 492 if (mp_init_multi(&pKeyContext->rsa.e, &pKeyContext->rsa.d, &pKeyContext->rsa.N, 493 &pKeyContext->rsa.dQ,&pKeyContext->rsa.dP,&pKeyContext->rsa.qP, 494 &pKeyContext->rsa.p, &pKeyContext->rsa.q, NULL) != MP_OKAY) 495 { 496 SetLastError(NTE_FAIL); 497 return FALSE; 498 } 499 500 pbTemp = HeapAlloc(GetProcessHeap(), 0, 2*dwKeyLen+5*((dwKeyLen+1)>>1)); 501 if (!pbTemp) return FALSE; 502 memcpy(pbTemp, pbSrc, min(dwDataLen, 2*dwKeyLen+5*((dwKeyLen+1)>>1))); 503 pbBigNum = pbTemp; 504 505 pKeyContext->rsa.type = PK_PRIVATE; 506 reverse_bytes(pbBigNum, dwKeyLen); 507 mp_read_unsigned_bin(&pKeyContext->rsa.N, pbBigNum, dwKeyLen); 508 pbBigNum += dwKeyLen; 509 reverse_bytes(pbBigNum, (dwKeyLen+1)>>1); 510 mp_read_unsigned_bin(&pKeyContext->rsa.p, pbBigNum, (dwKeyLen+1)>>1); 511 pbBigNum += (dwKeyLen+1)>>1; 512 reverse_bytes(pbBigNum, (dwKeyLen+1)>>1); 513 mp_read_unsigned_bin(&pKeyContext->rsa.q, pbBigNum, (dwKeyLen+1)>>1); 514 pbBigNum += (dwKeyLen+1)>>1; 515 reverse_bytes(pbBigNum, (dwKeyLen+1)>>1); 516 mp_read_unsigned_bin(&pKeyContext->rsa.dP, pbBigNum, (dwKeyLen+1)>>1); 517 pbBigNum += (dwKeyLen+1)>>1; 518 reverse_bytes(pbBigNum, (dwKeyLen+1)>>1); 519 mp_read_unsigned_bin(&pKeyContext->rsa.dQ, pbBigNum, (dwKeyLen+1)>>1); 520 pbBigNum += (dwKeyLen+1)>>1; 521 reverse_bytes(pbBigNum, (dwKeyLen+1)>>1); 522 mp_read_unsigned_bin(&pKeyContext->rsa.qP, pbBigNum, (dwKeyLen+1)>>1); 523 pbBigNum += (dwKeyLen+1)>>1; 524 /* The size of the private exponent d is inferred from the remaining 525 * data length. 526 */ 527 dwKeyLen = min(dwKeyLen, dwDataLen - (pbBigNum - pbTemp)); 528 reverse_bytes(pbBigNum, dwKeyLen); 529 mp_read_unsigned_bin(&pKeyContext->rsa.d, pbBigNum, dwKeyLen); 530 mp_set_int(&pKeyContext->rsa.e, dwPubExp); 531 532 HeapFree(GetProcessHeap(), 0, pbTemp); 533 return TRUE; 534 } 535