1238384Sjkim/* crypto/rsa/rsa_lib.c */ 2238384Sjkim/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3238384Sjkim * All rights reserved. 4238384Sjkim * 5238384Sjkim * This package is an SSL implementation written 6238384Sjkim * by Eric Young (eay@cryptsoft.com). 7238384Sjkim * The implementation was written so as to conform with Netscapes SSL. 8296341Sdelphij * 9238384Sjkim * This library is free for commercial and non-commercial use as long as 10238384Sjkim * the following conditions are aheared to. The following conditions 11238384Sjkim * apply to all code found in this distribution, be it the RC4, RSA, 12238384Sjkim * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13238384Sjkim * included with this distribution is covered by the same copyright terms 14238384Sjkim * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15296341Sdelphij * 16238384Sjkim * Copyright remains Eric Young's, and as such any Copyright notices in 17238384Sjkim * the code are not to be removed. 18238384Sjkim * If this package is used in a product, Eric Young should be given attribution 19238384Sjkim * as the author of the parts of the library used. 20238384Sjkim * This can be in the form of a textual message at program startup or 21238384Sjkim * in documentation (online or textual) provided with the package. 22296341Sdelphij * 23238384Sjkim * Redistribution and use in source and binary forms, with or without 24238384Sjkim * modification, are permitted provided that the following conditions 25238384Sjkim * are met: 26238384Sjkim * 1. Redistributions of source code must retain the copyright 27238384Sjkim * notice, this list of conditions and the following disclaimer. 28238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 29238384Sjkim * notice, this list of conditions and the following disclaimer in the 30238384Sjkim * documentation and/or other materials provided with the distribution. 31238384Sjkim * 3. All advertising materials mentioning features or use of this software 32238384Sjkim * must display the following acknowledgement: 33238384Sjkim * "This product includes cryptographic software written by 34238384Sjkim * Eric Young (eay@cryptsoft.com)" 35238384Sjkim * The word 'cryptographic' can be left out if the rouines from the library 36238384Sjkim * being used are not cryptographic related :-). 37296341Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from 38238384Sjkim * the apps directory (application code) you must include an acknowledgement: 39238384Sjkim * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40296341Sdelphij * 41238384Sjkim * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42238384Sjkim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44238384Sjkim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45238384Sjkim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46238384Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47238384Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49238384Sjkim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50238384Sjkim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51238384Sjkim * SUCH DAMAGE. 52296341Sdelphij * 53238384Sjkim * The licence and distribution terms for any publically available version or 54238384Sjkim * derivative of this code cannot be changed. i.e. this code cannot simply be 55238384Sjkim * copied and put under another distribution licence 56238384Sjkim * [including the GNU Public Licence.] 57238384Sjkim */ 58238384Sjkim 59238384Sjkim#include <stdio.h> 60238384Sjkim#include <openssl/crypto.h> 61238384Sjkim#include "cryptlib.h" 62238384Sjkim#include <openssl/lhash.h> 63238384Sjkim#include <openssl/bn.h> 64238384Sjkim#include <openssl/rsa.h> 65238384Sjkim#include <openssl/rand.h> 66238384Sjkim#ifndef OPENSSL_NO_ENGINE 67296341Sdelphij# include <openssl/engine.h> 68238384Sjkim#endif 69238384Sjkim 70238384Sjkimint RSA_size(const RSA *r) 71296341Sdelphij{ 72296341Sdelphij return (BN_num_bytes(r->n)); 73296341Sdelphij} 74238384Sjkim 75238384Sjkimint RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, 76296341Sdelphij RSA *rsa, int padding) 77296341Sdelphij{ 78238384Sjkim#ifdef OPENSSL_FIPS 79296341Sdelphij if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) 80296341Sdelphij && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { 81296341Sdelphij RSAerr(RSA_F_RSA_PUBLIC_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD); 82296341Sdelphij return -1; 83296341Sdelphij } 84238384Sjkim#endif 85296341Sdelphij return (rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding)); 86296341Sdelphij} 87238384Sjkim 88296341Sdelphijint RSA_private_encrypt(int flen, const unsigned char *from, 89296341Sdelphij unsigned char *to, RSA *rsa, int padding) 90296341Sdelphij{ 91238384Sjkim#ifdef OPENSSL_FIPS 92296341Sdelphij if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) 93296341Sdelphij && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { 94296341Sdelphij RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD); 95296341Sdelphij return -1; 96296341Sdelphij } 97238384Sjkim#endif 98296341Sdelphij return (rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding)); 99296341Sdelphij} 100238384Sjkim 101296341Sdelphijint RSA_private_decrypt(int flen, const unsigned char *from, 102296341Sdelphij unsigned char *to, RSA *rsa, int padding) 103296341Sdelphij{ 104238384Sjkim#ifdef OPENSSL_FIPS 105296341Sdelphij if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) 106296341Sdelphij && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { 107296341Sdelphij RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD); 108296341Sdelphij return -1; 109296341Sdelphij } 110238384Sjkim#endif 111296341Sdelphij return (rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding)); 112296341Sdelphij} 113238384Sjkim 114238384Sjkimint RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, 115296341Sdelphij RSA *rsa, int padding) 116296341Sdelphij{ 117238384Sjkim#ifdef OPENSSL_FIPS 118296341Sdelphij if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) 119296341Sdelphij && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { 120296341Sdelphij RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD); 121296341Sdelphij return -1; 122296341Sdelphij } 123238384Sjkim#endif 124296341Sdelphij return (rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding)); 125296341Sdelphij} 126238384Sjkim 127238384Sjkimint RSA_flags(const RSA *r) 128296341Sdelphij{ 129296341Sdelphij return ((r == NULL) ? 0 : r->meth->flags); 130296341Sdelphij} 131238384Sjkim 132238384Sjkimvoid RSA_blinding_off(RSA *rsa) 133296341Sdelphij{ 134296341Sdelphij if (rsa->blinding != NULL) { 135296341Sdelphij BN_BLINDING_free(rsa->blinding); 136296341Sdelphij rsa->blinding = NULL; 137296341Sdelphij } 138296341Sdelphij rsa->flags &= ~RSA_FLAG_BLINDING; 139296341Sdelphij rsa->flags |= RSA_FLAG_NO_BLINDING; 140296341Sdelphij} 141238384Sjkim 142238384Sjkimint RSA_blinding_on(RSA *rsa, BN_CTX *ctx) 143296341Sdelphij{ 144296341Sdelphij int ret = 0; 145238384Sjkim 146296341Sdelphij if (rsa->blinding != NULL) 147296341Sdelphij RSA_blinding_off(rsa); 148238384Sjkim 149296341Sdelphij rsa->blinding = RSA_setup_blinding(rsa, ctx); 150296341Sdelphij if (rsa->blinding == NULL) 151296341Sdelphij goto err; 152238384Sjkim 153296341Sdelphij rsa->flags |= RSA_FLAG_BLINDING; 154296341Sdelphij rsa->flags &= ~RSA_FLAG_NO_BLINDING; 155296341Sdelphij ret = 1; 156296341Sdelphij err: 157296341Sdelphij return (ret); 158296341Sdelphij} 159238384Sjkim 160238384Sjkimstatic BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p, 161296341Sdelphij const BIGNUM *q, BN_CTX *ctx) 162238384Sjkim{ 163296341Sdelphij BIGNUM *ret = NULL, *r0, *r1, *r2; 164238384Sjkim 165296341Sdelphij if (d == NULL || p == NULL || q == NULL) 166296341Sdelphij return NULL; 167238384Sjkim 168296341Sdelphij BN_CTX_start(ctx); 169296341Sdelphij r0 = BN_CTX_get(ctx); 170296341Sdelphij r1 = BN_CTX_get(ctx); 171296341Sdelphij r2 = BN_CTX_get(ctx); 172296341Sdelphij if (r2 == NULL) 173296341Sdelphij goto err; 174238384Sjkim 175296341Sdelphij if (!BN_sub(r1, p, BN_value_one())) 176296341Sdelphij goto err; 177296341Sdelphij if (!BN_sub(r2, q, BN_value_one())) 178296341Sdelphij goto err; 179296341Sdelphij if (!BN_mul(r0, r1, r2, ctx)) 180296341Sdelphij goto err; 181238384Sjkim 182296341Sdelphij ret = BN_mod_inverse(NULL, d, r0, ctx); 183296341Sdelphij err: 184296341Sdelphij BN_CTX_end(ctx); 185296341Sdelphij return ret; 186238384Sjkim} 187238384Sjkim 188238384SjkimBN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) 189238384Sjkim{ 190296341Sdelphij BIGNUM local_n; 191296341Sdelphij BIGNUM *e, *n; 192296341Sdelphij BN_CTX *ctx; 193296341Sdelphij BN_BLINDING *ret = NULL; 194238384Sjkim 195296341Sdelphij if (in_ctx == NULL) { 196296341Sdelphij if ((ctx = BN_CTX_new()) == NULL) 197296341Sdelphij return 0; 198296341Sdelphij } else 199296341Sdelphij ctx = in_ctx; 200238384Sjkim 201296341Sdelphij BN_CTX_start(ctx); 202296341Sdelphij e = BN_CTX_get(ctx); 203296341Sdelphij if (e == NULL) { 204296341Sdelphij RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); 205296341Sdelphij goto err; 206296341Sdelphij } 207238384Sjkim 208296341Sdelphij if (rsa->e == NULL) { 209296341Sdelphij e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); 210296341Sdelphij if (e == NULL) { 211296341Sdelphij RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); 212296341Sdelphij goto err; 213296341Sdelphij } 214296341Sdelphij } else 215296341Sdelphij e = rsa->e; 216238384Sjkim 217296341Sdelphij if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL) { 218296341Sdelphij /* 219296341Sdelphij * if PRNG is not properly seeded, resort to secret exponent as 220296341Sdelphij * unpredictable seed 221296341Sdelphij */ 222296341Sdelphij RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0); 223296341Sdelphij } 224238384Sjkim 225296341Sdelphij if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { 226296341Sdelphij /* Set BN_FLG_CONSTTIME flag */ 227296341Sdelphij n = &local_n; 228296341Sdelphij BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); 229296341Sdelphij } else 230296341Sdelphij n = rsa->n; 231238384Sjkim 232296341Sdelphij ret = BN_BLINDING_create_param(NULL, e, n, ctx, 233296341Sdelphij rsa->meth->bn_mod_exp, rsa->_method_mod_n); 234296341Sdelphij if (ret == NULL) { 235296341Sdelphij RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); 236296341Sdelphij goto err; 237296341Sdelphij } 238296341Sdelphij CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret)); 239296341Sdelphij err: 240296341Sdelphij BN_CTX_end(ctx); 241296341Sdelphij if (in_ctx == NULL) 242296341Sdelphij BN_CTX_free(ctx); 243296341Sdelphij if (rsa->e == NULL) 244296341Sdelphij BN_free(e); 245238384Sjkim 246296341Sdelphij return ret; 247238384Sjkim} 248