1 /* 2 * Copyright 1998-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <openssl/opensslconf.h> 11 #include "internal/cryptlib.h" 12 #include "bn_local.h" 13 14 #define BN_BLINDING_COUNTER 32 15 16 struct bn_blinding_st { 17 BIGNUM *A; 18 BIGNUM *Ai; 19 BIGNUM *e; 20 BIGNUM *mod; /* just a reference */ 21 CRYPTO_THREAD_ID tid; 22 int counter; 23 unsigned long flags; 24 BN_MONT_CTX *m_ctx; 25 int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 26 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 27 CRYPTO_RWLOCK *lock; 28 }; 29 30 BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) 31 { 32 BN_BLINDING *ret = NULL; 33 34 bn_check_top(mod); 35 36 if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { 37 BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE); 38 return NULL; 39 } 40 41 ret->lock = CRYPTO_THREAD_lock_new(); 42 if (ret->lock == NULL) { 43 BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE); 44 OPENSSL_free(ret); 45 return NULL; 46 } 47 48 BN_BLINDING_set_current_thread(ret); 49 50 if (A != NULL) { 51 if ((ret->A = BN_dup(A)) == NULL) 52 goto err; 53 } 54 55 if (Ai != NULL) { 56 if ((ret->Ai = BN_dup(Ai)) == NULL) 57 goto err; 58 } 59 60 /* save a copy of mod in the BN_BLINDING structure */ 61 if ((ret->mod = BN_dup(mod)) == NULL) 62 goto err; 63 64 if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) 65 BN_set_flags(ret->mod, BN_FLG_CONSTTIME); 66 67 /* 68 * Set the counter to the special value -1 to indicate that this is 69 * never-used fresh blinding that does not need updating before first 70 * use. 71 */ 72 ret->counter = -1; 73 74 return ret; 75 76 err: 77 BN_BLINDING_free(ret); 78 return NULL; 79 } 80 81 void BN_BLINDING_free(BN_BLINDING *r) 82 { 83 if (r == NULL) 84 return; 85 BN_free(r->A); 86 BN_free(r->Ai); 87 BN_free(r->e); 88 BN_free(r->mod); 89 CRYPTO_THREAD_lock_free(r->lock); 90 OPENSSL_free(r); 91 } 92 93 int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx) 94 { 95 int ret = 0; 96 97 if ((b->A == NULL) || (b->Ai == NULL)) { 98 BNerr(BN_F_BN_BLINDING_UPDATE, BN_R_NOT_INITIALIZED); 99 goto err; 100 } 101 102 if (b->counter == -1) 103 b->counter = 0; 104 105 if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL && 106 !(b->flags & BN_BLINDING_NO_RECREATE)) { 107 /* re-create blinding parameters */ 108 if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL)) 109 goto err; 110 } else if (!(b->flags & BN_BLINDING_NO_UPDATE)) { 111 if (b->m_ctx != NULL) { 112 if (!bn_mul_mont_fixed_top(b->Ai, b->Ai, b->Ai, b->m_ctx, ctx) 113 || !bn_mul_mont_fixed_top(b->A, b->A, b->A, b->m_ctx, ctx)) 114 goto err; 115 } else { 116 if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx) 117 || !BN_mod_mul(b->A, b->A, b->A, b->mod, ctx)) 118 goto err; 119 } 120 } 121 122 ret = 1; 123 err: 124 if (b->counter == BN_BLINDING_COUNTER) 125 b->counter = 0; 126 return ret; 127 } 128 129 int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) 130 { 131 return BN_BLINDING_convert_ex(n, NULL, b, ctx); 132 } 133 134 int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) 135 { 136 int ret = 1; 137 138 bn_check_top(n); 139 140 if ((b->A == NULL) || (b->Ai == NULL)) { 141 BNerr(BN_F_BN_BLINDING_CONVERT_EX, BN_R_NOT_INITIALIZED); 142 return 0; 143 } 144 145 if (b->counter == -1) 146 /* Fresh blinding, doesn't need updating. */ 147 b->counter = 0; 148 else if (!BN_BLINDING_update(b, ctx)) 149 return 0; 150 151 if (r != NULL && (BN_copy(r, b->Ai) == NULL)) 152 return 0; 153 154 if (b->m_ctx != NULL) 155 ret = BN_mod_mul_montgomery(n, n, b->A, b->m_ctx, ctx); 156 else 157 ret = BN_mod_mul(n, n, b->A, b->mod, ctx); 158 159 return ret; 160 } 161 162 int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) 163 { 164 return BN_BLINDING_invert_ex(n, NULL, b, ctx); 165 } 166 167 int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, 168 BN_CTX *ctx) 169 { 170 int ret; 171 172 bn_check_top(n); 173 174 if (r == NULL && (r = b->Ai) == NULL) { 175 BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED); 176 return 0; 177 } 178 179 if (b->m_ctx != NULL) { 180 /* ensure that BN_mod_mul_montgomery takes pre-defined path */ 181 if (n->dmax >= r->top) { 182 size_t i, rtop = r->top, ntop = n->top; 183 BN_ULONG mask; 184 185 for (i = 0; i < rtop; i++) { 186 mask = (BN_ULONG)0 - ((i - ntop) >> (8 * sizeof(i) - 1)); 187 n->d[i] &= mask; 188 } 189 mask = (BN_ULONG)0 - ((rtop - ntop) >> (8 * sizeof(ntop) - 1)); 190 /* always true, if (rtop >= ntop) n->top = r->top; */ 191 n->top = (int)(rtop & ~mask) | (ntop & mask); 192 n->flags |= (BN_FLG_FIXED_TOP & ~mask); 193 } 194 ret = BN_mod_mul_montgomery(n, n, r, b->m_ctx, ctx); 195 } else { 196 ret = BN_mod_mul(n, n, r, b->mod, ctx); 197 } 198 199 bn_check_top(n); 200 return ret; 201 } 202 203 int BN_BLINDING_is_current_thread(BN_BLINDING *b) 204 { 205 return CRYPTO_THREAD_compare_id(CRYPTO_THREAD_get_current_id(), b->tid); 206 } 207 208 void BN_BLINDING_set_current_thread(BN_BLINDING *b) 209 { 210 b->tid = CRYPTO_THREAD_get_current_id(); 211 } 212 213 int BN_BLINDING_lock(BN_BLINDING *b) 214 { 215 return CRYPTO_THREAD_write_lock(b->lock); 216 } 217 218 int BN_BLINDING_unlock(BN_BLINDING *b) 219 { 220 return CRYPTO_THREAD_unlock(b->lock); 221 } 222 223 unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b) 224 { 225 return b->flags; 226 } 227 228 void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags) 229 { 230 b->flags = flags; 231 } 232 233 BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, 234 const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, 235 int (*bn_mod_exp) (BIGNUM *r, 236 const BIGNUM *a, 237 const BIGNUM *p, 238 const BIGNUM *m, 239 BN_CTX *ctx, 240 BN_MONT_CTX *m_ctx), 241 BN_MONT_CTX *m_ctx) 242 { 243 int retry_counter = 32; 244 BN_BLINDING *ret = NULL; 245 246 if (b == NULL) 247 ret = BN_BLINDING_new(NULL, NULL, m); 248 else 249 ret = b; 250 251 if (ret == NULL) 252 goto err; 253 254 if (ret->A == NULL && (ret->A = BN_new()) == NULL) 255 goto err; 256 if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL) 257 goto err; 258 259 if (e != NULL) { 260 BN_free(ret->e); 261 ret->e = BN_dup(e); 262 } 263 if (ret->e == NULL) 264 goto err; 265 266 if (bn_mod_exp != NULL) 267 ret->bn_mod_exp = bn_mod_exp; 268 if (m_ctx != NULL) 269 ret->m_ctx = m_ctx; 270 271 do { 272 int rv; 273 if (!BN_priv_rand_range(ret->A, ret->mod)) 274 goto err; 275 if (int_bn_mod_inverse(ret->Ai, ret->A, ret->mod, ctx, &rv)) 276 break; 277 278 /* 279 * this should almost never happen for good RSA keys 280 */ 281 if (!rv) 282 goto err; 283 284 if (retry_counter-- == 0) { 285 BNerr(BN_F_BN_BLINDING_CREATE_PARAM, BN_R_TOO_MANY_ITERATIONS); 286 goto err; 287 } 288 } while (1); 289 290 if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) { 291 if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx)) 292 goto err; 293 } else { 294 if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx)) 295 goto err; 296 } 297 298 if (ret->m_ctx != NULL) { 299 if (!bn_to_mont_fixed_top(ret->Ai, ret->Ai, ret->m_ctx, ctx) 300 || !bn_to_mont_fixed_top(ret->A, ret->A, ret->m_ctx, ctx)) 301 goto err; 302 } 303 304 return ret; 305 err: 306 if (b == NULL) { 307 BN_BLINDING_free(ret); 308 ret = NULL; 309 } 310 311 return ret; 312 } 313