Commit 800e400d authored by Nils Larsch's avatar Nils Larsch
Browse files

some updates for the blinding code; summary:

- possibility of re-creation of the blinding parameters after a
  fixed number of uses (suggested by Bodo)
- calculatition of the rsa::e in case it's absent and p and q
  are present (see bug report #785)
- improve the performance when if one rsa structure is shared by
  more than a thread (see bug report #555)
- fix the problem described in bug report #827
- hide the definition ot the BN_BLINDING structure in bn_blind.c
parent 05886a6f
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -4,6 +4,18 @@

 Changes between 0.9.7g and 0.9.8  [xx XXX xxxx]

  *) Add new functionality to the bn blinding code:
     - automatic re-creation of the BN_BLINDING parameters after
       a fixed number of uses (currently 32)
     - add new function for parameter creation
     - introduce flags to control the update behaviour of the
       BN_BLINDING parameters
     - hide BN_BLINDING structure
     Add a second BN_BLINDING slot to the RSA structure to improve
     performance when a single RSA object is shared among several
     threads.
     [Nils Larsch]

  *) Add support for DTLS.
     [Nagendra Modadugu <nagendra@cs.stanford.edu> and Ben Laurie]

+18 −12
Original line number Diff line number Diff line
@@ -274,16 +274,6 @@ struct bignum_st
	int flags;
	};

struct bn_blinding_st
	{
	int init;
	BIGNUM *A;
	BIGNUM *Ai;
	BIGNUM *mod; /* just a reference */
	unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b;
				  * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
	};

/* Used for montgomery multiplication */
struct bn_mont_ctx_st
	{
@@ -521,11 +511,26 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont);
int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *mod,BN_CTX *ctx);
BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);

BN_BLINDING *BN_BLINDING_new(BIGNUM *A,BIGNUM *Ai,BIGNUM *mod);
/* BN_BLINDING flags */
#define	BN_BLINDING_NO_UPDATE	0x00000001
#define	BN_BLINDING_NO_RECREATE	0x00000002

BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
void BN_BLINDING_free(BN_BLINDING *b);
int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *r, BN_CTX *ctx);
int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
	BN_MONT_CTX *m_ctx);

#ifndef OPENSSL_NO_DEPRECATED
void BN_set_params(int mul,int high,int low,int mont);
@@ -727,6 +732,7 @@ void ERR_load_BN_strings(void);
/* Function codes. */
#define BN_F_BNRAND					 114
#define BN_F_BN_BLINDING_CONVERT			 100
#define BN_F_BN_BLINDING_CREATE_PARAM			 133
#define BN_F_BN_BLINDING_INVERT				 101
#define BN_F_BN_BLINDING_NEW				 102
#define BN_F_BN_BLINDING_UPDATE				 103
+222 −12
Original line number Diff line number Diff line
/* crypto/bn/bn_blind.c */
/* ====================================================================
 * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
@@ -60,11 +113,28 @@
#include "cryptlib.h"
#include "bn_lcl.h"

BN_BLINDING *BN_BLINDING_new(BIGNUM *A, BIGNUM *Ai, BIGNUM *mod)
#define BN_BLINDING_COUNTER	32

struct bn_blinding_st
	{
	BIGNUM *A;
	BIGNUM *Ai;
	BIGNUM *e;
	BIGNUM *mod; /* just a reference */
	unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b;
				  * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
	unsigned int  counter;
	unsigned long flags;
	BN_MONT_CTX *m_ctx;
	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
			  const BIGNUM *m, BN_CTX *ctx,
			  BN_MONT_CTX *m_ctx);
	};

BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
	{
	BN_BLINDING *ret=NULL;

	bn_check_top(Ai);
	bn_check_top(mod);

	if ((ret=(BN_BLINDING *)OPENSSL_malloc(sizeof(BN_BLINDING))) == NULL)
@@ -73,11 +143,16 @@ BN_BLINDING *BN_BLINDING_new(BIGNUM *A, BIGNUM *Ai, BIGNUM *mod)
		return(NULL);
		}
	memset(ret,0,sizeof(BN_BLINDING));
	if ((ret->A=BN_new()) == NULL) goto err;
	if ((ret->Ai=BN_new()) == NULL) goto err;
	if (!BN_copy(ret->A,A)) goto err;
	if (!BN_copy(ret->Ai,Ai)) goto err;
	if (A != NULL)
		{
		if ((ret->A  = BN_dup(A))  == NULL) goto err;
		}
	if (Ai != NULL)
		{
		if ((ret->Ai = BN_dup(Ai)) == NULL) goto err;
		}
	ret->mod = mod;
	ret->counter = BN_BLINDING_COUNTER;
	return(ret);
err:
	if (ret != NULL) BN_BLINDING_free(ret);
@@ -91,6 +166,7 @@ void BN_BLINDING_free(BN_BLINDING *r)

	if (r->A  != NULL) BN_free(r->A );
	if (r->Ai != NULL) BN_free(r->Ai);
	if (r->e  != NULL) BN_free(r->e );
	OPENSSL_free(r);
	}

@@ -104,15 +180,32 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
		goto err;
		}

	if (--(b->counter) == 0 && b->e != NULL &&
		!(b->flags & BN_BLINDING_NO_RECREATE))
		{
		/* re-create blinding parameters */
		if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL))
			goto err;
		}
	else if (!(b->flags & BN_BLINDING_NO_UPDATE))
		{
		if (!BN_mod_mul(b->A,b->A,b->A,b->mod,ctx)) goto err;
		if (!BN_mod_mul(b->Ai,b->Ai,b->Ai,b->mod,ctx)) goto err;
		}

	ret=1;
