From 8837c1be2ba8a3c123df3f5a87003daa9aac6539 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Mon, 30 Dec 2013 11:54:23 +0100 Subject: [PATCH] crypto: selective support for GF2m curves Newer OpenSSL versions allow to selectively disable GF2m elliptic curves. Selectively enable GF2m curves is support for them is available. --- lib/crypto/c_src/crypto.c | 8 +++++++- lib/crypto/doc/src/crypto.xml | 13 ++++++++++--- lib/crypto/src/crypto_ec_curves.erl | 23 +++++++++++++++++------ lib/ssl/src/tls_v1.erl | 19 +++++++++++++------ 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 49b6f9cc5509..925ad0c09154 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -625,7 +625,7 @@ static void unload(ErlNifEnv* env, void* priv_data) static int algo_hash_cnt; static ERL_NIF_TERM algo_hash[8]; /* increase when extending the list */ static int algo_pubkey_cnt; -static ERL_NIF_TERM algo_pubkey[2]; /* increase when extending the list */ +static ERL_NIF_TERM algo_pubkey[3]; /* increase when extending the list */ static int algo_cipher_cnt; static ERL_NIF_TERM algo_cipher[2]; /* increase when extending the list */ @@ -651,6 +651,9 @@ static void init_algorithms_types(ErlNifEnv* env) algo_pubkey_cnt = 0; #if defined(HAVE_EC) +#if !defined(OPENSSL_NO_EC2M) + algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env,"ec_gf2m"); +#endif algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env,"ecdsa"); algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env,"ecdh"); #endif @@ -2915,6 +2918,8 @@ static EC_KEY* ec_key_new(ErlNifEnv* env, ERL_NIF_TERM curve_arg) /* create the EC_GROUP structure */ group = EC_GROUP_new_curve_GFp(p, a, b, NULL); +#if !defined(OPENSSL_NO_EC2M) + } else if (f_arity == 3 && field[0] == atom_characteristic_two_field) { /* {characteristic_two_field, M, Basis} */ @@ -2973,6 +2978,7 @@ static EC_KEY* ec_key_new(ErlNifEnv* env, ERL_NIF_TERM curve_arg) goto out_err; group = EC_GROUP_new_curve_GF2m(p, a, b, NULL); +#endif } else goto out_err; diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 42c733d243e3..aa60bba96a64 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -120,7 +120,11 @@ brainpoolP160r1| brainpoolP160t1| brainpoolP192r1| brainpoolP192t1| brainpoolP224r1| brainpoolP224t1| brainpoolP256r1| brainpoolP256t1| brainpoolP320r1| brainpoolP320t1| brainpoolP384r1| brainpoolP384t1| brainpoolP512r1| brainpoolP512t1 -

+ + Note that the sect curves are GF2m (characteristic two) curves and are only supported if the + underlying OpenSSL has support for them. + See also crypto:supports/0 +

stream_cipher() = rc4 | aes_ctr

@@ -149,8 +153,11 @@

cipher_algorithms() = des_cbc | des_cfb | des3_cbc | des3_cbf | des_ede3 | blowfish_cbc | blowfish_cfb64 | aes_cbc128 | aes_cfb128| aes_cbc256 | aes_ige256 | rc2_cbc | aes_ctr| rc4

-

public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh

- +

public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh | ec_gf2m + Note that ec_gf2m is not strictly a public key algorithm, but a restriction on what curves are supported + with ecdsa and ecdh. +

