comctl32: Introduce _PSP structure to store HPROPSHEETPAGE data.
[wine.git] / dlls / rsaenh / implglue.c
blobb4fe985af9b6a7bb331be946e5ddef8c0f188d83
1 /*
2 * dlls/rsaenh/implglue.c
3 * Glueing the RSAENH specific code to the crypto library
5 * Copyright (c) 2004, 2005 Michael Jung
6 * Copyright (c) 2007 Vijay Kiran Kamuju
8 * based on code by Mike McCormack and David Hammerton
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.
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.
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
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wincrypt.h"
32 #include "implglue.h"
34 /* Function prototype copied from dlls/advapi32/crypt.c */
35 BOOL WINAPI SystemFunction036(PVOID pbBuffer, ULONG dwLen);
37 BOOL init_hash_impl(ALG_ID aiAlgid, BCRYPT_HASH_HANDLE *hash_handle)
39 switch (aiAlgid)
41 case CALG_MD2:
42 return !BCryptCreateHash(BCRYPT_MD2_ALG_HANDLE, hash_handle, NULL, 0, NULL, 0, 0);
44 case CALG_MD4:
45 return !BCryptCreateHash(BCRYPT_MD4_ALG_HANDLE, hash_handle, NULL, 0, NULL, 0, 0);
47 case CALG_MD5:
48 return !BCryptCreateHash(BCRYPT_MD5_ALG_HANDLE, hash_handle, NULL, 0, NULL, 0, 0);
50 case CALG_SHA:
51 return !BCryptCreateHash(BCRYPT_SHA1_ALG_HANDLE, hash_handle, NULL, 0, NULL, 0, 0);
53 case CALG_SHA_256:
54 return !BCryptCreateHash(BCRYPT_SHA256_ALG_HANDLE, hash_handle, NULL, 0, NULL, 0, 0);
56 case CALG_SHA_384:
57 return !BCryptCreateHash(BCRYPT_SHA384_ALG_HANDLE, hash_handle, NULL, 0, NULL, 0, 0);
59 case CALG_SHA_512:
60 return !BCryptCreateHash(BCRYPT_SHA512_ALG_HANDLE, hash_handle, NULL, 0, NULL, 0, 0);
62 default:
63 return TRUE;
67 BOOL update_hash_impl(BCRYPT_HASH_HANDLE hash_handle, const BYTE *pbData, DWORD dwDataLen)
69 BCryptHashData(hash_handle, (UCHAR*)pbData, dwDataLen, 0);
70 return TRUE;
73 BOOL finalize_hash_impl(BCRYPT_HASH_HANDLE hash_handle, BYTE *pbHashValue)
75 BCryptFinishHash(hash_handle, pbHashValue, RSAENH_MAX_HASH_SIZE, 0);
76 BCryptDestroyHash(hash_handle);
77 return TRUE;
80 BOOL duplicate_hash_impl(BCRYPT_HASH_HANDLE src_hash_handle, BCRYPT_HASH_HANDLE *dest_hash_handle)
82 return !BCryptDuplicateHash(src_hash_handle, dest_hash_handle, NULL, 0, 0);
85 BOOL new_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen)
87 switch (aiAlgid)
89 case CALG_RSA_KEYX:
90 case CALG_RSA_SIGN:
91 if (rsa_make_key((int)dwKeyLen, 65537, &pKeyContext->rsa) != CRYPT_OK) {
92 SetLastError(NTE_FAIL);
93 return FALSE;
95 return TRUE;
98 return TRUE;
101 BOOL free_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext)
103 switch (aiAlgid)
105 case CALG_RSA_KEYX:
106 case CALG_RSA_SIGN:
107 rsa_free(&pKeyContext->rsa);
110 return TRUE;
113 BOOL setup_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
114 DWORD dwEffectiveKeyLen, DWORD dwSaltLen, BYTE *abKeyValue)
116 switch (aiAlgid)
118 case CALG_RC4:
119 rc4_start(&pKeyContext->rc4);
120 rc4_add_entropy(abKeyValue, dwKeyLen + dwSaltLen, &pKeyContext->rc4);
121 rc4_ready(&pKeyContext->rc4);
122 break;
124 case CALG_RC2:
125 rc2_setup(abKeyValue, dwKeyLen + dwSaltLen, dwEffectiveKeyLen ?
126 dwEffectiveKeyLen : dwKeyLen << 3, 0, &pKeyContext->rc2);
127 break;
129 case CALG_3DES:
130 des3_setup(abKeyValue, 24, 0, &pKeyContext->des3);
131 break;
133 case CALG_3DES_112:
134 memcpy(abKeyValue+16, abKeyValue, 8);
135 des3_setup(abKeyValue, 24, 0, &pKeyContext->des3);
136 break;
138 case CALG_DES:
139 des_setup(abKeyValue, 8, 0, &pKeyContext->des);
140 break;
142 case CALG_AES:
143 case CALG_AES_128:
144 aes_setup(abKeyValue, 16, 0, &pKeyContext->aes);
145 break;
147 case CALG_AES_192:
148 aes_setup(abKeyValue, 24, 0, &pKeyContext->aes);
149 break;
151 case CALG_AES_256:
152 aes_setup(abKeyValue, 32, 0, &pKeyContext->aes);
153 break;
156 return TRUE;
159 BOOL duplicate_key_impl(ALG_ID aiAlgid, const KEY_CONTEXT *pSrcKeyContext,
160 KEY_CONTEXT *pDestKeyContext)
162 switch (aiAlgid)
164 case CALG_RC4:
165 case CALG_RC2:
166 case CALG_3DES:
167 case CALG_3DES_112:
168 case CALG_DES:
169 case CALG_AES:
170 case CALG_AES_128:
171 case CALG_AES_192:
172 case CALG_AES_256:
173 *pDestKeyContext = *pSrcKeyContext;
174 break;
175 case CALG_RSA_KEYX:
176 case CALG_RSA_SIGN:
177 pDestKeyContext->rsa.type = pSrcKeyContext->rsa.type;
178 mp_init_copy(&pDestKeyContext->rsa.e, &pSrcKeyContext->rsa.e);
179 mp_init_copy(&pDestKeyContext->rsa.d, &pSrcKeyContext->rsa.d);
180 mp_init_copy(&pDestKeyContext->rsa.N, &pSrcKeyContext->rsa.N);
181 mp_init_copy(&pDestKeyContext->rsa.p, &pSrcKeyContext->rsa.p);
182 mp_init_copy(&pDestKeyContext->rsa.q, &pSrcKeyContext->rsa.q);
183 mp_init_copy(&pDestKeyContext->rsa.qP, &pSrcKeyContext->rsa.qP);
184 mp_init_copy(&pDestKeyContext->rsa.dP, &pSrcKeyContext->rsa.dP);
185 mp_init_copy(&pDestKeyContext->rsa.dQ, &pSrcKeyContext->rsa.dQ);
186 break;
188 default:
189 SetLastError(NTE_BAD_ALGID);
190 return FALSE;
193 return TRUE;
196 static inline void reverse_bytes(BYTE *pbData, DWORD dwLen) {
197 BYTE swap;
198 DWORD i;
200 for (i=0; i<dwLen/2; i++) {
201 swap = pbData[i];
202 pbData[i] = pbData[dwLen-i-1];
203 pbData[dwLen-i-1] = swap;
207 BOOL encrypt_block_impl(ALG_ID aiAlgid, DWORD dwKeySpec, KEY_CONTEXT *pKeyContext, const BYTE *in,
208 BYTE *out, DWORD enc)
210 unsigned long inlen, outlen;
211 BYTE *in_reversed = NULL;
213 switch (aiAlgid) {
214 case CALG_RC2:
215 if (enc) {
216 rc2_ecb_encrypt(in, out, &pKeyContext->rc2);
217 } else {
218 rc2_ecb_decrypt(in, out, &pKeyContext->rc2);
220 break;
222 case CALG_3DES:
223 case CALG_3DES_112:
224 if (enc) {
225 des3_ecb_encrypt(in, out, &pKeyContext->des3);
226 } else {
227 des3_ecb_decrypt(in, out, &pKeyContext->des3);
229 break;
231 case CALG_DES:
232 if (enc) {
233 des_ecb_encrypt(in, out, &pKeyContext->des);
234 } else {
235 des_ecb_decrypt(in, out, &pKeyContext->des);
237 break;
239 case CALG_AES:
240 case CALG_AES_128:
241 case CALG_AES_192:
242 case CALG_AES_256:
243 if (enc) {
244 aes_ecb_encrypt(in, out, &pKeyContext->aes);
245 } else {
246 aes_ecb_decrypt(in, out, &pKeyContext->aes);
248 break;
250 case CALG_RSA_KEYX:
251 case CALG_RSA_SIGN:
252 case CALG_SSL3_SHAMD5:
253 outlen = inlen = (mp_count_bits(&pKeyContext->rsa.N)+7)/8;
254 if (enc) {
255 if (rsa_exptmod(in, inlen, out, &outlen, dwKeySpec, &pKeyContext->rsa) != CRYPT_OK) {
256 SetLastError(NTE_FAIL);
257 return FALSE;
259 reverse_bytes(out, outlen);
260 } else {
261 in_reversed = malloc(inlen);
262 if (!in_reversed) {
263 SetLastError(NTE_NO_MEMORY);
264 return FALSE;
266 memcpy(in_reversed, in, inlen);
267 reverse_bytes(in_reversed, inlen);
268 if (rsa_exptmod(in_reversed, inlen, out, &outlen, dwKeySpec, &pKeyContext->rsa) != CRYPT_OK) {
269 free(in_reversed);
270 SetLastError(NTE_FAIL);
271 return FALSE;
273 free(in_reversed);
275 break;
277 default:
278 SetLastError(NTE_BAD_ALGID);
279 return FALSE;
282 return TRUE;
285 BOOL encrypt_stream_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, BYTE *stream, DWORD dwLen)
287 switch (aiAlgid) {
288 case CALG_RC4:
289 rc4_read(stream, dwLen, &pKeyContext->rc4);
290 break;
292 default:
293 SetLastError(NTE_BAD_ALGID);
294 return FALSE;
297 return TRUE;
300 BOOL gen_rand_impl(BYTE *pbBuffer, DWORD dwLen)
302 return SystemFunction036(pbBuffer, dwLen);
305 BOOL export_public_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,DWORD *pdwPubExp)
307 mp_to_unsigned_bin(&pKeyContext->rsa.N, pbDest);
308 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.N));
309 if (mp_unsigned_bin_size(&pKeyContext->rsa.N) < dwKeyLen)
310 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.N), 0,
311 dwKeyLen - mp_unsigned_bin_size(&pKeyContext->rsa.N));
312 *pdwPubExp = (DWORD)mp_get_int(&pKeyContext->rsa.e);
313 return TRUE;
316 BOOL import_public_key_impl(const BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
317 DWORD dwPubExp)
319 BYTE *pbTemp;
321 if (mp_init_multi(&pKeyContext->rsa.e, &pKeyContext->rsa.d, &pKeyContext->rsa.N,
322 &pKeyContext->rsa.dQ,&pKeyContext->rsa.dP,&pKeyContext->rsa.qP,
323 &pKeyContext->rsa.p, &pKeyContext->rsa.q, NULL) != MP_OKAY)
325 SetLastError(NTE_FAIL);
326 return FALSE;
329 pbTemp = malloc(dwKeyLen);
330 if (!pbTemp) return FALSE;
331 memcpy(pbTemp, pbSrc, dwKeyLen);
333 pKeyContext->rsa.type = PK_PUBLIC;
334 reverse_bytes(pbTemp, dwKeyLen);
335 mp_read_unsigned_bin(&pKeyContext->rsa.N, pbTemp, dwKeyLen);
336 free(pbTemp);
337 mp_set_int(&pKeyContext->rsa.e, dwPubExp);
339 return TRUE;
342 BOOL export_private_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
343 DWORD *pdwPubExp)
345 mp_to_unsigned_bin(&pKeyContext->rsa.N, pbDest);
346 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.N));
347 if (mp_unsigned_bin_size(&pKeyContext->rsa.N) < dwKeyLen)
348 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.N), 0,
349 dwKeyLen - mp_unsigned_bin_size(&pKeyContext->rsa.N));
350 pbDest += dwKeyLen;
351 mp_to_unsigned_bin(&pKeyContext->rsa.p, pbDest);
352 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.p));
353 if (mp_unsigned_bin_size(&pKeyContext->rsa.p) < (dwKeyLen+1)>>1)
354 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.p), 0,
355 ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.p));
356 pbDest += (dwKeyLen+1)>>1;
357 mp_to_unsigned_bin(&pKeyContext->rsa.q, pbDest);
358 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.q));
359 if (mp_unsigned_bin_size(&pKeyContext->rsa.q) < (dwKeyLen+1)>>1)
360 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.q), 0,
361 ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.q));
362 pbDest += (dwKeyLen+1)>>1;
363 mp_to_unsigned_bin(&pKeyContext->rsa.dP, pbDest);
364 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.dP));
365 if (mp_unsigned_bin_size(&pKeyContext->rsa.dP) < (dwKeyLen+1)>>1)
366 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.dP), 0,
367 ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.dP));
368 pbDest += (dwKeyLen+1)>>1;
369 mp_to_unsigned_bin(&pKeyContext->rsa.dQ, pbDest);
370 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.dQ));
371 if (mp_unsigned_bin_size(&pKeyContext->rsa.dQ) < (dwKeyLen+1)>>1)
372 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.dQ), 0,
373 ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.dQ));
374 pbDest += (dwKeyLen+1)>>1;
375 mp_to_unsigned_bin(&pKeyContext->rsa.qP, pbDest);
376 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.qP));
377 if (mp_unsigned_bin_size(&pKeyContext->rsa.qP) < (dwKeyLen+1)>>1)
378 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.qP), 0,
379 ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.qP));
380 pbDest += (dwKeyLen+1)>>1;
381 mp_to_unsigned_bin(&pKeyContext->rsa.d, pbDest);
382 reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.d));
383 if (mp_unsigned_bin_size(&pKeyContext->rsa.d) < dwKeyLen)
384 memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.d), 0,
385 dwKeyLen - mp_unsigned_bin_size(&pKeyContext->rsa.d));
386 *pdwPubExp = (DWORD)mp_get_int(&pKeyContext->rsa.e);
388 return TRUE;
391 BOOL import_private_key_impl(const BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
392 DWORD dwDataLen, DWORD dwPubExp)
394 BYTE *pbTemp, *pbBigNum;
396 if (mp_init_multi(&pKeyContext->rsa.e, &pKeyContext->rsa.d, &pKeyContext->rsa.N,
397 &pKeyContext->rsa.dQ,&pKeyContext->rsa.dP,&pKeyContext->rsa.qP,
398 &pKeyContext->rsa.p, &pKeyContext->rsa.q, NULL) != MP_OKAY)
400 SetLastError(NTE_FAIL);
401 return FALSE;
404 pbTemp = malloc(2*dwKeyLen+5*((dwKeyLen+1)>>1));
405 if (!pbTemp) return FALSE;
406 memcpy(pbTemp, pbSrc, min(dwDataLen, 2*dwKeyLen+5*((dwKeyLen+1)>>1)));
407 pbBigNum = pbTemp;
409 pKeyContext->rsa.type = PK_PRIVATE;
410 reverse_bytes(pbBigNum, dwKeyLen);
411 mp_read_unsigned_bin(&pKeyContext->rsa.N, pbBigNum, dwKeyLen);
412 pbBigNum += dwKeyLen;
413 reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
414 mp_read_unsigned_bin(&pKeyContext->rsa.p, pbBigNum, (dwKeyLen+1)>>1);
415 pbBigNum += (dwKeyLen+1)>>1;
416 reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
417 mp_read_unsigned_bin(&pKeyContext->rsa.q, pbBigNum, (dwKeyLen+1)>>1);
418 pbBigNum += (dwKeyLen+1)>>1;
419 reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
420 mp_read_unsigned_bin(&pKeyContext->rsa.dP, pbBigNum, (dwKeyLen+1)>>1);
421 pbBigNum += (dwKeyLen+1)>>1;
422 reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
423 mp_read_unsigned_bin(&pKeyContext->rsa.dQ, pbBigNum, (dwKeyLen+1)>>1);
424 pbBigNum += (dwKeyLen+1)>>1;
425 reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
426 mp_read_unsigned_bin(&pKeyContext->rsa.qP, pbBigNum, (dwKeyLen+1)>>1);
427 pbBigNum += (dwKeyLen+1)>>1;
428 /* The size of the private exponent d is inferred from the remaining
429 * data length.
431 dwKeyLen = min(dwKeyLen, dwDataLen - (pbBigNum - pbTemp));
432 reverse_bytes(pbBigNum, dwKeyLen);
433 mp_read_unsigned_bin(&pKeyContext->rsa.d, pbBigNum, dwKeyLen);
434 mp_set_int(&pKeyContext->rsa.e, dwPubExp);
436 free(pbTemp);
437 return TRUE;