Example #1
0
int EVP_PKEY_set_std_dp(EVP_PKEY *key, int stnd_dp) {

    DH *dh = NULL;
    EC_KEY *ec = NULL;

    if (!key) {
        log_err("Invalid arguments");
        return 0;
    }

    /* Generate key from standardized domain parameters */
    switch(stnd_dp) {
        case 0:
        case 1:
        case 2:
            if (!init_dh(&dh, stnd_dp))
                return 0;
            EVP_PKEY_set1_DH(key, dh);
            /* Decrement reference count */
            DH_free(dh);
            break;

        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
        case 14:
        case 15:
        case 16:
        case 17:
        case 18:
            if (!init_ecdh(&ec, stnd_dp))
                return 0;
            EVP_PKEY_set1_EC_KEY(key, ec);
            /* Decrement reference count */
            EC_KEY_free(ec);
            break;

        default:
            log_err("Invalid arguments");
            return 0;
    }

    return 1;
}
Example #2
0
int
EVP_PKEY_set_keys(EVP_PKEY *evp_pkey,
        const unsigned char *privkey, size_t privkey_len,
           const unsigned char *pubkey, size_t pubkey_len,
           BN_CTX *bn_ctx)
{
    EC_KEY *ec_key = NULL;
    DH *dh = NULL;
    EC_POINT *ec_point = NULL;
    BIGNUM *bn = NULL, *dh_pub_key, *dh_priv_key;
    int ok = 0;
    const EC_GROUP *group;

    check(evp_pkey, "Invalid arguments");

    switch (EVP_PKEY_base_id(evp_pkey)) {
        case EVP_PKEY_EC:
            ec_key = EVP_PKEY_get1_EC_KEY(evp_pkey);
            if (!ec_key)
                goto err;
            group = EC_KEY_get0_group(ec_key);

            if (pubkey) {
                ec_point = EC_POINT_new(group);
                if (!ec_point
                        || !EC_POINT_oct2point(group, ec_point, pubkey,
                            pubkey_len, bn_ctx)
                        || !EC_KEY_set_public_key(ec_key, ec_point))
                    goto err;
            }
            if (privkey) {
                bn = BN_bin2bn(privkey, privkey_len, bn);
                if (!bn || !EC_KEY_set_private_key(ec_key, bn))
                    goto err;
            }

            if (!EVP_PKEY_set1_EC_KEY(evp_pkey, ec_key))
                goto err;
            break;

        case EVP_PKEY_DH:
            dh = EVP_PKEY_get1_DH(evp_pkey);
            if (!dh)
                goto err;

            if (pubkey) {
                dh_pub_key = BN_bin2bn(pubkey, pubkey_len, NULL);
                if (!dh_pub_key || !DH_set0_key(dh, dh_pub_key, NULL))
                    goto err;
            }
            if (privkey) {
                dh_priv_key = BN_bin2bn(privkey, privkey_len, NULL);
                if (!dh_priv_key || !DH_set0_key(dh, NULL, dh_priv_key))
                    goto err;
            }

            if (!EVP_PKEY_set1_DH(evp_pkey, dh))
                goto err;
            break;

        default:
            log_err("Unknown type of key");
            goto err;
            break;
    }

    ok = 1;

err:
    if (bn)
        BN_clear_free(bn);
    if (ec_key)
        EC_KEY_free(ec_key);
    if (dh)
        DH_free(dh);
    if (ec_point)
        EC_POINT_clear_free(ec_point);

    return ok;
}
Example #3
0
EVP_PKEY *
EVP_PKEY_dup(EVP_PKEY *key)
{
    EVP_PKEY *out = NULL;
    DH *dh_in = NULL, *dh_out = NULL;
    EC_KEY *ec_in = NULL, *ec_out = NULL;
    RSA *rsa_in = NULL, *rsa_out = NULL;

    check(key, "Invalid arguments");

    out = EVP_PKEY_new();

    if (!out)
        goto err;

    switch (EVP_PKEY_base_id(key)) {
        case EVP_PKEY_DH:
            dh_in = EVP_PKEY_get1_DH(key);
            if (!dh_in)
                goto err;

            dh_out = DHparams_dup_with_q(dh_in);
            if (!dh_out)
                goto err;

            EVP_PKEY_set1_DH(out, dh_out);
            DH_free(dh_out);
            DH_free(dh_in);
            break;

        case EVP_PKEY_EC:
            ec_in = EVP_PKEY_get1_EC_KEY(key);
            if (!ec_in)
                goto err;

            ec_out = EC_KEY_dup(ec_in);
            if (!ec_out)
                goto err;

            EVP_PKEY_set1_EC_KEY(out, ec_out);
            EC_KEY_free(ec_out);
            EC_KEY_free(ec_in);
            break;

        case EVP_PKEY_RSA:
            rsa_in = EVP_PKEY_get1_RSA(key);
            if (!rsa_in)
                goto err;

            rsa_out = RSAPrivateKey_dup(rsa_in);
            if (!rsa_out)
                goto err;

            EVP_PKEY_set1_RSA(out, rsa_out);
            RSA_free(rsa_out);
            RSA_free(rsa_in);
            break;

        default:
            log_err("Unknown protocol");
            goto err;
    }

    return out;

err:
    if (dh_in)
        DH_free(dh_in);
    if (ec_in)
        EC_KEY_free(ec_in);
    if (rsa_in)
        RSA_free(rsa_in);

    return NULL;
}
Example #4
0
File: dh.c Project: KennethL/otp
ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (PrivKey|undefined, DHParams=[P,G], Mpint, Len|0) */
    DH *dh_params = NULL;
    int mpint; /* 0 or 4 */

    {
        ERL_NIF_TERM head, tail;
        BIGNUM
            *dh_p = NULL,
            *dh_g = NULL,
            *priv_key_in = NULL;
        unsigned long
            len = 0;

        if (!(get_bn_from_bin(env, argv[0], &priv_key_in)
              || argv[0] == atom_undefined)
            || !enif_get_list_cell(env, argv[1], &head, &tail)
            || !get_bn_from_bin(env, head, &dh_p)
            || !enif_get_list_cell(env, tail, &head, &tail)
            || !get_bn_from_bin(env, head, &dh_g)
            || !enif_is_empty_list(env, tail)
            || !enif_get_int(env, argv[2], &mpint) || (mpint & ~4)
            || !enif_get_ulong(env, argv[3], &len)

            /* Load dh_params with values to use by the generator.
               Mem mgmnt transfered from dh_p etc to dh_params */
            || !(dh_params = DH_new())
            || (priv_key_in && !DH_set0_key(dh_params, NULL, priv_key_in))
            || !DH_set0_pqg(dh_params, dh_p, NULL, dh_g)
            ) {
            if (priv_key_in) BN_free(priv_key_in);
            if (dh_p) BN_free(dh_p);
            if (dh_g) BN_free(dh_g);
            if (dh_params) DH_free(dh_params);
            return enif_make_badarg(env);
        }

        if (len) {
            if (len < BN_num_bits(dh_p))
                DH_set_length(dh_params, len);
            else {
                if (priv_key_in) BN_free(priv_key_in);
                if (dh_p) BN_free(dh_p);
                if (dh_g) BN_free(dh_g);
                if (dh_params) DH_free(dh_params);
                return enif_make_badarg(env);
            }
        }
    }

