Skip to content

Commit

Permalink
Merge branch 'RoadRunnr/crypto-ecc-gen-key'
Browse files Browse the repository at this point in the history
OTP-12394

* RoadRunnr/crypto-ecc-gen-key:
  [crypto] enhance generate_key for ECC keys
  • Loading branch information
brucify committed Jan 12, 2015
2 parents f8c523d + 0875354 commit 71b35f7
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 28 deletions.
47 changes: 26 additions & 21 deletions lib/crypto/c_src/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ static ErlNifFunc nif_funcs[] = {
{"bf_ecb_crypt", 3, bf_ecb_crypt},
{"blowfish_ofb64_encrypt", 3, blowfish_ofb64_encrypt},

{"ec_key_generate", 1, ec_key_generate},
{"ec_key_generate", 2, ec_key_generate},
{"ecdsa_sign_nif", 4, ecdsa_sign_nif},
{"ecdsa_verify_nif", 5, ecdsa_verify_nif},
{"ecdh_compute_key_nif", 3, ecdh_compute_key_nif},
Expand Down Expand Up @@ -3714,32 +3714,37 @@ static int get_ec_key(ErlNifEnv* env,
static ERL_NIF_TERM ec_key_generate(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
#if defined(HAVE_EC)
EC_KEY *key = ec_key_new(env, argv[0]);
EC_KEY *key;
const EC_GROUP *group;
const EC_POINT *public_key;
ERL_NIF_TERM priv_key;
ERL_NIF_TERM pub_key = atom_undefined;

CHECK_OSE_CRYPTO();

if (key && EC_KEY_generate_key(key)) {
const EC_GROUP *group;
const EC_POINT *public_key;
ERL_NIF_TERM priv_key;
ERL_NIF_TERM pub_key = atom_undefined;

group = EC_KEY_get0_group(key);
public_key = EC_KEY_get0_public_key(key);
if (!get_ec_key(env, argv[0], argv[1], atom_undefined, &key))
goto badarg;

if (group && public_key) {
pub_key = point2term(env, group, public_key,
EC_KEY_get_conv_form(key));
}
priv_key = bn2term(env, EC_KEY_get0_private_key(key));
EC_KEY_free(key);
return enif_make_tuple2(env, pub_key, priv_key);
if (argv[1] == atom_undefined) {
if (!EC_KEY_generate_key(key))
goto badarg;
}
else {
if (key)
EC_KEY_free(key);
return enif_make_badarg(env);

group = EC_KEY_get0_group(key);
public_key = EC_KEY_get0_public_key(key);

if (group && public_key) {
pub_key = point2term(env, group, public_key,
EC_KEY_get_conv_form(key));
}
priv_key = bn2term(env, EC_KEY_get0_private_key(key));
EC_KEY_free(key);
return enif_make_tuple2(env, pub_key, priv_key);

badarg:
if (key)
EC_KEY_free(key);
return enif_make_badarg(env);
#else
return atom_notsup;
#endif
Expand Down
2 changes: 1 addition & 1 deletion lib/crypto/doc/src/crypto.xml
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@
<v>SrpUserParams = {user, [Generator::binary(), Prime::binary(), Version::atom()]}</v>
<v>SrpHostParams = {host, [Verifier::binary(), Generator::binary(), Prime::binary(), Version::atom()]}</v>
<v>PublicKey = dh_public() | ecdh_public() | srp_public() </v>
<v>PrivKeyIn = undefined | dh_private() | srp_private() </v>
<v>PrivKeyIn = undefined | dh_private() | ecdh_private() | srp_private() </v>
<v>PrivKeyOut = dh_private() | ecdh_private() | srp_private() </v>
</type>
<desc>
Expand Down
7 changes: 3 additions & 4 deletions lib/crypto/src/crypto.erl
Original file line number Diff line number Diff line change
Expand Up @@ -588,9 +588,8 @@ generate_key(srp, {user, [Generator, Prime, Version]}, PrivateArg)
end,
user_srp_gen_key(Private, Generator, Prime);

generate_key(ecdh, Curve, undefined) ->
ec_key_generate(nif_curve_params(Curve)).

generate_key(ecdh, Curve, PrivKey) ->
ec_key_generate(nif_curve_params(Curve), ensure_int_as_bin(PrivKey)).

compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) ->
case dh_compute_key_nif(ensure_int_as_bin(OthersPublicKey),
Expand Down Expand Up @@ -1555,7 +1554,7 @@ dh_compute_key(OthersPublicKey, MyPrivateKey, DHParameters) ->

dh_compute_key_nif(_OthersPublicKey, _MyPrivateKey, _DHParameters) -> ?nif_stub.

ec_key_generate(_Key) -> ?nif_stub.
ec_key_generate(_Curve, _Key) -> ?nif_stub.

ecdh_compute_key_nif(_Others, _Curve, _My) -> ?nif_stub.

Expand Down
40 changes: 38 additions & 2 deletions lib/crypto/test/crypto_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ groups() ->
{dss, [], [sign_verify]},
{ecdsa, [], [sign_verify]},
{dh, [], [generate_compute]},
{ecdh, [], [compute]},
{ecdh, [], [compute, generate]},
{srp, [], [generate_compute]},
{des_cbc, [], [block]},
{des_cfb, [], [block]},
Expand Down Expand Up @@ -243,6 +243,12 @@ compute(Config) when is_list(Config) ->
Gen = proplists:get_value(compute, Config),
lists:foreach(fun do_compute/1, Gen).
%%--------------------------------------------------------------------
generate() ->
[{doc, " Test crypto:generate_key"}].
generate(Config) when is_list(Config) ->
Gen = proplists:get_value(generate, Config),
lists:foreach(fun do_generate/1, Gen).
%%--------------------------------------------------------------------
mod_pow() ->
[{doc, "mod_pow testing (A ^ M % P with bignums)"}].
mod_pow(Config) when is_list(Config) ->
Expand Down Expand Up @@ -494,6 +500,14 @@ do_compute({ecdh = Type, Pub, Priv, Curve, SharedSecret}) ->
ct:fail({{crypto, compute_key, [Type, Pub, Priv, Curve]}, {expected, SharedSecret}, {got, Other}})
end.

do_generate({ecdh = Type, Curve, Priv, Pub}) ->
case crypto:generate_key(Type, Curve, Priv) of
{Pub, _} ->
ok;
{Other, _} ->
ct:fail({{crypto, generate_key, [Type, Priv, Curve]}, {expected, Pub}, {got, Other}})
end.

hexstr2point(X, Y) ->
<<4:8, (hexstr2bin(X))/binary, (hexstr2bin(Y))/binary>>.

Expand Down Expand Up @@ -721,7 +735,8 @@ group_config(srp, Config) ->
[{generate_compute, GenerateCompute} | Config];
group_config(ecdh, Config) ->
Compute = ecdh(),
[{compute, Compute} | Config];
Generate = ecc(),
[{compute, Compute}, {generate, Generate} | Config];
group_config(dh, Config) ->
GenerateCompute = [dh()],
[{generate_compute, GenerateCompute} | Config];
Expand Down Expand Up @@ -1968,6 +1983,27 @@ rsa_oaep() ->
Msg = hexstr2bin("750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"),
{rsa, Public, Private, Msg, rsa_pkcs1_oaep_padding}.

ecc() ->
%% http://point-at-infinity.org/ecc/nisttv
%%
%% Test vectors for the NIST elliptic curves P192, P224, P256, P384, P521,
%% B163, B233, B283, B409, B571, K163, K233, K283, K409 and K571. For more
%% information about the curves see
%% http://csrc.nist.gov/encryption/dss/ecdsa/NISTReCur.pdf
%%
[{ecdh,secp192r1,1,
hexstr2point("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
"07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")},
{ecdh,secp192r1,2,
hexstr2point("DAFEBF5828783F2AD35534631588A3F629A70FB16982A888",
"DD6BDA0D993DA0FA46B27BBC141B868F59331AFA5C7E93AB")},
{ecdh,secp192r1,3,
hexstr2point("76E32A2557599E6EDCD283201FB2B9AADFD0D359CBB263DA",
"782C37E372BA4520AA62E0FED121D49EF3B543660CFD05FD")},
{ecdh,secp192r1,4,
hexstr2point("35433907297CC378B0015703374729D7A4FE46647084E4BA",
"A2649984F2135C301EA3ACB0776CD4F125389B311DB3BE32")}].

no_padding() ->
Public = [_, Mod] = rsa_public(),
Private = rsa_private(),
Expand Down

0 comments on commit 71b35f7

Please sign in to comment.