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