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; }
static ccec_const_cp_t getCPForPrivateSize(CFIndex encoded_length) { size_t keysize = ccec_x963_import_priv_size(encoded_length); if(ccec_keysize_is_supported(keysize)) { return ccec_get_cp(keysize); } ccec_const_cp_t nullCP = { .zp = NULL }; return nullCP; }
static int ECDSA_POST() { // Pair wise consistency test size_t keySize = 256; int iResult = 0; struct ccrng_system_state system_rng; struct ccrng_state *rng = (struct ccrng_state *)&system_rng; ccrng_system_init(&system_rng); ccec_const_cp_t cp = ccec_get_cp(keySize); ccec_full_ctx_decl_cp(cp, full_ec_key); size_t signedDataLen = ccec_sign_max_size(cp); uint8_t signedData[signedDataLen]; cc_zero(signedDataLen, signedData); iResult = ccec_generate_key_fips(cp, rng, full_ec_key); ccec_full_ctx_clear_cp(cp, full_ec_key); ccrng_system_done(&system_rng); return iResult; }
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; }
SecKeyRef SOSUserKeygen(CFDataRef password, CFDataRef parameters, CFErrorRef *error) { size_t saltlen; const uint8_t *salt = NULL; size_t iterations = 0; size_t keysize = 0; const uint8_t *der = CFDataGetBytePtr(parameters); const uint8_t *der_end = der + CFDataGetLength(parameters); der = der_decode_pbkdf2_params(&saltlen, &salt, &iterations, &keysize, der, der_end); if (der == NULL) { SOSCreateErrorWithFormat(kSOSErrorDecodeFailure, NULL, error, NULL, CFSTR("Bad paramter encoding, got: %@"), parameters); return NULL; } if (keysize != 256) { SOSCreateErrorWithFormat(kSOSErrorUnsupported, NULL, error, NULL, CFSTR("Key size not supported, requested %zd."), keysize); return NULL; } if (saltlen < 4) { SOSCreateErrorWithFormat(kSOSErrorUnsupported, NULL, error, NULL, CFSTR("Salt length not supported, requested %zd."), saltlen); return NULL; } if (iterations < ITERATIONMIN) { SOSCreateErrorWithFormat(kSOSErrorUnsupported, NULL, error, NULL, CFSTR("Too few iterations, params suggested %zd."), iterations); return NULL; } const uint8_t *password_bytes = CFDataGetBytePtr(password); size_t password_length = CFDataGetLength(password); const size_t maxbytes = 128; ccec_const_cp_t cp = ccec_get_cp(keysize); struct ccrng_pbkdf2_prng_state pbkdf2_prng; ccec_full_ctx_decl_cp(cp, tmpkey); secnotice("keygen", "Generating key for: iterations %zd, keysize %zd: %@", iterations, keysize, parameters); if (ccrng_pbkdf2_prng_init(&pbkdf2_prng, maxbytes, password_length, password_bytes, saltlen, salt, iterations)) { SOSCreateError(kSOSErrorProcessingFailure, CFSTR("prng init failed"), NULL, error); return NULL; } if (ccec_generate_key(cp, (struct ccrng_state *)&pbkdf2_prng, tmpkey)) { SOSCreateError(kSOSErrorProcessingFailure, CFSTR("Keygen failed"), NULL, error); return NULL; } return ccec2SecKey(tmpkey); }