示例#1
0
文件: rand.c 项目: KennethL/otp
ERL_NIF_TERM rand_uniform_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Lo,Hi) */
    BIGNUM *bn_from = NULL, *bn_to, *bn_rand;
    unsigned char* data;
    unsigned dlen;
    ERL_NIF_TERM ret;

    if (!get_bn_from_mpint(env, argv[0], &bn_from)
	|| !get_bn_from_mpint(env, argv[1], &bn_rand)) {
	if (bn_from) BN_free(bn_from);
	return enif_make_badarg(env);
    }

    bn_to = BN_new();
    BN_sub(bn_to, bn_rand, bn_from);
    BN_pseudo_rand_range(bn_rand, bn_to);
    BN_add(bn_rand, bn_rand, bn_from);
    dlen = BN_num_bytes(bn_rand);
    data = enif_make_new_binary(env, dlen+4, &ret);
    put_int32(data, dlen);
    BN_bn2bin(bn_rand, data+4);
    ERL_VALGRIND_MAKE_MEM_DEFINED(data+4, dlen);
    BN_free(bn_rand);
    BN_free(bn_from);
    BN_free(bn_to);
    return ret;
}
示例#2
0
文件: rand.c 项目: KennethL/otp
ERL_NIF_TERM strong_rand_bytes_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Bytes) */
    unsigned bytes;
    unsigned char* data;
    ERL_NIF_TERM ret;

    if (!enif_get_uint(env, argv[0], &bytes)) {
	return enif_make_badarg(env);
    }
    data = enif_make_new_binary(env, bytes, &ret);
    if ( RAND_bytes(data, bytes) != 1) {
        return atom_false;
    }
    ERL_VALGRIND_MAKE_MEM_DEFINED(data, bytes);
    return ret;
}
示例#3
0
文件: bn.c 项目: HansN/otp
ERL_NIF_TERM bn2term(ErlNifEnv* env, const BIGNUM *bn)
{
    int dlen;
    unsigned char* ptr;
    ERL_NIF_TERM ret;

    if (bn == NULL)
        return atom_undefined;

    dlen = BN_num_bytes(bn);
    if (dlen < 0)
        goto err;
    if ((ptr = enif_make_new_binary(env, (size_t)dlen, &ret)) == NULL)
        goto err;

    BN_bn2bin(bn, ptr);

    ERL_VALGRIND_MAKE_MEM_DEFINED(ptr, dlen);
    return ret;

 err:
    return enif_make_badarg(env);
}
示例#4
0
文件: dh.c 项目: 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);
    }
}