From 5ab9a20e2929fe5810c63252b932bd534abb593c Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Fri, 20 Apr 2012 17:19:51 +0200 Subject: crypto: Optimize RSA private key handling by using extra redundant information as part of the key that will speed things up for OpenSSL. Affects rsa_sign, rsa_private_encrypt and rsa_private_decrypt. --- lib/crypto/c_src/crypto.c | 50 +++++++++++++++++++++++++++---------------- lib/crypto/doc/src/crypto.xml | 23 ++++++++++++++++---- lib/crypto/vsn.mk | 2 +- 3 files changed, 52 insertions(+), 23 deletions(-) (limited to 'lib') diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 4dc62421d2..4be593e208 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -1456,10 +1456,37 @@ static ERL_NIF_TERM rc2_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a return ret; } +static int get_rsa_private_key(ErlNifEnv* env, ERL_NIF_TERM key, RSA *rsa) +{ + /* key=[E,N,D]|[E,N,D,P1,P2,E1,E2,C] */ + ERL_NIF_TERM head, tail; + + if (!enif_get_list_cell(env, key, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->e) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->n) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->d) + || (!enif_is_empty_list(env, tail) && + (!enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->p) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->q) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->dmp1) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->dmq1) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->iqmp) + || !enif_is_empty_list(env, tail)))) { + return 0; + } + return 1; +} + static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Type,Data,Key=[E,N,D]) */ +{/* (Type,Data,Key=[E,N,D]|[E,N,D,P1,P2,E1,E2,C]) */ ErlNifBinary data_bin, ret_bin; - ERL_NIF_TERM head, tail; unsigned char hmacbuf[SHA_DIGEST_LENGTH]; unsigned rsa_s_len; RSA *rsa = RSA_new(); @@ -1470,13 +1497,7 @@ static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar else goto badarg; if (!inspect_mpint(env,argv[1],&data_bin) - || !enif_get_list_cell(env, argv[2], &head, &tail) - || !get_bn_from_mpint(env, head, &rsa->e) - || !enif_get_list_cell(env, tail, &head, &tail) - || !get_bn_from_mpint(env, head, &rsa->n) - || !enif_get_list_cell(env, tail, &head, &tail) - || !get_bn_from_mpint(env, head, &rsa->d) - || !enif_is_empty_list(env,tail)) { + || !get_rsa_private_key(env, argv[2], rsa)) { badarg: RSA_free(rsa); return enif_make_badarg(env); @@ -1623,20 +1644,13 @@ static ERL_NIF_TERM rsa_public_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TER } static ERL_NIF_TERM rsa_private_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Data, PublKey=[E,N,D], Padding, IsEncrypt) */ +{/* (Data, Key=[E,N,D]|[E,N,D,P1,P2,E1,E2,C], Padding, IsEncrypt) */ ErlNifBinary data_bin, ret_bin; - ERL_NIF_TERM head, tail; int padding, i; RSA* rsa = RSA_new(); if (!enif_inspect_binary(env, argv[0], &data_bin) - || !enif_get_list_cell(env, argv[1], &head, &tail) - || !get_bn_from_mpint(env, head, &rsa->e) - || !enif_get_list_cell(env, tail, &head, &tail) - || !get_bn_from_mpint(env, head, &rsa->n) - || !enif_get_list_cell(env, tail, &head, &tail) - || !get_bn_from_mpint(env, head, &rsa->d) - || !enif_is_empty_list(env,tail) + || !get_rsa_private_key(env, argv[1], rsa) || !rsa_pad(argv[2], &padding)) { RSA_free(rsa); diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 8cb893cd1c..19db6c9dd4 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -870,10 +870,15 @@ Mpint() = >]]> Sign the data using rsa with the given key. Data = Mpint - Key = [E, N, D] + Key = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] E, N, D = Mpint Where E is the public exponent, N is public modulus and D is the private exponent. + P1, P2, E1, E2, C = Mpint + The longer key format contains redundant information that will make + the calculation faster. P1,P2 are first and second prime factors. + E1,E2 are first and second exponents. C is the CRT coefficient. + Terminology is taken from RFC 3447. DigestType = md5 | sha The default DigestType is sha. Mpint = binary() @@ -943,10 +948,15 @@ Mpint() = >]]> Decrypts ChipherText using the private Key. ChipherText = binary() - PrivateKey = [E, N, D] + PrivateKey = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] E, N, D = Mpint Where E is the public exponent, N is public modulus and D is the private exponent. + P1, P2, E1, E2, C = Mpint + The longer key format contains redundant information that will make + the calculation faster. P1,P2 are first and second prime factors. + E1,E2 are first and second exponents. C is the CRT coefficient. + Terminology is taken from RFC 3447. Padding = rsa_pkcs1_padding | rsa_pkcs1_oaep_padding | rsa_no_padding PlainText = binary() @@ -965,10 +975,15 @@ Mpint() = >]]> Encrypts Msg using the private Key. PlainText = binary() - PrivateKey = [E, N, D] - E, N, D = Mpint + PrivateKey = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] + E, N, D = Mpint Where E is the public exponent, N is public modulus and D is the private exponent. + P1, P2, E1, E2, C = Mpint + The longer key format contains redundant information that will make + the calculation faster. P1,P2 are first and second prime factors. + E1,E2 are first and second exponents. C is the CRT coefficient. + Terminology is taken from RFC 3447. Padding = rsa_pkcs1_padding | rsa_no_padding ChipherText = binary() diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk index 7e82e47d38..ccfb1fd66e 100644 --- a/lib/crypto/vsn.mk +++ b/lib/crypto/vsn.mk @@ -1 +1 @@ -CRYPTO_VSN = 2.1 +CRYPTO_VSN = 2.2 -- cgit v1.2.3