1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/rsa/rsa_lib.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,487 @@
1.4 +/* crypto/rsa/rsa_lib.c */
1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.6 + * All rights reserved.
1.7 + *
1.8 + * This package is an SSL implementation written
1.9 + * by Eric Young (eay@cryptsoft.com).
1.10 + * The implementation was written so as to conform with Netscapes SSL.
1.11 + *
1.12 + * This library is free for commercial and non-commercial use as long as
1.13 + * the following conditions are aheared to. The following conditions
1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
1.15 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.16 + * included with this distribution is covered by the same copyright terms
1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.18 + *
1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.20 + * the code are not to be removed.
1.21 + * If this package is used in a product, Eric Young should be given attribution
1.22 + * as the author of the parts of the library used.
1.23 + * This can be in the form of a textual message at program startup or
1.24 + * in documentation (online or textual) provided with the package.
1.25 + *
1.26 + * Redistribution and use in source and binary forms, with or without
1.27 + * modification, are permitted provided that the following conditions
1.28 + * are met:
1.29 + * 1. Redistributions of source code must retain the copyright
1.30 + * notice, this list of conditions and the following disclaimer.
1.31 + * 2. Redistributions in binary form must reproduce the above copyright
1.32 + * notice, this list of conditions and the following disclaimer in the
1.33 + * documentation and/or other materials provided with the distribution.
1.34 + * 3. All advertising materials mentioning features or use of this software
1.35 + * must display the following acknowledgement:
1.36 + * "This product includes cryptographic software written by
1.37 + * Eric Young (eay@cryptsoft.com)"
1.38 + * The word 'cryptographic' can be left out if the rouines from the library
1.39 + * being used are not cryptographic related :-).
1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.41 + * the apps directory (application code) you must include an acknowledgement:
1.42 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.43 + *
1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.47 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.54 + * SUCH DAMAGE.
1.55 + *
1.56 + * The licence and distribution terms for any publically available version or
1.57 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.58 + * copied and put under another distribution licence
1.59 + * [including the GNU Public Licence.]
1.60 + */
1.61 +/*
1.62 + © Portions copyright (c) 2006 Nokia Corporation. All rights reserved.
1.63 + */
1.64 +
1.65 +#include <stdio.h>
1.66 +#include <openssl/crypto.h>
1.67 +#include "cryptlib.h"
1.68 +#include <openssl/lhash.h>
1.69 +#include <openssl/bn.h>
1.70 +#include <openssl/rsa.h>
1.71 +#include <openssl/rand.h>
1.72 +#ifndef OPENSSL_NO_ENGINE
1.73 +#include <openssl/engine.h>
1.74 +#endif
1.75 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
1.76 +#include "libcrypto_wsd_macros.h"
1.77 +#include "libcrypto_wsd.h"
1.78 +#endif
1.79 +
1.80 +
1.81 +const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT;
1.82 +
1.83 +#ifndef EMULATOR
1.84 +static const RSA_METHOD *default_RSA_meth=NULL;
1.85 +#else
1.86 +GET_STATIC_VAR_FROM_TLS(default_RSA_meth,rsa_lib,const RSA_METHOD *)
1.87 +#define default_RSA_meth (*GET_WSD_VAR_NAME(default_RSA_meth,rsa_lib, s)())
1.88 +#endif
1.89 +
1.90 +EXPORT_C RSA *RSA_new(void)
1.91 + {
1.92 + RSA *r=RSA_new_method(NULL);
1.93 +
1.94 + return r;
1.95 + }
1.96 +
1.97 +EXPORT_C void RSA_set_default_method(const RSA_METHOD *meth)
1.98 + {
1.99 + default_RSA_meth = meth;
1.100 + }
1.101 +
1.102 +EXPORT_C const RSA_METHOD *RSA_get_default_method(void)
1.103 + {
1.104 + if (default_RSA_meth == NULL)
1.105 + {
1.106 +#ifdef RSA_NULL
1.107 + default_RSA_meth=RSA_null_method();
1.108 +#else
1.109 +#if 0 /* was: #ifdef RSAref */
1.110 + default_RSA_meth=RSA_PKCS1_RSAref();
1.111 +#else
1.112 + default_RSA_meth=RSA_PKCS1_SSLeay();
1.113 +#endif
1.114 +#endif
1.115 + }
1.116 +
1.117 + return default_RSA_meth;
1.118 + }
1.119 +
1.120 +EXPORT_C const RSA_METHOD *RSA_get_method(const RSA *rsa)
1.121 + {
1.122 + return rsa->meth;
1.123 + }
1.124 +
1.125 +EXPORT_C int RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
1.126 + {
1.127 + /* NB: The caller is specifically setting a method, so it's not up to us
1.128 + * to deal with which ENGINE it comes from. */
1.129 + const RSA_METHOD *mtmp;
1.130 + mtmp = rsa->meth;
1.131 + if (mtmp->finish) mtmp->finish(rsa);
1.132 +#ifndef OPENSSL_NO_ENGINE
1.133 + if (rsa->engine)
1.134 + {
1.135 + ENGINE_finish(rsa->engine);
1.136 + rsa->engine = NULL;
1.137 + }
1.138 +#endif
1.139 + rsa->meth = meth;
1.140 + if (meth->init) meth->init(rsa);
1.141 + return 1;
1.142 + }
1.143 +
1.144 +EXPORT_C RSA *RSA_new_method(ENGINE *engine)
1.145 + {
1.146 + RSA *ret;
1.147 +
1.148 + ret=(RSA *)OPENSSL_malloc(sizeof(RSA));
1.149 + if (ret == NULL)
1.150 + {
1.151 + RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
1.152 + return NULL;
1.153 + }
1.154 +
1.155 + ret->meth = RSA_get_default_method();
1.156 +#ifndef OPENSSL_NO_ENGINE
1.157 + if (engine)
1.158 + {
1.159 + if (!ENGINE_init(engine))
1.160 + {
1.161 + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
1.162 + OPENSSL_free(ret);
1.163 + return NULL;
1.164 + }
1.165 + ret->engine = engine;
1.166 + }
1.167 + else
1.168 + ret->engine = ENGINE_get_default_RSA();
1.169 + if(ret->engine)
1.170 + {
1.171 + ret->meth = ENGINE_get_RSA(ret->engine);
1.172 + if(!ret->meth)
1.173 + {
1.174 + RSAerr(RSA_F_RSA_NEW_METHOD,
1.175 + ERR_R_ENGINE_LIB);
1.176 + ENGINE_finish(ret->engine);
1.177 + OPENSSL_free(ret);
1.178 + return NULL;
1.179 + }
1.180 + }
1.181 +#endif
1.182 +
1.183 + ret->pad=0;
1.184 + ret->version=0;
1.185 + ret->n=NULL;
1.186 + ret->e=NULL;
1.187 + ret->d=NULL;
1.188 + ret->p=NULL;
1.189 + ret->q=NULL;
1.190 + ret->dmp1=NULL;
1.191 + ret->dmq1=NULL;
1.192 + ret->iqmp=NULL;
1.193 + ret->references=1;
1.194 + ret->_method_mod_n=NULL;
1.195 + ret->_method_mod_p=NULL;
1.196 + ret->_method_mod_q=NULL;
1.197 + ret->blinding=NULL;
1.198 + ret->mt_blinding=NULL;
1.199 + ret->bignum_data=NULL;
1.200 + ret->flags=ret->meth->flags;
1.201 + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
1.202 + if ((ret->meth->init != NULL) && !ret->meth->init(ret))
1.203 + {
1.204 +#ifndef OPENSSL_NO_ENGINE
1.205 + if (ret->engine)
1.206 + ENGINE_finish(ret->engine);
1.207 +#endif
1.208 + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
1.209 + OPENSSL_free(ret);
1.210 + ret=NULL;
1.211 + }
1.212 + return(ret);
1.213 + }
1.214 +
1.215 +EXPORT_C void RSA_free(RSA *r)
1.216 + {
1.217 + int i;
1.218 +
1.219 + if (r == NULL) return;
1.220 +
1.221 + i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_RSA);
1.222 +#ifdef REF_PRINT
1.223 + REF_PRINT("RSA",r);
1.224 +#endif
1.225 + if (i > 0) return;
1.226 +#ifdef REF_CHECK
1.227 + if (i < 0)
1.228 + {
1.229 + fprintf(stderr,"RSA_free, bad reference count\n");
1.230 + abort();
1.231 + }
1.232 +#endif
1.233 +
1.234 + if (r->meth->finish)
1.235 + r->meth->finish(r);
1.236 +#ifndef OPENSSL_NO_ENGINE
1.237 + if (r->engine)
1.238 + ENGINE_finish(r->engine);
1.239 +#endif
1.240 +
1.241 + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data);
1.242 +
1.243 + if (r->n != NULL) BN_clear_free(r->n);
1.244 + if (r->e != NULL) BN_clear_free(r->e);
1.245 + if (r->d != NULL) BN_clear_free(r->d);
1.246 + if (r->p != NULL) BN_clear_free(r->p);
1.247 + if (r->q != NULL) BN_clear_free(r->q);
1.248 + if (r->dmp1 != NULL) BN_clear_free(r->dmp1);
1.249 + if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
1.250 + if (r->iqmp != NULL) BN_clear_free(r->iqmp);
1.251 + if (r->blinding != NULL) BN_BLINDING_free(r->blinding);
1.252 + if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding);
1.253 + if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data);
1.254 + OPENSSL_free(r);
1.255 + }
1.256 +
1.257 +EXPORT_C int RSA_up_ref(RSA *r)
1.258 + {
1.259 + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA);
1.260 +#ifdef REF_PRINT
1.261 + REF_PRINT("RSA",r);
1.262 +#endif
1.263 +#ifdef REF_CHECK
1.264 + if (i < 2)
1.265 + {
1.266 + fprintf(stderr, "RSA_up_ref, bad reference count\n");
1.267 + abort();
1.268 + }
1.269 +#endif
1.270 + return ((i > 1) ? 1 : 0);
1.271 + }
1.272 +
1.273 +EXPORT_C int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
1.274 + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
1.275 + {
1.276 + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp,
1.277 + new_func, dup_func, free_func);
1.278 + }
1.279 +
1.280 +EXPORT_C int RSA_set_ex_data(RSA *r, int idx, void *arg)
1.281 + {
1.282 + return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
1.283 + }
1.284 +
1.285 +EXPORT_C void *RSA_get_ex_data(const RSA *r, int idx)
1.286 + {
1.287 + return(CRYPTO_get_ex_data(&r->ex_data,idx));
1.288 + }
1.289 +
1.290 +EXPORT_C int RSA_size(const RSA *r)
1.291 + {
1.292 + return(BN_num_bytes(r->n));
1.293 + }
1.294 +
1.295 +EXPORT_C int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
1.296 + RSA *rsa, int padding)
1.297 + {
1.298 + return(rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding));
1.299 + }
1.300 +
1.301 +EXPORT_C int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
1.302 + RSA *rsa, int padding)
1.303 + {
1.304 + return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
1.305 + }
1.306 +
1.307 +EXPORT_C int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
1.308 + RSA *rsa, int padding)
1.309 + {
1.310 + return(rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding));
1.311 + }
1.312 +
1.313 +EXPORT_C int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
1.314 + RSA *rsa, int padding)
1.315 + {
1.316 + return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
1.317 + }
1.318 +
1.319 +EXPORT_C int RSA_flags(const RSA *r)
1.320 + {
1.321 + return((r == NULL)?0:r->meth->flags);
1.322 + }
1.323 +
1.324 +EXPORT_C void RSA_blinding_off(RSA *rsa)
1.325 + {
1.326 + if (rsa->blinding != NULL)
1.327 + {
1.328 + BN_BLINDING_free(rsa->blinding);
1.329 + rsa->blinding=NULL;
1.330 + }
1.331 + rsa->flags &= ~RSA_FLAG_BLINDING;
1.332 + rsa->flags |= RSA_FLAG_NO_BLINDING;
1.333 + }
1.334 +
1.335 +EXPORT_C int RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
1.336 + {
1.337 + int ret=0;
1.338 +
1.339 + if (rsa->blinding != NULL)
1.340 + RSA_blinding_off(rsa);
1.341 +
1.342 + rsa->blinding = RSA_setup_blinding(rsa, ctx);
1.343 + if (rsa->blinding == NULL)
1.344 + goto err;
1.345 +
1.346 + rsa->flags |= RSA_FLAG_BLINDING;
1.347 + rsa->flags &= ~RSA_FLAG_NO_BLINDING;
1.348 + ret=1;
1.349 +err:
1.350 + return(ret);
1.351 + }
1.352 +
1.353 +static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
1.354 + const BIGNUM *q, BN_CTX *ctx)
1.355 +{
1.356 + BIGNUM *ret = NULL, *r0, *r1, *r2;
1.357 +
1.358 + if (d == NULL || p == NULL || q == NULL)
1.359 + return NULL;
1.360 +
1.361 + BN_CTX_start(ctx);
1.362 + r0 = BN_CTX_get(ctx);
1.363 + r1 = BN_CTX_get(ctx);
1.364 + r2 = BN_CTX_get(ctx);
1.365 + if (r2 == NULL)
1.366 + goto err;
1.367 +
1.368 + if (!BN_sub(r1, p, BN_value_one())) goto err;
1.369 + if (!BN_sub(r2, q, BN_value_one())) goto err;
1.370 + if (!BN_mul(r0, r1, r2, ctx)) goto err;
1.371 +
1.372 + ret = BN_mod_inverse(NULL, d, r0, ctx);
1.373 +err:
1.374 + BN_CTX_end(ctx);
1.375 + return ret;
1.376 +}
1.377 +
1.378 +EXPORT_C BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
1.379 +{
1.380 + BIGNUM local_n;
1.381 + BIGNUM *e,*n;
1.382 + BN_CTX *ctx;
1.383 + BN_BLINDING *ret = NULL;
1.384 +
1.385 + if (in_ctx == NULL)
1.386 + {
1.387 + if ((ctx = BN_CTX_new()) == NULL) return 0;
1.388 + }
1.389 + else
1.390 + ctx = in_ctx;
1.391 +
1.392 + BN_CTX_start(ctx);
1.393 + e = BN_CTX_get(ctx);
1.394 + if (e == NULL)
1.395 + {
1.396 + RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
1.397 + goto err;
1.398 + }
1.399 +
1.400 + if (rsa->e == NULL)
1.401 + {
1.402 + e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
1.403 + if (e == NULL)
1.404 + {
1.405 + RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT);
1.406 + goto err;
1.407 + }
1.408 + }
1.409 + else
1.410 + e = rsa->e;
1.411 +
1.412 +
1.413 + if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
1.414 + {
1.415 + /* if PRNG is not properly seeded, resort to secret
1.416 + * exponent as unpredictable seed */
1.417 + RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
1.418 + }
1.419 +
1.420 + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
1.421 + {
1.422 + /* Set BN_FLG_CONSTTIME flag */
1.423 + n = &local_n;
1.424 + BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
1.425 + }
1.426 + else
1.427 + n = rsa->n;
1.428 +
1.429 + ret = BN_BLINDING_create_param(NULL, e, n, ctx,
1.430 + rsa->meth->bn_mod_exp, rsa->_method_mod_n);
1.431 + if (ret == NULL)
1.432 + {
1.433 + RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
1.434 + goto err;
1.435 + }
1.436 + BN_BLINDING_set_thread_id(ret, CRYPTO_thread_id());
1.437 +err:
1.438 + BN_CTX_end(ctx);
1.439 + if (in_ctx == NULL)
1.440 + BN_CTX_free(ctx);
1.441 + if(rsa->e == NULL)
1.442 + BN_free(e);
1.443 +
1.444 + return ret;
1.445 +}
1.446 +
1.447 +EXPORT_C int RSA_memory_lock(RSA *r)
1.448 + {
1.449 + int i,j,k,off;
1.450 + char *p;
1.451 + BIGNUM *bn,**t[6],*b;
1.452 + BN_ULONG *ul;
1.453 +
1.454 + if (r->d == NULL) return(1);
1.455 + t[0]= &r->d;
1.456 + t[1]= &r->p;
1.457 + t[2]= &r->q;
1.458 + t[3]= &r->dmp1;
1.459 + t[4]= &r->dmq1;
1.460 + t[5]= &r->iqmp;
1.461 + k=sizeof(BIGNUM)*6;
1.462 + off=k/sizeof(BN_ULONG)+1;
1.463 + j=1;
1.464 + for (i=0; i<6; i++)
1.465 + j+= (*t[i])->top;
1.466 + if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL)
1.467 + {
1.468 + RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE);
1.469 + return(0);
1.470 + }
1.471 + bn=(BIGNUM *)p;
1.472 + ul=(BN_ULONG *)&(p[off]);
1.473 + for (i=0; i<6; i++)
1.474 + {
1.475 + b= *(t[i]);
1.476 + *(t[i])= &(bn[i]);
1.477 + memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM));
1.478 + bn[i].flags=BN_FLG_STATIC_DATA;
1.479 + bn[i].d=ul;
1.480 + memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top);
1.481 + ul+=b->top;
1.482 + BN_clear_free(b);
1.483 + }
1.484 +
1.485 + /* I should fix this so it can still be done */
1.486 + r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC);
1.487 +
1.488 + r->bignum_data=p;
1.489 + return(1);
1.490 + }