samlib: Add stubbed samlib.dll.
[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             outlen = inlen = (mp_count_bits(&pKeyContext->rsa.N)+7)/8;
346             if (enc) {
347                 if (rsa_exptmod(in, inlen, out, &outlen, dwKeySpec, &pKeyContext->rsa) != CRYPT_OK) {
348                     SetLastError(NTE_FAIL);
349                     return FALSE;
350                 }
351                 reverse_bytes(out, outlen);
352             } else {
353                 in_reversed = HeapAlloc(GetProcessHeap(), 0, inlen);
354                 if (!in_reversed) {
355                     SetLastError(NTE_NO_MEMORY);
356                     return FALSE;
357                 }
358                 memcpy(in_reversed, in, inlen);
359                 reverse_bytes(in_reversed, inlen);
360                 if (rsa_exptmod(in_reversed, inlen, out, &outlen, dwKeySpec, &pKeyContext->rsa) != CRYPT_OK) {
361                     HeapFree(GetProcessHeap(), 0, in_reversed);
362                     SetLastError(NTE_FAIL);
363                     return FALSE;
364                 }
365                 HeapFree(GetProcessHeap(), 0, in_reversed);
366             }
367             break;
368
369         default:
370             SetLastError(NTE_BAD_ALGID);
371             return FALSE;
372     }
373
374     return TRUE;
375 }
376
377 BOOL encrypt_stream_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, BYTE *stream, DWORD dwLen)
378 {
379     switch (aiAlgid) {
380         case CALG_RC4:
381             rc4_read(stream, dwLen, &pKeyContext->rc4);
382             break;
383
384         default:
385             SetLastError(NTE_BAD_ALGID);
386             return FALSE;
387     }
388
389     return TRUE;
390 }
391
392 BOOL gen_rand_impl(BYTE *pbBuffer, DWORD dwLen)
393 {
394     return SystemFunction036(pbBuffer, dwLen);
395 }
396
397 BOOL export_public_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,DWORD *pdwPubExp)
398 {
399     mp_to_unsigned_bin(&pKeyContext->rsa.N, pbDest);
400     reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.N));
401     if (mp_unsigned_bin_size(&pKeyContext->rsa.N) < dwKeyLen)
402         memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.N), 0,
403                dwKeyLen - mp_unsigned_bin_size(&pKeyContext->rsa.N));
404     *pdwPubExp = (DWORD)mp_get_int(&pKeyContext->rsa.e);
405     return TRUE;
406 }
407
408 BOOL import_public_key_impl(CONST BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, 
409                             DWORD dwPubExp)
410 {
411     BYTE *pbTemp;
412
413     if (mp_init_multi(&pKeyContext->rsa.e, &pKeyContext->rsa.d, &pKeyContext->rsa.N, 
414                       &pKeyContext->rsa.dQ,&pKeyContext->rsa.dP,&pKeyContext->rsa.qP, 
415                       &pKeyContext->rsa.p, &pKeyContext->rsa.q, NULL) != MP_OKAY)
416     {
417         SetLastError(NTE_FAIL);
418         return FALSE;
419     }
420
421     pbTemp = HeapAlloc(GetProcessHeap(), 0, dwKeyLen);
422     if (!pbTemp) return FALSE;
423     memcpy(pbTemp, pbSrc, dwKeyLen);
424     
425     pKeyContext->rsa.type = PK_PUBLIC;
426     reverse_bytes(pbTemp, dwKeyLen);
427     mp_read_unsigned_bin(&pKeyContext->rsa.N, pbTemp, dwKeyLen);
428     HeapFree(GetProcessHeap(), 0, pbTemp);
429     mp_set_int(&pKeyContext->rsa.e, dwPubExp);
430
431     return TRUE;    
432 }
433
434 BOOL export_private_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
435                              DWORD *pdwPubExp)
436 {
437     mp_to_unsigned_bin(&pKeyContext->rsa.N, pbDest);
438     reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.N));
439     if (mp_unsigned_bin_size(&pKeyContext->rsa.N) < dwKeyLen)
440         memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.N), 0,
441                dwKeyLen - mp_unsigned_bin_size(&pKeyContext->rsa.N));
442     pbDest += dwKeyLen;
443     mp_to_unsigned_bin(&pKeyContext->rsa.p, pbDest);
444     reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.p));
445     if (mp_unsigned_bin_size(&pKeyContext->rsa.p) < (dwKeyLen+1)>>1)
446         memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.p), 0,
447                ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.p));
448     pbDest += (dwKeyLen+1)>>1;
449     mp_to_unsigned_bin(&pKeyContext->rsa.q, pbDest);
450     reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.q));
451     if (mp_unsigned_bin_size(&pKeyContext->rsa.q) < (dwKeyLen+1)>>1)
452         memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.q), 0,
453                ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.q));
454     pbDest += (dwKeyLen+1)>>1;
455     mp_to_unsigned_bin(&pKeyContext->rsa.dP, pbDest);
456     reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.dP));
457     if (mp_unsigned_bin_size(&pKeyContext->rsa.dP) < (dwKeyLen+1)>>1)
458         memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.dP), 0,
459                ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.dP));
460     pbDest += (dwKeyLen+1)>>1;
461     mp_to_unsigned_bin(&pKeyContext->rsa.dQ, pbDest);
462     reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.dQ));
463     if (mp_unsigned_bin_size(&pKeyContext->rsa.dQ) < (dwKeyLen+1)>>1)
464         memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.dQ), 0,
465                ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.dQ));
466     pbDest += (dwKeyLen+1)>>1;
467     mp_to_unsigned_bin(&pKeyContext->rsa.qP, pbDest);
468     reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.qP));
469     if (mp_unsigned_bin_size(&pKeyContext->rsa.qP) < (dwKeyLen+1)>>1)
470         memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.qP), 0,
471                ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.qP));
472     pbDest += (dwKeyLen+1)>>1;
473     mp_to_unsigned_bin(&pKeyContext->rsa.d, pbDest);
474     reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.d));
475     if (mp_unsigned_bin_size(&pKeyContext->rsa.d) < dwKeyLen)
476         memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.d), 0,
477                dwKeyLen - mp_unsigned_bin_size(&pKeyContext->rsa.d));
478     *pdwPubExp = (DWORD)mp_get_int(&pKeyContext->rsa.e);
479
480     return TRUE;
481 }
482
483 BOOL import_private_key_impl(CONST BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, 
484                              DWORD dwPubExp)
485 {
486     BYTE *pbTemp, *pbBigNum;
487
488     if (mp_init_multi(&pKeyContext->rsa.e, &pKeyContext->rsa.d, &pKeyContext->rsa.N, 
489                       &pKeyContext->rsa.dQ,&pKeyContext->rsa.dP,&pKeyContext->rsa.qP, 
490                       &pKeyContext->rsa.p, &pKeyContext->rsa.q, NULL) != MP_OKAY)
491     {
492         SetLastError(NTE_FAIL);
493         return FALSE;
494     }
495
496     pbTemp = HeapAlloc(GetProcessHeap(), 0, 2*dwKeyLen+5*((dwKeyLen+1)>>1));
497     if (!pbTemp) return FALSE;
498     memcpy(pbTemp, pbSrc, 2*dwKeyLen+5*((dwKeyLen+1)>>1));
499     pbBigNum = pbTemp;
500
501     pKeyContext->rsa.type = PK_PRIVATE;
502     reverse_bytes(pbBigNum, dwKeyLen);
503     mp_read_unsigned_bin(&pKeyContext->rsa.N, pbBigNum, dwKeyLen);
504     pbBigNum += dwKeyLen;
505     reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
506     mp_read_unsigned_bin(&pKeyContext->rsa.p, pbBigNum, (dwKeyLen+1)>>1);
507     pbBigNum += (dwKeyLen+1)>>1;
508     reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
509     mp_read_unsigned_bin(&pKeyContext->rsa.q, pbBigNum, (dwKeyLen+1)>>1);
510     pbBigNum += (dwKeyLen+1)>>1;
511     reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
512     mp_read_unsigned_bin(&pKeyContext->rsa.dP, pbBigNum, (dwKeyLen+1)>>1);
513     pbBigNum += (dwKeyLen+1)>>1;
514     reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
515     mp_read_unsigned_bin(&pKeyContext->rsa.dQ, pbBigNum, (dwKeyLen+1)>>1);
516     pbBigNum += (dwKeyLen+1)>>1;
517     reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
518     mp_read_unsigned_bin(&pKeyContext->rsa.qP, pbBigNum, (dwKeyLen+1)>>1);
519     pbBigNum += (dwKeyLen+1)>>1;
520     reverse_bytes(pbBigNum, dwKeyLen);
521     mp_read_unsigned_bin(&pKeyContext->rsa.d, pbBigNum, dwKeyLen);
522     mp_set_int(&pKeyContext->rsa.e, dwPubExp);
523     
524     HeapFree(GetProcessHeap(), 0, pbTemp);
525     return TRUE;
526 }