提交 5ee6f96c 编写于 作者: G Geoff Thorpe

Paul Sheer optimised the OpenSSL to/from libGMP conversions for the case

where they both use the same limb size. I've tweaked his patch slightly, so
blame me if it breaks.

Submitted by: Paul Sheer
Reviewed by: Geoff Thorpe
上级 dc634aff
......@@ -681,6 +681,11 @@
Changes between 0.9.8g and 0.9.8h [xx XXX xxxx]
*) Update the GMP engine glue to do direct copies between BIGNUM and
mpz_t when openssl and GMP use the same limb size. Otherwise the
existing "conversion via a text string export" trick is still used.
[Paul Sheer <paulsheer@gmail.com>, Geoff Thorpe]
*) Zlib compression BIO. This is a filter BIO which compressed and
uncompresses any data passed through it.
[Steve Henson]
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册