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. 8280304Sjkim * 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). 15280304Sjkim * 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. 22280304Sjkim * 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 :-). 37280304Sjkim * 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)" 40280304Sjkim * 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. 52280304Sjkim * 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 67280304Sjkim# include <openssl/engine.h> 68111150Snectar#endif 6956083Skris 70238405Sjkim#ifdef OPENSSL_FIPS 71280304Sjkim# include <openssl/fips.h> 72238405Sjkim#endif 73238405Sjkim 74280304Sjkimconst char RSA_version[] = "RSA" OPENSSL_VERSION_PTEXT; 75238405Sjkim 76280304Sjkimstatic const RSA_METHOD *default_RSA_meth = NULL; 77238405Sjkim 78238405SjkimRSA *RSA_new(void) 79280304Sjkim{ 80280304Sjkim RSA *r = RSA_new_method(NULL); 81238405Sjkim 82280304Sjkim return r; 83280304Sjkim} 8456083Skris 85238405Sjkimvoid RSA_set_default_method(const RSA_METHOD *meth) 86280304Sjkim{ 87280304Sjkim default_RSA_meth = meth; 88280304Sjkim} 89238405Sjkim 90238405Sjkimconst RSA_METHOD *RSA_get_default_method(void) 91280304Sjkim{ 92280304Sjkim if (default_RSA_meth == NULL) { 93194206Ssimon#ifdef OPENSSL_FIPS 94280304Sjkim if (FIPS_mode()) 95280304Sjkim return FIPS_rsa_pkcs1_ssleay(); 96280304Sjkim else 97280304Sjkim return RSA_PKCS1_SSLeay(); 98238405Sjkim#else 99280304Sjkim# ifdef RSA_NULL 100280304Sjkim default_RSA_meth = RSA_null_method(); 101280304Sjkim# else 102280304Sjkim default_RSA_meth = RSA_PKCS1_SSLeay(); 103280304Sjkim# endif 104238405Sjkim#endif 105280304Sjkim } 106238405Sjkim 107280304Sjkim return default_RSA_meth; 108280304Sjkim} 10956083Skris 110238405Sjkimconst RSA_METHOD *RSA_get_method(const RSA *rsa) 111280304Sjkim{ 112280304Sjkim return rsa->meth; 113280304Sjkim} 11456083Skris 115238405Sjkimint RSA_set_method(RSA *rsa, const RSA_METHOD *meth) 116280304Sjkim{ 117280304Sjkim /* 118280304Sjkim * NB: The caller is specifically setting a method, so it's not up to us 119280304Sjkim * to deal with which ENGINE it comes from. 120280304Sjkim */ 121280304Sjkim const RSA_METHOD *mtmp; 122280304Sjkim mtmp = rsa->meth; 123280304Sjkim if (mtmp->finish) 124280304Sjkim mtmp->finish(rsa); 125238405Sjkim#ifndef OPENSSL_NO_ENGINE 126280304Sjkim if (rsa->engine) { 127280304Sjkim ENGINE_finish(rsa->engine); 128280304Sjkim rsa->engine = NULL; 129280304Sjkim } 130194206Ssimon#endif 131280304Sjkim rsa->meth = meth; 132280304Sjkim if (meth->init) 133280304Sjkim meth->init(rsa); 134280304Sjkim return 1; 135280304Sjkim} 13656083Skris 137238405SjkimRSA *RSA_new_method(ENGINE *engine) 138280304Sjkim{ 139280304Sjkim RSA *ret; 14056083Skris 141280304Sjkim ret = (RSA *)OPENSSL_malloc(sizeof(RSA)); 142280304Sjkim if (ret == NULL) { 143280304Sjkim RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); 144280304Sjkim return NULL; 145280304Sjkim } 14656083Skris 147280304Sjkim ret->meth = RSA_get_default_method(); 148238405Sjkim#ifndef OPENSSL_NO_ENGINE 149280304Sjkim if (engine) { 150280304Sjkim if (!ENGINE_init(engine)) { 151280304Sjkim RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); 152280304Sjkim OPENSSL_free(ret); 153280304Sjkim return NULL; 154280304Sjkim } 155280304Sjkim ret->engine = engine; 156280304Sjkim } else 157280304Sjkim ret->engine = ENGINE_get_default_RSA(); 158280304Sjkim if (ret->engine) { 159280304Sjkim ret->meth = ENGINE_get_RSA(ret->engine); 160280304Sjkim if (!ret->meth) { 161280304Sjkim RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); 162280304Sjkim ENGINE_finish(ret->engine); 163280304Sjkim OPENSSL_free(ret); 164280304Sjkim return NULL; 165280304Sjkim } 166280304Sjkim } 167238405Sjkim#endif 16856083Skris 169280304Sjkim ret->pad = 0; 170280304Sjkim ret->version = 0; 171280304Sjkim ret->n = NULL; 172280304Sjkim ret->e = NULL; 173280304Sjkim ret->d = NULL; 174280304Sjkim ret->p = NULL; 175280304Sjkim ret->q = NULL; 176280304Sjkim ret->dmp1 = NULL; 177280304Sjkim ret->dmq1 = NULL; 178280304Sjkim ret->iqmp = NULL; 179280304Sjkim ret->references = 1; 180280304Sjkim ret->_method_mod_n = NULL; 181280304Sjkim ret->_method_mod_p = NULL; 182280304Sjkim ret->_method_mod_q = NULL; 183280304Sjkim ret->blinding = NULL; 184280304Sjkim ret->mt_blinding = NULL; 185280304Sjkim ret->bignum_data = NULL; 186280304Sjkim ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; 187280304Sjkim if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { 188238405Sjkim#ifndef OPENSSL_NO_ENGINE 189280304Sjkim if (ret->engine) 190280304Sjkim ENGINE_finish(ret->engine); 191238405Sjkim#endif 192280304Sjkim OPENSSL_free(ret); 193280304Sjkim return (NULL); 194280304Sjkim } 195160817Ssimon 196280304Sjkim if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { 197238405Sjkim#ifndef OPENSSL_NO_ENGINE 198280304Sjkim if (ret->engine) 199280304Sjkim ENGINE_finish(ret->engine); 200238405Sjkim#endif 201280304Sjkim CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); 202280304Sjkim OPENSSL_free(ret); 203280304Sjkim ret = NULL; 204280304Sjkim } 205280304Sjkim return (ret); 206280304Sjkim} 207160817Ssimon 208238405Sjkimvoid RSA_free(RSA *r) 209280304Sjkim{ 210280304Sjkim int i; 211160817Ssimon 212280304Sjkim if (r == NULL) 213280304Sjkim return; 214160817Ssimon 215280304Sjkim i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_RSA); 216238405Sjkim#ifdef REF_PRINT 217280304Sjkim REF_PRINT("RSA", r); 218238405Sjkim#endif 219280304Sjkim if (i > 0) 220280304Sjkim return; 221238405Sjkim#ifdef REF_CHECK 222280304Sjkim if (i < 0) { 223280304Sjkim fprintf(stderr, "RSA_free, bad reference count\n"); 224280304Sjkim abort(); 225280304Sjkim } 226238405Sjkim#endif 227160817Ssimon 228280304Sjkim if (r->meth->finish) 229280304Sjkim r->meth->finish(r); 230238405Sjkim#ifndef OPENSSL_NO_ENGINE 231280304Sjkim if (r->engine) 232280304Sjkim ENGINE_finish(r->engine); 233238405Sjkim#endif 234160817Ssimon 235280304Sjkim CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); 236160817Ssimon 237280304Sjkim if (r->n != NULL) 238280304Sjkim BN_clear_free(r->n); 239280304Sjkim if (r->e != NULL) 240280304Sjkim BN_clear_free(r->e); 241280304Sjkim if (r->d != NULL) 242280304Sjkim BN_clear_free(r->d); 243280304Sjkim if (r->p != NULL) 244280304Sjkim BN_clear_free(r->p); 245280304Sjkim if (r->q != NULL) 246280304Sjkim BN_clear_free(r->q); 247280304Sjkim if (r->dmp1 != NULL) 248280304Sjkim BN_clear_free(r->dmp1); 249280304Sjkim if (r->dmq1 != NULL) 250280304Sjkim BN_clear_free(r->dmq1); 251280304Sjkim if (r->iqmp != NULL) 252280304Sjkim BN_clear_free(r->iqmp); 253280304Sjkim if (r->blinding != NULL) 254280304Sjkim BN_BLINDING_free(r->blinding); 255280304Sjkim if (r->mt_blinding != NULL) 256280304Sjkim BN_BLINDING_free(r->mt_blinding); 257280304Sjkim if (r->bignum_data != NULL) 258280304Sjkim OPENSSL_free_locked(r->bignum_data); 259280304Sjkim OPENSSL_free(r); 260280304Sjkim} 261160817Ssimon 262238405Sjkimint RSA_up_ref(RSA *r) 263280304Sjkim{ 264280304Sjkim int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA); 265238405Sjkim#ifdef REF_PRINT 266280304Sjkim REF_PRINT("RSA", r); 267238405Sjkim#endif 268238405Sjkim#ifdef REF_CHECK 269280304Sjkim if (i < 2) { 270280304Sjkim fprintf(stderr, "RSA_up_ref, bad reference count\n"); 271280304Sjkim abort(); 272280304Sjkim } 273238405Sjkim#endif 274280304Sjkim return ((i > 1) ? 1 : 0); 275280304Sjkim} 27656083Skris 277238405Sjkimint RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 278280304Sjkim CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) 279280304Sjkim{ 280280304Sjkim return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp, 281280304Sjkim new_func, dup_func, free_func); 282280304Sjkim} 28356083Skris 284238405Sjkimint RSA_set_ex_data(RSA *r, int idx, void *arg) 285280304Sjkim{ 286280304Sjkim return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); 287280304Sjkim} 288160817Ssimon 289238405Sjkimvoid *RSA_get_ex_data(const RSA *r, int idx) 290280304Sjkim{ 291280304Sjkim return (CRYPTO_get_ex_data(&r->ex_data, idx)); 292280304Sjkim} 29356083Skris 294238405Sjkimint RSA_memory_lock(RSA *r) 295280304Sjkim{ 296280304Sjkim int i, j, k, off; 297280304Sjkim char *p; 298280304Sjkim BIGNUM *bn, **t[6], *b; 299280304Sjkim BN_ULONG *ul; 300238405Sjkim 301280304Sjkim if (r->d == NULL) 302280304Sjkim return (1); 303280304Sjkim t[0] = &r->d; 304280304Sjkim t[1] = &r->p; 305280304Sjkim t[2] = &r->q; 306280304Sjkim t[3] = &r->dmp1; 307280304Sjkim t[4] = &r->dmq1; 308280304Sjkim t[5] = &r->iqmp; 309280304Sjkim k = sizeof(BIGNUM) * 6; 310280304Sjkim off = k / sizeof(BN_ULONG) + 1; 311280304Sjkim j = 1; 312280304Sjkim for (i = 0; i < 6; i++) 313280304Sjkim j += (*t[i])->top; 314280304Sjkim if ((p = OPENSSL_malloc_locked((off + j) * sizeof(BN_ULONG))) == NULL) { 315280304Sjkim RSAerr(RSA_F_RSA_MEMORY_LOCK, ERR_R_MALLOC_FAILURE); 316280304Sjkim return (0); 317280304Sjkim } 318280304Sjkim bn = (BIGNUM *)p; 319280304Sjkim ul = (BN_ULONG *)&(p[off]); 320280304Sjkim for (i = 0; i < 6; i++) { 321280304Sjkim b = *(t[i]); 322280304Sjkim *(t[i]) = &(bn[i]); 323280304Sjkim memcpy((char *)&(bn[i]), (char *)b, sizeof(BIGNUM)); 324280304Sjkim bn[i].flags = BN_FLG_STATIC_DATA; 325280304Sjkim bn[i].d = ul; 326280304Sjkim memcpy((char *)ul, b->d, sizeof(BN_ULONG) * b->top); 327280304Sjkim ul += b->top; 328280304Sjkim BN_clear_free(b); 329280304Sjkim } 33056083Skris 331280304Sjkim /* I should fix this so it can still be done */ 332280304Sjkim r->flags &= ~(RSA_FLAG_CACHE_PRIVATE | RSA_FLAG_CACHE_PUBLIC); 333280304Sjkim 334280304Sjkim r->bignum_data = p; 335280304Sjkim return (1); 336280304Sjkim} 337