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 ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); 38 return NULL; 39 } 40 41 ret->lock = CRYPTO_THREAD_lock_new(); 42 if (ret->lock == NULL) { 43 ERR_raise(ERR_LIB_BN, 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 ERR_raise(ERR_LIB_BN, 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 ERR_raise(ERR_LIB_BN, 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 ERR_raise(ERR_LIB_BN, 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_mul_mont_fixed_top(n, n, r, b->m_ctx, ctx); 195 bn_correct_top_consttime(n); 196 } else { 197 ret = BN_mod_mul(n, n, r, b->mod, ctx); 198 } 199 200 bn_check_top(n); 201 return ret; 202 } 203 204 int BN_BLINDING_is_current_thread(BN_BLINDING *b) 205 { 206 return CRYPTO_THREAD_compare_id(CRYPTO_THREAD_get_current_id(), b->tid); 207 } 208 209 void BN_BLINDING_set_current_thread(BN_BLINDING *b) 210 { 211 b->tid = CRYPTO_THREAD_get_current_id(); 212 } 213 214 int BN_BLINDING_lock(BN_BLINDING *b) 215 { 216 return CRYPTO_THREAD_write_lock(b->lock); 217 } 218 219 int BN_BLINDING_unlock(BN_BLINDING *b) 220 { 221 return CRYPTO_THREAD_unlock(b->lock); 222 } 223 224 unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b) 225 { 226 return b->flags; 227 } 228 229 void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags) 230 { 231 b->flags = flags; 232 } 233 234 BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, 235 const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, 236 int (*bn_mod_exp) (BIGNUM *r, 237 const BIGNUM *a, 238 const BIGNUM *p, 239 const BIGNUM *m, 240 BN_CTX *ctx, 241 BN_MONT_CTX *m_ctx), 242 BN_MONT_CTX *m_ctx) 243 { 244 int retry_counter = 32; 245 BN_BLINDING *ret = NULL; 246 247 if (b == NULL) 248 ret = BN_BLINDING_new(NULL, NULL, m); 249 else 250 ret = b; 251 252 if (ret == NULL) 253 goto err; 254 255 if (ret->A == NULL && (ret->A = BN_new()) == NULL) 256 goto err; 257 if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL) 258 goto err; 259 260 if (e != NULL) { 261 BN_free(ret->e); 262 ret->e = BN_dup(e); 263 } 264 if (ret->e == NULL) 265 goto err; 266 267 if (bn_mod_exp != NULL) 268 ret->bn_mod_exp = bn_mod_exp; 269 if (m_ctx != NULL) 270 ret->m_ctx = m_ctx; 271 272 do { 273 int rv; 274 if (!BN_priv_rand_range_ex(ret->A, ret->mod, 0, ctx)) 275 goto err; 276 if (int_bn_mod_inverse(ret->Ai, ret->A, ret->mod, ctx, &rv)) 277 break; 278 279 /* 280 * this should almost never happen for good RSA keys 281 */ 282 if (!rv) 283 goto err; 284 285 if (retry_counter-- == 0) { 286 ERR_raise(ERR_LIB_BN, BN_R_TOO_MANY_ITERATIONS); 287 goto err; 288 } 289 } while (1); 290 291 if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) { 292 if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx)) 293 goto err; 294 } else { 295 if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx)) 296 goto err; 297 } 298 299 if (ret->m_ctx != NULL) { 300 if (!bn_to_mont_fixed_top(ret->Ai, ret->Ai, ret->m_ctx, ctx) 301 || !bn_to_mont_fixed_top(ret->A, ret->A, ret->m_ctx, ctx)) 302 goto err; 303 } 304 305 return ret; 306 err: 307 if (b == NULL) { 308 BN_BLINDING_free(ret); 309 ret = NULL; 310 } 311 312 return ret; 313 } 314