1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/ckfw/nssmkey/mrsa.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,510 @@ 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 "ckmk.h" 1.9 + 1.10 +/* Sigh, For all the talk about 'ease of use', apple has hidden the interfaces 1.11 + * needed to be able to truly use CSSM. These came from their modification 1.12 + * to NSS's S/MIME code. The following two functions currently are not 1.13 + * part of the SecKey.h interface. 1.14 + */ 1.15 +OSStatus 1.16 +SecKeyGetCredentials 1.17 +( 1.18 + SecKeyRef keyRef, 1.19 + CSSM_ACL_AUTHORIZATION_TAG authTag, 1.20 + int type, 1.21 + const CSSM_ACCESS_CREDENTIALS **creds 1.22 +); 1.23 + 1.24 +/* this function could be implemented using 'SecKeychainItemCopyKeychain' and 1.25 + * 'SecKeychainGetCSPHandle' */ 1.26 +OSStatus 1.27 +SecKeyGetCSPHandle 1.28 +( 1.29 + SecKeyRef keyRef, 1.30 + CSSM_CSP_HANDLE *cspHandle 1.31 +); 1.32 + 1.33 + 1.34 +typedef struct ckmkInternalCryptoOperationRSAPrivStr 1.35 + ckmkInternalCryptoOperationRSAPriv; 1.36 +struct ckmkInternalCryptoOperationRSAPrivStr 1.37 +{ 1.38 + NSSCKMDCryptoOperation mdOperation; 1.39 + NSSCKMDMechanism *mdMechanism; 1.40 + ckmkInternalObject *iKey; 1.41 + NSSItem *buffer; 1.42 + CSSM_CC_HANDLE cssmContext; 1.43 +}; 1.44 + 1.45 +typedef enum { 1.46 + CKMK_DECRYPT, 1.47 + CKMK_SIGN 1.48 +} ckmkRSAOpType; 1.49 + 1.50 +/* 1.51 + * ckmk_mdCryptoOperationRSAPriv_Create 1.52 + */ 1.53 +static NSSCKMDCryptoOperation * 1.54 +ckmk_mdCryptoOperationRSAPriv_Create 1.55 +( 1.56 + const NSSCKMDCryptoOperation *proto, 1.57 + NSSCKMDMechanism *mdMechanism, 1.58 + NSSCKMDObject *mdKey, 1.59 + ckmkRSAOpType type, 1.60 + CK_RV *pError 1.61 +) 1.62 +{ 1.63 + ckmkInternalObject *iKey = (ckmkInternalObject *)mdKey->etc; 1.64 + const NSSItem *classItem = nss_ckmk_FetchAttribute(iKey, CKA_CLASS, pError); 1.65 + const NSSItem *keyType = nss_ckmk_FetchAttribute(iKey, CKA_KEY_TYPE, pError); 1.66 + ckmkInternalCryptoOperationRSAPriv *iOperation; 1.67 + SecKeyRef privateKey; 1.68 + OSStatus macErr; 1.69 + CSSM_RETURN cssmErr; 1.70 + const CSSM_KEY *cssmKey; 1.71 + CSSM_CSP_HANDLE cspHandle; 1.72 + const CSSM_ACCESS_CREDENTIALS *creds = NULL; 1.73 + CSSM_CC_HANDLE cssmContext; 1.74 + CSSM_ACL_AUTHORIZATION_TAG authType; 1.75 + 1.76 + /* make sure we have the right objects */ 1.77 + if (((const NSSItem *)NULL == classItem) || 1.78 + (sizeof(CK_OBJECT_CLASS) != classItem->size) || 1.79 + (CKO_PRIVATE_KEY != *(CK_OBJECT_CLASS *)classItem->data) || 1.80 + ((const NSSItem *)NULL == keyType) || 1.81 + (sizeof(CK_KEY_TYPE) != keyType->size) || 1.82 + (CKK_RSA != *(CK_KEY_TYPE *)keyType->data)) { 1.83 + *pError = CKR_KEY_TYPE_INCONSISTENT; 1.84 + return (NSSCKMDCryptoOperation *)NULL; 1.85 + } 1.86 + 1.87 + privateKey = (SecKeyRef) iKey->u.item.itemRef; 1.88 + macErr = SecKeyGetCSSMKey(privateKey, &cssmKey); 1.89 + if (noErr != macErr) { 1.90 + CKMK_MACERR("Getting CSSM Key", macErr); 1.91 + *pError = CKR_KEY_HANDLE_INVALID; 1.92 + return (NSSCKMDCryptoOperation *)NULL; 1.93 + } 1.94 + macErr = SecKeyGetCSPHandle(privateKey, &cspHandle); 1.95 + if (noErr != macErr) { 1.96 + CKMK_MACERR("Getting CSP for Key", macErr); 1.97 + *pError = CKR_KEY_HANDLE_INVALID; 1.98 + return (NSSCKMDCryptoOperation *)NULL; 1.99 + } 1.100 + switch (type) { 1.101 + case CKMK_DECRYPT: 1.102 + authType = CSSM_ACL_AUTHORIZATION_DECRYPT; 1.103 + break; 1.104 + case CKMK_SIGN: 1.105 + authType = CSSM_ACL_AUTHORIZATION_SIGN; 1.106 + break; 1.107 + default: 1.108 + *pError = CKR_GENERAL_ERROR; 1.109 +#ifdef DEBUG 1.110 + fprintf(stderr,"RSAPriv_Create: bad type = %d\n", type); 1.111 +#endif 1.112 + return (NSSCKMDCryptoOperation *)NULL; 1.113 + } 1.114 + 1.115 + macErr = SecKeyGetCredentials(privateKey, authType, 0, &creds); 1.116 + if (noErr != macErr) { 1.117 + CKMK_MACERR("Getting Credentials for Key", macErr); 1.118 + *pError = CKR_KEY_HANDLE_INVALID; 1.119 + return (NSSCKMDCryptoOperation *)NULL; 1.120 + } 1.121 + 1.122 + switch (type) { 1.123 + case CKMK_DECRYPT: 1.124 + cssmErr = CSSM_CSP_CreateAsymmetricContext(cspHandle, CSSM_ALGID_RSA, 1.125 + creds, cssmKey, CSSM_PADDING_PKCS1, &cssmContext); 1.126 + break; 1.127 + case CKMK_SIGN: 1.128 + cssmErr = CSSM_CSP_CreateSignatureContext(cspHandle, CSSM_ALGID_RSA, 1.129 + creds, cssmKey, &cssmContext); 1.130 + break; 1.131 + default: 1.132 + *pError = CKR_GENERAL_ERROR; 1.133 +#ifdef DEBUG 1.134 + fprintf(stderr,"RSAPriv_Create: bad type = %d\n", type); 1.135 +#endif 1.136 + return (NSSCKMDCryptoOperation *)NULL; 1.137 + } 1.138 + if (noErr != cssmErr) { 1.139 + CKMK_MACERR("Getting Context for Key", cssmErr); 1.140 + *pError = CKR_GENERAL_ERROR; 1.141 + return (NSSCKMDCryptoOperation *)NULL; 1.142 + } 1.143 + 1.144 + iOperation = nss_ZNEW(NULL, ckmkInternalCryptoOperationRSAPriv); 1.145 + if ((ckmkInternalCryptoOperationRSAPriv *)NULL == iOperation) { 1.146 + *pError = CKR_HOST_MEMORY; 1.147 + return (NSSCKMDCryptoOperation *)NULL; 1.148 + } 1.149 + iOperation->mdMechanism = mdMechanism; 1.150 + iOperation->iKey = iKey; 1.151 + iOperation->cssmContext = cssmContext; 1.152 + 1.153 + nsslibc_memcpy(&iOperation->mdOperation, 1.154 + proto, sizeof(NSSCKMDCryptoOperation)); 1.155 + iOperation->mdOperation.etc = iOperation; 1.156 + 1.157 + return &iOperation->mdOperation; 1.158 +} 1.159 + 1.160 +static void 1.161 +ckmk_mdCryptoOperationRSAPriv_Destroy 1.162 +( 1.163 + NSSCKMDCryptoOperation *mdOperation, 1.164 + NSSCKFWCryptoOperation *fwOperation, 1.165 + NSSCKMDInstance *mdInstance, 1.166 + NSSCKFWInstance *fwInstance 1.167 +) 1.168 +{ 1.169 + ckmkInternalCryptoOperationRSAPriv *iOperation = 1.170 + (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc; 1.171 + 1.172 + if (iOperation->buffer) { 1.173 + nssItem_Destroy(iOperation->buffer); 1.174 + } 1.175 + if (iOperation->cssmContext) { 1.176 + CSSM_DeleteContext(iOperation->cssmContext); 1.177 + } 1.178 + nss_ZFreeIf(iOperation); 1.179 + return; 1.180 +} 1.181 + 1.182 +static CK_ULONG 1.183 +ckmk_mdCryptoOperationRSA_GetFinalLength 1.184 +( 1.185 + NSSCKMDCryptoOperation *mdOperation, 1.186 + NSSCKFWCryptoOperation *fwOperation, 1.187 + NSSCKMDSession *mdSession, 1.188 + NSSCKFWSession *fwSession, 1.189 + NSSCKMDToken *mdToken, 1.190 + NSSCKFWToken *fwToken, 1.191 + NSSCKMDInstance *mdInstance, 1.192 + NSSCKFWInstance *fwInstance, 1.193 + CK_RV *pError 1.194 +) 1.195 +{ 1.196 + ckmkInternalCryptoOperationRSAPriv *iOperation = 1.197 + (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc; 1.198 + const NSSItem *modulus = 1.199 + nss_ckmk_FetchAttribute(iOperation->iKey, CKA_MODULUS, pError); 1.200 + 1.201 + return modulus->size; 1.202 +} 1.203 + 1.204 + 1.205 +/* 1.206 + * ckmk_mdCryptoOperationRSADecrypt_GetOperationLength 1.207 + * we won't know the length until we actually decrypt the 1.208 + * input block. Since we go to all the work to decrypt the 1.209 + * the block, we'll save if for when the block is asked for 1.210 + */ 1.211 +static CK_ULONG 1.212 +ckmk_mdCryptoOperationRSADecrypt_GetOperationLength 1.213 +( 1.214 + NSSCKMDCryptoOperation *mdOperation, 1.215 + NSSCKFWCryptoOperation *fwOperation, 1.216 + NSSCKMDSession *mdSession, 1.217 + NSSCKFWSession *fwSession, 1.218 + NSSCKMDToken *mdToken, 1.219 + NSSCKFWToken *fwToken, 1.220 + NSSCKMDInstance *mdInstance, 1.221 + NSSCKFWInstance *fwInstance, 1.222 + const NSSItem *input, 1.223 + CK_RV *pError 1.224 +) 1.225 +{ 1.226 + ckmkInternalCryptoOperationRSAPriv *iOperation = 1.227 + (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc; 1.228 + CSSM_DATA cssmInput; 1.229 + CSSM_DATA cssmOutput = { 0, NULL }; 1.230 + PRUint32 bytesDecrypted; 1.231 + CSSM_DATA remainder = { 0, NULL }; 1.232 + NSSItem output; 1.233 + CSSM_RETURN cssmErr; 1.234 + 1.235 + if (iOperation->buffer) { 1.236 + return iOperation->buffer->size; 1.237 + } 1.238 + 1.239 + cssmInput.Data = input->data; 1.240 + cssmInput.Length = input->size; 1.241 + 1.242 + cssmErr = CSSM_DecryptData(iOperation->cssmContext, 1.243 + &cssmInput, 1, &cssmOutput, 1, 1.244 + &bytesDecrypted, &remainder); 1.245 + if (CSSM_OK != cssmErr) { 1.246 + CKMK_MACERR("Decrypt Failed", cssmErr); 1.247 + *pError = CKR_DATA_INVALID; 1.248 + return 0; 1.249 + } 1.250 + /* we didn't suppy any buffers, so it should all be in remainder */ 1.251 + output.data = nss_ZNEWARRAY(NULL, char, bytesDecrypted + remainder.Length); 1.252 + if (NULL == output.data) { 1.253 + free(cssmOutput.Data); 1.254 + free(remainder.Data); 1.255 + *pError = CKR_HOST_MEMORY; 1.256 + return 0; 1.257 + } 1.258 + output.size = bytesDecrypted + remainder.Length; 1.259 + 1.260 + if (0 != bytesDecrypted) { 1.261 + nsslibc_memcpy(output.data, cssmOutput.Data, bytesDecrypted); 1.262 + free(cssmOutput.Data); 1.263 + } 1.264 + if (0 != remainder.Length) { 1.265 + nsslibc_memcpy(((char *)output.data)+bytesDecrypted, 1.266 + remainder.Data, remainder.Length); 1.267 + free(remainder.Data); 1.268 + } 1.269 + 1.270 + iOperation->buffer = nssItem_Duplicate(&output, NULL, NULL); 1.271 + nss_ZFreeIf(output.data); 1.272 + if ((NSSItem *) NULL == iOperation->buffer) { 1.273 + *pError = CKR_HOST_MEMORY; 1.274 + return 0; 1.275 + } 1.276 + 1.277 + return iOperation->buffer->size; 1.278 +} 1.279 + 1.280 +/* 1.281 + * ckmk_mdCryptoOperationRSADecrypt_UpdateFinal 1.282 + * 1.283 + * NOTE: ckmk_mdCryptoOperationRSADecrypt_GetOperationLength is presumed to 1.284 + * have been called previously. 1.285 + */ 1.286 +static CK_RV 1.287 +ckmk_mdCryptoOperationRSADecrypt_UpdateFinal 1.288 +( 1.289 + NSSCKMDCryptoOperation *mdOperation, 1.290 + NSSCKFWCryptoOperation *fwOperation, 1.291 + NSSCKMDSession *mdSession, 1.292 + NSSCKFWSession *fwSession, 1.293 + NSSCKMDToken *mdToken, 1.294 + NSSCKFWToken *fwToken, 1.295 + NSSCKMDInstance *mdInstance, 1.296 + NSSCKFWInstance *fwInstance, 1.297 + const NSSItem *input, 1.298 + NSSItem *output 1.299 +) 1.300 +{ 1.301 + ckmkInternalCryptoOperationRSAPriv *iOperation = 1.302 + (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc; 1.303 + NSSItem *buffer = iOperation->buffer; 1.304 + 1.305 + if ((NSSItem *)NULL == buffer) { 1.306 + return CKR_GENERAL_ERROR; 1.307 + } 1.308 + nsslibc_memcpy(output->data, buffer->data, buffer->size); 1.309 + output->size = buffer->size; 1.310 + return CKR_OK; 1.311 +} 1.312 + 1.313 +/* 1.314 + * ckmk_mdCryptoOperationRSASign_UpdateFinal 1.315 + * 1.316 + */ 1.317 +static CK_RV 1.318 +ckmk_mdCryptoOperationRSASign_UpdateFinal 1.319 +( 1.320 + NSSCKMDCryptoOperation *mdOperation, 1.321 + NSSCKFWCryptoOperation *fwOperation, 1.322 + NSSCKMDSession *mdSession, 1.323 + NSSCKFWSession *fwSession, 1.324 + NSSCKMDToken *mdToken, 1.325 + NSSCKFWToken *fwToken, 1.326 + NSSCKMDInstance *mdInstance, 1.327 + NSSCKFWInstance *fwInstance, 1.328 + const NSSItem *input, 1.329 + NSSItem *output 1.330 +) 1.331 +{ 1.332 + ckmkInternalCryptoOperationRSAPriv *iOperation = 1.333 + (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc; 1.334 + CSSM_DATA cssmInput; 1.335 + CSSM_DATA cssmOutput = { 0, NULL }; 1.336 + CSSM_RETURN cssmErr; 1.337 + 1.338 + cssmInput.Data = input->data; 1.339 + cssmInput.Length = input->size; 1.340 + 1.341 + cssmErr = CSSM_SignData(iOperation->cssmContext, &cssmInput, 1, 1.342 + CSSM_ALGID_NONE, &cssmOutput); 1.343 + if (CSSM_OK != cssmErr) { 1.344 + CKMK_MACERR("Signed Failed", cssmErr); 1.345 + return CKR_FUNCTION_FAILED; 1.346 + } 1.347 + if (cssmOutput.Length > output->size) { 1.348 + free(cssmOutput.Data); 1.349 + return CKR_BUFFER_TOO_SMALL; 1.350 + } 1.351 + nsslibc_memcpy(output->data, cssmOutput.Data, cssmOutput.Length); 1.352 + free(cssmOutput.Data); 1.353 + output->size = cssmOutput.Length; 1.354 + 1.355 + return CKR_OK; 1.356 +} 1.357 + 1.358 + 1.359 +NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation 1.360 +ckmk_mdCryptoOperationRSADecrypt_proto = { 1.361 + NULL, /* etc */ 1.362 + ckmk_mdCryptoOperationRSAPriv_Destroy, 1.363 + NULL, /* GetFinalLengh - not needed for one shot Decrypt/Encrypt */ 1.364 + ckmk_mdCryptoOperationRSADecrypt_GetOperationLength, 1.365 + NULL, /* Final - not needed for one shot operation */ 1.366 + NULL, /* Update - not needed for one shot operation */ 1.367 + NULL, /* DigetUpdate - not needed for one shot operation */ 1.368 + ckmk_mdCryptoOperationRSADecrypt_UpdateFinal, 1.369 + NULL, /* UpdateCombo - not needed for one shot operation */ 1.370 + NULL, /* DigetKey - not needed for one shot operation */ 1.371 + (void *)NULL /* null terminator */ 1.372 +}; 1.373 + 1.374 +NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation 1.375 +ckmk_mdCryptoOperationRSASign_proto = { 1.376 + NULL, /* etc */ 1.377 + ckmk_mdCryptoOperationRSAPriv_Destroy, 1.378 + ckmk_mdCryptoOperationRSA_GetFinalLength, 1.379 + NULL, /* GetOperationLengh - not needed for one shot Sign/Verify */ 1.380 + NULL, /* Final - not needed for one shot operation */ 1.381 + NULL, /* Update - not needed for one shot operation */ 1.382 + NULL, /* DigetUpdate - not needed for one shot operation */ 1.383 + ckmk_mdCryptoOperationRSASign_UpdateFinal, 1.384 + NULL, /* UpdateCombo - not needed for one shot operation */ 1.385 + NULL, /* DigetKey - not needed for one shot operation */ 1.386 + (void *)NULL /* null terminator */ 1.387 +}; 1.388 + 1.389 +/********** NSSCKMDMechansim functions ***********************/ 1.390 +/* 1.391 + * ckmk_mdMechanismRSA_Destroy 1.392 + */ 1.393 +static void 1.394 +ckmk_mdMechanismRSA_Destroy 1.395 +( 1.396 + NSSCKMDMechanism *mdMechanism, 1.397 + NSSCKFWMechanism *fwMechanism, 1.398 + NSSCKMDInstance *mdInstance, 1.399 + NSSCKFWInstance *fwInstance 1.400 +) 1.401 +{ 1.402 + nss_ZFreeIf(fwMechanism); 1.403 +} 1.404 + 1.405 +/* 1.406 + * ckmk_mdMechanismRSA_GetMinKeySize 1.407 + */ 1.408 +static CK_ULONG 1.409 +ckmk_mdMechanismRSA_GetMinKeySize 1.410 +( 1.411 + NSSCKMDMechanism *mdMechanism, 1.412 + NSSCKFWMechanism *fwMechanism, 1.413 + NSSCKMDToken *mdToken, 1.414 + NSSCKFWToken *fwToken, 1.415 + NSSCKMDInstance *mdInstance, 1.416 + NSSCKFWInstance *fwInstance, 1.417 + CK_RV *pError 1.418 +) 1.419 +{ 1.420 + return 384; 1.421 +} 1.422 + 1.423 +/* 1.424 + * ckmk_mdMechanismRSA_GetMaxKeySize 1.425 + */ 1.426 +static CK_ULONG 1.427 +ckmk_mdMechanismRSA_GetMaxKeySize 1.428 +( 1.429 + NSSCKMDMechanism *mdMechanism, 1.430 + NSSCKFWMechanism *fwMechanism, 1.431 + NSSCKMDToken *mdToken, 1.432 + NSSCKFWToken *fwToken, 1.433 + NSSCKMDInstance *mdInstance, 1.434 + NSSCKFWInstance *fwInstance, 1.435 + CK_RV *pError 1.436 +) 1.437 +{ 1.438 + return 16384; 1.439 +} 1.440 + 1.441 +/* 1.442 + * ckmk_mdMechanismRSA_DecryptInit 1.443 + */ 1.444 +static NSSCKMDCryptoOperation * 1.445 +ckmk_mdMechanismRSA_DecryptInit 1.446 +( 1.447 + NSSCKMDMechanism *mdMechanism, 1.448 + NSSCKFWMechanism *fwMechanism, 1.449 + CK_MECHANISM *pMechanism, 1.450 + NSSCKMDSession *mdSession, 1.451 + NSSCKFWSession *fwSession, 1.452 + NSSCKMDToken *mdToken, 1.453 + NSSCKFWToken *fwToken, 1.454 + NSSCKMDInstance *mdInstance, 1.455 + NSSCKFWInstance *fwInstance, 1.456 + NSSCKMDObject *mdKey, 1.457 + NSSCKFWObject *fwKey, 1.458 + CK_RV *pError 1.459 +) 1.460 +{ 1.461 + return ckmk_mdCryptoOperationRSAPriv_Create( 1.462 + &ckmk_mdCryptoOperationRSADecrypt_proto, 1.463 + mdMechanism, mdKey, CKMK_DECRYPT, pError); 1.464 +} 1.465 + 1.466 +/* 1.467 + * ckmk_mdMechanismRSA_SignInit 1.468 + */ 1.469 +static NSSCKMDCryptoOperation * 1.470 +ckmk_mdMechanismRSA_SignInit 1.471 +( 1.472 + NSSCKMDMechanism *mdMechanism, 1.473 + NSSCKFWMechanism *fwMechanism, 1.474 + CK_MECHANISM *pMechanism, 1.475 + NSSCKMDSession *mdSession, 1.476 + NSSCKFWSession *fwSession, 1.477 + NSSCKMDToken *mdToken, 1.478 + NSSCKFWToken *fwToken, 1.479 + NSSCKMDInstance *mdInstance, 1.480 + NSSCKFWInstance *fwInstance, 1.481 + NSSCKMDObject *mdKey, 1.482 + NSSCKFWObject *fwKey, 1.483 + CK_RV *pError 1.484 +) 1.485 +{ 1.486 + return ckmk_mdCryptoOperationRSAPriv_Create( 1.487 + &ckmk_mdCryptoOperationRSASign_proto, 1.488 + mdMechanism, mdKey, CKMK_SIGN, pError); 1.489 +} 1.490 + 1.491 + 1.492 +NSS_IMPLEMENT_DATA const NSSCKMDMechanism 1.493 +nss_ckmk_mdMechanismRSA = { 1.494 + (void *)NULL, /* etc */ 1.495 + ckmk_mdMechanismRSA_Destroy, 1.496 + ckmk_mdMechanismRSA_GetMinKeySize, 1.497 + ckmk_mdMechanismRSA_GetMaxKeySize, 1.498 + NULL, /* GetInHardware - default false */ 1.499 + NULL, /* EncryptInit - default errs */ 1.500 + ckmk_mdMechanismRSA_DecryptInit, 1.501 + NULL, /* DigestInit - default errs*/ 1.502 + ckmk_mdMechanismRSA_SignInit, 1.503 + NULL, /* VerifyInit - default errs */ 1.504 + ckmk_mdMechanismRSA_SignInit, /* SignRecoverInit */ 1.505 + NULL, /* VerifyRecoverInit - default errs */ 1.506 + NULL, /* GenerateKey - default errs */ 1.507 + NULL, /* GenerateKeyPair - default errs */ 1.508 + NULL, /* GetWrapKeyLength - default errs */ 1.509 + NULL, /* WrapKey - default errs */ 1.510 + NULL, /* UnwrapKey - default errs */ 1.511 + NULL, /* DeriveKey - default errs */ 1.512 + (void *)NULL /* null terminator */ 1.513 +};