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