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