示例#1
0
CCCryptorStatus
CCRSAGetKeyComponents(CCRSACryptorRef rsaKey, uint8_t *modulus, size_t *modulusLength, uint8_t *exponent, size_t *exponentLength,
                      uint8_t *p, size_t *pLength, uint8_t *q, size_t *qLength)
{
    CCRSACryptor *rsa = rsaKey;
    
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
	switch(rsa->keyType) {
		case ccRSAKeyPublic: {
            if(ccrsa_get_pubkey_components(ccrsa_ctx_public(rsaKey->fk), modulus, modulusLength, exponent, exponentLength)) return kCCParamError;
            break;
        }
            
		case ccRSAKeyPrivate: {
            if(ccrsa_get_fullkey_components(rsaKey->fk, modulus, modulusLength, exponent, exponentLength,
                                             p, pLength, q, qLength)) return kCCParamError;
            break;
        }
            
		default:
			return kCCParamError;
    }
            
    return kCCSuccess;
}
示例#2
0
CCCryptorStatus 
CCRSACryptorVerify(CCRSACryptorRef publicKey, CCAsymmetricPadding padding,
                   const void *hash, size_t hashLen, 
                   CCDigestAlgorithm digestType, size_t saltLen,
                   const void *signedData, size_t signedDataLen)
{
    bool valid;
    
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
    if(!publicKey || !hash || !signedData) return kCCParamError;
    
    switch(padding) {
        case ccPKCS1Padding: 
            if(ccrsa_verify_pkcs1v15(ccrsa_ctx_public(publicKey->fk), CCDigestGetDigestInfo(digestType)->oid,
                                     hashLen, hash, signedDataLen, signedData, &valid) != 0)
                return kCCDecodeError;
            if(!valid) return kCCDecodeError;
            break;
            
        case ccOAEPPadding:
            if(ccrsa_verify_oaep(ccrsa_ctx_public(publicKey->fk),  CCDigestGetDigestInfo(digestType),
                                 hashLen, hash, signedDataLen, signedData, &valid) != 0)
                return kCCDecodeError;
            if(!valid) return kCCDecodeError;
            break;
        case ccX931Padding:
        case ccPKCS1PaddingRaw:
        case ccPaddingNone:
        default:
            return kCCParamError;
            break;
    }
    return kCCSuccess;
}
示例#3
0
CCCryptorStatus 
CCRSACryptorDecrypt(CCRSACryptorRef privateKey, CCAsymmetricPadding padding, const void *cipherText, size_t cipherTextLen,
				 void *plainText, size_t *plainTextLen, const void *tagData, size_t tagDataLen, CCDigestAlgorithm digestType)
{
    CCCryptorStatus retval = kCCSuccess;
    
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
    if(!privateKey || !cipherText || !plainText || !plainTextLen) return kCCParamError;
    
    switch (padding) {
        case ccPKCS1Padding:
            if(ccrsa_decrypt_eme_pkcs1v15(privateKey->fk, plainTextLen, plainText, cipherTextLen, (uint8_t *) cipherText) != 0)
                retval =  kCCDecodeError;
            break;
        case ccOAEPPadding:
            if(ccrsa_decrypt_oaep(privateKey->fk, CCDigestGetDigestInfo(digestType), plainTextLen, plainText, cipherTextLen, (uint8_t *) cipherText,
                                  tagDataLen, tagData) != 0) 
                retval =  kCCDecodeError;
            break;
        default:
            goto errOut;
    }
    
errOut:
    
    return retval;
}
示例#4
0
CCCryptorStatus 
CCRSACryptorSign(CCRSACryptorRef privateKey, CCAsymmetricPadding padding, 
                 const void *hashToSign, size_t hashSignLen,
                 CCDigestAlgorithm digestType, size_t saltLen,
                 void *signedData, size_t *signedDataLen)
{    
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
    if(!privateKey || !hashToSign || !signedData) return kCCParamError;
    
    switch(padding) {
        case ccPKCS1Padding: 
            if(ccrsa_sign_pkcs1v15(privateKey->fk, CCDigestGetDigestInfo(digestType)->oid,
                                   hashSignLen, hashToSign, signedDataLen, signedData) != 0)
                return kCCDecodeError;
            break;
            
        case ccOAEPPadding:           
            if(ccrsa_sign_oaep(privateKey->fk, CCDigestGetDigestInfo(digestType),
                               ccDRBGGetRngState(), hashSignLen, hashToSign, 
                               signedDataLen, signedData) != 0)
                return kCCDecodeError;
            break;
        case ccX931Padding:
        case ccPKCS1PaddingRaw:
        case ccPaddingNone:
        default:
            return kCCParamError;
            break;
    }
    return kCCSuccess;
}
示例#5
0
CCCryptorStatus CCRSACryptorExport(CCRSACryptorRef cryptor, void *out, size_t *outLen)
{
    CCCryptorStatus retval = kCCSuccess;
    size_t bufsiz;
    
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
    if(!cryptor || !out) return kCCParamError;
    switch(cryptor->keyType) {
        case ccRSAKeyPublic:
            bufsiz = ccrsa_export_pub_size(ccrsa_ctx_public(cryptor->fk));
            if(*outLen <= bufsiz) {
                *outLen = bufsiz;
                return kCCBufferTooSmall;
            }
            *outLen = bufsiz;
            if(ccrsa_export_pub(ccrsa_ctx_public(cryptor->fk), bufsiz, out))
                return kCCDecodeError;
            break;
        case ccRSAKeyPrivate:
            bufsiz = ccrsa_export_priv_size(cryptor->fk);
            if(*outLen < bufsiz) {
                *outLen = bufsiz;
                return kCCBufferTooSmall;
            }
            *outLen = bufsiz;
            if(ccrsa_export_priv(cryptor->fk, bufsiz, out))
                return kCCDecodeError;
            break;
        default:
            retval = kCCParamError;
    }
    return retval;
}
示例#6
0
CCCryptorStatus 
CCRSACryptorCrypt(CCRSACryptorRef rsaKey, const void *in, size_t inLen, void *out, size_t *outLen)
{    
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
    if(!rsaKey || !in || !out || !outLen) return kCCParamError;
    
    size_t keysizeBytes = (rsaKey->keySize+7)/8;
    
    if(inLen != keysizeBytes || *outLen < keysizeBytes) return kCCMemoryFailure;
    
    cc_size n = ccrsa_ctx_n(rsaKey->fk);
    cc_unit buf[n];
    ccn_read_uint(n, buf, inLen, in);
    
    switch(rsaKey->keyType) {
        case ccRSAKeyPublic: 
            ccrsa_pub_crypt(ccrsa_ctx_public(rsaKey->fk), buf, buf);
            break;
        case ccRSAKeyPrivate:
            ccrsa_priv_crypt(ccrsa_ctx_private(rsaKey->fk), buf, buf);
            break;
        default:
            return kCCParamError;
    }
    
    *outLen = keysizeBytes;
    ccn_write_uint_padded(n, buf, *outLen, out);
    return kCCSuccess;
}
示例#7
0
CCCryptorStatus
CCRSACryptorCreateFromData( CCRSAKeyType keyType, uint8_t *modulus, size_t modulusLength, 
                            uint8_t *exponent, size_t exponentLength,
                            uint8_t *p, size_t pLength, uint8_t *q, size_t qLength,
                            CCRSACryptorRef *ref)
{
    CCCryptorStatus retval = kCCSuccess;
	CCRSACryptor *rsaKey = NULL;
    size_t n = ccn_nof_size(modulusLength);
    cc_unit m[n];
    
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
    __Require_Action(ccn_read_uint(n, m, modulusLength, modulus) == 0, errOut, retval = kCCParamError);
    size_t nbits = ccn_bitlen(n, m);

    __Require_Action((rsaKey = ccMallocRSACryptor(nbits, keyType)) != NULL, errOut, retval = kCCMemoryFailure);

    __Require_Action(ccn_read_uint(n, ccrsa_ctx_m(rsaKey->fk), modulusLength, modulus) == 0, errOut, retval = kCCParamError);
    __Require_Action(ccn_read_uint(n, ccrsa_ctx_e(rsaKey->fk), exponentLength, exponent) == 0, errOut, retval = kCCParamError);
    cczp_init(ccrsa_ctx_zm(rsaKey->fk));
    rsaKey->keySize = ccn_bitlen(n, ccrsa_ctx_m(rsaKey->fk));

	switch(keyType) {
		case ccRSAKeyPublic:
            rsaKey->keyType = ccRSAKeyPublic;
            break;
		
		case ccRSAKeyPrivate: {
            ccrsa_priv_ctx_t privk = ccrsa_ctx_private(rsaKey->fk);
            size_t psize = ccn_nof_size(pLength);
            size_t qsize = ccn_nof_size(qLength);

            
            CCZP_N(ccrsa_ctx_private_zp(privk)) = psize;
            __Require_Action(ccn_read_uint(psize, CCZP_PRIME(ccrsa_ctx_private_zp(privk)), pLength, p) == 0, errOut, retval = kCCParamError);
            CCZP_N(ccrsa_ctx_private_zq(privk)) = qsize;
            __Require_Action(ccn_read_uint(qsize, CCZP_PRIME(ccrsa_ctx_private_zq(privk)), qLength, q) == 0, errOut, retval = kCCParamError);

            ccrsa_crt_makekey(ccrsa_ctx_zm(rsaKey->fk), ccrsa_ctx_e(rsaKey->fk), ccrsa_ctx_d(rsaKey->fk),
                              ccrsa_ctx_private_zp(privk),
                              ccrsa_ctx_private_dp(privk), ccrsa_ctx_private_qinv(privk),
                              ccrsa_ctx_private_zq(privk), ccrsa_ctx_private_dq(privk));
            
            rsaKey->keyType = ccRSAKeyPrivate;

       		break;
        }
		
		default:
            retval = kCCParamError;
			goto errOut;
	}
	*ref = rsaKey;
	return kCCSuccess;
	
errOut:
	if(rsaKey) ccRSACryptorClear(rsaKey);
	return retval;
}
示例#8
0
int CCRSAGetKeySize(CCRSACryptorRef key)
{
    CCRSACryptor *cryptor = key;
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
    if(key == NULL) return kCCParamError;    
    
    return (int) cryptor->keySize;
}
示例#9
0
CCRSACryptorRef CCRSACryptorGetPublicKeyFromPrivateKey(CCRSACryptorRef privateCryptorRef)
{
    CCRSACryptor *publicCryptor = NULL, *privateCryptor = privateCryptorRef;
    
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
    if((publicCryptor = ccMallocRSACryptor(privateCryptor->keySize, ccRSAKeyPublic)) == NULL)  return NULL;
    ccrsa_init_pub(ccrsa_ctx_public(publicCryptor->fk), ccrsa_ctx_m(privateCryptor->fk), ccrsa_ctx_e(privateCryptor->fk));
    publicCryptor->keyType = ccRSAKeyPublic;
    return publicCryptor;
}
示例#10
0
CCRSAKeyType CCRSAGetKeyType(CCRSACryptorRef key)
{
    CCRSACryptor *cryptor = key;
    CCRSAKeyType retval;

    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
    if(key == NULL) return ccRSABadKey;
    retval = cryptor->keyType;
    if(retval != ccRSAKeyPublic && retval != ccRSAKeyPrivate) return ccRSABadKey;
    return retval;
}
示例#11
0
void CCAESCmac(const void *key,
               const uint8_t *data,
               size_t dataLength,			/* length of data in bytes */
               void *macOut)				/* MAC written here */
{
    uint8_t       X[16],Y[16], M_last[16], padded[16];
    uint8_t       K1[16], K2[16];
    int         flag;
    size_t      n;
    const struct ccmode_ecb *aesmode = getCipherMode(kCCAlgorithmAES128, kCCModeECB, kCCEncrypt).ecb;
    ccecb_ctx_decl(aesmode->size, ctx);

    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");

	// CMacInit
    
    aesmode->init(aesmode, ctx, 16, key);
    aesmode->ecb(ctx, 1, Y, X);
    ccGenAESSubKey(aesmode, ctx, K1, K2);
    
    // CMacUpdates (all in this case)
    
    n = (dataLength+15) / 16;       /* n is number of rounds */
    
    if ( 0 == n ) {
        n = 1;
        flag = 0;
    } else {
        if ( (dataLength%16) == 0 ) flag = 1;
        else  flag = 0;
    }
    
    if ( flag ) { /* last block is complete block */
        xor_128(&data[16*(n-1)],K1,M_last);
    } else {
        ccAESCMacPadding(&data[16*(n-1)],padded,dataLength%16);
        xor_128(padded,K2,M_last);
    }
    
    memset(X, 0, 16);
    for (size_t i=0; i<n-1; i++ ) {
        xor_128(X,&data[16*i],Y); /* Y := Mi (+) X  */
        aesmode->ecb(ctx, 1, Y, X);
    }
    
    // CMacFinal
    
    xor_128(X,M_last,Y);
    aesmode->ecb(ctx, 1, Y, X);
    
    memcpy(macOut, X, 16);
}
示例#12
0
CCCryptorStatus CCRSACryptorImport(const void *keyPackage, size_t keyPackageLen, CCRSACryptorRef *key)
{
    CCRSACryptor *cryptor = NULL;
    CCCryptorStatus retval;
    CCRSAKeyType keyToMake;
    cc_size keyN;
    
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
    if(!keyPackage || !key) return kCCParamError;
    if((keyN = ccrsa_import_priv_n(keyPackageLen, keyPackage)) != 0) keyToMake = ccRSAKeyPrivate;
    else if((keyN = ccrsa_import_pub_n(keyPackageLen, keyPackage)) != 0) keyToMake = ccRSAKeyPublic;
    else return kCCDecodeError;
    
    __Require_Action((cryptor = ccMallocRSACryptor(kCCMaximumRSAKeyBits, keyToMake)) != NULL, errOut, retval = kCCMemoryFailure);
    
    switch(keyToMake) {
        case ccRSAKeyPublic:
            ccrsa_ctx_n(ccrsa_ctx_public(cryptor->fk)) = keyN;
            if(ccrsa_import_pub(ccrsa_ctx_public(cryptor->fk), keyPackageLen, keyPackage)) {
                ccRSACryptorClear(cryptor);
                return kCCDecodeError;
            }
            break;
        case ccRSAKeyPrivate:
            ccrsa_ctx_n(cryptor->fk) = keyN;
            if(ccrsa_import_priv(cryptor->fk, keyPackageLen, keyPackage)) {
                ccRSACryptorClear(cryptor);
                return kCCDecodeError;
            }
            break;
    }
    cryptor->keyType = keyToMake;
    *key = cryptor;
    cryptor->keySize = ccRSAkeysize(cryptor);

    return kCCSuccess;
    
errOut:
    if(cryptor) ccRSACryptorClear(cryptor);
    *key = NULL;
    return retval;
}
示例#13
0
CCCryptorStatus 
CCRSACryptorGeneratePair(size_t keysize, uint32_t e, CCRSACryptorRef *publicKey, CCRSACryptorRef *privateKey)
{
    CCCryptorStatus retval;
    CCRSACryptor *privateCryptor = NULL;
    CCRSACryptor *publicCryptor = NULL;
    struct ccrng_state *theRng1 = ccDRBGGetRngState();
    struct ccrng_state *theRng2 = ccDevRandomGetRngState();
    
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
    // ccrsa_generate_key() requires the exponent as length / pointer to bytes
    cc_unit cc_unit_e = (cc_unit) e;
    
    size_t eSize = ccn_write_int_size(1, &cc_unit_e);
    uint8_t eBytes[eSize];
    ccn_write_int(1, &cc_unit_e, eSize, eBytes);
    
    *publicKey = *privateKey = NULL;
    
    __Require_Action((privateCryptor = ccMallocRSACryptor(keysize, ccRSAKeyPrivate)) != NULL, errOut, retval = kCCMemoryFailure);
        
    // __Require_Action((ccrsa_generate_key(keysize, privateCryptor->rsaKey.full, sizeof(e), &e, theRng) == 0), errOut, retval = kCCDecodeError);
    __Require_Action((ccrsa_generate_931_key(keysize, privateCryptor->fk, eSize, eBytes, theRng1, theRng2) == 0), errOut, retval = kCCDecodeError);
    
    privateCryptor->keyType = ccRSAKeyPrivate;
    
    __Require_Action((publicCryptor = CCRSACryptorGetPublicKeyFromPrivateKey(privateCryptor)) != NULL, errOut, retval = kCCMemoryFailure);
    
    *publicKey = publicCryptor;
    *privateKey = privateCryptor;
    
    __Require_Action(ccRSApairwiseConsistencyCheck(*privateKey, *publicKey) == true, errOut, retval = kCCDecodeError);

    return kCCSuccess;
    
errOut:
    if(privateCryptor) ccRSACryptorClear(privateCryptor);
    if(publicCryptor) ccRSACryptorClear(publicCryptor);
    *publicKey = *privateKey = NULL;
    return retval;
}
uint
CCCalibratePBKDF(CCPBKDFAlgorithm algorithm, size_t passwordLen, size_t saltLen,
				 CCPseudoRandomAlgorithm prf, size_t derivedKeyLen, uint32_t msec)
{
	char        *password;
	uint8_t     *salt;
	uint64_t	startTime, endTime, elapsedTime;
	uint8_t     *derivedKey;
	int         i;
    
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
	if (derivedKeyLen == 0) return -1; // bad parameters
	if (saltLen == 0 || saltLen > CC_MAX_PRF_WORKSPACE) return -1; // out of bounds parameters
	if (passwordLen == 0 ) passwordLen = 1;
	if(algorithm != kCCPBKDF2) return -1;
    
	if((password = malloc(passwordLen)) == NULL) return -1;
	for(i=0; i<passwordLen; i++) password[i] = 'a';
	if((salt = malloc(saltLen)) == NULL) return -1;
	for(i=0; i<saltLen; i++) salt[i] = i%256;
	if((derivedKey = malloc(derivedKeyLen)) == NULL) return -1;
    
    for(elapsedTime = 0, i=0; i < 5 && elapsedTime == 0; i++) {
        startTime = timer();
        if(CCKeyDerivationPBKDF(algorithm, password, passwordLen, salt, saltLen, prf, ROUNDMEASURE, derivedKey, derivedKeyLen)) return -2;
        endTime = timer();
        
        elapsedTime = endTime - startTime;
	}
    
    if(elapsedTime == 0) return 123456; // arbitrary, but something is seriously wrong
    
	free(password);
	free(salt);
	free(derivedKey);
    
	return (msec * ROUNDMEASURE)/elapsedTime;
}
int 
CCKeyDerivationPBKDF( CCPBKDFAlgorithm algorithm, const char *password, size_t passwordLen,
					 const uint8_t *salt, size_t saltLen,
					 CCPseudoRandomAlgorithm prf, uint rounds, 
					 uint8_t *derivedKey, size_t derivedKeyLen)
{
    const struct ccdigest_info *di;

    CC_DEBUG_LOG(ASL_LEVEL_ERR, "PasswordLen %lu SaltLen %lU PRF %d Rounds %u DKLen %lu\n", passwordLen, saltLen, prf, rounds, derivedKeyLen);
    if(algorithm != kCCPBKDF2) return -1;
    switch(prf) {
        case kCCPRFHmacAlgSHA1: di = CCDigestGetDigestInfo(kCCDigestSHA1); break;
        case kCCPRFHmacAlgSHA224: di = CCDigestGetDigestInfo(kCCDigestSHA224); break;
        case kCCPRFHmacAlgSHA256: di = CCDigestGetDigestInfo(kCCDigestSHA256); break;
        case kCCPRFHmacAlgSHA384: di = CCDigestGetDigestInfo(kCCDigestSHA384); break;
        case kCCPRFHmacAlgSHA512: di = CCDigestGetDigestInfo(kCCDigestSHA512); break;
        default: return -1;
    }
    if(!password || !salt || !derivedKey || (derivedKeyLen == 0) || (rounds == 0)) return -1;
    
    ccpbkdf2_hmac(di, passwordLen, password, saltLen, salt, rounds, derivedKeyLen, derivedKey);
    return 0;
}
示例#16
0
void 
CCRSACryptorRelease(CCRSACryptorRef key)
{
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
    ccRSACryptorClear(key);
}
示例#17
0
CCCryptorStatus 
CCRSACryptorCreatePairFromData(uint32_t e, 
    uint8_t *xp1, size_t xp1Length,
    uint8_t *xp2, size_t xp2Length,
    uint8_t *xp, size_t xpLength,
    uint8_t *xq1, size_t xq1Length,
    uint8_t *xq2, size_t xq2Length,
    uint8_t *xq, size_t xqLength,
    CCRSACryptorRef *publicKey, CCRSACryptorRef *privateKey,
    uint8_t *retp, size_t *retpLength,
    uint8_t *retq, size_t *retqLength,
    uint8_t *retm, size_t *retmLength,
    uint8_t *retd, size_t *retdLength)
{
    CCCryptorStatus retval;
    CCRSACryptor *privateCryptor = NULL;
    CCRSACryptor *publicCryptor = NULL;
    cc_unit x_p1[ccn_nof_size(xp1Length)];
    cc_unit x_p2[ccn_nof_size(xp2Length)];
    cc_unit x_p[ccn_nof_size(xpLength)];
    cc_unit x_q1[ccn_nof_size(xq1Length)];
    cc_unit x_q2[ccn_nof_size(xq2Length)];
    cc_unit x_q[ccn_nof_size(xqLength)];
    cc_unit e_value[1];
    size_t nbits = xpLength * 8 + xqLength * 8; // or we'll add this as a parameter.  This appears to be correct for FIPS
    cc_size n = ccn_nof(nbits);
    cc_unit p[n], q[n], m[n], d[n];
    cc_size np, nq, nm, nd;
    
    np = nq = nm = nd = n;
    
    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");
    e_value[0] = (cc_unit) e;

    __Require_Action((privateCryptor = ccMallocRSACryptor(nbits, ccRSAKeyPrivate)) != NULL, errOut, retval = kCCMemoryFailure);

    __Require_Action(ccn_read_uint(ccn_nof_size(xp1Length), x_p1, xp1Length, xp1) == 0, errOut, retval = kCCParamError);
    __Require_Action(ccn_read_uint(ccn_nof_size(xp2Length), x_p2, xp2Length, xp2)== 0, errOut, retval = kCCParamError);
    __Require_Action(ccn_read_uint(ccn_nof_size(xpLength), x_p, xpLength, xp) == 0, errOut, retval = kCCParamError);
    __Require_Action(ccn_read_uint(ccn_nof_size(xq1Length), x_q1, xq1Length, xq1) == 0, errOut, retval = kCCParamError);
    __Require_Action(ccn_read_uint(ccn_nof_size(xq2Length), x_q2, xq2Length, xq2) == 0, errOut, retval = kCCParamError);
    __Require_Action(ccn_read_uint(ccn_nof_size(xqLength), x_q, xqLength, xq) == 0, errOut, retval = kCCParamError);
    
	__Require_Action(ccrsa_make_931_key(nbits, 1, e_value, 
                                        ccn_nof_size(xp1Length), x_p1, ccn_nof_size(xp2Length), x_p2, ccn_nof_size(xpLength), x_p,
                                        ccn_nof_size(xq1Length), x_q1, ccn_nof_size(xq2Length), x_q2, ccn_nof_size(xqLength), x_q,
                                        privateCryptor->fk,
                                        &np, p,
                                        &nq, q,
                                        &nm, m,
                                        &nd, d) == 0, errOut, retval = kCCDecodeError);
    
    privateCryptor->keyType = ccRSAKeyPrivate;
    
    __Require_Action((publicCryptor = CCRSACryptorGetPublicKeyFromPrivateKey(privateCryptor)) != NULL, errOut, retval = kCCMemoryFailure);

    *publicKey = publicCryptor;
    *privateKey = privateCryptor;
    ccn_write_arg(np, p, retp, retpLength);
    ccn_write_arg(nq, q, retq, retqLength);
    ccn_write_arg(nm, m, retm, retmLength);
    ccn_write_arg(nd, d, retd, retdLength);
    
    return kCCSuccess;
    
errOut:
    if(privateCryptor) ccRSACryptorClear(privateCryptor);
    if(publicCryptor) ccRSACryptorClear(publicCryptor);
    // CLEAR the bits
    *publicKey = *privateKey = NULL;
    return retval;

}