aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2012-04-20 17:19:51 +0200
committerSverker Eriksson <[email protected]>2012-04-20 17:42:22 +0200
commit5ab9a20e2929fe5810c63252b932bd534abb593c (patch)
tree70f4804e6aee9738da463a32ccd0b9f61fbf5638
parente7a9ae8d070b8751a9dba511ade2753066c40883 (diff)
downloadotp-5ab9a20e2929fe5810c63252b932bd534abb593c.tar.gz
otp-5ab9a20e2929fe5810c63252b932bd534abb593c.tar.bz2
otp-5ab9a20e2929fe5810c63252b932bd534abb593c.zip
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.
-rw-r--r--lib/crypto/c_src/crypto.c50
-rw-r--r--lib/crypto/doc/src/crypto.xml23
-rw-r--r--lib/crypto/vsn.mk2
3 files changed, 52 insertions, 23 deletions
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() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
<fsummary>Sign the data using rsa with the given key.</fsummary>
<type>
<v>Data = Mpint</v>
- <v>Key = [E, N, D]</v>
+ <v>Key = [E, N, D] | [E, N, D, P1, P2, E1, E2, C]</v>
<v>E, N, D = Mpint</v>
<d>Where <c>E</c> is the public exponent, <c>N</c> is public modulus and
<c>D</c> is the private exponent.</d>
+ <v>P1, P2, E1, E2, C = Mpint</v>
+ <d>The longer key format contains redundant information that will make
+ the calculation faster. <c>P1,P2</c> are first and second prime factors.
+ <c>E1,E2</c> are first and second exponents. <c>C</c> is the CRT coefficient.
+ Terminology is taken from RFC 3447.</d>
<v>DigestType = md5 | sha</v>
<d>The default <c>DigestType</c> is sha.</d>
<v>Mpint = binary()</v>
@@ -943,10 +948,15 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
<fsummary>Decrypts ChipherText using the private Key.</fsummary>
<type>
<v>ChipherText = binary()</v>
- <v>PrivateKey = [E, N, D]</v>
+ <v>PrivateKey = [E, N, D] | [E, N, D, P1, P2, E1, E2, C]</v>
<v>E, N, D = Mpint</v>
<d>Where <c>E</c> is the public exponent, <c>N</c> is public modulus and
<c>D</c> is the private exponent.</d>
+ <v>P1, P2, E1, E2, C = Mpint</v>
+ <d>The longer key format contains redundant information that will make
+ the calculation faster. <c>P1,P2</c> are first and second prime factors.
+ <c>E1,E2</c> are first and second exponents. <c>C</c> is the CRT coefficient.
+ Terminology is taken from RFC 3447.</d>
<v>Padding = rsa_pkcs1_padding | rsa_pkcs1_oaep_padding | rsa_no_padding</v>
<v>PlainText = binary()</v>
</type>
@@ -965,10 +975,15 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
<fsummary>Encrypts Msg using the private Key.</fsummary>
<type>
<v>PlainText = binary()</v>
- <v>PrivateKey = [E, N, D]</v>
- <v>E, N, D = Mpint</v>
+ <v>PrivateKey = [E, N, D] | [E, N, D, P1, P2, E1, E2, C]</v>
+ <v>E, N, D = Mpint</v>
<d>Where <c>E</c> is the public exponent, <c>N</c> is public modulus and
<c>D</c> is the private exponent.</d>
+ <v>P1, P2, E1, E2, C = Mpint</v>
+ <d>The longer key format contains redundant information that will make
+ the calculation faster. <c>P1,P2</c> are first and second prime factors.
+ <c>E1,E2</c> are first and second exponents. <c>C</c> is the CRT coefficient.
+ Terminology is taken from RFC 3447.</d>
<v>Padding = rsa_pkcs1_padding | rsa_no_padding</v>
<v>ChipherText = binary()</v>
</type>
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