#ifdef HAS_EVP_PKEY_CTX
    {
        EVP_PKEY_CTX *ctx;
        EVP_PKEY *dhkey, *params;
        int success;

        params = EVP_PKEY_new();
        success = EVP_PKEY_set1_DH(params, dh_params);   /* set the key referenced by params to dh_params... */
        DH_free(dh_params);                              /* ...dh_params (and params) must be freed */
        if (!success) return atom_error;

        ctx = EVP_PKEY_CTX_new(params, NULL);
        EVP_PKEY_free(params);
        if (!ctx) {
            return atom_error;
        }

        if (!EVP_PKEY_keygen_init(ctx)) {
            /* EVP_PKEY_CTX_free(ctx); */
            return atom_error;
        }

        dhkey = EVP_PKEY_new();
        if (!EVP_PKEY_keygen(ctx, &dhkey)) {         /* "performs a key generation operation, the ... */
                                                     /*... generated key is written to ppkey." (=last arg) */
             /* EVP_PKEY_CTX_free(ctx); */
             /* EVP_PKEY_free(dhkey); */
             return atom_error;
        }

        dh_params = EVP_PKEY_get1_DH(dhkey); /* return the referenced key. dh_params and dhkey must be freed */
        EVP_PKEY_free(dhkey);
        if (!dh_params) {
            /* EVP_PKEY_CTX_free(ctx); */
            return atom_error;
        }
        EVP_PKEY_CTX_free(ctx);
    }
#else
    if (!DH_generate_key(dh_params)) return atom_error;
