156083Skris/* crypto/rsa/rsa_lib.c */ 256083Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 356083Skris * All rights reserved. 456083Skris * 556083Skris * This package is an SSL implementation written 656083Skris * by Eric Young (eay@cryptsoft.com). 756083Skris * The implementation was written so as to conform with Netscapes SSL. 856083Skris * 956083Skris * This library is free for commercial and non-commercial use as long as 1056083Skris * the following conditions are aheared to. The following conditions 1156083Skris * apply to all code found in this distribution, be it the RC4, RSA, 1256083Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1356083Skris * included with this distribution is covered by the same copyright terms 1456083Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1556083Skris * 1656083Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1756083Skris * the code are not to be removed. 1856083Skris * If this package is used in a product, Eric Young should be given attribution 1956083Skris * as the author of the parts of the library used. 2056083Skris * This can be in the form of a textual message at program startup or 2156083Skris * in documentation (online or textual) provided with the package. 2256083Skris * 2356083Skris * Redistribution and use in source and binary forms, with or without 2456083Skris * modification, are permitted provided that the following conditions 2556083Skris * are met: 2656083Skris * 1. Redistributions of source code must retain the copyright 2756083Skris * notice, this list of conditions and the following disclaimer. 2856083Skris * 2. Redistributions in binary form must reproduce the above copyright 2956083Skris * notice, this list of conditions and the following disclaimer in the 3056083Skris * documentation and/or other materials provided with the distribution. 3156083Skris * 3. All advertising materials mentioning features or use of this software 3256083Skris * must display the following acknowledgement: 3356083Skris * "This product includes cryptographic software written by 3456083Skris * Eric Young (eay@cryptsoft.com)" 3556083Skris * The word 'cryptographic' can be left out if the rouines from the library 3656083Skris * being used are not cryptographic related :-). 3756083Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3856083Skris * the apps directory (application code) you must include an acknowledgement: 3956083Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4056083Skris * 4156083Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4256083Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4356083Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4456083Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4556083Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4656083Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4756083Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4856083Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4956083Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5056083Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5156083Skris * SUCH DAMAGE. 5256083Skris * 5356083Skris * The licence and distribution terms for any publically available version or 5456083Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5556083Skris * copied and put under another distribution licence 5656083Skris * [including the GNU Public Licence.] 5756083Skris */ 5856083Skris 5956083Skris#include <stdio.h> 6056083Skris#include <openssl/crypto.h> 6156083Skris#include "cryptlib.h" 6256083Skris#include <openssl/lhash.h> 6356083Skris#include <openssl/bn.h> 6456083Skris#include <openssl/rsa.h> 65120635Snectar#include <openssl/rand.h> 66111150Snectar#ifndef OPENSSL_NO_ENGINE 67110007Smarkm#include <openssl/engine.h> 68111150Snectar#endif 6956083Skris 70238405Sjkim#ifdef OPENSSL_FIPS 71238405Sjkim#include <openssl/fips.h> 72238405Sjkim#endif 73238405Sjkim 74238405Sjkimconst char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT; 75238405Sjkim 76238405Sjkimstatic const RSA_METHOD *default_RSA_meth=NULL; 77238405Sjkim 78238405SjkimRSA *RSA_new(void) 7956083Skris { 80238405Sjkim RSA *r=RSA_new_method(NULL); 81238405Sjkim 82238405Sjkim return r; 8356083Skris } 8456083Skris 85238405Sjkimvoid RSA_set_default_method(const RSA_METHOD *meth) 8656083Skris { 87238405Sjkim default_RSA_meth = meth; 88238405Sjkim } 89238405Sjkim 90238405Sjkimconst RSA_METHOD *RSA_get_default_method(void) 91238405Sjkim { 92238405Sjkim if (default_RSA_meth == NULL) 93238405Sjkim { 94194206Ssimon#ifdef OPENSSL_FIPS 95238405Sjkim if (FIPS_mode()) 96238405Sjkim return FIPS_rsa_pkcs1_ssleay(); 97238405Sjkim else 98238405Sjkim return RSA_PKCS1_SSLeay(); 99238405Sjkim#else 100238405Sjkim#ifdef RSA_NULL 101238405Sjkim default_RSA_meth=RSA_null_method(); 102238405Sjkim#else 103238405Sjkim default_RSA_meth=RSA_PKCS1_SSLeay(); 104238405Sjkim#endif 105238405Sjkim#endif 106194206Ssimon } 107238405Sjkim 108238405Sjkim return default_RSA_meth; 10956083Skris } 11056083Skris 111238405Sjkimconst RSA_METHOD *RSA_get_method(const RSA *rsa) 11256083Skris { 113238405Sjkim return rsa->meth; 11456083Skris } 11556083Skris 116238405Sjkimint RSA_set_method(RSA *rsa, const RSA_METHOD *meth) 11756083Skris { 118238405Sjkim /* NB: The caller is specifically setting a method, so it's not up to us 119238405Sjkim * to deal with which ENGINE it comes from. */ 120238405Sjkim const RSA_METHOD *mtmp; 121238405Sjkim mtmp = rsa->meth; 122238405Sjkim if (mtmp->finish) mtmp->finish(rsa); 123238405Sjkim#ifndef OPENSSL_NO_ENGINE 124238405Sjkim if (rsa->engine) 125194206Ssimon { 126238405Sjkim ENGINE_finish(rsa->engine); 127238405Sjkim rsa->engine = NULL; 128194206Ssimon } 129194206Ssimon#endif 130238405Sjkim rsa->meth = meth; 131238405Sjkim if (meth->init) meth->init(rsa); 132238405Sjkim return 1; 13356083Skris } 13456083Skris 135238405SjkimRSA *RSA_new_method(ENGINE *engine) 13656083Skris { 137238405Sjkim RSA *ret; 13856083Skris 139238405Sjkim ret=(RSA *)OPENSSL_malloc(sizeof(RSA)); 140238405Sjkim if (ret == NULL) 14156083Skris { 142238405Sjkim RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE); 143238405Sjkim return NULL; 14456083Skris } 14556083Skris 146238405Sjkim ret->meth = RSA_get_default_method(); 147238405Sjkim#ifndef OPENSSL_NO_ENGINE 148238405Sjkim if (engine) 149238405Sjkim { 150238405Sjkim if (!ENGINE_init(engine)) 151238405Sjkim { 152238405Sjkim RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); 153238405Sjkim OPENSSL_free(ret); 154238405Sjkim return NULL; 155238405Sjkim } 156238405Sjkim ret->engine = engine; 157238405Sjkim } 158238405Sjkim else 159238405Sjkim ret->engine = ENGINE_get_default_RSA(); 160238405Sjkim if(ret->engine) 161238405Sjkim { 162238405Sjkim ret->meth = ENGINE_get_RSA(ret->engine); 163238405Sjkim if(!ret->meth) 164238405Sjkim { 165238405Sjkim RSAerr(RSA_F_RSA_NEW_METHOD, 166238405Sjkim ERR_R_ENGINE_LIB); 167238405Sjkim ENGINE_finish(ret->engine); 168238405Sjkim OPENSSL_free(ret); 169238405Sjkim return NULL; 170238405Sjkim } 171238405Sjkim } 172238405Sjkim#endif 17356083Skris 174238405Sjkim ret->pad=0; 175238405Sjkim ret->version=0; 176238405Sjkim ret->n=NULL; 177238405Sjkim ret->e=NULL; 178238405Sjkim ret->d=NULL; 179238405Sjkim ret->p=NULL; 180238405Sjkim ret->q=NULL; 181238405Sjkim ret->dmp1=NULL; 182238405Sjkim ret->dmq1=NULL; 183238405Sjkim ret->iqmp=NULL; 184238405Sjkim ret->references=1; 185238405Sjkim ret->_method_mod_n=NULL; 186238405Sjkim ret->_method_mod_p=NULL; 187238405Sjkim ret->_method_mod_q=NULL; 188238405Sjkim ret->blinding=NULL; 189238405Sjkim ret->mt_blinding=NULL; 190238405Sjkim ret->bignum_data=NULL; 191238405Sjkim ret->flags=ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; 192238405Sjkim if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) 193238405Sjkim { 194238405Sjkim#ifndef OPENSSL_NO_ENGINE 195238405Sjkim if (ret->engine) 196238405Sjkim ENGINE_finish(ret->engine); 197238405Sjkim#endif 198238405Sjkim OPENSSL_free(ret); 199238405Sjkim return(NULL); 200238405Sjkim } 201160817Ssimon 202238405Sjkim if ((ret->meth->init != NULL) && !ret->meth->init(ret)) 203238405Sjkim { 204238405Sjkim#ifndef OPENSSL_NO_ENGINE 205238405Sjkim if (ret->engine) 206238405Sjkim ENGINE_finish(ret->engine); 207238405Sjkim#endif 208238405Sjkim CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); 209238405Sjkim OPENSSL_free(ret); 210238405Sjkim ret=NULL; 211238405Sjkim } 212160817Ssimon return(ret); 213160817Ssimon } 214160817Ssimon 215238405Sjkimvoid RSA_free(RSA *r) 216238405Sjkim { 217238405Sjkim int i; 218160817Ssimon 219238405Sjkim if (r == NULL) return; 220160817Ssimon 221238405Sjkim i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_RSA); 222238405Sjkim#ifdef REF_PRINT 223238405Sjkim REF_PRINT("RSA",r); 224238405Sjkim#endif 225238405Sjkim if (i > 0) return; 226238405Sjkim#ifdef REF_CHECK 227238405Sjkim if (i < 0) 228238405Sjkim { 229238405Sjkim fprintf(stderr,"RSA_free, bad reference count\n"); 230238405Sjkim abort(); 231238405Sjkim } 232238405Sjkim#endif 233160817Ssimon 234238405Sjkim if (r->meth->finish) 235238405Sjkim r->meth->finish(r); 236238405Sjkim#ifndef OPENSSL_NO_ENGINE 237238405Sjkim if (r->engine) 238238405Sjkim ENGINE_finish(r->engine); 239238405Sjkim#endif 240160817Ssimon 241238405Sjkim CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); 242160817Ssimon 243238405Sjkim if (r->n != NULL) BN_clear_free(r->n); 244238405Sjkim if (r->e != NULL) BN_clear_free(r->e); 245238405Sjkim if (r->d != NULL) BN_clear_free(r->d); 246238405Sjkim if (r->p != NULL) BN_clear_free(r->p); 247238405Sjkim if (r->q != NULL) BN_clear_free(r->q); 248238405Sjkim if (r->dmp1 != NULL) BN_clear_free(r->dmp1); 249238405Sjkim if (r->dmq1 != NULL) BN_clear_free(r->dmq1); 250238405Sjkim if (r->iqmp != NULL) BN_clear_free(r->iqmp); 251238405Sjkim if (r->blinding != NULL) BN_BLINDING_free(r->blinding); 252238405Sjkim if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding); 253238405Sjkim if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data); 254238405Sjkim OPENSSL_free(r); 255238405Sjkim } 256160817Ssimon 257238405Sjkimint RSA_up_ref(RSA *r) 258238405Sjkim { 259238405Sjkim int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA); 260238405Sjkim#ifdef REF_PRINT 261238405Sjkim REF_PRINT("RSA",r); 262238405Sjkim#endif 263238405Sjkim#ifdef REF_CHECK 264238405Sjkim if (i < 2) 26556083Skris { 266238405Sjkim fprintf(stderr, "RSA_up_ref, bad reference count\n"); 267238405Sjkim abort(); 26856083Skris } 269238405Sjkim#endif 270238405Sjkim return ((i > 1) ? 1 : 0); 271238405Sjkim } 27256083Skris 273238405Sjkimint RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 274238405Sjkim CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) 275238405Sjkim { 276238405Sjkim return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp, 277238405Sjkim new_func, dup_func, free_func); 278238405Sjkim } 27956083Skris 280238405Sjkimint RSA_set_ex_data(RSA *r, int idx, void *arg) 281238405Sjkim { 282238405Sjkim return(CRYPTO_set_ex_data(&r->ex_data,idx,arg)); 283238405Sjkim } 284160817Ssimon 285238405Sjkimvoid *RSA_get_ex_data(const RSA *r, int idx) 286238405Sjkim { 287238405Sjkim return(CRYPTO_get_ex_data(&r->ex_data,idx)); 288238405Sjkim } 28956083Skris 290238405Sjkimint RSA_memory_lock(RSA *r) 291238405Sjkim { 292238405Sjkim int i,j,k,off; 293238405Sjkim char *p; 294238405Sjkim BIGNUM *bn,**t[6],*b; 295238405Sjkim BN_ULONG *ul; 296238405Sjkim 297238405Sjkim if (r->d == NULL) return(1); 298238405Sjkim t[0]= &r->d; 299238405Sjkim t[1]= &r->p; 300238405Sjkim t[2]= &r->q; 301238405Sjkim t[3]= &r->dmp1; 302238405Sjkim t[4]= &r->dmq1; 303238405Sjkim t[5]= &r->iqmp; 304238405Sjkim k=sizeof(BIGNUM)*6; 305238405Sjkim off=k/sizeof(BN_ULONG)+1; 306238405Sjkim j=1; 307238405Sjkim for (i=0; i<6; i++) 308238405Sjkim j+= (*t[i])->top; 309238405Sjkim if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL) 310194206Ssimon { 311238405Sjkim RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE); 312238405Sjkim return(0); 313194206Ssimon } 314238405Sjkim bn=(BIGNUM *)p; 315238405Sjkim ul=(BN_ULONG *)&(p[off]); 316238405Sjkim for (i=0; i<6; i++) 317160817Ssimon { 318238405Sjkim b= *(t[i]); 319238405Sjkim *(t[i])= &(bn[i]); 320238405Sjkim memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM)); 321238405Sjkim bn[i].flags=BN_FLG_STATIC_DATA; 322238405Sjkim bn[i].d=ul; 323238405Sjkim memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top); 324238405Sjkim ul+=b->top; 325238405Sjkim BN_clear_free(b); 326160817Ssimon } 327238405Sjkim 328238405Sjkim /* I should fix this so it can still be done */ 329238405Sjkim r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC); 33056083Skris 331238405Sjkim r->bignum_data=p; 332238405Sjkim return(1); 333238405Sjkim } 334