1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2020 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 <assert.h> 11e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 12e1051a39Sopenharmony_ci#include "bn_local.h" 13e1051a39Sopenharmony_ci 14e1051a39Sopenharmony_ciint BN_lshift1(BIGNUM *r, const BIGNUM *a) 15e1051a39Sopenharmony_ci{ 16e1051a39Sopenharmony_ci register BN_ULONG *ap, *rp, t, c; 17e1051a39Sopenharmony_ci int i; 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ci bn_check_top(r); 20e1051a39Sopenharmony_ci bn_check_top(a); 21e1051a39Sopenharmony_ci 22e1051a39Sopenharmony_ci if (r != a) { 23e1051a39Sopenharmony_ci r->neg = a->neg; 24e1051a39Sopenharmony_ci if (bn_wexpand(r, a->top + 1) == NULL) 25e1051a39Sopenharmony_ci return 0; 26e1051a39Sopenharmony_ci r->top = a->top; 27e1051a39Sopenharmony_ci } else { 28e1051a39Sopenharmony_ci if (bn_wexpand(r, a->top + 1) == NULL) 29e1051a39Sopenharmony_ci return 0; 30e1051a39Sopenharmony_ci } 31e1051a39Sopenharmony_ci ap = a->d; 32e1051a39Sopenharmony_ci rp = r->d; 33e1051a39Sopenharmony_ci c = 0; 34e1051a39Sopenharmony_ci for (i = 0; i < a->top; i++) { 35e1051a39Sopenharmony_ci t = *(ap++); 36e1051a39Sopenharmony_ci *(rp++) = ((t << 1) | c) & BN_MASK2; 37e1051a39Sopenharmony_ci c = t >> (BN_BITS2 - 1); 38e1051a39Sopenharmony_ci } 39e1051a39Sopenharmony_ci *rp = c; 40e1051a39Sopenharmony_ci r->top += c; 41e1051a39Sopenharmony_ci bn_check_top(r); 42e1051a39Sopenharmony_ci return 1; 43e1051a39Sopenharmony_ci} 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_ciint BN_rshift1(BIGNUM *r, const BIGNUM *a) 46e1051a39Sopenharmony_ci{ 47e1051a39Sopenharmony_ci BN_ULONG *ap, *rp, t, c; 48e1051a39Sopenharmony_ci int i; 49e1051a39Sopenharmony_ci 50e1051a39Sopenharmony_ci bn_check_top(r); 51e1051a39Sopenharmony_ci bn_check_top(a); 52e1051a39Sopenharmony_ci 53e1051a39Sopenharmony_ci if (BN_is_zero(a)) { 54e1051a39Sopenharmony_ci BN_zero(r); 55e1051a39Sopenharmony_ci return 1; 56e1051a39Sopenharmony_ci } 57e1051a39Sopenharmony_ci i = a->top; 58e1051a39Sopenharmony_ci ap = a->d; 59e1051a39Sopenharmony_ci if (a != r) { 60e1051a39Sopenharmony_ci if (bn_wexpand(r, i) == NULL) 61e1051a39Sopenharmony_ci return 0; 62e1051a39Sopenharmony_ci r->neg = a->neg; 63e1051a39Sopenharmony_ci } 64e1051a39Sopenharmony_ci rp = r->d; 65e1051a39Sopenharmony_ci r->top = i; 66e1051a39Sopenharmony_ci t = ap[--i]; 67e1051a39Sopenharmony_ci rp[i] = t >> 1; 68e1051a39Sopenharmony_ci c = t << (BN_BITS2 - 1); 69e1051a39Sopenharmony_ci r->top -= (t == 1); 70e1051a39Sopenharmony_ci while (i > 0) { 71e1051a39Sopenharmony_ci t = ap[--i]; 72e1051a39Sopenharmony_ci rp[i] = ((t >> 1) & BN_MASK2) | c; 73e1051a39Sopenharmony_ci c = t << (BN_BITS2 - 1); 74e1051a39Sopenharmony_ci } 75e1051a39Sopenharmony_ci if (!r->top) 76e1051a39Sopenharmony_ci r->neg = 0; /* don't allow negative zero */ 77e1051a39Sopenharmony_ci bn_check_top(r); 78e1051a39Sopenharmony_ci return 1; 79e1051a39Sopenharmony_ci} 80e1051a39Sopenharmony_ci 81e1051a39Sopenharmony_ciint BN_lshift(BIGNUM *r, const BIGNUM *a, int n) 82e1051a39Sopenharmony_ci{ 83e1051a39Sopenharmony_ci int ret; 84e1051a39Sopenharmony_ci 85e1051a39Sopenharmony_ci if (n < 0) { 86e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_BN, BN_R_INVALID_SHIFT); 87e1051a39Sopenharmony_ci return 0; 88e1051a39Sopenharmony_ci } 89e1051a39Sopenharmony_ci 90e1051a39Sopenharmony_ci ret = bn_lshift_fixed_top(r, a, n); 91e1051a39Sopenharmony_ci 92e1051a39Sopenharmony_ci bn_correct_top(r); 93e1051a39Sopenharmony_ci bn_check_top(r); 94e1051a39Sopenharmony_ci 95e1051a39Sopenharmony_ci return ret; 96e1051a39Sopenharmony_ci} 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ci/* 99e1051a39Sopenharmony_ci * In respect to shift factor the execution time is invariant of 100e1051a39Sopenharmony_ci * |n % BN_BITS2|, but not |n / BN_BITS2|. Or in other words pre-condition 101e1051a39Sopenharmony_ci * for constant-time-ness is |n < BN_BITS2| or |n / BN_BITS2| being 102e1051a39Sopenharmony_ci * non-secret. 103e1051a39Sopenharmony_ci */ 104e1051a39Sopenharmony_ciint bn_lshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n) 105e1051a39Sopenharmony_ci{ 106e1051a39Sopenharmony_ci int i, nw; 107e1051a39Sopenharmony_ci unsigned int lb, rb; 108e1051a39Sopenharmony_ci BN_ULONG *t, *f; 109e1051a39Sopenharmony_ci BN_ULONG l, m, rmask = 0; 110e1051a39Sopenharmony_ci 111e1051a39Sopenharmony_ci assert(n >= 0); 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_ci bn_check_top(r); 114e1051a39Sopenharmony_ci bn_check_top(a); 115e1051a39Sopenharmony_ci 116e1051a39Sopenharmony_ci nw = n / BN_BITS2; 117e1051a39Sopenharmony_ci if (bn_wexpand(r, a->top + nw + 1) == NULL) 118e1051a39Sopenharmony_ci return 0; 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ci if (a->top != 0) { 121e1051a39Sopenharmony_ci lb = (unsigned int)n % BN_BITS2; 122e1051a39Sopenharmony_ci rb = BN_BITS2 - lb; 123e1051a39Sopenharmony_ci rb %= BN_BITS2; /* say no to undefined behaviour */ 124e1051a39Sopenharmony_ci rmask = (BN_ULONG)0 - rb; /* rmask = 0 - (rb != 0) */ 125e1051a39Sopenharmony_ci rmask |= rmask >> 8; 126e1051a39Sopenharmony_ci f = &(a->d[0]); 127e1051a39Sopenharmony_ci t = &(r->d[nw]); 128e1051a39Sopenharmony_ci l = f[a->top - 1]; 129e1051a39Sopenharmony_ci t[a->top] = (l >> rb) & rmask; 130e1051a39Sopenharmony_ci for (i = a->top - 1; i > 0; i--) { 131e1051a39Sopenharmony_ci m = l << lb; 132e1051a39Sopenharmony_ci l = f[i - 1]; 133e1051a39Sopenharmony_ci t[i] = (m | ((l >> rb) & rmask)) & BN_MASK2; 134e1051a39Sopenharmony_ci } 135e1051a39Sopenharmony_ci t[0] = (l << lb) & BN_MASK2; 136e1051a39Sopenharmony_ci } else { 137e1051a39Sopenharmony_ci /* shouldn't happen, but formally required */ 138e1051a39Sopenharmony_ci r->d[nw] = 0; 139e1051a39Sopenharmony_ci } 140e1051a39Sopenharmony_ci if (nw != 0) 141e1051a39Sopenharmony_ci memset(r->d, 0, sizeof(*t) * nw); 142e1051a39Sopenharmony_ci 143e1051a39Sopenharmony_ci r->neg = a->neg; 144e1051a39Sopenharmony_ci r->top = a->top + nw + 1; 145e1051a39Sopenharmony_ci r->flags |= BN_FLG_FIXED_TOP; 146e1051a39Sopenharmony_ci 147e1051a39Sopenharmony_ci return 1; 148e1051a39Sopenharmony_ci} 149e1051a39Sopenharmony_ci 150e1051a39Sopenharmony_ciint BN_rshift(BIGNUM *r, const BIGNUM *a, int n) 151e1051a39Sopenharmony_ci{ 152e1051a39Sopenharmony_ci int ret = 0; 153e1051a39Sopenharmony_ci 154e1051a39Sopenharmony_ci if (n < 0) { 155e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_BN, BN_R_INVALID_SHIFT); 156e1051a39Sopenharmony_ci return 0; 157e1051a39Sopenharmony_ci } 158e1051a39Sopenharmony_ci 159e1051a39Sopenharmony_ci ret = bn_rshift_fixed_top(r, a, n); 160e1051a39Sopenharmony_ci 161e1051a39Sopenharmony_ci bn_correct_top(r); 162e1051a39Sopenharmony_ci bn_check_top(r); 163e1051a39Sopenharmony_ci 164e1051a39Sopenharmony_ci return ret; 165e1051a39Sopenharmony_ci} 166e1051a39Sopenharmony_ci 167e1051a39Sopenharmony_ci/* 168e1051a39Sopenharmony_ci * In respect to shift factor the execution time is invariant of 169e1051a39Sopenharmony_ci * |n % BN_BITS2|, but not |n / BN_BITS2|. Or in other words pre-condition 170e1051a39Sopenharmony_ci * for constant-time-ness for sufficiently[!] zero-padded inputs is 171e1051a39Sopenharmony_ci * |n < BN_BITS2| or |n / BN_BITS2| being non-secret. 172e1051a39Sopenharmony_ci */ 173e1051a39Sopenharmony_ciint bn_rshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n) 174e1051a39Sopenharmony_ci{ 175e1051a39Sopenharmony_ci int i, top, nw; 176e1051a39Sopenharmony_ci unsigned int lb, rb; 177e1051a39Sopenharmony_ci BN_ULONG *t, *f; 178e1051a39Sopenharmony_ci BN_ULONG l, m, mask; 179e1051a39Sopenharmony_ci 180e1051a39Sopenharmony_ci bn_check_top(r); 181e1051a39Sopenharmony_ci bn_check_top(a); 182e1051a39Sopenharmony_ci 183e1051a39Sopenharmony_ci assert(n >= 0); 184e1051a39Sopenharmony_ci 185e1051a39Sopenharmony_ci nw = n / BN_BITS2; 186e1051a39Sopenharmony_ci if (nw >= a->top) { 187e1051a39Sopenharmony_ci /* shouldn't happen, but formally required */ 188e1051a39Sopenharmony_ci BN_zero(r); 189e1051a39Sopenharmony_ci return 1; 190e1051a39Sopenharmony_ci } 191e1051a39Sopenharmony_ci 192e1051a39Sopenharmony_ci rb = (unsigned int)n % BN_BITS2; 193e1051a39Sopenharmony_ci lb = BN_BITS2 - rb; 194e1051a39Sopenharmony_ci lb %= BN_BITS2; /* say no to undefined behaviour */ 195e1051a39Sopenharmony_ci mask = (BN_ULONG)0 - lb; /* mask = 0 - (lb != 0) */ 196e1051a39Sopenharmony_ci mask |= mask >> 8; 197e1051a39Sopenharmony_ci top = a->top - nw; 198e1051a39Sopenharmony_ci if (r != a && bn_wexpand(r, top) == NULL) 199e1051a39Sopenharmony_ci return 0; 200e1051a39Sopenharmony_ci 201e1051a39Sopenharmony_ci t = &(r->d[0]); 202e1051a39Sopenharmony_ci f = &(a->d[nw]); 203e1051a39Sopenharmony_ci l = f[0]; 204e1051a39Sopenharmony_ci for (i = 0; i < top - 1; i++) { 205e1051a39Sopenharmony_ci m = f[i + 1]; 206e1051a39Sopenharmony_ci t[i] = (l >> rb) | ((m << lb) & mask); 207e1051a39Sopenharmony_ci l = m; 208e1051a39Sopenharmony_ci } 209e1051a39Sopenharmony_ci t[i] = l >> rb; 210e1051a39Sopenharmony_ci 211e1051a39Sopenharmony_ci r->neg = a->neg; 212e1051a39Sopenharmony_ci r->top = top; 213e1051a39Sopenharmony_ci r->flags |= BN_FLG_FIXED_TOP; 214e1051a39Sopenharmony_ci 215e1051a39Sopenharmony_ci return 1; 216e1051a39Sopenharmony_ci} 217