#endif
    {
        unsigned char *pub_ptr, *prv_ptr;
        int pub_len, prv_len;
        ERL_NIF_TERM ret_pub, ret_prv;
        const BIGNUM *pub_key_gen, *priv_key_gen;

        DH_get0_key(dh_params,
                    &pub_key_gen, &priv_key_gen); /* Get pub_key_gen and priv_key_gen.
                                                     "The values point to the internal representation of
                                                     the public key and private key values. This memory
                                                     should not be freed directly." says man */
        pub_len = BN_num_bytes(pub_key_gen);
        prv_len = BN_num_bytes(priv_key_gen);
        pub_ptr = enif_make_new_binary(env, pub_len+mpint, &ret_pub);
        prv_ptr = enif_make_new_binary(env, prv_len+mpint, &ret_prv);
        if (mpint) {
            put_int32(pub_ptr, pub_len); pub_ptr += 4;
            put_int32(prv_ptr, prv_len); prv_ptr += 4;
        }
        BN_bn2bin(pub_key_gen, pub_ptr);
        BN_bn2bin(priv_key_gen, prv_ptr);
        ERL_VALGRIND_MAKE_MEM_DEFINED(pub_ptr, pub_len);
        ERL_VALGRIND_MAKE_MEM_DEFINED(prv_ptr, prv_len);

        DH_free(dh_params);

        return enif_make_tuple2(env, ret_pub, ret_prv);
    }
}
Example #5
0
int
dh_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, *bn_h = NULL, *bn_g = NULL;
    DH *static_key = NULL, *ephemeral_key = NULL;

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

    BN_CTX_start(bn_ctx);

    static_key = EVP_PKEY_get1_DH(ctx->static_key);
    if (!static_key)
        goto err;

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

    /* complete the DH and convert the result to a BIGNUM */
    mem_h = dh_compute_key(ctx->static_key, in, bn_ctx);
    if (!mem_h)
        goto err;
    bn_h = BN_bin2bn((unsigned char *) mem_h->data, mem_h->length, bn_h);
    if (!bn_h)
        goto err;

    /* Initialize ephemeral parameters with parameters from the static key */
    ephemeral_key = DHparams_dup_with_q(static_key);
    if (!ephemeral_key)
        goto err;

    /* map to new generator */
    bn_g = BN_CTX_get(bn_ctx);
    if (!bn_g ||
        /* bn_g = g^s mod p */
        !BN_mod_exp(bn_g, static_key->g, bn_s, static_key->p, bn_ctx) ||
        /* ephemeral_key->g = bn_g * h mod p = g^s * h mod p */
        !BN_mod_mul(ephemeral_key->g, bn_g, bn_h, static_key->p, bn_ctx))
        goto err;

    /* Copy ephemeral key to context structure */
    if (!EVP_PKEY_set1_DH(ctx->ka_ctx->key, ephemeral_key))
        goto err;

    ret = 1;

err:
    if (mem_h) {
        OPENSSL_cleanse(mem_h->data, mem_h->max);
        BUF_MEM_free(mem_h);
    }
    if (bn_h)
        BN_clear_free(bn_h);
    if (bn_s)
        BN_clear_free(bn_s);
    /* Decrement reference count, keys are still available via PACE_CTX */
    if (static_key)
        DH_free(static_key);
    if (ephemeral_key)
        DH_free(ephemeral_key);
    BN_CTX_end(bn_ctx);

    return ret;
}
Example #6
0
int
dh_im_compute_key(PACE_CTX * ctx, const BUF_MEM * s, const BUF_MEM * in,
        BN_CTX *bn_ctx)
{
    int ret = 0;
    BUF_MEM * x_mem = NULL;
    BIGNUM * x_bn = NULL, *a = NULL, *p_1 = NULL, *q = NULL;
    DH *static_key = NULL, *ephemeral_key = NULL;

    check((ctx && in && ctx->ka_ctx), "Invalid arguments");
    if (in->length < (size_t) EVP_CIPHER_key_length(ctx->ka_ctx->cipher)
            || !ctx->static_key)
        goto err;

    BN_CTX_start(bn_ctx);

    static_key = EVP_PKEY_get1_DH(ctx->static_key);
    if (!static_key)
        goto err;

    /* Initialize ephemeral parameters with parameters from the static key */
    ephemeral_key = DHparams_dup_with_q(static_key);
    if (!ephemeral_key)
        goto err;

    /* Perform the actual mapping */
    x_mem = cipher_no_pad(ctx->ka_ctx, NULL, in, s, 1);
    if (!x_mem)
        goto err;
    x_bn = BN_bin2bn((unsigned char *) x_mem->data, x_mem->length, x_bn);
    a = BN_CTX_get(bn_ctx);
    q = DH_get_q(static_key, bn_ctx);
    p_1 = BN_dup(static_key->p);
    if (!x_bn || !a || !q || !p_1 ||
            /* p_1 = p-1 */
            !BN_sub_word(p_1, 1) ||
            /* a = p-1 / q */
            !BN_div(a, NULL, p_1, q, bn_ctx) ||
            /* g~ = x^a mod p */
            !BN_mod_exp(ephemeral_key->g, x_bn, a, static_key->p, bn_ctx))
        goto err;

    /* check if g~ != 1 */
    check((!BN_is_one(ephemeral_key->g)), "Bad DH generator");

    /* Copy ephemeral key to context structure */
    if (!EVP_PKEY_set1_DH(ctx->ka_ctx->key, ephemeral_key))
        goto err;

    ret = 1;

err:
    if (q)
        BN_clear_free(q);
    if (p_1)
        BN_clear_free(p_1);
    if (x_bn)
        BN_clear_free(x_bn);
    if (x_mem)
        BUF_MEM_free(x_mem);
    /* Decrement reference count, keys are still available via PACE_CTX */
    if (static_key)
        DH_free(static_key);
    if (ephemeral_key)
        DH_free(ephemeral_key);
    BN_CTX_end(bn_ctx);

    return ret;
}