diff options
author | Geoff Thorpe <geoff@openssl.org> | 2008-04-27 18:52:14 +0000 |
---|---|---|
committer | Geoff Thorpe <geoff@openssl.org> | 2008-04-27 18:52:14 +0000 |
commit | 292248b8c28a077cd3325639984b6ae10df4c4cf (patch) | |
tree | 8423714fda9d5b38cbbda25b6e5db54d4658f46c /engines | |
parent | d3eef3e5afc806ba61ca1b6a1af456b24363eda8 (diff) |
Update from HEAD.
Diffstat (limited to 'engines')
-rw-r--r-- | engines/e_gmp.c | 66 |
1 files changed, 51 insertions, 15 deletions
diff --git a/engines/e_gmp.c b/engines/e_gmp.c index f7126d8621..e62e6fcd07 100644 --- a/engines/e_gmp.c +++ b/engines/e_gmp.c @@ -85,6 +85,8 @@ #include <openssl/crypto.h> #include <openssl/buffer.h> #include <openssl/engine.h> +#include <openssl/rsa.h> +#include <openssl/bn.h> #ifndef OPENSSL_NO_HW #ifndef OPENSSL_NO_GMP @@ -251,27 +253,61 @@ static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) return to_return; } -/* HACK - use text I/O functions in openssl and GMP to handle conversions. This - * is vile. */ + +/* Most often limb sizes will be the same. If not, we use hex conversion + * which is neat, but extremely inefficient. */ static int bn2gmp(const BIGNUM *bn, mpz_t g) { - int toret; - char *tmpchar = BN_bn2hex(bn); - if(!tmpchar) return 0; - toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0); - OPENSSL_free(tmpchar); - return toret; + bn_check_top(bn); + if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) && + (BN_BITS2 == GMP_NUMB_BITS)) + { + /* The common case */ + if(!_mpz_realloc (g, bn->top)) + return 0; + memcpy(&g->_mp_d[0], &bn->d[0], bn->top * sizeof(bn->d[0])); + g->_mp_size = bn->top; + if(bn->neg) + g->_mp_size = -g->_mp_size; + return 1; + } + else + { + int toret; + char *tmpchar = BN_bn2hex(bn); + if(!tmpchar) return 0; + toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0); + OPENSSL_free(tmpchar); + return toret; + } } static int gmp2bn(mpz_t g, BIGNUM *bn) { - int toret; - char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10); - if(!tmpchar) return 0; - mpz_get_str(tmpchar, 16, g); - toret = BN_hex2bn(&bn, tmpchar); - OPENSSL_free(tmpchar); - return toret; + if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) && + (BN_BITS2 == GMP_NUMB_BITS)) + { + /* The common case */ + int s = (g->_mp_size >= 0) ? g->_mp_size : -g->_mp_size; + BN_zero(bn); + if(bn_expand2 (bn, s) == NULL) + return 0; + bn->top = s; + memcpy(&bn->d[0], &g->_mp_d[0], s * sizeof(bn->d[0])); + bn_correct_top(bn); + bn->neg = g->_mp_size >= 0 ? 0 : 1; + return 1; + } + else + { + int toret; + char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10); + if(!tmpchar) return 0; + mpz_get_str(tmpchar, 16, g); + toret = BN_hex2bn(&bn, tmpchar); + OPENSSL_free(tmpchar); + return toret; + } } #ifndef OPENSSL_NO_RSA |