/src/openssl30/crypto/bn/bn_intern.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * Copyright 2014-2020 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 "internal/cryptlib.h" | 
| 11 |  | #include "bn_local.h" | 
| 12 |  |  | 
| 13 |  | /* | 
| 14 |  |  * Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'. | 
| 15 |  |  * This is an array  r[]  of values that are either zero or odd with an | 
| 16 |  |  * absolute value less than  2^w  satisfying | 
| 17 |  |  *     scalar = \sum_j r[j]*2^j | 
| 18 |  |  * where at most one of any  w+1  consecutive digits is non-zero | 
| 19 |  |  * with the exception that the most significant digit may be only | 
| 20 |  |  * w-1 zeros away from that next non-zero digit. | 
| 21 |  |  */ | 
| 22 |  | signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) | 
| 23 | 1.67k | { | 
| 24 | 1.67k |     int window_val; | 
| 25 | 1.67k |     signed char *r = NULL; | 
| 26 | 1.67k |     int sign = 1; | 
| 27 | 1.67k |     int bit, next_bit, mask; | 
| 28 | 1.67k |     size_t len = 0, j; | 
| 29 |  |  | 
| 30 | 1.67k |     if (BN_is_zero(scalar)) { | 
| 31 | 15 |         r = OPENSSL_malloc(1); | 
| 32 | 15 |         if (r == NULL) { | 
| 33 | 0 |             ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); | 
| 34 | 0 |             goto err; | 
| 35 | 0 |         } | 
| 36 | 15 |         r[0] = 0; | 
| 37 | 15 |         *ret_len = 1; | 
| 38 | 15 |         return r; | 
| 39 | 15 |     } | 
| 40 |  |  | 
| 41 | 1.66k |     if (w <= 0 || w > 7) {      /* 'signed char' can represent integers with | 
| 42 |  |                                  * absolute values less than 2^7 */ | 
| 43 | 0 |         ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR); | 
| 44 | 0 |         goto err; | 
| 45 | 0 |     } | 
| 46 | 1.66k |     bit = 1 << w;               /* at most 128 */ | 
| 47 | 1.66k |     next_bit = bit << 1;        /* at most 256 */ | 
| 48 | 1.66k |     mask = next_bit - 1;        /* at most 255 */ | 
| 49 |  |  | 
| 50 | 1.66k |     if (BN_is_negative(scalar)) { | 
| 51 | 0 |         sign = -1; | 
| 52 | 0 |     } | 
| 53 |  |  | 
| 54 | 1.66k |     if (scalar->d == NULL || scalar->top == 0) { | 
| 55 | 0 |         ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR); | 
| 56 | 0 |         goto err; | 
| 57 | 0 |     } | 
| 58 |  |  | 
| 59 | 1.66k |     len = BN_num_bits(scalar); | 
| 60 | 1.66k |     r = OPENSSL_malloc(len + 1); /* | 
| 61 |  |                                   * Modified wNAF may be one digit longer than binary representation | 
| 62 |  |                                   * (*ret_len will be set to the actual length, i.e. at most | 
| 63 |  |                                   * BN_num_bits(scalar) + 1) | 
| 64 |  |                                   */ | 
| 65 | 1.66k |     if (r == NULL) { | 
| 66 | 0 |         ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); | 
| 67 | 0 |         goto err; | 
| 68 | 0 |     } | 
| 69 | 1.66k |     window_val = scalar->d[0] & mask; | 
| 70 | 1.66k |     j = 0; | 
| 71 | 350k |     while ((window_val != 0) || (j + w + 1 < len)) { /* if j+w+1 >= len, | 
| 72 |  |                                                       * window_val will not | 
| 73 |  |                                                       * increase */ | 
| 74 | 348k |         int digit = 0; | 
| 75 |  |  | 
| 76 |  |         /* 0 <= window_val <= 2^(w+1) */ | 
| 77 |  |  | 
| 78 | 348k |         if (window_val & 1) { | 
| 79 |  |             /* 0 < window_val < 2^(w+1) */ | 
| 80 |  |  | 
| 81 | 48.8k |             if (window_val & bit) { | 
| 82 | 22.3k |                 digit = window_val - next_bit; /* -2^w < digit < 0 */ | 
| 83 |  |  | 
| 84 | 22.3k | #if 1                           /* modified wNAF */ | 
| 85 | 22.3k |                 if (j + w + 1 >= len) { | 
| 86 |  |                     /* | 
| 87 |  |                      * Special case for generating modified wNAFs: | 
| 88 |  |                      * no new bits will be added into window_val, | 
| 89 |  |                      * so using a positive digit here will decrease | 
| 90 |  |                      * the total length of the representation | 
| 91 |  |                      */ | 
| 92 |  |  | 
| 93 | 248 |                     digit = window_val & (mask >> 1); /* 0 < digit < 2^w */ | 
| 94 | 248 |                 } | 
| 95 | 22.3k | #endif | 
| 96 | 26.4k |             } else { | 
| 97 | 26.4k |                 digit = window_val; /* 0 < digit < 2^w */ | 
| 98 | 26.4k |             } | 
| 99 |  |  | 
| 100 | 48.8k |             if (digit <= -bit || digit >= bit || !(digit & 1)) { | 
| 101 | 0 |                 ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR); | 
| 102 | 0 |                 goto err; | 
| 103 | 0 |             } | 
| 104 |  |  | 
| 105 | 48.8k |             window_val -= digit; | 
| 106 |  |  | 
| 107 |  |             /* | 
| 108 |  |              * now window_val is 0 or 2^(w+1) in standard wNAF generation; | 
| 109 |  |              * for modified window NAFs, it may also be 2^w | 
| 110 |  |              */ | 
| 111 | 48.8k |             if (window_val != 0 && window_val != next_bit | 
| 112 | 48.8k |                 && window_val != bit) { | 
| 113 | 0 |                 ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR); | 
| 114 | 0 |                 goto err; | 
| 115 | 0 |             } | 
| 116 | 48.8k |         } | 
| 117 |  |  | 
| 118 | 348k |         r[j++] = sign * digit; | 
| 119 |  |  | 
| 120 | 348k |         window_val >>= 1; | 
| 121 | 348k |         window_val += bit * BN_is_bit_set(scalar, j + w); | 
| 122 |  |  | 
| 123 | 348k |         if (window_val > next_bit) { | 
| 124 | 0 |             ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR); | 
| 125 | 0 |             goto err; | 
| 126 | 0 |         } | 
| 127 | 348k |     } | 
| 128 |  |  | 
| 129 | 1.66k |     if (j > len + 1) { | 
| 130 | 0 |         ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR); | 
| 131 | 0 |         goto err; | 
| 132 | 0 |     } | 
| 133 | 1.66k |     *ret_len = j; | 
| 134 | 1.66k |     return r; | 
| 135 |  |  | 
| 136 | 0 |  err: | 
| 137 | 0 |     OPENSSL_free(r); | 
| 138 | 0 |     return NULL; | 
| 139 | 1.66k | } | 
| 140 |  |  | 
| 141 |  | int bn_get_top(const BIGNUM *a) | 
| 142 | 89.2k | { | 
| 143 | 89.2k |     return a->top; | 
| 144 | 89.2k | } | 
| 145 |  |  | 
| 146 |  | int bn_get_dmax(const BIGNUM *a) | 
| 147 | 0 | { | 
| 148 | 0 |     return a->dmax; | 
| 149 | 0 | } | 
| 150 |  |  | 
| 151 |  | void bn_set_all_zero(BIGNUM *a) | 
| 152 | 374k | { | 
| 153 | 374k |     int i; | 
| 154 |  |  | 
| 155 | 882k |     for (i = a->top; i < a->dmax; i++) | 
| 156 | 508k |         a->d[i] = 0; | 
| 157 | 374k | } | 
| 158 |  |  | 
| 159 |  | int bn_copy_words(BN_ULONG *out, const BIGNUM *in, int size) | 
| 160 | 81.1k | { | 
| 161 | 81.1k |     if (in->top > size) | 
| 162 | 0 |         return 0; | 
| 163 |  |  | 
| 164 | 81.1k |     memset(out, 0, sizeof(*out) * size); | 
| 165 | 81.1k |     if (in->d != NULL) | 
| 166 | 81.1k |         memcpy(out, in->d, sizeof(*out) * in->top); | 
| 167 | 81.1k |     return 1; | 
| 168 | 81.1k | } | 
| 169 |  |  | 
| 170 |  | BN_ULONG *bn_get_words(const BIGNUM *a) | 
| 171 | 239k | { | 
| 172 | 239k |     return a->d; | 
| 173 | 239k | } | 
| 174 |  |  | 
| 175 |  | void bn_set_static_words(BIGNUM *a, const BN_ULONG *words, int size) | 
| 176 | 0 | { | 
| 177 |  |     /* | 
| 178 |  |      * |const| qualifier omission is compensated by BN_FLG_STATIC_DATA | 
| 179 |  |      * flag, which effectively means "read-only data". | 
| 180 |  |      */ | 
| 181 | 0 |     a->d = (BN_ULONG *)words; | 
| 182 | 0 |     a->dmax = a->top = size; | 
| 183 | 0 |     a->neg = 0; | 
| 184 | 0 |     a->flags |= BN_FLG_STATIC_DATA; | 
| 185 | 0 |     bn_correct_top(a); | 
| 186 | 0 | } | 
| 187 |  |  | 
| 188 |  | int bn_set_words(BIGNUM *a, const BN_ULONG *words, int num_words) | 
| 189 | 63.9k | { | 
| 190 | 63.9k |     if (bn_wexpand(a, num_words) == NULL) { | 
| 191 | 0 |         ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); | 
| 192 | 0 |         return 0; | 
| 193 | 0 |     } | 
| 194 |  |  | 
| 195 | 63.9k |     memcpy(a->d, words, sizeof(BN_ULONG) * num_words); | 
| 196 | 63.9k |     a->top = num_words; | 
| 197 | 63.9k |     bn_correct_top(a); | 
| 198 | 63.9k |     return 1; | 
| 199 | 63.9k | } |