Ejemplo n.º 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);
}
Ejemplo n.º 2
0
int
ecdh_gm_compute_key(PACE_CTX * ctx, const BUF_MEM * s, const BUF_MEM * in,
        BN_CTX *bn_ctx)
{
    int ret = 0;
    BUF_MEM * mem_h = NULL;
    BIGNUM * bn_s = NULL, *order = NULL, *cofactor = NULL;
    EC_POINT * ecp_h = NULL, *ecp_g = NULL;
    const ECDH_METHOD *default_method;
    EC_GROUP *group = NULL;
    EC_KEY *static_key = NULL, *ephemeral_key = NULL;

    BN_CTX_start(bn_ctx);

    check((ctx && ctx->static_key && s && ctx->ka_ctx), "Invalid arguments");

    static_key = EVP_PKEY_get1_EC_KEY(ctx->static_key);
    check(static_key, "could not get key object");

    /* Extract group parameters */
    group = EC_GROUP_dup(EC_KEY_get0_group(static_key));
    order = BN_CTX_get(bn_ctx);
    cofactor = BN_CTX_get(bn_ctx);
    check(group && cofactor, "internal error");
    if (!EC_GROUP_get_order(group, order, bn_ctx)
            || !EC_GROUP_get_cofactor(group, cofactor, bn_ctx))
        goto err;

    /* Convert nonce to BIGNUM */
    bn_s = BN_bin2bn((unsigned char *) s->data, s->length, bn_s);
    if (!bn_s)
        goto err;

    default_method = ECDH_get_default_method();
    ECDH_set_default_method(ECDH_OpenSSL_Point());
    /* complete the ECDH and get the resulting point h */
    mem_h = ecdh_compute_key(ctx->static_key, in, bn_ctx);
    ECDH_set_default_method(default_method);
    ecp_h = EC_POINT_new(group);
    if (!mem_h || !ecp_h || !EC_POINT_oct2point(group, ecp_h,
            (unsigned char *) mem_h->data, mem_h->length, bn_ctx))
        goto err;

    /* map to new generator */
    ecp_g = EC_POINT_new(group);
    /* g' = g*s + h*1 */
    if (!EC_POINT_mul(group, ecp_g, bn_s, ecp_h, BN_value_one(), bn_ctx))
        goto err;

    /* Initialize ephemeral parameters with parameters from the static key */
    ephemeral_key = EC_KEY_dup(static_key);
    if (!ephemeral_key)
        goto err;
    EVP_PKEY_set1_EC_KEY(ctx->ka_ctx->key, ephemeral_key);

    /* configure the new EC_KEY */
    if (!EC_GROUP_set_generator(group, ecp_g, order, cofactor)
            || !EC_GROUP_check(group, bn_ctx)
            || !EC_KEY_set_group(ephemeral_key, group))
        goto err;

    ret = 1;

err:
    if (ecp_g)
        EC_POINT_clear_free(ecp_g);
    if (ecp_h)
        EC_POINT_clear_free(ecp_h);
    if (mem_h)
        BUF_MEM_free(mem_h);
    if (bn_s)
        BN_clear_free(bn_s);
    BN_CTX_end(bn_ctx);
    /* Decrement reference count, keys are still available via PACE_CTX */
    if (static_key)
        EC_KEY_free(static_key);
    if (ephemeral_key)
        EC_KEY_free(ephemeral_key);
    if (group)
        EC_GROUP_clear_free(group);

    return ret;
}