+ diff --git a/lib/crypto/src/crypto_ec_curves.erl b/lib/crypto/src/crypto_ec_curves.erl index 8bd1f21edd2c..fe17643d963c 100644 --- a/lib/crypto/src/crypto_ec_curves.erl +++ b/lib/crypto/src/crypto_ec_curves.erl @@ -3,19 +3,30 @@ -export([curve/1, curves/0]). curves() -> + CryptoSupport = crypto:supports(), + HasGF2m = proplists:get_bool(ec_gf2m, proplists:get_value(public_keys, CryptoSupport)), + prime_curves() ++ characteristic_two_curves(HasGF2m). + + +prime_curves() -> [secp112r1,secp112r2,secp128r1,secp128r2,secp160k1,secp160r1,secp160r2, secp192r1,secp192k1,secp224k1,secp224r1,secp256k1,secp256r1,secp384r1, secp521r1,prime192v1,prime192v2,prime192v3,prime239v1,prime239v2,prime239v3, - prime256v1,sect113r1,sect113r2,sect131r1,sect131r2,sect163k1,sect163r1, + prime256v1,wtls6,wtls7,wtls8,wtls9,wtls12, + brainpoolP160r1,brainpoolP160t1,brainpoolP192r1,brainpoolP192t1, + brainpoolP224r1,brainpoolP224t1,brainpoolP256r1,brainpoolP256t1, + brainpoolP320r1,brainpoolP320t1,brainpoolP384r1,brainpoolP384t1, + brainpoolP512r1,brainpoolP512t1]. + +characteristic_two_curves(true) -> + [sect113r1,sect113r2,sect131r1,sect131r2,sect163k1,sect163r1, sect163r2,sect193r1,sect193r2,sect233k1,sect233r1,sect239k1,sect283k1, sect283r1,sect409k1,sect409r1,sect571k1,sect571r1,c2pnb163v1,c2pnb163v2, c2pnb163v3,c2pnb176v1,c2tnb191v1,c2tnb191v2,c2tnb191v3,c2pnb208w1,c2tnb239v1, c2tnb239v2,c2tnb239v3,c2pnb272w1,c2pnb304w1,c2tnb359v1,c2pnb368w1,c2tnb431r1, - wtls1,wtls3,wtls4,wtls5,wtls6,wtls7,wtls8,wtls9,wtls10,wtls11,wtls12,ipsec3, - ipsec4,brainpoolP160r1,brainpoolP160t1,brainpoolP192r1,brainpoolP192t1, - brainpoolP224r1,brainpoolP224t1,brainpoolP256r1,brainpoolP256t1, - brainpoolP320r1,brainpoolP320t1,brainpoolP384r1,brainpoolP384t1, - brainpoolP512r1,brainpoolP512t1]. + wtls1,wtls3,wtls4,wtls5,wtls10,wtls11,ipsec3,ipsec4]; +characteristic_two_curves(_) -> + []. curve(secp112r1) -> { diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl index b618675ccea2..7c7fdd64c38f 100644 --- a/lib/ssl/src/tls_v1.erl +++ b/lib/ssl/src/tls_v1.erl @@ -368,12 +368,19 @@ finished_label(server) -> %% list ECC curves in prefered order ecc_curves(_Minor) -> - [?sect571r1,?sect571k1,?secp521r1,?brainpoolP512r1, - ?sect409k1,?sect409r1,?brainpoolP384r1,?secp384r1, - ?sect283k1,?sect283r1,?brainpoolP256r1,?secp256k1,?secp256r1, - ?sect239k1,?sect233k1,?sect233r1,?secp224k1,?secp224r1, - ?sect193r1,?sect193r2,?secp192k1,?secp192r1,?sect163k1, - ?sect163r1,?sect163r2,?secp160k1,?secp160r1,?secp160r2]. + TLSCurves = [sect571r1,sect571k1,secp521r1,brainpoolP512r1, + sect409k1,sect409r1,brainpoolP384r1,secp384r1, + sect283k1,sect283r1,brainpoolP256r1,secp256k1,secp256r1, + sect239k1,sect233k1,sect233r1,secp224k1,secp224r1, + sect193r1,sect193r2,secp192k1,secp192r1,sect163k1, + sect163r1,sect163r2,secp160k1,secp160r1,secp160r2], + CryptoCurves = crypto:ec_curves(), + lists:foldr(fun(Curve, Curves) -> + case proplists:get_bool(Curve, CryptoCurves) of + true -> [pubkey_cert_records:namedCurves(Curve)|Curves]; + false -> Curves + end + end, [], TLSCurves). %% ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) oid_to_enum(?sect163k1) -> 1;