From e3350922cdf6f87e98fa62cd9c641232af168534 Mon Sep 17 00:00:00 2001 From: beck <> Date: Thu, 15 Jun 2000 17:16:32 +0000 Subject: RSA goes in tree for next our next release, as it will be after Sept 21. Note: This means you shouldn't really be running -current for anything in the United States. Either wait for Sept 21, or for the next release, or move to the free world :) --- src/lib/libcrypto/rsa/rsa_eay.c | 252 +++++++++++++++++++++++++++++++++++----- 1 file changed, 222 insertions(+), 30 deletions(-) (limited to 'src/lib/libcrypto/rsa/rsa_eay.c') diff --git a/src/lib/libcrypto/rsa/rsa_eay.c b/src/lib/libcrypto/rsa/rsa_eay.c index f835be8afc..b7d2460754 100644 --- a/src/lib/libcrypto/rsa/rsa_eay.c +++ b/src/lib/libcrypto/rsa/rsa_eay.c @@ -1,13 +1,3 @@ - -/* This file has been explicitly broken by ryker for OpenBSD, July - * 1, 1998. In spite of the title, there is no implementation of the - * RSA algorithm left in this file. All these routines will return an - * error and fail when called. They exist as stubs and can be - * ressurected from the bit bucket by someone in the free world once - * the RSA algorithm is no longer subject to patent problems. Eric - * Young's original copyright is below. - */ - /* crypto/rsa/rsa_eay.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. @@ -184,13 +174,62 @@ static int RSA_eay_private_encrypt(int flen, unsigned char *from, unsigned char *buf=NULL; BN_CTX *ctx=NULL; - BN_init(&f); - BN_init(&ret); + BN_init(&f); + BN_init(&ret); + + if ((ctx=BN_CTX_new()) == NULL) goto err; + num=BN_num_bytes(rsa->n); + if ((buf=(unsigned char *)Malloc(num)) == NULL) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) + { + case RSA_PKCS1_PADDING: + i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen); + break; + case RSA_NO_PADDING: + i=RSA_padding_add_none(buf,num,from,flen); + break; + case RSA_SSLV23_PADDING: + default: + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (i <= 0) goto err; + + if (BN_bin2bn(buf,num,&f) == NULL) goto err; + + if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL)) + RSA_blinding_on(rsa,ctx); + if (rsa->flags & RSA_FLAG_BLINDING) + if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err; - /* Body of this routine removed for OpenBSD - will return - * when the RSA patent expires - */ + if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || + ((rsa->p != NULL) && + (rsa->q != NULL) && + (rsa->dmp1 != NULL) && + (rsa->dmq1 != NULL) && + (rsa->iqmp != NULL)) ) + { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; } + else + { + if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err; + } + + if (rsa->flags & RSA_FLAG_BLINDING) + if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err; + + /* put in leading 0 bytes if the number is less than the + * length of the modulus */ + j=BN_num_bytes(&ret); + i=BN_bn2bin(&ret,&(to[num-j])); + for (k=0; k<(num-i); k++) + to[k]=0; + r=num; err: if (ctx != NULL) BN_CTX_free(ctx); BN_clear_free(&ret); @@ -212,12 +251,77 @@ static int RSA_eay_private_decrypt(int flen, unsigned char *from, unsigned char *buf=NULL; BN_CTX *ctx=NULL; - BN_init(&f); - BN_init(&ret); + BN_init(&f); + BN_init(&ret); + ctx=BN_CTX_new(); + if (ctx == NULL) goto err; + + num=BN_num_bytes(rsa->n); + + if ((buf=(unsigned char *)Malloc(num)) == NULL) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE); + goto err; + } + + /* This check was for equality but PGP does evil things + * and chops off the top '0' bytes */ + if (flen > num) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + /* make data into a big number */ + if (BN_bin2bn(from,(int)flen,&f) == NULL) goto err; - /* Body of this routine removed for OpenBSD - will return - * when the RSA patent expires - */ + if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL)) + RSA_blinding_on(rsa,ctx); + if (rsa->flags & RSA_FLAG_BLINDING) + if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err; + + /* do the decrypt */ + if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || + ((rsa->p != NULL) && + (rsa->q != NULL) && + (rsa->dmp1 != NULL) && + (rsa->dmq1 != NULL) && + (rsa->iqmp != NULL)) ) + { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; } + else + { + if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) + goto err; + } + + if (rsa->flags & RSA_FLAG_BLINDING) + if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err; + + p=buf; + j=BN_bn2bin(&ret,p); /* j is only used with no-padding mode */ + + switch (padding) + { + case RSA_PKCS1_PADDING: + r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num); + break; +#ifndef NO_SHA + case RSA_PKCS1_OAEP_PADDING: + r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0); + break; +#endif + case RSA_SSLV23_PADDING: + r=RSA_padding_check_SSLv23(to,num,buf,j,num); + break; + case RSA_NO_PADDING: + r=RSA_padding_check_none(to,num,buf,j,num); + break; + default: + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (r < 0) + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED); err: if (ctx != NULL) BN_CTX_free(ctx); @@ -240,12 +344,56 @@ static int RSA_eay_public_decrypt(int flen, unsigned char *from, unsigned char *buf=NULL; BN_CTX *ctx=NULL; - BN_init(&f); - BN_init(&ret); + BN_init(&f); + BN_init(&ret); + ctx=BN_CTX_new(); + if (ctx == NULL) goto err; + + num=BN_num_bytes(rsa->n); + buf=(unsigned char *)Malloc(num); + if (buf == NULL) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE); + goto err; + } - /* Body of this routine removed for OpenBSD - will return - * when the RSA patent expires - */ + /* This check was for equality but PGP does evil things + * and chops off the top '0' bytes */ + if (flen > num) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + if (BN_bin2bn(from,flen,&f) == NULL) goto err; + /* do the decrypt */ + if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC)) + { + if ((rsa->_method_mod_n=BN_MONT_CTX_new()) != NULL) + if (!BN_MONT_CTX_set(rsa->_method_mod_n,rsa->n,ctx)) + goto err; + } + + if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx, + rsa->_method_mod_n)) goto err; + + p=buf; + i=BN_bn2bin(&ret,p); + + switch (padding) + { + case RSA_PKCS1_PADDING: + r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num); + break; + case RSA_NO_PADDING: + r=RSA_padding_check_none(to,num,buf,i,num); + break; + default: + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (r < 0) + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED); err: if (ctx != NULL) BN_CTX_free(ctx); @@ -263,15 +411,59 @@ static int RSA_eay_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) { BIGNUM r1,m1; int ret=0; - BN_CTX *ctx = NULL; + BN_CTX *ctx; + if ((ctx=BN_CTX_new()) == NULL) goto err; BN_init(&m1); BN_init(&r1); - if ((ctx=BN_CTX_new()) == NULL) goto err; - /* Body of this routine removed for OpenBSD - will return - * when the RSA patent expires - */ + if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) + { + if (rsa->_method_mod_p == NULL) + { + if ((rsa->_method_mod_p=BN_MONT_CTX_new()) != NULL) + if (!BN_MONT_CTX_set(rsa->_method_mod_p,rsa->p, + ctx)) + goto err; + } + if (rsa->_method_mod_q == NULL) + { + if ((rsa->_method_mod_q=BN_MONT_CTX_new()) != NULL) + if (!BN_MONT_CTX_set(rsa->_method_mod_q,rsa->q, + ctx)) + goto err; + } + } + + if (!BN_mod(&r1,I,rsa->q,ctx)) goto err; + if (!rsa->meth->bn_mod_exp(&m1,&r1,rsa->dmq1,rsa->q,ctx, + rsa->_method_mod_q)) goto err; + + if (!BN_mod(&r1,I,rsa->p,ctx)) goto err; + if (!rsa->meth->bn_mod_exp(r0,&r1,rsa->dmp1,rsa->p,ctx, + rsa->_method_mod_p)) goto err; + + if (!BN_sub(r0,r0,&m1)) goto err; + /* This will help stop the size of r0 increasing, which does + * affect the multiply if it optimised for a power of 2 size */ + if (r0->neg) + if (!BN_add(r0,r0,rsa->p)) goto err; + + if (!BN_mul(&r1,r0,rsa->iqmp,ctx)) goto err; + if (!BN_mod(r0,&r1,rsa->p,ctx)) goto err; + /* If p < q it is occasionally possible for the correction of + * adding 'p' if r0 is negative above to leave the result still + * negative. This can break the private key operations: the following + * second correction should *always* correct this rare occurrence. + * This will *never* happen with OpenSSL generated keys because + * they ensure p > q [steve] + */ + if (r0->neg) + if (!BN_add(r0,r0,rsa->p)) goto err; + if (!BN_mul(&r1,r0,rsa->q,ctx)) goto err; + if (!BN_add(r0,&r1,&m1)) goto err; + + ret=1; err: BN_clear_free(&m1); BN_clear_free(&r1); -- cgit v1.2.3-55-g6feb