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. 8280297Sjkim * 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). 15280297Sjkim * 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. 22280297Sjkim * 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 :-). 37280297Sjkim * 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)" 40280297Sjkim * 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. 52280297Sjkim * 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 67280297Sjkim# include <openssl/engine.h> 68111150Snectar#endif 6956083Skris 70238405Sjkim#ifdef OPENSSL_FIPS 71280297Sjkim# include <openssl/fips.h> 72238405Sjkim#endif 73238405Sjkim 74280297Sjkimconst char RSA_version[] = "RSA" OPENSSL_VERSION_PTEXT; 75238405Sjkim 76280297Sjkimstatic const RSA_METHOD *default_RSA_meth = NULL; 77238405Sjkim 78238405SjkimRSA *RSA_new(void) 79280297Sjkim{ 80280297Sjkim RSA *r = RSA_new_method(NULL); 81238405Sjkim 82280297Sjkim return r; 83280297Sjkim} 8456083Skris 85238405Sjkimvoid RSA_set_default_method(const RSA_METHOD *meth) 86280297Sjkim{ 87280297Sjkim default_RSA_meth = meth; 88280297Sjkim} 89238405Sjkim 90238405Sjkimconst RSA_METHOD *RSA_get_default_method(void) 91280297Sjkim{ 92280297Sjkim if (default_RSA_meth == NULL) { 93194206Ssimon#ifdef OPENSSL_FIPS 94280297Sjkim if (FIPS_mode()) 95280297Sjkim return FIPS_rsa_pkcs1_ssleay(); 96280297Sjkim else 97280297Sjkim return RSA_PKCS1_SSLeay(); 98238405Sjkim#else 99280297Sjkim# ifdef RSA_NULL 100280297Sjkim default_RSA_meth = RSA_null_method(); 101280297Sjkim# else 102280297Sjkim default_RSA_meth = RSA_PKCS1_SSLeay(); 103280297Sjkim# endif 104238405Sjkim#endif 105280297Sjkim } 106238405Sjkim 107280297Sjkim return default_RSA_meth; 108280297Sjkim} 10956083Skris 110238405Sjkimconst RSA_METHOD *RSA_get_method(const RSA *rsa) 111280297Sjkim{ 112280297Sjkim return rsa->meth; 113280297Sjkim} 11456083Skris 115238405Sjkimint RSA_set_method(RSA *rsa, const RSA_METHOD *meth) 116280297Sjkim{ 117280297Sjkim /* 118280297Sjkim * NB: The caller is specifically setting a method, so it's not up to us 119280297Sjkim * to deal with which ENGINE it comes from. 120280297Sjkim */ 121280297Sjkim const RSA_METHOD *mtmp; 122280297Sjkim mtmp = rsa->meth; 123280297Sjkim if (mtmp->finish) 124280297Sjkim mtmp->finish(rsa); 125238405Sjkim#ifndef OPENSSL_NO_ENGINE 126280297Sjkim if (rsa->engine) { 127280297Sjkim ENGINE_finish(rsa->engine); 128280297Sjkim rsa->engine = NULL; 129280297Sjkim } 130194206Ssimon#endif 131280297Sjkim rsa->meth = meth; 132280297Sjkim if (meth->init) 133280297Sjkim meth->init(rsa); 134280297Sjkim return 1; 135280297Sjkim} 13656083Skris 137238405SjkimRSA *RSA_new_method(ENGINE *engine) 138280297Sjkim{ 139280297Sjkim RSA *ret; 14056083Skris 141280297Sjkim ret = (RSA *)OPENSSL_malloc(sizeof(RSA)); 142280297Sjkim if (ret == NULL) { 143280297Sjkim RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); 144280297Sjkim return NULL; 145280297Sjkim } 146306195Sjkim memset(ret,0,sizeof(RSA)); 14756083Skris 148280297Sjkim ret->meth = RSA_get_default_method(); 149238405Sjkim#ifndef OPENSSL_NO_ENGINE 150280297Sjkim if (engine) { 151280297Sjkim if (!ENGINE_init(engine)) { 152280297Sjkim RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); 153280297Sjkim OPENSSL_free(ret); 154280297Sjkim return NULL; 155280297Sjkim } 156280297Sjkim ret->engine = engine; 157280297Sjkim } else 158280297Sjkim ret->engine = ENGINE_get_default_RSA(); 159280297Sjkim if (ret->engine) { 160280297Sjkim ret->meth = ENGINE_get_RSA(ret->engine); 161280297Sjkim if (!ret->meth) { 162280297Sjkim RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); 163280297Sjkim ENGINE_finish(ret->engine); 164280297Sjkim OPENSSL_free(ret); 165280297Sjkim return NULL; 166280297Sjkim } 167280297Sjkim } 168238405Sjkim#endif 16956083Skris 170280297Sjkim ret->pad = 0; 171280297Sjkim ret->version = 0; 172280297Sjkim ret->n = NULL; 173280297Sjkim ret->e = NULL; 174280297Sjkim ret->d = NULL; 175280297Sjkim ret->p = NULL; 176280297Sjkim ret->q = NULL; 177280297Sjkim ret->dmp1 = NULL; 178280297Sjkim ret->dmq1 = NULL; 179280297Sjkim ret->iqmp = NULL; 180280297Sjkim ret->references = 1; 181280297Sjkim ret->_method_mod_n = NULL; 182280297Sjkim ret->_method_mod_p = NULL; 183280297Sjkim ret->_method_mod_q = NULL; 184280297Sjkim ret->blinding = NULL; 185280297Sjkim ret->mt_blinding = NULL; 186280297Sjkim ret->bignum_data = NULL; 187280297Sjkim ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; 188280297Sjkim if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { 189238405Sjkim#ifndef OPENSSL_NO_ENGINE 190280297Sjkim if (ret->engine) 191280297Sjkim ENGINE_finish(ret->engine); 192238405Sjkim#endif 193280297Sjkim OPENSSL_free(ret); 194280297Sjkim return (NULL); 195280297Sjkim } 196160817Ssimon 197280297Sjkim if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { 198238405Sjkim#ifndef OPENSSL_NO_ENGINE 199280297Sjkim if (ret->engine) 200280297Sjkim ENGINE_finish(ret->engine); 201238405Sjkim#endif 202280297Sjkim CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); 203280297Sjkim OPENSSL_free(ret); 204280297Sjkim ret = NULL; 205280297Sjkim } 206280297Sjkim return (ret); 207280297Sjkim} 208160817Ssimon 209238405Sjkimvoid RSA_free(RSA *r) 210280297Sjkim{ 211280297Sjkim int i; 212160817Ssimon 213280297Sjkim if (r == NULL) 214280297Sjkim return; 215160817Ssimon 216280297Sjkim i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_RSA); 217238405Sjkim#ifdef REF_PRINT 218280297Sjkim REF_PRINT("RSA", r); 219238405Sjkim#endif 220280297Sjkim if (i > 0) 221280297Sjkim return; 222238405Sjkim#ifdef REF_CHECK 223280297Sjkim if (i < 0) { 224280297Sjkim fprintf(stderr, "RSA_free, bad reference count\n"); 225280297Sjkim abort(); 226280297Sjkim } 227238405Sjkim#endif 228160817Ssimon 229280297Sjkim if (r->meth->finish) 230280297Sjkim r->meth->finish(r); 231238405Sjkim#ifndef OPENSSL_NO_ENGINE 232280297Sjkim if (r->engine) 233280297Sjkim ENGINE_finish(r->engine); 234238405Sjkim#endif 235160817Ssimon 236280297Sjkim CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); 237160817Ssimon 238280297Sjkim if (r->n != NULL) 239280297Sjkim BN_clear_free(r->n); 240280297Sjkim if (r->e != NULL) 241280297Sjkim BN_clear_free(r->e); 242280297Sjkim if (r->d != NULL) 243280297Sjkim BN_clear_free(r->d); 244280297Sjkim if (r->p != NULL) 245280297Sjkim BN_clear_free(r->p); 246280297Sjkim if (r->q != NULL) 247280297Sjkim BN_clear_free(r->q); 248280297Sjkim if (r->dmp1 != NULL) 249280297Sjkim BN_clear_free(r->dmp1); 250280297Sjkim if (r->dmq1 != NULL) 251280297Sjkim BN_clear_free(r->dmq1); 252280297Sjkim if (r->iqmp != NULL) 253280297Sjkim BN_clear_free(r->iqmp); 254280297Sjkim if (r->blinding != NULL) 255280297Sjkim BN_BLINDING_free(r->blinding); 256280297Sjkim if (r->mt_blinding != NULL) 257280297Sjkim BN_BLINDING_free(r->mt_blinding); 258280297Sjkim if (r->bignum_data != NULL) 259280297Sjkim OPENSSL_free_locked(r->bignum_data); 260280297Sjkim OPENSSL_free(r); 261280297Sjkim} 262160817Ssimon 263238405Sjkimint RSA_up_ref(RSA *r) 264280297Sjkim{ 265280297Sjkim int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA); 266238405Sjkim#ifdef REF_PRINT 267280297Sjkim REF_PRINT("RSA", r); 268238405Sjkim#endif 269238405Sjkim#ifdef REF_CHECK 270280297Sjkim if (i < 2) { 271280297Sjkim fprintf(stderr, "RSA_up_ref, bad reference count\n"); 272280297Sjkim abort(); 273280297Sjkim } 274238405Sjkim#endif 275280297Sjkim return ((i > 1) ? 1 : 0); 276280297Sjkim} 27756083Skris 278238405Sjkimint RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 279280297Sjkim CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) 280280297Sjkim{ 281280297Sjkim return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp, 282280297Sjkim new_func, dup_func, free_func); 283280297Sjkim} 28456083Skris 285238405Sjkimint RSA_set_ex_data(RSA *r, int idx, void *arg) 286280297Sjkim{ 287280297Sjkim return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); 288280297Sjkim} 289160817Ssimon 290238405Sjkimvoid *RSA_get_ex_data(const RSA *r, int idx) 291280297Sjkim{ 292280297Sjkim return (CRYPTO_get_ex_data(&r->ex_data, idx)); 293280297Sjkim} 29456083Skris 295238405Sjkimint RSA_memory_lock(RSA *r) 296280297Sjkim{ 297280297Sjkim int i, j, k, off; 298280297Sjkim char *p; 299280297Sjkim BIGNUM *bn, **t[6], *b; 300280297Sjkim BN_ULONG *ul; 301238405Sjkim 302280297Sjkim if (r->d == NULL) 303280297Sjkim return (1); 304280297Sjkim t[0] = &r->d; 305280297Sjkim t[1] = &r->p; 306280297Sjkim t[2] = &r->q; 307280297Sjkim t[3] = &r->dmp1; 308280297Sjkim t[4] = &r->dmq1; 309280297Sjkim t[5] = &r->iqmp; 310280297Sjkim k = sizeof(BIGNUM) * 6; 311280297Sjkim off = k / sizeof(BN_ULONG) + 1; 312280297Sjkim j = 1; 313280297Sjkim for (i = 0; i < 6; i++) 314280297Sjkim j += (*t[i])->top; 315280297Sjkim if ((p = OPENSSL_malloc_locked((off + j) * sizeof(BN_ULONG))) == NULL) { 316280297Sjkim RSAerr(RSA_F_RSA_MEMORY_LOCK, ERR_R_MALLOC_FAILURE); 317280297Sjkim return (0); 318280297Sjkim } 319280297Sjkim bn = (BIGNUM *)p; 320280297Sjkim ul = (BN_ULONG *)&(p[off]); 321280297Sjkim for (i = 0; i < 6; i++) { 322280297Sjkim b = *(t[i]); 323280297Sjkim *(t[i]) = &(bn[i]); 324280297Sjkim memcpy((char *)&(bn[i]), (char *)b, sizeof(BIGNUM)); 325280297Sjkim bn[i].flags = BN_FLG_STATIC_DATA; 326280297Sjkim bn[i].d = ul; 327280297Sjkim memcpy((char *)ul, b->d, sizeof(BN_ULONG) * b->top); 328280297Sjkim ul += b->top; 329280297Sjkim BN_clear_free(b); 330280297Sjkim } 33156083Skris 332280297Sjkim /* I should fix this so it can still be done */ 333280297Sjkim r->flags &= ~(RSA_FLAG_CACHE_PRIVATE | RSA_FLAG_CACHE_PUBLIC); 334280297Sjkim 335280297Sjkim r->bignum_data = p; 336280297Sjkim return (1); 337280297Sjkim} 338