int ccec_get_fullkey_components(ccec_full_ctx_t key, size_t *nbits, uint8_t *x, size_t *xsize, uint8_t *y, size_t *ysize, uint8_t *d, size_t *dsize) { cc_size n = ccec_ctx_n(key); size_t len; if(ccec_get_pubkey_components(key, nbits, x, xsize, y, ysize)) return -1; if((len = ccn_write_uint_size(n, ccec_ctx_k(key))) > *dsize) return -1; *dsize = len; ccn_write_uint(n, ccec_ctx_k(key), *dsize, d); return 0; }
int ccec_make_priv(size_t nbits, size_t xlength, uint8_t *x, size_t ylength, uint8_t *y, size_t klength, uint8_t *k, ccec_full_ctx_t key) { int result; ccec_const_cp_t cp = ccec_get_cp(nbits); ccec_ctx_init(cp, key); if ((result = ccn_read_uint(ccec_cp_n(cp), ccec_ctx_x(key), xlength, x))) goto errOut; if ((result = ccn_read_uint(ccec_cp_n(cp), ccec_ctx_y(key), ylength, y))) goto errOut; if ((result = ccn_read_uint(ccec_cp_n(cp), ccec_ctx_k(key), klength, k))) goto errOut; ccn_seti(ccec_cp_n(cp), ccec_ctx_z(key), 1); errOut: return result; }
int ccec_generate_key_internal_fips(ccec_const_cp_t cp, struct ccrng_state *rng, ccec_full_ctx_t key) { int result=CCEC_GENERATE_KEY_DEFAULT_ERR; /* Get base point G in projected form. */ ccec_point_decl_cp(cp, base); cczp_const_t zq = ccec_cp_zq(cp); cc_require((result=ccec_projectify(cp, base, ccec_cp_g(cp),rng))==0,errOut); /* Generate a random private key k. */ ccec_ctx_init(cp, key); cc_unit *k = ccec_ctx_k(key); cc_unit *q_minus_2 = ccec_ctx_x(key); // used as temp buffer int cmp_result=1; /* Need to test candidate against q-2 */ ccn_sub1(ccec_cp_n(cp), q_minus_2, cczp_prime(zq), 2); size_t i; /* Generate adequate random for private key */ for (i = 0; i < MAX_RETRY && cmp_result>0; i++) { /* Random bits */ cc_require(((result = ccn_random_bits(ccec_cp_order_bitlen(cp), k, rng)) == 0),errOut); /* If k <= q-2, the number is valid */ cmp_result=ccn_cmp(ccec_cp_n(cp), k, q_minus_2); } if (i >= MAX_RETRY) { result=CCEC_GENERATE_KEY_TOO_MANY_TRIES; } else { cc_assert(cmp_result<=0); /* k is now in range [ 0, q-2 ] ==> +1 for range [ 1, q-1 ] */ ccn_add1(ccec_cp_n(cp), k, k, 1); /* Calculate the public key for k. */ cc_require_action(ccec_mult(cp, ccec_ctx_point(key), k, base,rng) == 0 ,errOut, result=CCEC_GENERATE_KEY_MULT_FAIL); cc_require_action(ccec_is_point_projective(cp, ccec_ctx_point(key)),errOut, result=CCEC_GENERATE_NOT_ON_CURVE); cc_require_action(ccec_affinify(cp, ccec_ctx_point(key), ccec_ctx_point(key)) == 0,errOut, result=CCEC_GENERATE_KEY_AFF_FAIL); ccn_seti(ccec_cp_n(cp), ccec_ctx_z(key), 1); result=0; } errOut: return result; }
static CFDataRef SecECPPrivateKeyExport(CFAllocatorRef allocator, ccec_full_ctx_t fullkey) { size_t prime_size = ccec_cp_prime_size(ccec_ctx_cp(fullkey)); size_t key_size = ccec_export_pub_size(fullkey) + prime_size; CFMutableDataRef blob = CFDataCreateMutable(allocator, key_size); if (blob) { CFDataSetLength(blob, key_size); ccec_export_pub(fullkey, CFDataGetMutableBytePtr(blob)); UInt8 *dest = CFDataGetMutableBytePtr(blob) + ccec_export_pub_size(fullkey); const cc_unit *k = ccec_ctx_k(fullkey); ccn_write_uint_padded(ccec_ctx_n(fullkey), k, prime_size, dest); } return blob; }
static OSStatus SecECPrivateKeyInit(SecKeyRef key, const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) { ccec_full_ctx_t fullkey; fullkey.hdr = key->key; OSStatus err = errSecParam; switch (encoding) { case kSecKeyEncodingPkcs1: { /* TODO: DER import size (and thus cp), pub.x, pub.y and k. */ //err = ecc_import(keyData, keyDataLength, fullkey); /* DER != PKCS#1, but we'll go along with it */ ccoid_t oid; size_t n; ccec_const_cp_t cp; require_noerr(ccec_der_import_priv_keytype(keyDataLength, keyData, &oid, &n), abort); cp = ccec_cp_for_oid(oid); if (cp.zp == NULL) { cp = ccec_curve_for_length_lookup(n * 8 /* bytes -> bits */, ccec_cp_192(), ccec_cp_224(), ccec_cp_256(), ccec_cp_384(), ccec_cp_521(), NULL); } require_action(cp.zp != NULL, abort, err = errSecDecode); ccec_ctx_init(cp, fullkey); require_noerr(ccec_der_import_priv(cp, keyDataLength, keyData, fullkey), abort); err = errSecSuccess; break; } case kSecKeyEncodingBytes: { ccec_const_cp_t cp = getCPForPrivateSize(keyDataLength); require(cp.zp != NULL, abort); ccec_ctx_init(cp, fullkey); size_t pubSize = ccec_export_pub_size(fullkey); require(pubSize < (size_t) keyDataLength, abort); require_noerr_action(ccec_import_pub(cp, pubSize, keyData, fullkey), abort, err = errSecDecode); keyData += pubSize; keyDataLength -= pubSize; cc_unit *k = ccec_ctx_k(fullkey); require_noerr_action(ccn_read_uint(ccec_ctx_n(fullkey), k, keyDataLength, keyData), abort, err = errSecDecode); err = errSecSuccess; break; } case kSecGenerateKey: { CFDictionaryRef parameters = (CFDictionaryRef) keyData; CFTypeRef ksize = CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits); CFIndex keyLengthInBits = getIntValue(ksize); ccec_const_cp_t cp = ccec_get_cp(keyLengthInBits); if (!cp.zp) { secwarning("Invalid or missing key size in: %@", parameters); return errSecKeySizeNotAllowed; } if (!ccec_generate_key(cp, ccrng_seckey, fullkey)) err = errSecSuccess; break; } default: break; } abort: return err; }