aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto/c_src/crypto.c
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 /lib/crypto/c_src/crypto.c
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.
Diffstat (limited to 'lib/crypto/c_src/crypto.c')
-rw-r--r--lib/crypto/c_src/crypto.c50
1 files changed, 32 insertions, 18 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);