err:
	if (b->counter == 0)
		b->counter = BN_BLINDING_COUNTER;
	return(ret);
	}

int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
	{
	return BN_BLINDING_convert_ex(n, NULL, b, ctx);
	}

int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
	{
	bn_check_top(n);

@@ -121,10 +214,19 @@ int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
		BNerr(BN_F_BN_BLINDING_CONVERT,BN_R_NOT_INITIALIZED);
		return(0);
		}
	return(BN_mod_mul(n,n,b->A,b->mod,ctx));

	if (r != NULL)
		BN_copy(r, b->Ai);

	return BN_mod_mul(n,n,b->A,b->mod,ctx);
	}

int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
	{
	return BN_BLINDING_invert_ex(n, NULL, b, ctx);
	}

int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
	{
	int ret;

@@ -134,7 +236,13 @@ int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
		BNerr(BN_F_BN_BLINDING_INVERT,BN_R_NOT_INITIALIZED);
		return(0);
		}
	if ((ret=BN_mod_mul(n,n,b->Ai,b->mod,ctx)) >= 0)

	if (r != NULL)
		ret = BN_mod_mul(n, n, r, b->mod, ctx);
	else
		ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);

	if (ret >= 0)
		{
		if (!BN_BLINDING_update(b,ctx))
			return(0);
@@ -143,3 +251,105 @@ int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
	return(ret);
	}

unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b)
	{
	return b->thread_id;
	}

void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n)
	{
	b->thread_id = n;
	}

unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
	{
	return b->flags;
	}

void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags)
	{
	b->flags = flags;
	}

BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
	BN_MONT_CTX *m_ctx)
{
	int    retry_counter = 32;
	BIGNUM *a, *ai;
	BN_BLINDING *ret = NULL;

	if (b == NULL)
		ret = BN_BLINDING_new(NULL, NULL, m);
	else
		ret = b;

	if (ret == NULL)
		goto err;

	if (ret->A  == NULL && (ret->A  = BN_new()) == NULL)
		goto err;
	if (ret->Ai == NULL && (ret->Ai	= BN_new()) == NULL)
		goto err;

	if (e != NULL)
		{
		if (ret->e != NULL)
			BN_free(ret->e);
		ret->e = BN_dup(e);
		}
	if (ret->e == NULL)
		goto err;

	if (bn_mod_exp != NULL)
		ret->bn_mod_exp = bn_mod_exp;
	if (m_ctx != NULL)
		ret->m_ctx = m_ctx;

	do {
		if (!BN_rand_range(ret->A, ret->mod)) goto err;
		if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL)
			{
			/* this should almost never happen for good RSA keys */
			unsigned long error = ERR_peek_last_error();
			if (ERR_GET_REASON(error) == BN_R_NO_INVERSE)
				{
				if (retry_counter-- == 0)
				{
					BNerr(BN_F_BN_BLINDING_CREATE_PARAM,
						BN_R_TOO_MANY_ITERATIONS);
					goto err;
				}
				ERR_clear_error();
				}
			else
				goto err;
			}
		else
			break;
	} while (1);

	if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL)
		{
		if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx))
			goto err;
		}
	else
		{
		if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx))
			goto err;
		}

	return ret;
err:
	if (b == NULL && ret != NULL)
		{
		BN_BLINDING_free(ret);
		ret = NULL;
		}

	return ret;
}
+1 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ static ERR_STRING_DATA BN_str_functs[]=
	{
{ERR_FUNC(BN_F_BNRAND),	"BNRAND"},
{ERR_FUNC(BN_F_BN_BLINDING_CONVERT),	"BN_BLINDING_convert"},
{ERR_FUNC(BN_F_BN_BLINDING_CREATE_PARAM),	"BN_BLINDING_create_param"},
{ERR_FUNC(BN_F_BN_BLINDING_INVERT),	"BN_BLINDING_invert"},
{ERR_FUNC(BN_F_BN_BLINDING_NEW),	"BN_BLINDING_new"},
{ERR_FUNC(BN_F_BN_BLINDING_UPDATE),	"BN_BLINDING_update"},
+4 −0
Original line number Diff line number Diff line
@@ -156,6 +156,7 @@ struct rsa_st
	 * NULL */
	char *bignum_data;
	BN_BLINDING *blinding;
	BN_BLINDING *mt_blinding;
	};

#define RSA_3	0x3L
@@ -279,6 +280,7 @@ int RSA_verify_ASN1_OCTET_STRING(int type,

int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
void RSA_blinding_off(RSA *rsa);
BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx);

int RSA_padding_add_PKCS1_type_1(unsigned char *to,int tlen,
	const unsigned char *f,int fl);
@@ -341,6 +343,7 @@ void ERR_load_RSA_strings(void);
#define RSA_F_RSA_PADDING_CHECK_SSLV23			 114
#define RSA_F_RSA_PRINT					 115
#define RSA_F_RSA_PRINT_FP				 116
#define RSA_F_RSA_SETUP_BLINDING			 125
#define RSA_F_RSA_SIGN					 117
#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING		 118
#define RSA_F_RSA_VERIFY				 119
@@ -367,6 +370,7 @@ void ERR_load_RSA_strings(void);
#define RSA_R_INVALID_MESSAGE_LENGTH			 131
#define RSA_R_IQMP_NOT_INVERSE_OF_Q			 126
#define RSA_R_KEY_SIZE_TOO_SMALL			 120
#define RSA_R_NO_PUBLIC_EXPONENT			 133
#define RSA_R_NULL_BEFORE_BLOCK_MISSING			 113
#define RSA_R_N_DOES_NOT_EQUAL_P_Q			 127
#define RSA_R_OAEP_DECODING_ERROR			 121
Loading