示例#1
0
static ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
{
    ECDH_DATA *ret;

    ret = OPENSSL_malloc(sizeof(*ret));
    if (ret == NULL) {
        ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
        return (NULL);
    }

    ret->init = NULL;

    ret->meth = ECDH_get_default_method();
    ret->engine = engine;
#ifndef OPENSSL_NO_ENGINE
    if (!ret->engine)
        ret->engine = ENGINE_get_default_ECDH();
    if (ret->engine) {
        ret->meth = ENGINE_get_ECDH(ret->engine);
        if (!ret->meth) {
            ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_ENGINE_LIB);
            ENGINE_finish(ret->engine);
            OPENSSL_free(ret);
            return NULL;
        }
    }
#endif

    ret->flags = ret->meth->flags;
    CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data);
    return (ret);
}
示例#2
0
ECDH_DATA *ecdh_check(EC_KEY *key)
{
    ECDH_DATA *ecdh_data;

    void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup,
                                            ecdh_data_free, ecdh_data_free);
    if (data == NULL) {
        ecdh_data = (ECDH_DATA *)ecdh_data_new();
        if (ecdh_data == NULL)
            return NULL;
        data = EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
                                             ecdh_data_dup, ecdh_data_free,
                                             ecdh_data_free);
        if (data != NULL) {
            /*
             * Another thread raced us to install the key_method data and
             * won.
             */
            ecdh_data_free(ecdh_data);
            ecdh_data = (ECDH_DATA *)data;
        }
    } else
        ecdh_data = (ECDH_DATA *)data;
#ifdef OPENSSL_FIPS
    if (FIPS_mode() && !(ecdh_data->flags & ECDH_FLAG_FIPS_METHOD)
        && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) {
        ECDHerr(ECDH_F_ECDH_CHECK, ECDH_R_NON_FIPS_METHOD);
        return NULL;
    }
#endif

    return ecdh_data;
}
示例#3
0
/* This implementation is based on the following primitives in the IEEE 1363 standard:
 *  - ECKAS-DH1
 *  - ECSVDP-DH
 * Finally an optional KDF is applied.
 */
static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
	EC_KEY *ecdh,
	void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
	{
	BN_CTX *ctx;
	EC_POINT *tmp=NULL;
	BIGNUM *x=NULL, *y=NULL;
	const BIGNUM *priv_key;
	const EC_GROUP* group;
	int ret= -1;
	size_t buflen, len;
	unsigned char *buf=NULL;

	if (outlen > INT_MAX)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); /* sort of, anyway */
		return -1;
		}

	if ((ctx = BN_CTX_new()) == NULL) goto err;
	BN_CTX_start(ctx);
	x = BN_CTX_get(ctx);
	y = BN_CTX_get(ctx);
	
	priv_key = EC_KEY_get0_private_key(ecdh);
	if (priv_key == NULL)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
		goto err;
		}

	group = EC_KEY_get0_group(ecdh);
	if ((tmp=EC_POINT_new(group)) == NULL)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) 
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
		goto err;
		}
		
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 
		{
		if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) 
			{
			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
			goto err;
			}
		}
#ifndef OPENSSL_NO_EC2M
	else
		{
		if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) 
			{
			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
			goto err;
			}
		}
#endif

	buflen = (EC_GROUP_get_degree(group) + 7)/8;
	len = BN_num_bytes(x);
	if (len > buflen)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_INTERNAL_ERROR);
		goto err;
		}
	if ((buf = malloc(buflen)) == NULL)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	
	memset(buf, 0, buflen - len);
	if (len != (size_t)BN_bn2bin(x, buf + buflen - len))
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
		goto err;
		}

	if (KDF != 0)
		{
		if (KDF(buf, buflen, out, &outlen) == NULL)
			{
			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_KDF_FAILED);
			goto err;
			}
		ret = outlen;
		}
	else
		{
		/* no KDF, just copy as much as we can */
		if (outlen > buflen)
			outlen = buflen;
		memcpy(out, buf, outlen);
		ret = outlen;
		}
	
err:
	EC_POINT_free(tmp);
	if (ctx)
		BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	free(buf);
	return(ret);
	}