1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 11e1051a39Sopenharmony_ci#include "bn_local.h" 12e1051a39Sopenharmony_ci 13e1051a39Sopenharmony_ci/* 14e1051a39Sopenharmony_ci * bn_mod_inverse_no_branch is a special version of BN_mod_inverse. It does 15e1051a39Sopenharmony_ci * not contain branches that may leak sensitive information. 16e1051a39Sopenharmony_ci * 17e1051a39Sopenharmony_ci * This is a static function, we ensure all callers in this file pass valid 18e1051a39Sopenharmony_ci * arguments: all passed pointers here are non-NULL. 19e1051a39Sopenharmony_ci */ 20e1051a39Sopenharmony_cistatic ossl_inline 21e1051a39Sopenharmony_ciBIGNUM *bn_mod_inverse_no_branch(BIGNUM *in, 22e1051a39Sopenharmony_ci const BIGNUM *a, const BIGNUM *n, 23e1051a39Sopenharmony_ci BN_CTX *ctx, int *pnoinv) 24e1051a39Sopenharmony_ci{ 25e1051a39Sopenharmony_ci BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; 26e1051a39Sopenharmony_ci BIGNUM *ret = NULL; 27e1051a39Sopenharmony_ci int sign; 28e1051a39Sopenharmony_ci 29e1051a39Sopenharmony_ci bn_check_top(a); 30e1051a39Sopenharmony_ci bn_check_top(n); 31e1051a39Sopenharmony_ci 32e1051a39Sopenharmony_ci BN_CTX_start(ctx); 33e1051a39Sopenharmony_ci A = BN_CTX_get(ctx); 34e1051a39Sopenharmony_ci B = BN_CTX_get(ctx); 35e1051a39Sopenharmony_ci X = BN_CTX_get(ctx); 36e1051a39Sopenharmony_ci D = BN_CTX_get(ctx); 37e1051a39Sopenharmony_ci M = BN_CTX_get(ctx); 38e1051a39Sopenharmony_ci Y = BN_CTX_get(ctx); 39e1051a39Sopenharmony_ci T = BN_CTX_get(ctx); 40e1051a39Sopenharmony_ci if (T == NULL) 41e1051a39Sopenharmony_ci goto err; 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_ci if (in == NULL) 44e1051a39Sopenharmony_ci R = BN_new(); 45e1051a39Sopenharmony_ci else 46e1051a39Sopenharmony_ci R = in; 47e1051a39Sopenharmony_ci if (R == NULL) 48e1051a39Sopenharmony_ci goto err; 49e1051a39Sopenharmony_ci 50e1051a39Sopenharmony_ci if (!BN_one(X)) 51e1051a39Sopenharmony_ci goto err; 52e1051a39Sopenharmony_ci BN_zero(Y); 53e1051a39Sopenharmony_ci if (BN_copy(B, a) == NULL) 54e1051a39Sopenharmony_ci goto err; 55e1051a39Sopenharmony_ci if (BN_copy(A, n) == NULL) 56e1051a39Sopenharmony_ci goto err; 57e1051a39Sopenharmony_ci A->neg = 0; 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_ci if (B->neg || (BN_ucmp(B, A) >= 0)) { 60e1051a39Sopenharmony_ci /* 61e1051a39Sopenharmony_ci * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, 62e1051a39Sopenharmony_ci * BN_div_no_branch will be called eventually. 63e1051a39Sopenharmony_ci */ 64e1051a39Sopenharmony_ci { 65e1051a39Sopenharmony_ci BIGNUM local_B; 66e1051a39Sopenharmony_ci bn_init(&local_B); 67e1051a39Sopenharmony_ci BN_with_flags(&local_B, B, BN_FLG_CONSTTIME); 68e1051a39Sopenharmony_ci if (!BN_nnmod(B, &local_B, A, ctx)) 69e1051a39Sopenharmony_ci goto err; 70e1051a39Sopenharmony_ci /* Ensure local_B goes out of scope before any further use of B */ 71e1051a39Sopenharmony_ci } 72e1051a39Sopenharmony_ci } 73e1051a39Sopenharmony_ci sign = -1; 74e1051a39Sopenharmony_ci /*- 75e1051a39Sopenharmony_ci * From B = a mod |n|, A = |n| it follows that 76e1051a39Sopenharmony_ci * 77e1051a39Sopenharmony_ci * 0 <= B < A, 78e1051a39Sopenharmony_ci * -sign*X*a == B (mod |n|), 79e1051a39Sopenharmony_ci * sign*Y*a == A (mod |n|). 80e1051a39Sopenharmony_ci */ 81e1051a39Sopenharmony_ci 82e1051a39Sopenharmony_ci while (!BN_is_zero(B)) { 83e1051a39Sopenharmony_ci BIGNUM *tmp; 84e1051a39Sopenharmony_ci 85e1051a39Sopenharmony_ci /*- 86e1051a39Sopenharmony_ci * 0 < B < A, 87e1051a39Sopenharmony_ci * (*) -sign*X*a == B (mod |n|), 88e1051a39Sopenharmony_ci * sign*Y*a == A (mod |n|) 89e1051a39Sopenharmony_ci */ 90e1051a39Sopenharmony_ci 91e1051a39Sopenharmony_ci /* 92e1051a39Sopenharmony_ci * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, 93e1051a39Sopenharmony_ci * BN_div_no_branch will be called eventually. 94e1051a39Sopenharmony_ci */ 95e1051a39Sopenharmony_ci { 96e1051a39Sopenharmony_ci BIGNUM local_A; 97e1051a39Sopenharmony_ci bn_init(&local_A); 98e1051a39Sopenharmony_ci BN_with_flags(&local_A, A, BN_FLG_CONSTTIME); 99e1051a39Sopenharmony_ci 100e1051a39Sopenharmony_ci /* (D, M) := (A/B, A%B) ... */ 101e1051a39Sopenharmony_ci if (!BN_div(D, M, &local_A, B, ctx)) 102e1051a39Sopenharmony_ci goto err; 103e1051a39Sopenharmony_ci /* Ensure local_A goes out of scope before any further use of A */ 104e1051a39Sopenharmony_ci } 105e1051a39Sopenharmony_ci 106e1051a39Sopenharmony_ci /*- 107e1051a39Sopenharmony_ci * Now 108e1051a39Sopenharmony_ci * A = D*B + M; 109e1051a39Sopenharmony_ci * thus we have 110e1051a39Sopenharmony_ci * (**) sign*Y*a == D*B + M (mod |n|). 111e1051a39Sopenharmony_ci */ 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_ci tmp = A; /* keep the BIGNUM object, the value does not 114e1051a39Sopenharmony_ci * matter */ 115e1051a39Sopenharmony_ci 116e1051a39Sopenharmony_ci /* (A, B) := (B, A mod B) ... */ 117e1051a39Sopenharmony_ci A = B; 118e1051a39Sopenharmony_ci B = M; 119e1051a39Sopenharmony_ci /* ... so we have 0 <= B < A again */ 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ci /*- 122e1051a39Sopenharmony_ci * Since the former M is now B and the former B is now A, 123e1051a39Sopenharmony_ci * (**) translates into 124e1051a39Sopenharmony_ci * sign*Y*a == D*A + B (mod |n|), 125e1051a39Sopenharmony_ci * i.e. 126e1051a39Sopenharmony_ci * sign*Y*a - D*A == B (mod |n|). 127e1051a39Sopenharmony_ci * Similarly, (*) translates into 128e1051a39Sopenharmony_ci * -sign*X*a == A (mod |n|). 129e1051a39Sopenharmony_ci * 130e1051a39Sopenharmony_ci * Thus, 131e1051a39Sopenharmony_ci * sign*Y*a + D*sign*X*a == B (mod |n|), 132e1051a39Sopenharmony_ci * i.e. 133e1051a39Sopenharmony_ci * sign*(Y + D*X)*a == B (mod |n|). 134e1051a39Sopenharmony_ci * 135e1051a39Sopenharmony_ci * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at 136e1051a39Sopenharmony_ci * -sign*X*a == B (mod |n|), 137e1051a39Sopenharmony_ci * sign*Y*a == A (mod |n|). 138e1051a39Sopenharmony_ci * Note that X and Y stay non-negative all the time. 139e1051a39Sopenharmony_ci */ 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci if (!BN_mul(tmp, D, X, ctx)) 142e1051a39Sopenharmony_ci goto err; 143e1051a39Sopenharmony_ci if (!BN_add(tmp, tmp, Y)) 144e1051a39Sopenharmony_ci goto err; 145e1051a39Sopenharmony_ci 146e1051a39Sopenharmony_ci M = Y; /* keep the BIGNUM object, the value does not 147e1051a39Sopenharmony_ci * matter */ 148e1051a39Sopenharmony_ci Y = X; 149e1051a39Sopenharmony_ci X = tmp; 150e1051a39Sopenharmony_ci sign = -sign; 151e1051a39Sopenharmony_ci } 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_ci /*- 154e1051a39Sopenharmony_ci * The while loop (Euclid's algorithm) ends when 155e1051a39Sopenharmony_ci * A == gcd(a,n); 156e1051a39Sopenharmony_ci * we have 157e1051a39Sopenharmony_ci * sign*Y*a == A (mod |n|), 158e1051a39Sopenharmony_ci * where Y is non-negative. 159e1051a39Sopenharmony_ci */ 160e1051a39Sopenharmony_ci 161e1051a39Sopenharmony_ci if (sign < 0) { 162e1051a39Sopenharmony_ci if (!BN_sub(Y, n, Y)) 163e1051a39Sopenharmony_ci goto err; 164e1051a39Sopenharmony_ci } 165e1051a39Sopenharmony_ci /* Now Y*a == A (mod |n|). */ 166e1051a39Sopenharmony_ci 167e1051a39Sopenharmony_ci if (BN_is_one(A)) { 168e1051a39Sopenharmony_ci /* Y*a == 1 (mod |n|) */ 169e1051a39Sopenharmony_ci if (!Y->neg && BN_ucmp(Y, n) < 0) { 170e1051a39Sopenharmony_ci if (!BN_copy(R, Y)) 171e1051a39Sopenharmony_ci goto err; 172e1051a39Sopenharmony_ci } else { 173e1051a39Sopenharmony_ci if (!BN_nnmod(R, Y, n, ctx)) 174e1051a39Sopenharmony_ci goto err; 175e1051a39Sopenharmony_ci } 176e1051a39Sopenharmony_ci } else { 177e1051a39Sopenharmony_ci *pnoinv = 1; 178e1051a39Sopenharmony_ci /* caller sets the BN_R_NO_INVERSE error */ 179e1051a39Sopenharmony_ci goto err; 180e1051a39Sopenharmony_ci } 181e1051a39Sopenharmony_ci 182e1051a39Sopenharmony_ci ret = R; 183e1051a39Sopenharmony_ci *pnoinv = 0; 184e1051a39Sopenharmony_ci 185e1051a39Sopenharmony_ci err: 186e1051a39Sopenharmony_ci if ((ret == NULL) && (in == NULL)) 187e1051a39Sopenharmony_ci BN_free(R); 188e1051a39Sopenharmony_ci BN_CTX_end(ctx); 189e1051a39Sopenharmony_ci bn_check_top(ret); 190e1051a39Sopenharmony_ci return ret; 191e1051a39Sopenharmony_ci} 192e1051a39Sopenharmony_ci 193e1051a39Sopenharmony_ci/* 194e1051a39Sopenharmony_ci * This is an internal function, we assume all callers pass valid arguments: 195e1051a39Sopenharmony_ci * all pointers passed here are assumed non-NULL. 196e1051a39Sopenharmony_ci */ 197e1051a39Sopenharmony_ciBIGNUM *int_bn_mod_inverse(BIGNUM *in, 198e1051a39Sopenharmony_ci const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx, 199e1051a39Sopenharmony_ci int *pnoinv) 200e1051a39Sopenharmony_ci{ 201e1051a39Sopenharmony_ci BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; 202e1051a39Sopenharmony_ci BIGNUM *ret = NULL; 203e1051a39Sopenharmony_ci int sign; 204e1051a39Sopenharmony_ci 205e1051a39Sopenharmony_ci /* This is invalid input so we don't worry about constant time here */ 206e1051a39Sopenharmony_ci if (BN_abs_is_word(n, 1) || BN_is_zero(n)) { 207e1051a39Sopenharmony_ci *pnoinv = 1; 208e1051a39Sopenharmony_ci return NULL; 209e1051a39Sopenharmony_ci } 210e1051a39Sopenharmony_ci 211e1051a39Sopenharmony_ci *pnoinv = 0; 212e1051a39Sopenharmony_ci 213e1051a39Sopenharmony_ci if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) 214e1051a39Sopenharmony_ci || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) { 215e1051a39Sopenharmony_ci return bn_mod_inverse_no_branch(in, a, n, ctx, pnoinv); 216e1051a39Sopenharmony_ci } 217e1051a39Sopenharmony_ci 218e1051a39Sopenharmony_ci bn_check_top(a); 219e1051a39Sopenharmony_ci bn_check_top(n); 220e1051a39Sopenharmony_ci 221e1051a39Sopenharmony_ci BN_CTX_start(ctx); 222e1051a39Sopenharmony_ci A = BN_CTX_get(ctx); 223e1051a39Sopenharmony_ci B = BN_CTX_get(ctx); 224e1051a39Sopenharmony_ci X = BN_CTX_get(ctx); 225e1051a39Sopenharmony_ci D = BN_CTX_get(ctx); 226e1051a39Sopenharmony_ci M = BN_CTX_get(ctx); 227e1051a39Sopenharmony_ci Y = BN_CTX_get(ctx); 228e1051a39Sopenharmony_ci T = BN_CTX_get(ctx); 229e1051a39Sopenharmony_ci if (T == NULL) 230e1051a39Sopenharmony_ci goto err; 231e1051a39Sopenharmony_ci 232e1051a39Sopenharmony_ci if (in == NULL) 233e1051a39Sopenharmony_ci R = BN_new(); 234e1051a39Sopenharmony_ci else 235e1051a39Sopenharmony_ci R = in; 236e1051a39Sopenharmony_ci if (R == NULL) 237e1051a39Sopenharmony_ci goto err; 238e1051a39Sopenharmony_ci 239e1051a39Sopenharmony_ci if (!BN_one(X)) 240e1051a39Sopenharmony_ci goto err; 241e1051a39Sopenharmony_ci BN_zero(Y); 242e1051a39Sopenharmony_ci if (BN_copy(B, a) == NULL) 243e1051a39Sopenharmony_ci goto err; 244e1051a39Sopenharmony_ci if (BN_copy(A, n) == NULL) 245e1051a39Sopenharmony_ci goto err; 246e1051a39Sopenharmony_ci A->neg = 0; 247e1051a39Sopenharmony_ci if (B->neg || (BN_ucmp(B, A) >= 0)) { 248e1051a39Sopenharmony_ci if (!BN_nnmod(B, B, A, ctx)) 249e1051a39Sopenharmony_ci goto err; 250e1051a39Sopenharmony_ci } 251e1051a39Sopenharmony_ci sign = -1; 252e1051a39Sopenharmony_ci /*- 253e1051a39Sopenharmony_ci * From B = a mod |n|, A = |n| it follows that 254e1051a39Sopenharmony_ci * 255e1051a39Sopenharmony_ci * 0 <= B < A, 256e1051a39Sopenharmony_ci * -sign*X*a == B (mod |n|), 257e1051a39Sopenharmony_ci * sign*Y*a == A (mod |n|). 258e1051a39Sopenharmony_ci */ 259e1051a39Sopenharmony_ci 260e1051a39Sopenharmony_ci if (BN_is_odd(n) && (BN_num_bits(n) <= 2048)) { 261e1051a39Sopenharmony_ci /* 262e1051a39Sopenharmony_ci * Binary inversion algorithm; requires odd modulus. This is faster 263e1051a39Sopenharmony_ci * than the general algorithm if the modulus is sufficiently small 264e1051a39Sopenharmony_ci * (about 400 .. 500 bits on 32-bit systems, but much more on 64-bit 265e1051a39Sopenharmony_ci * systems) 266e1051a39Sopenharmony_ci */ 267e1051a39Sopenharmony_ci int shift; 268e1051a39Sopenharmony_ci 269e1051a39Sopenharmony_ci while (!BN_is_zero(B)) { 270e1051a39Sopenharmony_ci /*- 271e1051a39Sopenharmony_ci * 0 < B < |n|, 272e1051a39Sopenharmony_ci * 0 < A <= |n|, 273e1051a39Sopenharmony_ci * (1) -sign*X*a == B (mod |n|), 274e1051a39Sopenharmony_ci * (2) sign*Y*a == A (mod |n|) 275e1051a39Sopenharmony_ci */ 276e1051a39Sopenharmony_ci 277e1051a39Sopenharmony_ci /* 278e1051a39Sopenharmony_ci * Now divide B by the maximum possible power of two in the 279e1051a39Sopenharmony_ci * integers, and divide X by the same value mod |n|. When we're 280e1051a39Sopenharmony_ci * done, (1) still holds. 281e1051a39Sopenharmony_ci */ 282e1051a39Sopenharmony_ci shift = 0; 283e1051a39Sopenharmony_ci while (!BN_is_bit_set(B, shift)) { /* note that 0 < B */ 284e1051a39Sopenharmony_ci shift++; 285e1051a39Sopenharmony_ci 286e1051a39Sopenharmony_ci if (BN_is_odd(X)) { 287e1051a39Sopenharmony_ci if (!BN_uadd(X, X, n)) 288e1051a39Sopenharmony_ci goto err; 289e1051a39Sopenharmony_ci } 290e1051a39Sopenharmony_ci /* 291e1051a39Sopenharmony_ci * now X is even, so we can easily divide it by two 292e1051a39Sopenharmony_ci */ 293e1051a39Sopenharmony_ci if (!BN_rshift1(X, X)) 294e1051a39Sopenharmony_ci goto err; 295e1051a39Sopenharmony_ci } 296e1051a39Sopenharmony_ci if (shift > 0) { 297e1051a39Sopenharmony_ci if (!BN_rshift(B, B, shift)) 298e1051a39Sopenharmony_ci goto err; 299e1051a39Sopenharmony_ci } 300e1051a39Sopenharmony_ci 301e1051a39Sopenharmony_ci /* 302e1051a39Sopenharmony_ci * Same for A and Y. Afterwards, (2) still holds. 303e1051a39Sopenharmony_ci */ 304e1051a39Sopenharmony_ci shift = 0; 305e1051a39Sopenharmony_ci while (!BN_is_bit_set(A, shift)) { /* note that 0 < A */ 306e1051a39Sopenharmony_ci shift++; 307e1051a39Sopenharmony_ci 308e1051a39Sopenharmony_ci if (BN_is_odd(Y)) { 309e1051a39Sopenharmony_ci if (!BN_uadd(Y, Y, n)) 310e1051a39Sopenharmony_ci goto err; 311e1051a39Sopenharmony_ci } 312e1051a39Sopenharmony_ci /* now Y is even */ 313e1051a39Sopenharmony_ci if (!BN_rshift1(Y, Y)) 314e1051a39Sopenharmony_ci goto err; 315e1051a39Sopenharmony_ci } 316e1051a39Sopenharmony_ci if (shift > 0) { 317e1051a39Sopenharmony_ci if (!BN_rshift(A, A, shift)) 318e1051a39Sopenharmony_ci goto err; 319e1051a39Sopenharmony_ci } 320e1051a39Sopenharmony_ci 321e1051a39Sopenharmony_ci /*- 322e1051a39Sopenharmony_ci * We still have (1) and (2). 323e1051a39Sopenharmony_ci * Both A and B are odd. 324e1051a39Sopenharmony_ci * The following computations ensure that 325e1051a39Sopenharmony_ci * 326e1051a39Sopenharmony_ci * 0 <= B < |n|, 327e1051a39Sopenharmony_ci * 0 < A < |n|, 328e1051a39Sopenharmony_ci * (1) -sign*X*a == B (mod |n|), 329e1051a39Sopenharmony_ci * (2) sign*Y*a == A (mod |n|), 330e1051a39Sopenharmony_ci * 331e1051a39Sopenharmony_ci * and that either A or B is even in the next iteration. 332e1051a39Sopenharmony_ci */ 333e1051a39Sopenharmony_ci if (BN_ucmp(B, A) >= 0) { 334e1051a39Sopenharmony_ci /* -sign*(X + Y)*a == B - A (mod |n|) */ 335e1051a39Sopenharmony_ci if (!BN_uadd(X, X, Y)) 336e1051a39Sopenharmony_ci goto err; 337e1051a39Sopenharmony_ci /* 338e1051a39Sopenharmony_ci * NB: we could use BN_mod_add_quick(X, X, Y, n), but that 339e1051a39Sopenharmony_ci * actually makes the algorithm slower 340e1051a39Sopenharmony_ci */ 341e1051a39Sopenharmony_ci if (!BN_usub(B, B, A)) 342e1051a39Sopenharmony_ci goto err; 343e1051a39Sopenharmony_ci } else { 344e1051a39Sopenharmony_ci /* sign*(X + Y)*a == A - B (mod |n|) */ 345e1051a39Sopenharmony_ci if (!BN_uadd(Y, Y, X)) 346e1051a39Sopenharmony_ci goto err; 347e1051a39Sopenharmony_ci /* 348e1051a39Sopenharmony_ci * as above, BN_mod_add_quick(Y, Y, X, n) would slow things down 349e1051a39Sopenharmony_ci */ 350e1051a39Sopenharmony_ci if (!BN_usub(A, A, B)) 351e1051a39Sopenharmony_ci goto err; 352e1051a39Sopenharmony_ci } 353e1051a39Sopenharmony_ci } 354e1051a39Sopenharmony_ci } else { 355e1051a39Sopenharmony_ci /* general inversion algorithm */ 356e1051a39Sopenharmony_ci 357e1051a39Sopenharmony_ci while (!BN_is_zero(B)) { 358e1051a39Sopenharmony_ci BIGNUM *tmp; 359e1051a39Sopenharmony_ci 360e1051a39Sopenharmony_ci /*- 361e1051a39Sopenharmony_ci * 0 < B < A, 362e1051a39Sopenharmony_ci * (*) -sign*X*a == B (mod |n|), 363e1051a39Sopenharmony_ci * sign*Y*a == A (mod |n|) 364e1051a39Sopenharmony_ci */ 365e1051a39Sopenharmony_ci 366e1051a39Sopenharmony_ci /* (D, M) := (A/B, A%B) ... */ 367e1051a39Sopenharmony_ci if (BN_num_bits(A) == BN_num_bits(B)) { 368e1051a39Sopenharmony_ci if (!BN_one(D)) 369e1051a39Sopenharmony_ci goto err; 370e1051a39Sopenharmony_ci if (!BN_sub(M, A, B)) 371e1051a39Sopenharmony_ci goto err; 372e1051a39Sopenharmony_ci } else if (BN_num_bits(A) == BN_num_bits(B) + 1) { 373e1051a39Sopenharmony_ci /* A/B is 1, 2, or 3 */ 374e1051a39Sopenharmony_ci if (!BN_lshift1(T, B)) 375e1051a39Sopenharmony_ci goto err; 376e1051a39Sopenharmony_ci if (BN_ucmp(A, T) < 0) { 377e1051a39Sopenharmony_ci /* A < 2*B, so D=1 */ 378e1051a39Sopenharmony_ci if (!BN_one(D)) 379e1051a39Sopenharmony_ci goto err; 380e1051a39Sopenharmony_ci if (!BN_sub(M, A, B)) 381e1051a39Sopenharmony_ci goto err; 382e1051a39Sopenharmony_ci } else { 383e1051a39Sopenharmony_ci /* A >= 2*B, so D=2 or D=3 */ 384e1051a39Sopenharmony_ci if (!BN_sub(M, A, T)) 385e1051a39Sopenharmony_ci goto err; 386e1051a39Sopenharmony_ci if (!BN_add(D, T, B)) 387e1051a39Sopenharmony_ci goto err; /* use D (:= 3*B) as temp */ 388e1051a39Sopenharmony_ci if (BN_ucmp(A, D) < 0) { 389e1051a39Sopenharmony_ci /* A < 3*B, so D=2 */ 390e1051a39Sopenharmony_ci if (!BN_set_word(D, 2)) 391e1051a39Sopenharmony_ci goto err; 392e1051a39Sopenharmony_ci /* 393e1051a39Sopenharmony_ci * M (= A - 2*B) already has the correct value 394e1051a39Sopenharmony_ci */ 395e1051a39Sopenharmony_ci } else { 396e1051a39Sopenharmony_ci /* only D=3 remains */ 397e1051a39Sopenharmony_ci if (!BN_set_word(D, 3)) 398e1051a39Sopenharmony_ci goto err; 399e1051a39Sopenharmony_ci /* 400e1051a39Sopenharmony_ci * currently M = A - 2*B, but we need M = A - 3*B 401e1051a39Sopenharmony_ci */ 402e1051a39Sopenharmony_ci if (!BN_sub(M, M, B)) 403e1051a39Sopenharmony_ci goto err; 404e1051a39Sopenharmony_ci } 405e1051a39Sopenharmony_ci } 406e1051a39Sopenharmony_ci } else { 407e1051a39Sopenharmony_ci if (!BN_div(D, M, A, B, ctx)) 408e1051a39Sopenharmony_ci goto err; 409e1051a39Sopenharmony_ci } 410e1051a39Sopenharmony_ci 411e1051a39Sopenharmony_ci /*- 412e1051a39Sopenharmony_ci * Now 413e1051a39Sopenharmony_ci * A = D*B + M; 414e1051a39Sopenharmony_ci * thus we have 415e1051a39Sopenharmony_ci * (**) sign*Y*a == D*B + M (mod |n|). 416e1051a39Sopenharmony_ci */ 417e1051a39Sopenharmony_ci 418e1051a39Sopenharmony_ci tmp = A; /* keep the BIGNUM object, the value does not matter */ 419e1051a39Sopenharmony_ci 420e1051a39Sopenharmony_ci /* (A, B) := (B, A mod B) ... */ 421e1051a39Sopenharmony_ci A = B; 422e1051a39Sopenharmony_ci B = M; 423e1051a39Sopenharmony_ci /* ... so we have 0 <= B < A again */ 424e1051a39Sopenharmony_ci 425e1051a39Sopenharmony_ci /*- 426e1051a39Sopenharmony_ci * Since the former M is now B and the former B is now A, 427e1051a39Sopenharmony_ci * (**) translates into 428e1051a39Sopenharmony_ci * sign*Y*a == D*A + B (mod |n|), 429e1051a39Sopenharmony_ci * i.e. 430e1051a39Sopenharmony_ci * sign*Y*a - D*A == B (mod |n|). 431e1051a39Sopenharmony_ci * Similarly, (*) translates into 432e1051a39Sopenharmony_ci * -sign*X*a == A (mod |n|). 433e1051a39Sopenharmony_ci * 434e1051a39Sopenharmony_ci * Thus, 435e1051a39Sopenharmony_ci * sign*Y*a + D*sign*X*a == B (mod |n|), 436e1051a39Sopenharmony_ci * i.e. 437e1051a39Sopenharmony_ci * sign*(Y + D*X)*a == B (mod |n|). 438e1051a39Sopenharmony_ci * 439e1051a39Sopenharmony_ci * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at 440e1051a39Sopenharmony_ci * -sign*X*a == B (mod |n|), 441e1051a39Sopenharmony_ci * sign*Y*a == A (mod |n|). 442e1051a39Sopenharmony_ci * Note that X and Y stay non-negative all the time. 443e1051a39Sopenharmony_ci */ 444e1051a39Sopenharmony_ci 445e1051a39Sopenharmony_ci /* 446e1051a39Sopenharmony_ci * most of the time D is very small, so we can optimize tmp := D*X+Y 447e1051a39Sopenharmony_ci */ 448e1051a39Sopenharmony_ci if (BN_is_one(D)) { 449e1051a39Sopenharmony_ci if (!BN_add(tmp, X, Y)) 450e1051a39Sopenharmony_ci goto err; 451e1051a39Sopenharmony_ci } else { 452e1051a39Sopenharmony_ci if (BN_is_word(D, 2)) { 453e1051a39Sopenharmony_ci if (!BN_lshift1(tmp, X)) 454e1051a39Sopenharmony_ci goto err; 455e1051a39Sopenharmony_ci } else if (BN_is_word(D, 4)) { 456e1051a39Sopenharmony_ci if (!BN_lshift(tmp, X, 2)) 457e1051a39Sopenharmony_ci goto err; 458e1051a39Sopenharmony_ci } else if (D->top == 1) { 459e1051a39Sopenharmony_ci if (!BN_copy(tmp, X)) 460e1051a39Sopenharmony_ci goto err; 461e1051a39Sopenharmony_ci if (!BN_mul_word(tmp, D->d[0])) 462e1051a39Sopenharmony_ci goto err; 463e1051a39Sopenharmony_ci } else { 464e1051a39Sopenharmony_ci if (!BN_mul(tmp, D, X, ctx)) 465e1051a39Sopenharmony_ci goto err; 466e1051a39Sopenharmony_ci } 467e1051a39Sopenharmony_ci if (!BN_add(tmp, tmp, Y)) 468e1051a39Sopenharmony_ci goto err; 469e1051a39Sopenharmony_ci } 470e1051a39Sopenharmony_ci 471e1051a39Sopenharmony_ci M = Y; /* keep the BIGNUM object, the value does not matter */ 472e1051a39Sopenharmony_ci Y = X; 473e1051a39Sopenharmony_ci X = tmp; 474e1051a39Sopenharmony_ci sign = -sign; 475e1051a39Sopenharmony_ci } 476e1051a39Sopenharmony_ci } 477e1051a39Sopenharmony_ci 478e1051a39Sopenharmony_ci /*- 479e1051a39Sopenharmony_ci * The while loop (Euclid's algorithm) ends when 480e1051a39Sopenharmony_ci * A == gcd(a,n); 481e1051a39Sopenharmony_ci * we have 482e1051a39Sopenharmony_ci * sign*Y*a == A (mod |n|), 483e1051a39Sopenharmony_ci * where Y is non-negative. 484e1051a39Sopenharmony_ci */ 485e1051a39Sopenharmony_ci 486e1051a39Sopenharmony_ci if (sign < 0) { 487e1051a39Sopenharmony_ci if (!BN_sub(Y, n, Y)) 488e1051a39Sopenharmony_ci goto err; 489e1051a39Sopenharmony_ci } 490e1051a39Sopenharmony_ci /* Now Y*a == A (mod |n|). */ 491e1051a39Sopenharmony_ci 492e1051a39Sopenharmony_ci if (BN_is_one(A)) { 493e1051a39Sopenharmony_ci /* Y*a == 1 (mod |n|) */ 494e1051a39Sopenharmony_ci if (!Y->neg && BN_ucmp(Y, n) < 0) { 495e1051a39Sopenharmony_ci if (!BN_copy(R, Y)) 496e1051a39Sopenharmony_ci goto err; 497e1051a39Sopenharmony_ci } else { 498e1051a39Sopenharmony_ci if (!BN_nnmod(R, Y, n, ctx)) 499e1051a39Sopenharmony_ci goto err; 500e1051a39Sopenharmony_ci } 501e1051a39Sopenharmony_ci } else { 502e1051a39Sopenharmony_ci *pnoinv = 1; 503e1051a39Sopenharmony_ci goto err; 504e1051a39Sopenharmony_ci } 505e1051a39Sopenharmony_ci ret = R; 506e1051a39Sopenharmony_ci err: 507e1051a39Sopenharmony_ci if ((ret == NULL) && (in == NULL)) 508e1051a39Sopenharmony_ci BN_free(R); 509e1051a39Sopenharmony_ci BN_CTX_end(ctx); 510e1051a39Sopenharmony_ci bn_check_top(ret); 511e1051a39Sopenharmony_ci return ret; 512e1051a39Sopenharmony_ci} 513e1051a39Sopenharmony_ci 514e1051a39Sopenharmony_ci/* solves ax == 1 (mod n) */ 515e1051a39Sopenharmony_ciBIGNUM *BN_mod_inverse(BIGNUM *in, 516e1051a39Sopenharmony_ci const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) 517e1051a39Sopenharmony_ci{ 518e1051a39Sopenharmony_ci BN_CTX *new_ctx = NULL; 519e1051a39Sopenharmony_ci BIGNUM *rv; 520e1051a39Sopenharmony_ci int noinv = 0; 521e1051a39Sopenharmony_ci 522e1051a39Sopenharmony_ci if (ctx == NULL) { 523e1051a39Sopenharmony_ci ctx = new_ctx = BN_CTX_new_ex(NULL); 524e1051a39Sopenharmony_ci if (ctx == NULL) { 525e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); 526e1051a39Sopenharmony_ci return NULL; 527e1051a39Sopenharmony_ci } 528e1051a39Sopenharmony_ci } 529e1051a39Sopenharmony_ci 530e1051a39Sopenharmony_ci rv = int_bn_mod_inverse(in, a, n, ctx, &noinv); 531e1051a39Sopenharmony_ci if (noinv) 532e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_BN, BN_R_NO_INVERSE); 533e1051a39Sopenharmony_ci BN_CTX_free(new_ctx); 534e1051a39Sopenharmony_ci return rv; 535e1051a39Sopenharmony_ci} 536e1051a39Sopenharmony_ci 537e1051a39Sopenharmony_ci/*- 538e1051a39Sopenharmony_ci * This function is based on the constant-time GCD work by Bernstein and Yang: 539e1051a39Sopenharmony_ci * https://eprint.iacr.org/2019/266 540e1051a39Sopenharmony_ci * Generalized fast GCD function to allow even inputs. 541e1051a39Sopenharmony_ci * The algorithm first finds the shared powers of 2 between 542e1051a39Sopenharmony_ci * the inputs, and removes them, reducing at least one of the 543e1051a39Sopenharmony_ci * inputs to an odd value. Then it proceeds to calculate the GCD. 544e1051a39Sopenharmony_ci * Before returning the resulting GCD, we take care of adding 545e1051a39Sopenharmony_ci * back the powers of two removed at the beginning. 546e1051a39Sopenharmony_ci * Note 1: we assume the bit length of both inputs is public information, 547e1051a39Sopenharmony_ci * since access to top potentially leaks this information. 548e1051a39Sopenharmony_ci */ 549e1051a39Sopenharmony_ciint BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) 550e1051a39Sopenharmony_ci{ 551e1051a39Sopenharmony_ci BIGNUM *g, *temp = NULL; 552e1051a39Sopenharmony_ci BN_ULONG mask = 0; 553e1051a39Sopenharmony_ci int i, j, top, rlen, glen, m, bit = 1, delta = 1, cond = 0, shifts = 0, ret = 0; 554e1051a39Sopenharmony_ci 555e1051a39Sopenharmony_ci /* Note 2: zero input corner cases are not constant-time since they are 556e1051a39Sopenharmony_ci * handled immediately. An attacker can run an attack under this 557e1051a39Sopenharmony_ci * assumption without the need of side-channel information. */ 558e1051a39Sopenharmony_ci if (BN_is_zero(in_b)) { 559e1051a39Sopenharmony_ci ret = BN_copy(r, in_a) != NULL; 560e1051a39Sopenharmony_ci r->neg = 0; 561e1051a39Sopenharmony_ci return ret; 562e1051a39Sopenharmony_ci } 563e1051a39Sopenharmony_ci if (BN_is_zero(in_a)) { 564e1051a39Sopenharmony_ci ret = BN_copy(r, in_b) != NULL; 565e1051a39Sopenharmony_ci r->neg = 0; 566e1051a39Sopenharmony_ci return ret; 567e1051a39Sopenharmony_ci } 568e1051a39Sopenharmony_ci 569e1051a39Sopenharmony_ci bn_check_top(in_a); 570e1051a39Sopenharmony_ci bn_check_top(in_b); 571e1051a39Sopenharmony_ci 572e1051a39Sopenharmony_ci BN_CTX_start(ctx); 573e1051a39Sopenharmony_ci temp = BN_CTX_get(ctx); 574e1051a39Sopenharmony_ci g = BN_CTX_get(ctx); 575e1051a39Sopenharmony_ci 576e1051a39Sopenharmony_ci /* make r != 0, g != 0 even, so BN_rshift is not a potential nop */ 577e1051a39Sopenharmony_ci if (g == NULL 578e1051a39Sopenharmony_ci || !BN_lshift1(g, in_b) 579e1051a39Sopenharmony_ci || !BN_lshift1(r, in_a)) 580e1051a39Sopenharmony_ci goto err; 581e1051a39Sopenharmony_ci 582e1051a39Sopenharmony_ci /* find shared powers of two, i.e. "shifts" >= 1 */ 583e1051a39Sopenharmony_ci for (i = 0; i < r->dmax && i < g->dmax; i++) { 584e1051a39Sopenharmony_ci mask = ~(r->d[i] | g->d[i]); 585e1051a39Sopenharmony_ci for (j = 0; j < BN_BITS2; j++) { 586e1051a39Sopenharmony_ci bit &= mask; 587e1051a39Sopenharmony_ci shifts += bit; 588e1051a39Sopenharmony_ci mask >>= 1; 589e1051a39Sopenharmony_ci } 590e1051a39Sopenharmony_ci } 591e1051a39Sopenharmony_ci 592e1051a39Sopenharmony_ci /* subtract shared powers of two; shifts >= 1 */ 593e1051a39Sopenharmony_ci if (!BN_rshift(r, r, shifts) 594e1051a39Sopenharmony_ci || !BN_rshift(g, g, shifts)) 595e1051a39Sopenharmony_ci goto err; 596e1051a39Sopenharmony_ci 597e1051a39Sopenharmony_ci /* expand to biggest nword, with room for a possible extra word */ 598e1051a39Sopenharmony_ci top = 1 + ((r->top >= g->top) ? r->top : g->top); 599e1051a39Sopenharmony_ci if (bn_wexpand(r, top) == NULL 600e1051a39Sopenharmony_ci || bn_wexpand(g, top) == NULL 601e1051a39Sopenharmony_ci || bn_wexpand(temp, top) == NULL) 602e1051a39Sopenharmony_ci goto err; 603e1051a39Sopenharmony_ci 604e1051a39Sopenharmony_ci /* re arrange inputs s.t. r is odd */ 605e1051a39Sopenharmony_ci BN_consttime_swap((~r->d[0]) & 1, r, g, top); 606e1051a39Sopenharmony_ci 607e1051a39Sopenharmony_ci /* compute the number of iterations */ 608e1051a39Sopenharmony_ci rlen = BN_num_bits(r); 609e1051a39Sopenharmony_ci glen = BN_num_bits(g); 610e1051a39Sopenharmony_ci m = 4 + 3 * ((rlen >= glen) ? rlen : glen); 611e1051a39Sopenharmony_ci 612e1051a39Sopenharmony_ci for (i = 0; i < m; i++) { 613e1051a39Sopenharmony_ci /* conditionally flip signs if delta is positive and g is odd */ 614e1051a39Sopenharmony_ci cond = (-delta >> (8 * sizeof(delta) - 1)) & g->d[0] & 1 615e1051a39Sopenharmony_ci /* make sure g->top > 0 (i.e. if top == 0 then g == 0 always) */ 616e1051a39Sopenharmony_ci & (~((g->top - 1) >> (sizeof(g->top) * 8 - 1))); 617e1051a39Sopenharmony_ci delta = (-cond & -delta) | ((cond - 1) & delta); 618e1051a39Sopenharmony_ci r->neg ^= cond; 619e1051a39Sopenharmony_ci /* swap */ 620e1051a39Sopenharmony_ci BN_consttime_swap(cond, r, g, top); 621e1051a39Sopenharmony_ci 622e1051a39Sopenharmony_ci /* elimination step */ 623e1051a39Sopenharmony_ci delta++; 624e1051a39Sopenharmony_ci if (!BN_add(temp, g, r)) 625e1051a39Sopenharmony_ci goto err; 626e1051a39Sopenharmony_ci BN_consttime_swap(g->d[0] & 1 /* g is odd */ 627e1051a39Sopenharmony_ci /* make sure g->top > 0 (i.e. if top == 0 then g == 0 always) */ 628e1051a39Sopenharmony_ci & (~((g->top - 1) >> (sizeof(g->top) * 8 - 1))), 629e1051a39Sopenharmony_ci g, temp, top); 630e1051a39Sopenharmony_ci if (!BN_rshift1(g, g)) 631e1051a39Sopenharmony_ci goto err; 632e1051a39Sopenharmony_ci } 633e1051a39Sopenharmony_ci 634e1051a39Sopenharmony_ci /* remove possible negative sign */ 635e1051a39Sopenharmony_ci r->neg = 0; 636e1051a39Sopenharmony_ci /* add powers of 2 removed, then correct the artificial shift */ 637e1051a39Sopenharmony_ci if (!BN_lshift(r, r, shifts) 638e1051a39Sopenharmony_ci || !BN_rshift1(r, r)) 639e1051a39Sopenharmony_ci goto err; 640e1051a39Sopenharmony_ci 641e1051a39Sopenharmony_ci ret = 1; 642e1051a39Sopenharmony_ci 643e1051a39Sopenharmony_ci err: 644e1051a39Sopenharmony_ci BN_CTX_end(ctx); 645e1051a39Sopenharmony_ci bn_check_top(r); 646e1051a39Sopenharmony_ci return ret; 647e1051a39Sopenharmony_ci} 648