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;
}
Exemple #2
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;
}