/* Compute an DH shared secret between private_key and public_key. Return
   the result in computed_key and the
   length of the result in bytes in *computed_key_len.  Return 0 iff
   successful. */
int ccdh_compute_key(ccdh_full_ctx_t private_key, ccdh_pub_ctx_t public_key,
                     cc_unit *r) {
    int result = CCDH_ERROR_DEFAULT;
    ccdh_const_gp_t gp = ccdh_ctx_gp(private_key);
    cc_size n=ccdh_gp_n(gp);

    /* Validated the public key */
    result = ccdh_check_pub(gp,public_key);
    if(result!=0)
    {
        goto errOut;
    }

    /* Actual compuation */
    cczp_power(gp.zp, r, ccdh_ctx_y(public_key), ccdh_ctx_x(private_key));

    /* Result can't be 0 (computation issue) or 1 (y in the group) */
    result = CCDH_INVALID_INPUT;
    if (!(ccn_is_zero_or_one(n,r)))
    {
        result = 0;
    }

errOut:
    return result;
}
Exemple #2
0
void SecDHDestroy(SecDHContext dh) {
	/* Zero out key material. */
    ccdh_gp_t gp = SecDH_gp(dh);
    cc_size p_len = ccn_sizeof_n(ccdh_gp_n(gp));
    size_t context_size = SecDH_context_size(p_len);

    bzero(dh, context_size);
    free(dh);
}
Exemple #3
0
OSStatus SecDHGenerateKeypair(SecDHContext dh, uint8_t *pub_key,
	size_t *pub_key_len)
{
    int result;
    ccdh_gp_t gp = SecDH_gp(dh);
    ccdh_full_ctx_t priv = SecDH_priv(dh);

    if((result = ccdh_generate_key(gp, &dhrng, priv)))
        return result;

    /* output y as a big endian byte buffer */
    size_t ylen = ccn_write_uint_size(ccdh_gp_n(gp), ccdh_ctx_y(priv));
    if(*pub_key_len < ylen)
       return errSecBufferTooSmall;
    ccn_write_uint(ccdh_gp_n(gp),ccdh_ctx_y(priv), ylen, pub_key);
    *pub_key_len = ylen;

    return errSecSuccess;
}
int ccdh_import_priv(ccdh_const_gp_t gp, size_t in_len, const uint8_t *in,
                     ccdh_full_ctx_t key)
{
    const cc_unit *g = ccdh_gp_g(gp);
    ccdh_ctx_init(gp, key);
    cc_unit *x = ccdh_ctx_x(key);
    cc_unit *y = ccdh_ctx_y(key);

    if ((ccn_read_uint(ccdh_gp_n(gp), x, in_len, in)))
        return CCDH_INVALID_INPUT;
    
    if (ccn_cmp(ccdh_gp_n(gp), x, cczp_prime(gp.zp)) >= 0)
        return CCDH_SAFETY_CHECK;
    
    /* Generate the public key: y=g^x mod p */
    cczp_power(gp.zp, y, g, x);
    
    return 0;
}
Exemple #5
0
OSStatus SecDHComputeKey(SecDHContext dh,
	const uint8_t *pub_key, size_t pub_key_len,
    uint8_t *computed_key, size_t *computed_key_len)
{
    ccdh_gp_t gp = SecDH_gp(dh);
    ccdh_full_ctx_t priv = SecDH_priv(dh);
    ccdh_pub_ctx_decl_gp(gp, pub);
    cc_size n = ccdh_gp_n(gp);
    cc_unit r[n];

    if(ccdh_import_pub(gp, pub_key_len, pub_key, pub))
        return errSecInvalidKey;

    if(ccdh_compute_key(priv, pub, r))
        return errSecInvalidKey;

    ccn_write_uint(n, r, *computed_key_len, computed_key);
    size_t out_size = ccn_write_uint_size(n, r);
    if(out_size < *computed_key_len)
        *computed_key_len=out_size;

    return errSecSuccess;
}