Commit 5ee6f96c authored by Geoff Thorpe's avatar Geoff Thorpe
Browse files

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
parent dc634aff
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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]
+51 −15
Original line number Diff line number Diff line
@@ -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,9 +253,25 @@ 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)
	{
	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);
@@ -262,8 +280,25 @@ static int bn2gmp(const BIGNUM *bn, mpz_t g)
		OPENSSL_free(tmpchar);
		return toret;
		}
	}

static int gmp2bn(mpz_t g, BIGNUM *bn)
	{
	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);
@@ -273,6 +308,7 @@ static int gmp2bn(mpz_t g, BIGNUM *bn)
		OPENSSL_free(tmpchar);
		return toret;
		}
	}

#ifndef OPENSSL_NO_RSA 
typedef struct st_e_gmp_rsa_ctx