|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include "ckcapi.h" |
|
6 #include "secdert.h" |
|
7 |
|
8 #define SSL3_SHAMD5_HASH_SIZE 36 /* LEN_MD5 (16) + LEN_SHA1 (20) */ |
|
9 |
|
10 /* |
|
11 * ckcapi/crsa.c |
|
12 * |
|
13 * This file implements the NSSCKMDMechnaism and NSSCKMDCryptoOperation objects |
|
14 * for the RSA operation on the CAPI cryptoki module. |
|
15 */ |
|
16 |
|
17 /* |
|
18 * write a Decimal value to a string |
|
19 */ |
|
20 |
|
21 static char * |
|
22 putDecimalString(char *cstr, unsigned long value) |
|
23 { |
|
24 unsigned long tenpower; |
|
25 int first = 1; |
|
26 |
|
27 for (tenpower=10000000; tenpower; tenpower /= 10) { |
|
28 unsigned char digit = (unsigned char )(value/tenpower); |
|
29 value = value % tenpower; |
|
30 |
|
31 /* drop leading zeros */ |
|
32 if (first && (0 == digit)) { |
|
33 continue; |
|
34 } |
|
35 first = 0; |
|
36 *cstr++ = digit + '0'; |
|
37 } |
|
38 |
|
39 /* if value was zero, put one of them out */ |
|
40 if (first) { |
|
41 *cstr++ = '0'; |
|
42 } |
|
43 return cstr; |
|
44 } |
|
45 |
|
46 |
|
47 /* |
|
48 * Create a Capi OID string value from a DER OID |
|
49 */ |
|
50 static char * |
|
51 nss_ckcapi_GetOidString |
|
52 ( |
|
53 unsigned char *oidTag, |
|
54 unsigned int oidTagSize, |
|
55 CK_RV *pError |
|
56 ) |
|
57 { |
|
58 unsigned char *oid; |
|
59 char *oidStr; |
|
60 char *cstr; |
|
61 unsigned long value; |
|
62 unsigned int oidSize; |
|
63 |
|
64 if (DER_OBJECT_ID != *oidTag) { |
|
65 /* wasn't an oid */ |
|
66 *pError = CKR_DATA_INVALID; |
|
67 return NULL; |
|
68 } |
|
69 oid = nss_ckcapi_DERUnwrap(oidTag, oidTagSize, &oidSize, NULL); |
|
70 |
|
71 if (oidSize < 2) { |
|
72 *pError = CKR_DATA_INVALID; |
|
73 return NULL; |
|
74 } |
|
75 |
|
76 oidStr = nss_ZNEWARRAY( NULL, char, oidSize*4 ); |
|
77 if ((char *)NULL == oidStr) { |
|
78 *pError = CKR_HOST_MEMORY; |
|
79 return NULL; |
|
80 } |
|
81 cstr = oidStr; |
|
82 cstr = putDecimalString(cstr, (*oid) / 40); |
|
83 *cstr++ = '.'; |
|
84 cstr = putDecimalString(cstr, (*oid) % 40); |
|
85 oidSize--; |
|
86 |
|
87 value = 0; |
|
88 while (oidSize--) { |
|
89 oid++; |
|
90 value = (value << 7) + (*oid & 0x7f); |
|
91 if (0 == (*oid & 0x80)) { |
|
92 *cstr++ = '.'; |
|
93 cstr = putDecimalString(cstr, value); |
|
94 value = 0; |
|
95 } |
|
96 } |
|
97 |
|
98 *cstr = 0; /* NULL terminate */ |
|
99 |
|
100 if (value != 0) { |
|
101 nss_ZFreeIf(oidStr); |
|
102 *pError = CKR_DATA_INVALID; |
|
103 return NULL; |
|
104 } |
|
105 return oidStr; |
|
106 } |
|
107 |
|
108 |
|
109 /* |
|
110 * PKCS #11 sign for RSA expects to take a fully DER-encoded hash value, |
|
111 * which includes the hash OID. CAPI expects to take a Hash Context. While |
|
112 * CAPI does have the capability of setting a raw hash value, it does not |
|
113 * have the ability to sign an arbitrary value. This function tries to |
|
114 * reduce the passed in data into something that CAPI could actually sign. |
|
115 */ |
|
116 static CK_RV |
|
117 ckcapi_GetRawHash |
|
118 ( |
|
119 const NSSItem *input, |
|
120 NSSItem *hash, |
|
121 ALG_ID *hashAlg |
|
122 ) |
|
123 { |
|
124 unsigned char *current; |
|
125 unsigned char *algid; |
|
126 unsigned char *oid; |
|
127 unsigned char *hashData; |
|
128 char *oidStr; |
|
129 CK_RV error; |
|
130 unsigned int oidSize; |
|
131 unsigned int size; |
|
132 /* |
|
133 * there are 2 types of hashes NSS typically tries to sign, regular |
|
134 * RSA signature format (with encoded DER_OIDS), and SSL3 Signed hashes. |
|
135 * CAPI knows not to add any oids to SSL3_Signed hashes, so if we have any |
|
136 * random hash that is exactly the same size as an SSL3 hash, then we can |
|
137 * just pass the data through. CAPI has know way of knowing if the value |
|
138 * is really a combined hash or some other arbitrary data, so it's safe to |
|
139 * handle this case first. |
|
140 */ |
|
141 if (SSL3_SHAMD5_HASH_SIZE == input->size) { |
|
142 hash->data = input->data; |
|
143 hash->size = input->size; |
|
144 *hashAlg = CALG_SSL3_SHAMD5; |
|
145 return CKR_OK; |
|
146 } |
|
147 |
|
148 current = (unsigned char *)input->data; |
|
149 |
|
150 /* make sure we have a sequence tag */ |
|
151 if ((DER_SEQUENCE|DER_CONSTRUCTED) != *current) { |
|
152 return CKR_DATA_INVALID; |
|
153 } |
|
154 |
|
155 /* parse the input block to get 1) the hash oid, and 2) the raw hash value. |
|
156 * unfortunatly CAPI doesn't have a builtin function to do this work, so |
|
157 * we go ahead and do it by hand here. |
|
158 * |
|
159 * format is: |
|
160 * SEQUENCE { |
|
161 * SECQUENCE { // algid |
|
162 * OID {} // oid |
|
163 * ANY {} // optional params |
|
164 * } |
|
165 * OCTECT {} // hash |
|
166 */ |
|
167 |
|
168 /* unwrap */ |
|
169 algid = nss_ckcapi_DERUnwrap(current,input->size, &size, NULL); |
|
170 |
|
171 if (algid+size != current+input->size) { |
|
172 /* make sure there is not extra data at the end */ |
|
173 return CKR_DATA_INVALID; |
|
174 } |
|
175 |
|
176 if ((DER_SEQUENCE|DER_CONSTRUCTED) != *algid) { |
|
177 /* wasn't an algid */ |
|
178 return CKR_DATA_INVALID; |
|
179 } |
|
180 oid = nss_ckcapi_DERUnwrap(algid, size, &oidSize, &hashData); |
|
181 |
|
182 if (DER_OCTET_STRING != *hashData) { |
|
183 /* wasn't a hash */ |
|
184 return CKR_DATA_INVALID; |
|
185 } |
|
186 |
|
187 /* get the real hash */ |
|
188 current = hashData; |
|
189 size = size - (hashData-algid); |
|
190 hash->data = nss_ckcapi_DERUnwrap(current, size, &hash->size, NULL); |
|
191 |
|
192 /* get the real oid as a string. Again, Microsoft does not |
|
193 * export anything that does this for us */ |
|
194 oidStr = nss_ckcapi_GetOidString(oid, oidSize, &error); |
|
195 if ((char *)NULL == oidStr ) { |
|
196 return error; |
|
197 } |
|
198 |
|
199 /* look up the hash alg from the oid (fortunately CAPI does to this) */ |
|
200 *hashAlg = CertOIDToAlgId(oidStr); |
|
201 nss_ZFreeIf(oidStr); |
|
202 if (0 == *hashAlg) { |
|
203 return CKR_HOST_MEMORY; |
|
204 } |
|
205 |
|
206 /* hash looks reasonably consistent, we should be able to sign it now */ |
|
207 return CKR_OK; |
|
208 } |
|
209 |
|
210 /* |
|
211 * So everyone else in the worlds stores their bignum data MSB first, but not |
|
212 * Microsoft, we need to byte swap everything coming into and out of CAPI. |
|
213 */ |
|
214 void |
|
215 ckcapi_ReverseData(NSSItem *item) |
|
216 { |
|
217 int end = (item->size)-1; |
|
218 int middle = (item->size)/2; |
|
219 unsigned char *buf = item->data; |
|
220 int i; |
|
221 |
|
222 for (i=0; i < middle; i++) { |
|
223 unsigned char tmp = buf[i]; |
|
224 buf[i] = buf[end-i]; |
|
225 buf[end-i] = tmp; |
|
226 } |
|
227 return; |
|
228 } |
|
229 |
|
230 typedef struct ckcapiInternalCryptoOperationRSAPrivStr |
|
231 ckcapiInternalCryptoOperationRSAPriv; |
|
232 struct ckcapiInternalCryptoOperationRSAPrivStr |
|
233 { |
|
234 NSSCKMDCryptoOperation mdOperation; |
|
235 NSSCKMDMechanism *mdMechanism; |
|
236 ckcapiInternalObject *iKey; |
|
237 HCRYPTPROV hProv; |
|
238 DWORD keySpec; |
|
239 HCRYPTKEY hKey; |
|
240 NSSItem *buffer; |
|
241 }; |
|
242 |
|
243 /* |
|
244 * ckcapi_mdCryptoOperationRSAPriv_Create |
|
245 */ |
|
246 static NSSCKMDCryptoOperation * |
|
247 ckcapi_mdCryptoOperationRSAPriv_Create |
|
248 ( |
|
249 const NSSCKMDCryptoOperation *proto, |
|
250 NSSCKMDMechanism *mdMechanism, |
|
251 NSSCKMDObject *mdKey, |
|
252 CK_RV *pError |
|
253 ) |
|
254 { |
|
255 ckcapiInternalObject *iKey = (ckcapiInternalObject *)mdKey->etc; |
|
256 const NSSItem *classItem = nss_ckcapi_FetchAttribute(iKey, CKA_CLASS); |
|
257 const NSSItem *keyType = nss_ckcapi_FetchAttribute(iKey, CKA_KEY_TYPE); |
|
258 ckcapiInternalCryptoOperationRSAPriv *iOperation; |
|
259 CK_RV error; |
|
260 HCRYPTPROV hProv; |
|
261 DWORD keySpec; |
|
262 HCRYPTKEY hKey; |
|
263 |
|
264 /* make sure we have the right objects */ |
|
265 if (((const NSSItem *)NULL == classItem) || |
|
266 (sizeof(CK_OBJECT_CLASS) != classItem->size) || |
|
267 (CKO_PRIVATE_KEY != *(CK_OBJECT_CLASS *)classItem->data) || |
|
268 ((const NSSItem *)NULL == keyType) || |
|
269 (sizeof(CK_KEY_TYPE) != keyType->size) || |
|
270 (CKK_RSA != *(CK_KEY_TYPE *)keyType->data)) { |
|
271 *pError = CKR_KEY_TYPE_INCONSISTENT; |
|
272 return (NSSCKMDCryptoOperation *)NULL; |
|
273 } |
|
274 |
|
275 error = nss_ckcapi_FetchKeyContainer(iKey, &hProv, &keySpec, &hKey); |
|
276 if (error != CKR_OK) { |
|
277 *pError = error; |
|
278 return (NSSCKMDCryptoOperation *)NULL; |
|
279 } |
|
280 |
|
281 iOperation = nss_ZNEW(NULL, ckcapiInternalCryptoOperationRSAPriv); |
|
282 if ((ckcapiInternalCryptoOperationRSAPriv *)NULL == iOperation) { |
|
283 *pError = CKR_HOST_MEMORY; |
|
284 return (NSSCKMDCryptoOperation *)NULL; |
|
285 } |
|
286 iOperation->mdMechanism = mdMechanism; |
|
287 iOperation->iKey = iKey; |
|
288 iOperation->hProv = hProv; |
|
289 iOperation->keySpec = keySpec; |
|
290 iOperation->hKey = hKey; |
|
291 |
|
292 nsslibc_memcpy(&iOperation->mdOperation, |
|
293 proto, sizeof(NSSCKMDCryptoOperation)); |
|
294 iOperation->mdOperation.etc = iOperation; |
|
295 |
|
296 return &iOperation->mdOperation; |
|
297 } |
|
298 |
|
299 static CK_RV |
|
300 ckcapi_mdCryptoOperationRSAPriv_Destroy |
|
301 ( |
|
302 NSSCKMDCryptoOperation *mdOperation, |
|
303 NSSCKFWCryptoOperation *fwOperation, |
|
304 NSSCKMDInstance *mdInstance, |
|
305 NSSCKFWInstance *fwInstance |
|
306 ) |
|
307 { |
|
308 ckcapiInternalCryptoOperationRSAPriv *iOperation = |
|
309 (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc; |
|
310 |
|
311 if (iOperation->hKey) { |
|
312 CryptDestroyKey(iOperation->hKey); |
|
313 } |
|
314 if (iOperation->buffer) { |
|
315 nssItem_Destroy(iOperation->buffer); |
|
316 } |
|
317 nss_ZFreeIf(iOperation); |
|
318 return CKR_OK; |
|
319 } |
|
320 |
|
321 static CK_ULONG |
|
322 ckcapi_mdCryptoOperationRSA_GetFinalLength |
|
323 ( |
|
324 NSSCKMDCryptoOperation *mdOperation, |
|
325 NSSCKFWCryptoOperation *fwOperation, |
|
326 NSSCKMDSession *mdSession, |
|
327 NSSCKFWSession *fwSession, |
|
328 NSSCKMDToken *mdToken, |
|
329 NSSCKFWToken *fwToken, |
|
330 NSSCKMDInstance *mdInstance, |
|
331 NSSCKFWInstance *fwInstance, |
|
332 CK_RV *pError |
|
333 ) |
|
334 { |
|
335 ckcapiInternalCryptoOperationRSAPriv *iOperation = |
|
336 (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc; |
|
337 const NSSItem *modulus = |
|
338 nss_ckcapi_FetchAttribute(iOperation->iKey, CKA_MODULUS); |
|
339 |
|
340 return modulus->size; |
|
341 } |
|
342 |
|
343 |
|
344 /* |
|
345 * ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength |
|
346 * we won't know the length until we actually decrypt the |
|
347 * input block. Since we go to all the work to decrypt the |
|
348 * the block, we'll save if for when the block is asked for |
|
349 */ |
|
350 static CK_ULONG |
|
351 ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength |
|
352 ( |
|
353 NSSCKMDCryptoOperation *mdOperation, |
|
354 NSSCKFWCryptoOperation *fwOperation, |
|
355 NSSCKMDSession *mdSession, |
|
356 NSSCKFWSession *fwSession, |
|
357 NSSCKMDToken *mdToken, |
|
358 NSSCKFWToken *fwToken, |
|
359 NSSCKMDInstance *mdInstance, |
|
360 NSSCKFWInstance *fwInstance, |
|
361 const NSSItem *input, |
|
362 CK_RV *pError |
|
363 ) |
|
364 { |
|
365 ckcapiInternalCryptoOperationRSAPriv *iOperation = |
|
366 (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc; |
|
367 BOOL rc; |
|
368 |
|
369 /* Microsoft's Decrypt operation works in place. Since we don't want |
|
370 * to trash our input buffer, we make a copy of it */ |
|
371 iOperation->buffer = nssItem_Duplicate((NSSItem *)input, NULL, NULL); |
|
372 if ((NSSItem *) NULL == iOperation->buffer) { |
|
373 *pError = CKR_HOST_MEMORY; |
|
374 return 0; |
|
375 } |
|
376 /* Sigh, reverse it */ |
|
377 ckcapi_ReverseData(iOperation->buffer); |
|
378 |
|
379 rc = CryptDecrypt(iOperation->hKey, 0, TRUE, 0, |
|
380 iOperation->buffer->data, &iOperation->buffer->size); |
|
381 if (!rc) { |
|
382 DWORD msError = GetLastError(); |
|
383 switch (msError) { |
|
384 case NTE_BAD_DATA: |
|
385 *pError = CKR_ENCRYPTED_DATA_INVALID; |
|
386 break; |
|
387 case NTE_FAIL: |
|
388 case NTE_BAD_UID: |
|
389 *pError = CKR_DEVICE_ERROR; |
|
390 break; |
|
391 default: |
|
392 *pError = CKR_GENERAL_ERROR; |
|
393 } |
|
394 return 0; |
|
395 } |
|
396 |
|
397 return iOperation->buffer->size; |
|
398 } |
|
399 |
|
400 /* |
|
401 * ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal |
|
402 * |
|
403 * NOTE: ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength is presumed to |
|
404 * have been called previously. |
|
405 */ |
|
406 static CK_RV |
|
407 ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal |
|
408 ( |
|
409 NSSCKMDCryptoOperation *mdOperation, |
|
410 NSSCKFWCryptoOperation *fwOperation, |
|
411 NSSCKMDSession *mdSession, |
|
412 NSSCKFWSession *fwSession, |
|
413 NSSCKMDToken *mdToken, |
|
414 NSSCKFWToken *fwToken, |
|
415 NSSCKMDInstance *mdInstance, |
|
416 NSSCKFWInstance *fwInstance, |
|
417 const NSSItem *input, |
|
418 NSSItem *output |
|
419 ) |
|
420 { |
|
421 ckcapiInternalCryptoOperationRSAPriv *iOperation = |
|
422 (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc; |
|
423 NSSItem *buffer = iOperation->buffer; |
|
424 |
|
425 if ((NSSItem *)NULL == buffer) { |
|
426 return CKR_GENERAL_ERROR; |
|
427 } |
|
428 nsslibc_memcpy(output->data, buffer->data, buffer->size); |
|
429 output->size = buffer->size; |
|
430 return CKR_OK; |
|
431 } |
|
432 |
|
433 /* |
|
434 * ckcapi_mdCryptoOperationRSASign_UpdateFinal |
|
435 * |
|
436 */ |
|
437 static CK_RV |
|
438 ckcapi_mdCryptoOperationRSASign_UpdateFinal |
|
439 ( |
|
440 NSSCKMDCryptoOperation *mdOperation, |
|
441 NSSCKFWCryptoOperation *fwOperation, |
|
442 NSSCKMDSession *mdSession, |
|
443 NSSCKFWSession *fwSession, |
|
444 NSSCKMDToken *mdToken, |
|
445 NSSCKFWToken *fwToken, |
|
446 NSSCKMDInstance *mdInstance, |
|
447 NSSCKFWInstance *fwInstance, |
|
448 const NSSItem *input, |
|
449 NSSItem *output |
|
450 ) |
|
451 { |
|
452 ckcapiInternalCryptoOperationRSAPriv *iOperation = |
|
453 (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc; |
|
454 CK_RV error = CKR_OK; |
|
455 DWORD msError; |
|
456 NSSItem hash; |
|
457 HCRYPTHASH hHash = 0; |
|
458 ALG_ID hashAlg; |
|
459 DWORD hashSize; |
|
460 DWORD len; /* temp length value we throw away */ |
|
461 BOOL rc; |
|
462 |
|
463 /* |
|
464 * PKCS #11 sign for RSA expects to take a fully DER-encoded hash value, |
|
465 * which includes the hash OID. CAPI expects to take a Hash Context. While |
|
466 * CAPI does have the capability of setting a raw hash value, it does not |
|
467 * have the ability to sign an arbitrary value. This function tries to |
|
468 * reduce the passed in data into something that CAPI could actually sign. |
|
469 */ |
|
470 error = ckcapi_GetRawHash(input, &hash, &hashAlg); |
|
471 if (CKR_OK != error) { |
|
472 goto loser; |
|
473 } |
|
474 |
|
475 rc = CryptCreateHash(iOperation->hProv, hashAlg, 0, 0, &hHash); |
|
476 if (!rc) { |
|
477 goto loser; |
|
478 } |
|
479 |
|
480 /* make sure the hash lens match before we set it */ |
|
481 len = sizeof(DWORD); |
|
482 rc = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashSize, &len, 0); |
|
483 if (!rc) { |
|
484 goto loser; |
|
485 } |
|
486 |
|
487 if (hash.size != hashSize) { |
|
488 /* The input must have been bad for this to happen */ |
|
489 error = CKR_DATA_INVALID; |
|
490 goto loser; |
|
491 } |
|
492 |
|
493 /* we have an explicit hash, set it, note that the length is |
|
494 * implicit by the hashAlg used in create */ |
|
495 rc = CryptSetHashParam(hHash, HP_HASHVAL, hash.data, 0); |
|
496 if (!rc) { |
|
497 goto loser; |
|
498 } |
|
499 |
|
500 /* OK, we have the data in a hash structure, sign it! */ |
|
501 rc = CryptSignHash(hHash, iOperation->keySpec, NULL, 0, |
|
502 output->data, &output->size); |
|
503 if (!rc) { |
|
504 goto loser; |
|
505 } |
|
506 |
|
507 /* Don't return a signature that might have been broken because of a cosmic |
|
508 * ray, or a broken processor, verify that it is valid... */ |
|
509 rc = CryptVerifySignature(hHash, output->data, output->size, |
|
510 iOperation->hKey, NULL, 0); |
|
511 if (!rc) { |
|
512 goto loser; |
|
513 } |
|
514 |
|
515 /* OK, Microsoft likes to do things completely differently than anyone |
|
516 * else. We need to reverse the data we received here */ |
|
517 ckcapi_ReverseData(output); |
|
518 CryptDestroyHash(hHash); |
|
519 return CKR_OK; |
|
520 |
|
521 loser: |
|
522 /* map the microsoft error */ |
|
523 if (CKR_OK == error) { |
|
524 msError = GetLastError(); |
|
525 switch (msError) { |
|
526 case ERROR_NOT_ENOUGH_MEMORY: |
|
527 error = CKR_HOST_MEMORY; |
|
528 break; |
|
529 case NTE_NO_MEMORY: |
|
530 error = CKR_DEVICE_MEMORY; |
|
531 break; |
|
532 case ERROR_MORE_DATA: |
|
533 return CKR_BUFFER_TOO_SMALL; |
|
534 case ERROR_INVALID_PARAMETER: /* these params were derived from the */ |
|
535 case ERROR_INVALID_HANDLE: /* inputs, so if they are bad, the input */ |
|
536 case NTE_BAD_ALGID: /* data is bad */ |
|
537 case NTE_BAD_HASH: |
|
538 error = CKR_DATA_INVALID; |
|
539 break; |
|
540 case ERROR_BUSY: |
|
541 case NTE_FAIL: |
|
542 case NTE_BAD_UID: |
|
543 error = CKR_DEVICE_ERROR; |
|
544 break; |
|
545 default: |
|
546 error = CKR_GENERAL_ERROR; |
|
547 break; |
|
548 } |
|
549 } |
|
550 if (hHash) { |
|
551 CryptDestroyHash(hHash); |
|
552 } |
|
553 return error; |
|
554 } |
|
555 |
|
556 |
|
557 NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation |
|
558 ckcapi_mdCryptoOperationRSADecrypt_proto = { |
|
559 NULL, /* etc */ |
|
560 ckcapi_mdCryptoOperationRSAPriv_Destroy, |
|
561 NULL, /* GetFinalLengh - not needed for one shot Decrypt/Encrypt */ |
|
562 ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength, |
|
563 NULL, /* Final - not needed for one shot operation */ |
|
564 NULL, /* Update - not needed for one shot operation */ |
|
565 NULL, /* DigetUpdate - not needed for one shot operation */ |
|
566 ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal, |
|
567 NULL, /* UpdateCombo - not needed for one shot operation */ |
|
568 NULL, /* DigetKey - not needed for one shot operation */ |
|
569 (void *)NULL /* null terminator */ |
|
570 }; |
|
571 |
|
572 NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation |
|
573 ckcapi_mdCryptoOperationRSASign_proto = { |
|
574 NULL, /* etc */ |
|
575 ckcapi_mdCryptoOperationRSAPriv_Destroy, |
|
576 ckcapi_mdCryptoOperationRSA_GetFinalLength, |
|
577 NULL, /* GetOperationLengh - not needed for one shot Sign/Verify */ |
|
578 NULL, /* Final - not needed for one shot operation */ |
|
579 NULL, /* Update - not needed for one shot operation */ |
|
580 NULL, /* DigetUpdate - not needed for one shot operation */ |
|
581 ckcapi_mdCryptoOperationRSASign_UpdateFinal, |
|
582 NULL, /* UpdateCombo - not needed for one shot operation */ |
|
583 NULL, /* DigetKey - not needed for one shot operation */ |
|
584 (void *)NULL /* null terminator */ |
|
585 }; |
|
586 |
|
587 /********** NSSCKMDMechansim functions ***********************/ |
|
588 /* |
|
589 * ckcapi_mdMechanismRSA_Destroy |
|
590 */ |
|
591 static void |
|
592 ckcapi_mdMechanismRSA_Destroy |
|
593 ( |
|
594 NSSCKMDMechanism *mdMechanism, |
|
595 NSSCKFWMechanism *fwMechanism, |
|
596 NSSCKMDInstance *mdInstance, |
|
597 NSSCKFWInstance *fwInstance |
|
598 ) |
|
599 { |
|
600 nss_ZFreeIf(fwMechanism); |
|
601 } |
|
602 |
|
603 /* |
|
604 * ckcapi_mdMechanismRSA_GetMinKeySize |
|
605 */ |
|
606 static CK_ULONG |
|
607 ckcapi_mdMechanismRSA_GetMinKeySize |
|
608 ( |
|
609 NSSCKMDMechanism *mdMechanism, |
|
610 NSSCKFWMechanism *fwMechanism, |
|
611 NSSCKMDToken *mdToken, |
|
612 NSSCKFWToken *fwToken, |
|
613 NSSCKMDInstance *mdInstance, |
|
614 NSSCKFWInstance *fwInstance, |
|
615 CK_RV *pError |
|
616 ) |
|
617 { |
|
618 return 384; |
|
619 } |
|
620 |
|
621 /* |
|
622 * ckcapi_mdMechanismRSA_GetMaxKeySize |
|
623 */ |
|
624 static CK_ULONG |
|
625 ckcapi_mdMechanismRSA_GetMaxKeySize |
|
626 ( |
|
627 NSSCKMDMechanism *mdMechanism, |
|
628 NSSCKFWMechanism *fwMechanism, |
|
629 NSSCKMDToken *mdToken, |
|
630 NSSCKFWToken *fwToken, |
|
631 NSSCKMDInstance *mdInstance, |
|
632 NSSCKFWInstance *fwInstance, |
|
633 CK_RV *pError |
|
634 ) |
|
635 { |
|
636 return 16384; |
|
637 } |
|
638 |
|
639 /* |
|
640 * ckcapi_mdMechanismRSA_DecryptInit |
|
641 */ |
|
642 static NSSCKMDCryptoOperation * |
|
643 ckcapi_mdMechanismRSA_DecryptInit |
|
644 ( |
|
645 NSSCKMDMechanism *mdMechanism, |
|
646 NSSCKFWMechanism *fwMechanism, |
|
647 CK_MECHANISM *pMechanism, |
|
648 NSSCKMDSession *mdSession, |
|
649 NSSCKFWSession *fwSession, |
|
650 NSSCKMDToken *mdToken, |
|
651 NSSCKFWToken *fwToken, |
|
652 NSSCKMDInstance *mdInstance, |
|
653 NSSCKFWInstance *fwInstance, |
|
654 NSSCKMDObject *mdKey, |
|
655 NSSCKFWObject *fwKey, |
|
656 CK_RV *pError |
|
657 ) |
|
658 { |
|
659 return ckcapi_mdCryptoOperationRSAPriv_Create( |
|
660 &ckcapi_mdCryptoOperationRSADecrypt_proto, |
|
661 mdMechanism, mdKey, pError); |
|
662 } |
|
663 |
|
664 /* |
|
665 * ckcapi_mdMechanismRSA_SignInit |
|
666 */ |
|
667 static NSSCKMDCryptoOperation * |
|
668 ckcapi_mdMechanismRSA_SignInit |
|
669 ( |
|
670 NSSCKMDMechanism *mdMechanism, |
|
671 NSSCKFWMechanism *fwMechanism, |
|
672 CK_MECHANISM *pMechanism, |
|
673 NSSCKMDSession *mdSession, |
|
674 NSSCKFWSession *fwSession, |
|
675 NSSCKMDToken *mdToken, |
|
676 NSSCKFWToken *fwToken, |
|
677 NSSCKMDInstance *mdInstance, |
|
678 NSSCKFWInstance *fwInstance, |
|
679 NSSCKMDObject *mdKey, |
|
680 NSSCKFWObject *fwKey, |
|
681 CK_RV *pError |
|
682 ) |
|
683 { |
|
684 return ckcapi_mdCryptoOperationRSAPriv_Create( |
|
685 &ckcapi_mdCryptoOperationRSASign_proto, |
|
686 mdMechanism, mdKey, pError); |
|
687 } |
|
688 |
|
689 |
|
690 NSS_IMPLEMENT_DATA const NSSCKMDMechanism |
|
691 nss_ckcapi_mdMechanismRSA = { |
|
692 (void *)NULL, /* etc */ |
|
693 ckcapi_mdMechanismRSA_Destroy, |
|
694 ckcapi_mdMechanismRSA_GetMinKeySize, |
|
695 ckcapi_mdMechanismRSA_GetMaxKeySize, |
|
696 NULL, /* GetInHardware - default false */ |
|
697 NULL, /* EncryptInit - default errs */ |
|
698 ckcapi_mdMechanismRSA_DecryptInit, |
|
699 NULL, /* DigestInit - default errs*/ |
|
700 ckcapi_mdMechanismRSA_SignInit, |
|
701 NULL, /* VerifyInit - default errs */ |
|
702 ckcapi_mdMechanismRSA_SignInit, /* SignRecoverInit */ |
|
703 NULL, /* VerifyRecoverInit - default errs */ |
|
704 NULL, /* GenerateKey - default errs */ |
|
705 NULL, /* GenerateKeyPair - default errs */ |
|
706 NULL, /* GetWrapKeyLength - default errs */ |
|
707 NULL, /* WrapKey - default errs */ |
|
708 NULL, /* UnwrapKey - default errs */ |
|
709 NULL, /* DeriveKey - default errs */ |
|
710 (void *)NULL /* null terminator */ |
|
711 }; |