1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/ckfw/capi/crsa.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,711 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "ckcapi.h" 1.9 +#include "secdert.h" 1.10 + 1.11 +#define SSL3_SHAMD5_HASH_SIZE 36 /* LEN_MD5 (16) + LEN_SHA1 (20) */ 1.12 + 1.13 +/* 1.14 + * ckcapi/crsa.c 1.15 + * 1.16 + * This file implements the NSSCKMDMechnaism and NSSCKMDCryptoOperation objects 1.17 + * for the RSA operation on the CAPI cryptoki module. 1.18 + */ 1.19 + 1.20 +/* 1.21 + * write a Decimal value to a string 1.22 + */ 1.23 + 1.24 +static char * 1.25 +putDecimalString(char *cstr, unsigned long value) 1.26 +{ 1.27 + unsigned long tenpower; 1.28 + int first = 1; 1.29 + 1.30 + for (tenpower=10000000; tenpower; tenpower /= 10) { 1.31 + unsigned char digit = (unsigned char )(value/tenpower); 1.32 + value = value % tenpower; 1.33 + 1.34 + /* drop leading zeros */ 1.35 + if (first && (0 == digit)) { 1.36 + continue; 1.37 + } 1.38 + first = 0; 1.39 + *cstr++ = digit + '0'; 1.40 + } 1.41 + 1.42 + /* if value was zero, put one of them out */ 1.43 + if (first) { 1.44 + *cstr++ = '0'; 1.45 + } 1.46 + return cstr; 1.47 +} 1.48 + 1.49 + 1.50 +/* 1.51 + * Create a Capi OID string value from a DER OID 1.52 + */ 1.53 +static char * 1.54 +nss_ckcapi_GetOidString 1.55 +( 1.56 + unsigned char *oidTag, 1.57 + unsigned int oidTagSize, 1.58 + CK_RV *pError 1.59 +) 1.60 +{ 1.61 + unsigned char *oid; 1.62 + char *oidStr; 1.63 + char *cstr; 1.64 + unsigned long value; 1.65 + unsigned int oidSize; 1.66 + 1.67 + if (DER_OBJECT_ID != *oidTag) { 1.68 + /* wasn't an oid */ 1.69 + *pError = CKR_DATA_INVALID; 1.70 + return NULL; 1.71 + } 1.72 + oid = nss_ckcapi_DERUnwrap(oidTag, oidTagSize, &oidSize, NULL); 1.73 + 1.74 + if (oidSize < 2) { 1.75 + *pError = CKR_DATA_INVALID; 1.76 + return NULL; 1.77 + } 1.78 + 1.79 + oidStr = nss_ZNEWARRAY( NULL, char, oidSize*4 ); 1.80 + if ((char *)NULL == oidStr) { 1.81 + *pError = CKR_HOST_MEMORY; 1.82 + return NULL; 1.83 + } 1.84 + cstr = oidStr; 1.85 + cstr = putDecimalString(cstr, (*oid) / 40); 1.86 + *cstr++ = '.'; 1.87 + cstr = putDecimalString(cstr, (*oid) % 40); 1.88 + oidSize--; 1.89 + 1.90 + value = 0; 1.91 + while (oidSize--) { 1.92 + oid++; 1.93 + value = (value << 7) + (*oid & 0x7f); 1.94 + if (0 == (*oid & 0x80)) { 1.95 + *cstr++ = '.'; 1.96 + cstr = putDecimalString(cstr, value); 1.97 + value = 0; 1.98 + } 1.99 + } 1.100 + 1.101 + *cstr = 0; /* NULL terminate */ 1.102 + 1.103 + if (value != 0) { 1.104 + nss_ZFreeIf(oidStr); 1.105 + *pError = CKR_DATA_INVALID; 1.106 + return NULL; 1.107 + } 1.108 + return oidStr; 1.109 +} 1.110 + 1.111 + 1.112 +/* 1.113 + * PKCS #11 sign for RSA expects to take a fully DER-encoded hash value, 1.114 + * which includes the hash OID. CAPI expects to take a Hash Context. While 1.115 + * CAPI does have the capability of setting a raw hash value, it does not 1.116 + * have the ability to sign an arbitrary value. This function tries to 1.117 + * reduce the passed in data into something that CAPI could actually sign. 1.118 + */ 1.119 +static CK_RV 1.120 +ckcapi_GetRawHash 1.121 +( 1.122 + const NSSItem *input, 1.123 + NSSItem *hash, 1.124 + ALG_ID *hashAlg 1.125 +) 1.126 +{ 1.127 + unsigned char *current; 1.128 + unsigned char *algid; 1.129 + unsigned char *oid; 1.130 + unsigned char *hashData; 1.131 + char *oidStr; 1.132 + CK_RV error; 1.133 + unsigned int oidSize; 1.134 + unsigned int size; 1.135 + /* 1.136 + * there are 2 types of hashes NSS typically tries to sign, regular 1.137 + * RSA signature format (with encoded DER_OIDS), and SSL3 Signed hashes. 1.138 + * CAPI knows not to add any oids to SSL3_Signed hashes, so if we have any 1.139 + * random hash that is exactly the same size as an SSL3 hash, then we can 1.140 + * just pass the data through. CAPI has know way of knowing if the value 1.141 + * is really a combined hash or some other arbitrary data, so it's safe to 1.142 + * handle this case first. 1.143 + */ 1.144 + if (SSL3_SHAMD5_HASH_SIZE == input->size) { 1.145 + hash->data = input->data; 1.146 + hash->size = input->size; 1.147 + *hashAlg = CALG_SSL3_SHAMD5; 1.148 + return CKR_OK; 1.149 + } 1.150 + 1.151 + current = (unsigned char *)input->data; 1.152 + 1.153 + /* make sure we have a sequence tag */ 1.154 + if ((DER_SEQUENCE|DER_CONSTRUCTED) != *current) { 1.155 + return CKR_DATA_INVALID; 1.156 + } 1.157 + 1.158 + /* parse the input block to get 1) the hash oid, and 2) the raw hash value. 1.159 + * unfortunatly CAPI doesn't have a builtin function to do this work, so 1.160 + * we go ahead and do it by hand here. 1.161 + * 1.162 + * format is: 1.163 + * SEQUENCE { 1.164 + * SECQUENCE { // algid 1.165 + * OID {} // oid 1.166 + * ANY {} // optional params 1.167 + * } 1.168 + * OCTECT {} // hash 1.169 + */ 1.170 + 1.171 + /* unwrap */ 1.172 + algid = nss_ckcapi_DERUnwrap(current,input->size, &size, NULL); 1.173 + 1.174 + if (algid+size != current+input->size) { 1.175 + /* make sure there is not extra data at the end */ 1.176 + return CKR_DATA_INVALID; 1.177 + } 1.178 + 1.179 + if ((DER_SEQUENCE|DER_CONSTRUCTED) != *algid) { 1.180 + /* wasn't an algid */ 1.181 + return CKR_DATA_INVALID; 1.182 + } 1.183 + oid = nss_ckcapi_DERUnwrap(algid, size, &oidSize, &hashData); 1.184 + 1.185 + if (DER_OCTET_STRING != *hashData) { 1.186 + /* wasn't a hash */ 1.187 + return CKR_DATA_INVALID; 1.188 + } 1.189 + 1.190 + /* get the real hash */ 1.191 + current = hashData; 1.192 + size = size - (hashData-algid); 1.193 + hash->data = nss_ckcapi_DERUnwrap(current, size, &hash->size, NULL); 1.194 + 1.195 + /* get the real oid as a string. Again, Microsoft does not 1.196 + * export anything that does this for us */ 1.197 + oidStr = nss_ckcapi_GetOidString(oid, oidSize, &error); 1.198 + if ((char *)NULL == oidStr ) { 1.199 + return error; 1.200 + } 1.201 + 1.202 + /* look up the hash alg from the oid (fortunately CAPI does to this) */ 1.203 + *hashAlg = CertOIDToAlgId(oidStr); 1.204 + nss_ZFreeIf(oidStr); 1.205 + if (0 == *hashAlg) { 1.206 + return CKR_HOST_MEMORY; 1.207 + } 1.208 + 1.209 + /* hash looks reasonably consistent, we should be able to sign it now */ 1.210 + return CKR_OK; 1.211 +} 1.212 + 1.213 +/* 1.214 + * So everyone else in the worlds stores their bignum data MSB first, but not 1.215 + * Microsoft, we need to byte swap everything coming into and out of CAPI. 1.216 + */ 1.217 +void 1.218 +ckcapi_ReverseData(NSSItem *item) 1.219 +{ 1.220 + int end = (item->size)-1; 1.221 + int middle = (item->size)/2; 1.222 + unsigned char *buf = item->data; 1.223 + int i; 1.224 + 1.225 + for (i=0; i < middle; i++) { 1.226 + unsigned char tmp = buf[i]; 1.227 + buf[i] = buf[end-i]; 1.228 + buf[end-i] = tmp; 1.229 + } 1.230 + return; 1.231 +} 1.232 + 1.233 +typedef struct ckcapiInternalCryptoOperationRSAPrivStr 1.234 + ckcapiInternalCryptoOperationRSAPriv; 1.235 +struct ckcapiInternalCryptoOperationRSAPrivStr 1.236 +{ 1.237 + NSSCKMDCryptoOperation mdOperation; 1.238 + NSSCKMDMechanism *mdMechanism; 1.239 + ckcapiInternalObject *iKey; 1.240 + HCRYPTPROV hProv; 1.241 + DWORD keySpec; 1.242 + HCRYPTKEY hKey; 1.243 + NSSItem *buffer; 1.244 +}; 1.245 + 1.246 +/* 1.247 + * ckcapi_mdCryptoOperationRSAPriv_Create 1.248 + */ 1.249 +static NSSCKMDCryptoOperation * 1.250 +ckcapi_mdCryptoOperationRSAPriv_Create 1.251 +( 1.252 + const NSSCKMDCryptoOperation *proto, 1.253 + NSSCKMDMechanism *mdMechanism, 1.254 + NSSCKMDObject *mdKey, 1.255 + CK_RV *pError 1.256 +) 1.257 +{ 1.258 + ckcapiInternalObject *iKey = (ckcapiInternalObject *)mdKey->etc; 1.259 + const NSSItem *classItem = nss_ckcapi_FetchAttribute(iKey, CKA_CLASS); 1.260 + const NSSItem *keyType = nss_ckcapi_FetchAttribute(iKey, CKA_KEY_TYPE); 1.261 + ckcapiInternalCryptoOperationRSAPriv *iOperation; 1.262 + CK_RV error; 1.263 + HCRYPTPROV hProv; 1.264 + DWORD keySpec; 1.265 + HCRYPTKEY hKey; 1.266 + 1.267 + /* make sure we have the right objects */ 1.268 + if (((const NSSItem *)NULL == classItem) || 1.269 + (sizeof(CK_OBJECT_CLASS) != classItem->size) || 1.270 + (CKO_PRIVATE_KEY != *(CK_OBJECT_CLASS *)classItem->data) || 1.271 + ((const NSSItem *)NULL == keyType) || 1.272 + (sizeof(CK_KEY_TYPE) != keyType->size) || 1.273 + (CKK_RSA != *(CK_KEY_TYPE *)keyType->data)) { 1.274 + *pError = CKR_KEY_TYPE_INCONSISTENT; 1.275 + return (NSSCKMDCryptoOperation *)NULL; 1.276 + } 1.277 + 1.278 + error = nss_ckcapi_FetchKeyContainer(iKey, &hProv, &keySpec, &hKey); 1.279 + if (error != CKR_OK) { 1.280 + *pError = error; 1.281 + return (NSSCKMDCryptoOperation *)NULL; 1.282 + } 1.283 + 1.284 + iOperation = nss_ZNEW(NULL, ckcapiInternalCryptoOperationRSAPriv); 1.285 + if ((ckcapiInternalCryptoOperationRSAPriv *)NULL == iOperation) { 1.286 + *pError = CKR_HOST_MEMORY; 1.287 + return (NSSCKMDCryptoOperation *)NULL; 1.288 + } 1.289 + iOperation->mdMechanism = mdMechanism; 1.290 + iOperation->iKey = iKey; 1.291 + iOperation->hProv = hProv; 1.292 + iOperation->keySpec = keySpec; 1.293 + iOperation->hKey = hKey; 1.294 + 1.295 + nsslibc_memcpy(&iOperation->mdOperation, 1.296 + proto, sizeof(NSSCKMDCryptoOperation)); 1.297 + iOperation->mdOperation.etc = iOperation; 1.298 + 1.299 + return &iOperation->mdOperation; 1.300 +} 1.301 + 1.302 +static CK_RV 1.303 +ckcapi_mdCryptoOperationRSAPriv_Destroy 1.304 +( 1.305 + NSSCKMDCryptoOperation *mdOperation, 1.306 + NSSCKFWCryptoOperation *fwOperation, 1.307 + NSSCKMDInstance *mdInstance, 1.308 + NSSCKFWInstance *fwInstance 1.309 +) 1.310 +{ 1.311 + ckcapiInternalCryptoOperationRSAPriv *iOperation = 1.312 + (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc; 1.313 + 1.314 + if (iOperation->hKey) { 1.315 + CryptDestroyKey(iOperation->hKey); 1.316 + } 1.317 + if (iOperation->buffer) { 1.318 + nssItem_Destroy(iOperation->buffer); 1.319 + } 1.320 + nss_ZFreeIf(iOperation); 1.321 + return CKR_OK; 1.322 +} 1.323 + 1.324 +static CK_ULONG 1.325 +ckcapi_mdCryptoOperationRSA_GetFinalLength 1.326 +( 1.327 + NSSCKMDCryptoOperation *mdOperation, 1.328 + NSSCKFWCryptoOperation *fwOperation, 1.329 + NSSCKMDSession *mdSession, 1.330 + NSSCKFWSession *fwSession, 1.331 + NSSCKMDToken *mdToken, 1.332 + NSSCKFWToken *fwToken, 1.333 + NSSCKMDInstance *mdInstance, 1.334 + NSSCKFWInstance *fwInstance, 1.335 + CK_RV *pError 1.336 +) 1.337 +{ 1.338 + ckcapiInternalCryptoOperationRSAPriv *iOperation = 1.339 + (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc; 1.340 + const NSSItem *modulus = 1.341 + nss_ckcapi_FetchAttribute(iOperation->iKey, CKA_MODULUS); 1.342 + 1.343 + return modulus->size; 1.344 +} 1.345 + 1.346 + 1.347 +/* 1.348 + * ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength 1.349 + * we won't know the length until we actually decrypt the 1.350 + * input block. Since we go to all the work to decrypt the 1.351 + * the block, we'll save if for when the block is asked for 1.352 + */ 1.353 +static CK_ULONG 1.354 +ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength 1.355 +( 1.356 + NSSCKMDCryptoOperation *mdOperation, 1.357 + NSSCKFWCryptoOperation *fwOperation, 1.358 + NSSCKMDSession *mdSession, 1.359 + NSSCKFWSession *fwSession, 1.360 + NSSCKMDToken *mdToken, 1.361 + NSSCKFWToken *fwToken, 1.362 + NSSCKMDInstance *mdInstance, 1.363 + NSSCKFWInstance *fwInstance, 1.364 + const NSSItem *input, 1.365 + CK_RV *pError 1.366 +) 1.367 +{ 1.368 + ckcapiInternalCryptoOperationRSAPriv *iOperation = 1.369 + (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc; 1.370 + BOOL rc; 1.371 + 1.372 + /* Microsoft's Decrypt operation works in place. Since we don't want 1.373 + * to trash our input buffer, we make a copy of it */ 1.374 + iOperation->buffer = nssItem_Duplicate((NSSItem *)input, NULL, NULL); 1.375 + if ((NSSItem *) NULL == iOperation->buffer) { 1.376 + *pError = CKR_HOST_MEMORY; 1.377 + return 0; 1.378 + } 1.379 + /* Sigh, reverse it */ 1.380 + ckcapi_ReverseData(iOperation->buffer); 1.381 + 1.382 + rc = CryptDecrypt(iOperation->hKey, 0, TRUE, 0, 1.383 + iOperation->buffer->data, &iOperation->buffer->size); 1.384 + if (!rc) { 1.385 + DWORD msError = GetLastError(); 1.386 + switch (msError) { 1.387 + case NTE_BAD_DATA: 1.388 + *pError = CKR_ENCRYPTED_DATA_INVALID; 1.389 + break; 1.390 + case NTE_FAIL: 1.391 + case NTE_BAD_UID: 1.392 + *pError = CKR_DEVICE_ERROR; 1.393 + break; 1.394 + default: 1.395 + *pError = CKR_GENERAL_ERROR; 1.396 + } 1.397 + return 0; 1.398 + } 1.399 + 1.400 + return iOperation->buffer->size; 1.401 +} 1.402 + 1.403 +/* 1.404 + * ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal 1.405 + * 1.406 + * NOTE: ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength is presumed to 1.407 + * have been called previously. 1.408 + */ 1.409 +static CK_RV 1.410 +ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal 1.411 +( 1.412 + NSSCKMDCryptoOperation *mdOperation, 1.413 + NSSCKFWCryptoOperation *fwOperation, 1.414 + NSSCKMDSession *mdSession, 1.415 + NSSCKFWSession *fwSession, 1.416 + NSSCKMDToken *mdToken, 1.417 + NSSCKFWToken *fwToken, 1.418 + NSSCKMDInstance *mdInstance, 1.419 + NSSCKFWInstance *fwInstance, 1.420 + const NSSItem *input, 1.421 + NSSItem *output 1.422 +) 1.423 +{ 1.424 + ckcapiInternalCryptoOperationRSAPriv *iOperation = 1.425 + (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc; 1.426 + NSSItem *buffer = iOperation->buffer; 1.427 + 1.428 + if ((NSSItem *)NULL == buffer) { 1.429 + return CKR_GENERAL_ERROR; 1.430 + } 1.431 + nsslibc_memcpy(output->data, buffer->data, buffer->size); 1.432 + output->size = buffer->size; 1.433 + return CKR_OK; 1.434 +} 1.435 + 1.436 +/* 1.437 + * ckcapi_mdCryptoOperationRSASign_UpdateFinal 1.438 + * 1.439 + */ 1.440 +static CK_RV 1.441 +ckcapi_mdCryptoOperationRSASign_UpdateFinal 1.442 +( 1.443 + NSSCKMDCryptoOperation *mdOperation, 1.444 + NSSCKFWCryptoOperation *fwOperation, 1.445 + NSSCKMDSession *mdSession, 1.446 + NSSCKFWSession *fwSession, 1.447 + NSSCKMDToken *mdToken, 1.448 + NSSCKFWToken *fwToken, 1.449 + NSSCKMDInstance *mdInstance, 1.450 + NSSCKFWInstance *fwInstance, 1.451 + const NSSItem *input, 1.452 + NSSItem *output 1.453 +) 1.454 +{ 1.455 + ckcapiInternalCryptoOperationRSAPriv *iOperation = 1.456 + (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc; 1.457 + CK_RV error = CKR_OK; 1.458 + DWORD msError; 1.459 + NSSItem hash; 1.460 + HCRYPTHASH hHash = 0; 1.461 + ALG_ID hashAlg; 1.462 + DWORD hashSize; 1.463 + DWORD len; /* temp length value we throw away */ 1.464 + BOOL rc; 1.465 + 1.466 + /* 1.467 + * PKCS #11 sign for RSA expects to take a fully DER-encoded hash value, 1.468 + * which includes the hash OID. CAPI expects to take a Hash Context. While 1.469 + * CAPI does have the capability of setting a raw hash value, it does not 1.470 + * have the ability to sign an arbitrary value. This function tries to 1.471 + * reduce the passed in data into something that CAPI could actually sign. 1.472 + */ 1.473 + error = ckcapi_GetRawHash(input, &hash, &hashAlg); 1.474 + if (CKR_OK != error) { 1.475 + goto loser; 1.476 + } 1.477 + 1.478 + rc = CryptCreateHash(iOperation->hProv, hashAlg, 0, 0, &hHash); 1.479 + if (!rc) { 1.480 + goto loser; 1.481 + } 1.482 + 1.483 + /* make sure the hash lens match before we set it */ 1.484 + len = sizeof(DWORD); 1.485 + rc = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashSize, &len, 0); 1.486 + if (!rc) { 1.487 + goto loser; 1.488 + } 1.489 + 1.490 + if (hash.size != hashSize) { 1.491 + /* The input must have been bad for this to happen */ 1.492 + error = CKR_DATA_INVALID; 1.493 + goto loser; 1.494 + } 1.495 + 1.496 + /* we have an explicit hash, set it, note that the length is 1.497 + * implicit by the hashAlg used in create */ 1.498 + rc = CryptSetHashParam(hHash, HP_HASHVAL, hash.data, 0); 1.499 + if (!rc) { 1.500 + goto loser; 1.501 + } 1.502 + 1.503 + /* OK, we have the data in a hash structure, sign it! */ 1.504 + rc = CryptSignHash(hHash, iOperation->keySpec, NULL, 0, 1.505 + output->data, &output->size); 1.506 + if (!rc) { 1.507 + goto loser; 1.508 + } 1.509 + 1.510 + /* Don't return a signature that might have been broken because of a cosmic 1.511 + * ray, or a broken processor, verify that it is valid... */ 1.512 + rc = CryptVerifySignature(hHash, output->data, output->size, 1.513 + iOperation->hKey, NULL, 0); 1.514 + if (!rc) { 1.515 + goto loser; 1.516 + } 1.517 + 1.518 + /* OK, Microsoft likes to do things completely differently than anyone 1.519 + * else. We need to reverse the data we received here */ 1.520 + ckcapi_ReverseData(output); 1.521 + CryptDestroyHash(hHash); 1.522 + return CKR_OK; 1.523 + 1.524 +loser: 1.525 + /* map the microsoft error */ 1.526 + if (CKR_OK == error) { 1.527 + msError = GetLastError(); 1.528 + switch (msError) { 1.529 + case ERROR_NOT_ENOUGH_MEMORY: 1.530 + error = CKR_HOST_MEMORY; 1.531 + break; 1.532 + case NTE_NO_MEMORY: 1.533 + error = CKR_DEVICE_MEMORY; 1.534 + break; 1.535 + case ERROR_MORE_DATA: 1.536 + return CKR_BUFFER_TOO_SMALL; 1.537 + case ERROR_INVALID_PARAMETER: /* these params were derived from the */ 1.538 + case ERROR_INVALID_HANDLE: /* inputs, so if they are bad, the input */ 1.539 + case NTE_BAD_ALGID: /* data is bad */ 1.540 + case NTE_BAD_HASH: 1.541 + error = CKR_DATA_INVALID; 1.542 + break; 1.543 + case ERROR_BUSY: 1.544 + case NTE_FAIL: 1.545 + case NTE_BAD_UID: 1.546 + error = CKR_DEVICE_ERROR; 1.547 + break; 1.548 + default: 1.549 + error = CKR_GENERAL_ERROR; 1.550 + break; 1.551 + } 1.552 + } 1.553 + if (hHash) { 1.554 + CryptDestroyHash(hHash); 1.555 + } 1.556 + return error; 1.557 +} 1.558 + 1.559 + 1.560 +NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation 1.561 +ckcapi_mdCryptoOperationRSADecrypt_proto = { 1.562 + NULL, /* etc */ 1.563 + ckcapi_mdCryptoOperationRSAPriv_Destroy, 1.564 + NULL, /* GetFinalLengh - not needed for one shot Decrypt/Encrypt */ 1.565 + ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength, 1.566 + NULL, /* Final - not needed for one shot operation */ 1.567 + NULL, /* Update - not needed for one shot operation */ 1.568 + NULL, /* DigetUpdate - not needed for one shot operation */ 1.569 + ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal, 1.570 + NULL, /* UpdateCombo - not needed for one shot operation */ 1.571 + NULL, /* DigetKey - not needed for one shot operation */ 1.572 + (void *)NULL /* null terminator */ 1.573 +}; 1.574 + 1.575 +NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation 1.576 +ckcapi_mdCryptoOperationRSASign_proto = { 1.577 + NULL, /* etc */ 1.578 + ckcapi_mdCryptoOperationRSAPriv_Destroy, 1.579 + ckcapi_mdCryptoOperationRSA_GetFinalLength, 1.580 + NULL, /* GetOperationLengh - not needed for one shot Sign/Verify */ 1.581 + NULL, /* Final - not needed for one shot operation */ 1.582 + NULL, /* Update - not needed for one shot operation */ 1.583 + NULL, /* DigetUpdate - not needed for one shot operation */ 1.584 + ckcapi_mdCryptoOperationRSASign_UpdateFinal, 1.585 + NULL, /* UpdateCombo - not needed for one shot operation */ 1.586 + NULL, /* DigetKey - not needed for one shot operation */ 1.587 + (void *)NULL /* null terminator */ 1.588 +}; 1.589 + 1.590 +/********** NSSCKMDMechansim functions ***********************/ 1.591 +/* 1.592 + * ckcapi_mdMechanismRSA_Destroy 1.593 + */ 1.594 +static void 1.595 +ckcapi_mdMechanismRSA_Destroy 1.596 +( 1.597 + NSSCKMDMechanism *mdMechanism, 1.598 + NSSCKFWMechanism *fwMechanism, 1.599 + NSSCKMDInstance *mdInstance, 1.600 + NSSCKFWInstance *fwInstance 1.601 +) 1.602 +{ 1.603 + nss_ZFreeIf(fwMechanism); 1.604 +} 1.605 + 1.606 +/* 1.607 + * ckcapi_mdMechanismRSA_GetMinKeySize 1.608 + */ 1.609 +static CK_ULONG 1.610 +ckcapi_mdMechanismRSA_GetMinKeySize 1.611 +( 1.612 + NSSCKMDMechanism *mdMechanism, 1.613 + NSSCKFWMechanism *fwMechanism, 1.614 + NSSCKMDToken *mdToken, 1.615 + NSSCKFWToken *fwToken, 1.616 + NSSCKMDInstance *mdInstance, 1.617 + NSSCKFWInstance *fwInstance, 1.618 + CK_RV *pError 1.619 +) 1.620 +{ 1.621 + return 384; 1.622 +} 1.623 + 1.624 +/* 1.625 + * ckcapi_mdMechanismRSA_GetMaxKeySize 1.626 + */ 1.627 +static CK_ULONG 1.628 +ckcapi_mdMechanismRSA_GetMaxKeySize 1.629 +( 1.630 + NSSCKMDMechanism *mdMechanism, 1.631 + NSSCKFWMechanism *fwMechanism, 1.632 + NSSCKMDToken *mdToken, 1.633 + NSSCKFWToken *fwToken, 1.634 + NSSCKMDInstance *mdInstance, 1.635 + NSSCKFWInstance *fwInstance, 1.636 + CK_RV *pError 1.637 +) 1.638 +{ 1.639 + return 16384; 1.640 +} 1.641 + 1.642 +/* 1.643 + * ckcapi_mdMechanismRSA_DecryptInit 1.644 + */ 1.645 +static NSSCKMDCryptoOperation * 1.646 +ckcapi_mdMechanismRSA_DecryptInit 1.647 +( 1.648 + NSSCKMDMechanism *mdMechanism, 1.649 + NSSCKFWMechanism *fwMechanism, 1.650 + CK_MECHANISM *pMechanism, 1.651 + NSSCKMDSession *mdSession, 1.652 + NSSCKFWSession *fwSession, 1.653 + NSSCKMDToken *mdToken, 1.654 + NSSCKFWToken *fwToken, 1.655 + NSSCKMDInstance *mdInstance, 1.656 + NSSCKFWInstance *fwInstance, 1.657 + NSSCKMDObject *mdKey, 1.658 + NSSCKFWObject *fwKey, 1.659 + CK_RV *pError 1.660 +) 1.661 +{ 1.662 + return ckcapi_mdCryptoOperationRSAPriv_Create( 1.663 + &ckcapi_mdCryptoOperationRSADecrypt_proto, 1.664 + mdMechanism, mdKey, pError); 1.665 +} 1.666 + 1.667 +/* 1.668 + * ckcapi_mdMechanismRSA_SignInit 1.669 + */ 1.670 +static NSSCKMDCryptoOperation * 1.671 +ckcapi_mdMechanismRSA_SignInit 1.672 +( 1.673 + NSSCKMDMechanism *mdMechanism, 1.674 + NSSCKFWMechanism *fwMechanism, 1.675 + CK_MECHANISM *pMechanism, 1.676 + NSSCKMDSession *mdSession, 1.677 + NSSCKFWSession *fwSession, 1.678 + NSSCKMDToken *mdToken, 1.679 + NSSCKFWToken *fwToken, 1.680 + NSSCKMDInstance *mdInstance, 1.681 + NSSCKFWInstance *fwInstance, 1.682 + NSSCKMDObject *mdKey, 1.683 + NSSCKFWObject *fwKey, 1.684 + CK_RV *pError 1.685 +) 1.686 +{ 1.687 + return ckcapi_mdCryptoOperationRSAPriv_Create( 1.688 + &ckcapi_mdCryptoOperationRSASign_proto, 1.689 + mdMechanism, mdKey, pError); 1.690 +} 1.691 + 1.692 + 1.693 +NSS_IMPLEMENT_DATA const NSSCKMDMechanism 1.694 +nss_ckcapi_mdMechanismRSA = { 1.695 + (void *)NULL, /* etc */ 1.696 + ckcapi_mdMechanismRSA_Destroy, 1.697 + ckcapi_mdMechanismRSA_GetMinKeySize, 1.698 + ckcapi_mdMechanismRSA_GetMaxKeySize, 1.699 + NULL, /* GetInHardware - default false */ 1.700 + NULL, /* EncryptInit - default errs */ 1.701 + ckcapi_mdMechanismRSA_DecryptInit, 1.702 + NULL, /* DigestInit - default errs*/ 1.703 + ckcapi_mdMechanismRSA_SignInit, 1.704 + NULL, /* VerifyInit - default errs */ 1.705 + ckcapi_mdMechanismRSA_SignInit, /* SignRecoverInit */ 1.706 + NULL, /* VerifyRecoverInit - default errs */ 1.707 + NULL, /* GenerateKey - default errs */ 1.708 + NULL, /* GenerateKeyPair - default errs */ 1.709 + NULL, /* GetWrapKeyLength - default errs */ 1.710 + NULL, /* WrapKey - default errs */ 1.711 + NULL, /* UnwrapKey - default errs */ 1.712 + NULL, /* DeriveKey - default errs */ 1.713 + (void *)NULL /* null terminator */ 1.714 +};