bn_blind.c revision 194206
155714Skris/* crypto/bn/bn_blind.c */ 2160814Ssimon/* ==================================================================== 3160814Ssimon * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 4160814Ssimon * 5160814Ssimon * Redistribution and use in source and binary forms, with or without 6160814Ssimon * modification, are permitted provided that the following conditions 7160814Ssimon * are met: 8160814Ssimon * 9160814Ssimon * 1. Redistributions of source code must retain the above copyright 10160814Ssimon * notice, this list of conditions and the following disclaimer. 11160814Ssimon * 12160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 13160814Ssimon * notice, this list of conditions and the following disclaimer in 14160814Ssimon * the documentation and/or other materials provided with the 15160814Ssimon * distribution. 16160814Ssimon * 17160814Ssimon * 3. All advertising materials mentioning features or use of this 18160814Ssimon * software must display the following acknowledgment: 19160814Ssimon * "This product includes software developed by the OpenSSL Project 20160814Ssimon * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21160814Ssimon * 22160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23160814Ssimon * endorse or promote products derived from this software without 24160814Ssimon * prior written permission. For written permission, please contact 25160814Ssimon * openssl-core@openssl.org. 26160814Ssimon * 27160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 28160814Ssimon * nor may "OpenSSL" appear in their names without prior written 29160814Ssimon * permission of the OpenSSL Project. 30160814Ssimon * 31160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 32160814Ssimon * acknowledgment: 33160814Ssimon * "This product includes software developed by the OpenSSL Project 34160814Ssimon * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35160814Ssimon * 36160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 48160814Ssimon * ==================================================================== 49160814Ssimon * 50160814Ssimon * This product includes cryptographic software written by Eric Young 51160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 52160814Ssimon * Hudson (tjh@cryptsoft.com). 53160814Ssimon * 54160814Ssimon */ 5555714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 5655714Skris * All rights reserved. 5755714Skris * 5855714Skris * This package is an SSL implementation written 5955714Skris * by Eric Young (eay@cryptsoft.com). 6055714Skris * The implementation was written so as to conform with Netscapes SSL. 6155714Skris * 6255714Skris * This library is free for commercial and non-commercial use as long as 6355714Skris * the following conditions are aheared to. The following conditions 6455714Skris * apply to all code found in this distribution, be it the RC4, RSA, 6555714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 6655714Skris * included with this distribution is covered by the same copyright terms 6755714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 6855714Skris * 6955714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 7055714Skris * the code are not to be removed. 7155714Skris * If this package is used in a product, Eric Young should be given attribution 7255714Skris * as the author of the parts of the library used. 7355714Skris * This can be in the form of a textual message at program startup or 7455714Skris * in documentation (online or textual) provided with the package. 7555714Skris * 7655714Skris * Redistribution and use in source and binary forms, with or without 7755714Skris * modification, are permitted provided that the following conditions 7855714Skris * are met: 7955714Skris * 1. Redistributions of source code must retain the copyright 8055714Skris * notice, this list of conditions and the following disclaimer. 8155714Skris * 2. Redistributions in binary form must reproduce the above copyright 8255714Skris * notice, this list of conditions and the following disclaimer in the 8355714Skris * documentation and/or other materials provided with the distribution. 8455714Skris * 3. All advertising materials mentioning features or use of this software 8555714Skris * must display the following acknowledgement: 8655714Skris * "This product includes cryptographic software written by 8755714Skris * Eric Young (eay@cryptsoft.com)" 8855714Skris * The word 'cryptographic' can be left out if the rouines from the library 8955714Skris * being used are not cryptographic related :-). 9055714Skris * 4. If you include any Windows specific code (or a derivative thereof) from 9155714Skris * the apps directory (application code) you must include an acknowledgement: 9255714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 9355714Skris * 9455714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 9555714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9655714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 9755714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 9855714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 9955714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 10055714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 10155714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 10255714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 10355714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 10455714Skris * SUCH DAMAGE. 10555714Skris * 10655714Skris * The licence and distribution terms for any publically available version or 10755714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 10855714Skris * copied and put under another distribution licence 10955714Skris * [including the GNU Public Licence.] 11055714Skris */ 11155714Skris 11255714Skris#include <stdio.h> 11355714Skris#include "cryptlib.h" 11455714Skris#include "bn_lcl.h" 11555714Skris 116160814Ssimon#define BN_BLINDING_COUNTER 32 117160814Ssimon 118160814Ssimonstruct bn_blinding_st 11955714Skris { 120160814Ssimon BIGNUM *A; 121160814Ssimon BIGNUM *Ai; 122160814Ssimon BIGNUM *e; 123160814Ssimon BIGNUM *mod; /* just a reference */ 124160814Ssimon unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b; 125160814Ssimon * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */ 126160814Ssimon unsigned int counter; 127160814Ssimon unsigned long flags; 128160814Ssimon BN_MONT_CTX *m_ctx; 129160814Ssimon int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 130160814Ssimon const BIGNUM *m, BN_CTX *ctx, 131160814Ssimon BN_MONT_CTX *m_ctx); 132160814Ssimon }; 133160814Ssimon 134194206SsimonBN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod) 135160814Ssimon { 13655714Skris BN_BLINDING *ret=NULL; 13755714Skris 13855714Skris bn_check_top(mod); 13955714Skris 14068651Skris if ((ret=(BN_BLINDING *)OPENSSL_malloc(sizeof(BN_BLINDING))) == NULL) 14155714Skris { 14255714Skris BNerr(BN_F_BN_BLINDING_NEW,ERR_R_MALLOC_FAILURE); 14355714Skris return(NULL); 14455714Skris } 14555714Skris memset(ret,0,sizeof(BN_BLINDING)); 146160814Ssimon if (A != NULL) 147160814Ssimon { 148160814Ssimon if ((ret->A = BN_dup(A)) == NULL) goto err; 149160814Ssimon } 150160814Ssimon if (Ai != NULL) 151160814Ssimon { 152160814Ssimon if ((ret->Ai = BN_dup(Ai)) == NULL) goto err; 153160814Ssimon } 154194206Ssimon 155194206Ssimon /* save a copy of mod in the BN_BLINDING structure */ 156194206Ssimon if ((ret->mod = BN_dup(mod)) == NULL) goto err; 157194206Ssimon if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) 158194206Ssimon BN_set_flags(ret->mod, BN_FLG_CONSTTIME); 159194206Ssimon 160160814Ssimon ret->counter = BN_BLINDING_COUNTER; 16155714Skris return(ret); 16255714Skriserr: 16355714Skris if (ret != NULL) BN_BLINDING_free(ret); 16455714Skris return(NULL); 16555714Skris } 16655714Skris 16755714Skrisvoid BN_BLINDING_free(BN_BLINDING *r) 16855714Skris { 16955714Skris if(r == NULL) 17055714Skris return; 17155714Skris 17255714Skris if (r->A != NULL) BN_free(r->A ); 17355714Skris if (r->Ai != NULL) BN_free(r->Ai); 174160814Ssimon if (r->e != NULL) BN_free(r->e ); 175194206Ssimon if (r->mod != NULL) BN_free(r->mod); 17668651Skris OPENSSL_free(r); 17755714Skris } 17855714Skris 17955714Skrisint BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx) 18055714Skris { 18155714Skris int ret=0; 18255714Skris 18355714Skris if ((b->A == NULL) || (b->Ai == NULL)) 18455714Skris { 18555714Skris BNerr(BN_F_BN_BLINDING_UPDATE,BN_R_NOT_INITIALIZED); 18655714Skris goto err; 18755714Skris } 18855714Skris 189160814Ssimon if (--(b->counter) == 0 && b->e != NULL && 190160814Ssimon !(b->flags & BN_BLINDING_NO_RECREATE)) 191160814Ssimon { 192160814Ssimon /* re-create blinding parameters */ 193160814Ssimon if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL)) 194160814Ssimon goto err; 195160814Ssimon } 196160814Ssimon else if (!(b->flags & BN_BLINDING_NO_UPDATE)) 197160814Ssimon { 198160814Ssimon if (!BN_mod_mul(b->A,b->A,b->A,b->mod,ctx)) goto err; 199160814Ssimon if (!BN_mod_mul(b->Ai,b->Ai,b->Ai,b->mod,ctx)) goto err; 200160814Ssimon } 201160814Ssimon 20255714Skris ret=1; 20355714Skriserr: 204160814Ssimon if (b->counter == 0) 205160814Ssimon b->counter = BN_BLINDING_COUNTER; 20655714Skris return(ret); 20755714Skris } 20855714Skris 20955714Skrisint BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) 21055714Skris { 211160814Ssimon return BN_BLINDING_convert_ex(n, NULL, b, ctx); 212160814Ssimon } 213160814Ssimon 214160814Ssimonint BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) 215160814Ssimon { 216160814Ssimon int ret = 1; 217160814Ssimon 21855714Skris bn_check_top(n); 21955714Skris 22055714Skris if ((b->A == NULL) || (b->Ai == NULL)) 22155714Skris { 222160814Ssimon BNerr(BN_F_BN_BLINDING_CONVERT_EX,BN_R_NOT_INITIALIZED); 22355714Skris return(0); 22455714Skris } 225160814Ssimon 226160814Ssimon if (r != NULL) 227160814Ssimon { 228160814Ssimon if (!BN_copy(r, b->Ai)) ret=0; 229160814Ssimon } 230160814Ssimon 231160814Ssimon if (!BN_mod_mul(n,n,b->A,b->mod,ctx)) ret=0; 232160814Ssimon 233160814Ssimon return ret; 23455714Skris } 23555714Skris 23655714Skrisint BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) 23755714Skris { 238160814Ssimon return BN_BLINDING_invert_ex(n, NULL, b, ctx); 239160814Ssimon } 240160814Ssimon 241160814Ssimonint BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) 242160814Ssimon { 24355714Skris int ret; 24455714Skris 24555714Skris bn_check_top(n); 24655714Skris if ((b->A == NULL) || (b->Ai == NULL)) 24755714Skris { 248160814Ssimon BNerr(BN_F_BN_BLINDING_INVERT_EX,BN_R_NOT_INITIALIZED); 24955714Skris return(0); 25055714Skris } 251160814Ssimon 252160814Ssimon if (r != NULL) 253160814Ssimon ret = BN_mod_mul(n, n, r, b->mod, ctx); 254160814Ssimon else 255160814Ssimon ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx); 256160814Ssimon 257160814Ssimon if (ret >= 0) 25855714Skris { 25955714Skris if (!BN_BLINDING_update(b,ctx)) 26055714Skris return(0); 26155714Skris } 262160814Ssimon bn_check_top(n); 26355714Skris return(ret); 26455714Skris } 26555714Skris 266160814Ssimonunsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b) 267160814Ssimon { 268160814Ssimon return b->thread_id; 269160814Ssimon } 270160814Ssimon 271160814Ssimonvoid BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n) 272160814Ssimon { 273160814Ssimon b->thread_id = n; 274160814Ssimon } 275160814Ssimon 276160814Ssimonunsigned long BN_BLINDING_get_flags(const BN_BLINDING *b) 277160814Ssimon { 278160814Ssimon return b->flags; 279160814Ssimon } 280160814Ssimon 281160814Ssimonvoid BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags) 282160814Ssimon { 283160814Ssimon b->flags = flags; 284160814Ssimon } 285160814Ssimon 286160814SsimonBN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, 287194206Ssimon const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx, 288160814Ssimon int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 289160814Ssimon const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), 290160814Ssimon BN_MONT_CTX *m_ctx) 291160814Ssimon{ 292160814Ssimon int retry_counter = 32; 293160814Ssimon BN_BLINDING *ret = NULL; 294160814Ssimon 295160814Ssimon if (b == NULL) 296160814Ssimon ret = BN_BLINDING_new(NULL, NULL, m); 297160814Ssimon else 298160814Ssimon ret = b; 299160814Ssimon 300160814Ssimon if (ret == NULL) 301160814Ssimon goto err; 302160814Ssimon 303160814Ssimon if (ret->A == NULL && (ret->A = BN_new()) == NULL) 304160814Ssimon goto err; 305160814Ssimon if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL) 306160814Ssimon goto err; 307160814Ssimon 308160814Ssimon if (e != NULL) 309160814Ssimon { 310160814Ssimon if (ret->e != NULL) 311160814Ssimon BN_free(ret->e); 312160814Ssimon ret->e = BN_dup(e); 313160814Ssimon } 314160814Ssimon if (ret->e == NULL) 315160814Ssimon goto err; 316160814Ssimon 317160814Ssimon if (bn_mod_exp != NULL) 318160814Ssimon ret->bn_mod_exp = bn_mod_exp; 319160814Ssimon if (m_ctx != NULL) 320160814Ssimon ret->m_ctx = m_ctx; 321160814Ssimon 322160814Ssimon do { 323160814Ssimon if (!BN_rand_range(ret->A, ret->mod)) goto err; 324160814Ssimon if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL) 325160814Ssimon { 326160814Ssimon /* this should almost never happen for good RSA keys */ 327160814Ssimon unsigned long error = ERR_peek_last_error(); 328160814Ssimon if (ERR_GET_REASON(error) == BN_R_NO_INVERSE) 329160814Ssimon { 330160814Ssimon if (retry_counter-- == 0) 331160814Ssimon { 332160814Ssimon BNerr(BN_F_BN_BLINDING_CREATE_PARAM, 333160814Ssimon BN_R_TOO_MANY_ITERATIONS); 334160814Ssimon goto err; 335160814Ssimon } 336160814Ssimon ERR_clear_error(); 337160814Ssimon } 338160814Ssimon else 339160814Ssimon goto err; 340160814Ssimon } 341160814Ssimon else 342160814Ssimon break; 343160814Ssimon } while (1); 344160814Ssimon 345160814Ssimon if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) 346160814Ssimon { 347160814Ssimon if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx)) 348160814Ssimon goto err; 349160814Ssimon } 350160814Ssimon else 351160814Ssimon { 352160814Ssimon if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx)) 353160814Ssimon goto err; 354160814Ssimon } 355160814Ssimon 356160814Ssimon return ret; 357160814Ssimonerr: 358160814Ssimon if (b == NULL && ret != NULL) 359160814Ssimon { 360160814Ssimon BN_BLINDING_free(ret); 361160814Ssimon ret = NULL; 362160814Ssimon } 363160814Ssimon 364160814Ssimon return ret; 365160814Ssimon} 366