wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Committer:
wolfSSL
Date:
Sat Aug 18 22:20:43 2018 +0000
Revision:
15:117db924cf7c
Child:
16:8e0d178b1d1e
wolfSSL 3.15.3

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 15:117db924cf7c 1 /* wolfmath.c
wolfSSL 15:117db924cf7c 2 *
wolfSSL 15:117db924cf7c 3 * Copyright (C) 2006-2017 wolfSSL Inc.
wolfSSL 15:117db924cf7c 4 *
wolfSSL 15:117db924cf7c 5 * This file is part of wolfSSL.
wolfSSL 15:117db924cf7c 6 *
wolfSSL 15:117db924cf7c 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 15:117db924cf7c 8 * it under the terms of the GNU General Public License as published by
wolfSSL 15:117db924cf7c 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 15:117db924cf7c 10 * (at your option) any later version.
wolfSSL 15:117db924cf7c 11 *
wolfSSL 15:117db924cf7c 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 15:117db924cf7c 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 15:117db924cf7c 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 15:117db924cf7c 15 * GNU General Public License for more details.
wolfSSL 15:117db924cf7c 16 *
wolfSSL 15:117db924cf7c 17 * You should have received a copy of the GNU General Public License
wolfSSL 15:117db924cf7c 18 * along with this program; if not, write to the Free Software
wolfSSL 15:117db924cf7c 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 15:117db924cf7c 20 */
wolfSSL 15:117db924cf7c 21
wolfSSL 15:117db924cf7c 22
wolfSSL 15:117db924cf7c 23 /* common functions for either math library */
wolfSSL 15:117db924cf7c 24
wolfSSL 15:117db924cf7c 25 #ifdef HAVE_CONFIG_H
wolfSSL 15:117db924cf7c 26 #include <config.h>
wolfSSL 15:117db924cf7c 27 #endif
wolfSSL 15:117db924cf7c 28
wolfSSL 15:117db924cf7c 29 /* in case user set USE_FAST_MATH there */
wolfSSL 15:117db924cf7c 30 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 15:117db924cf7c 31
wolfSSL 15:117db924cf7c 32 #ifdef USE_FAST_MATH
wolfSSL 15:117db924cf7c 33 #include <wolfssl/wolfcrypt/tfm.h>
wolfSSL 15:117db924cf7c 34 #else
wolfSSL 15:117db924cf7c 35 #include <wolfssl/wolfcrypt/integer.h>
wolfSSL 15:117db924cf7c 36 #endif
wolfSSL 15:117db924cf7c 37
wolfSSL 15:117db924cf7c 38 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 15:117db924cf7c 39 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 15:117db924cf7c 40
wolfSSL 15:117db924cf7c 41 #if defined(USE_FAST_MATH) || !defined(NO_BIG_INT)
wolfSSL 15:117db924cf7c 42
wolfSSL 15:117db924cf7c 43 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 15:117db924cf7c 44 #include <wolfssl/wolfcrypt/async.h>
wolfSSL 15:117db924cf7c 45 #endif
wolfSSL 15:117db924cf7c 46
wolfSSL 15:117db924cf7c 47 #ifdef NO_INLINE
wolfSSL 15:117db924cf7c 48 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 15:117db924cf7c 49 #else
wolfSSL 15:117db924cf7c 50 #define WOLFSSL_MISC_INCLUDED
wolfSSL 15:117db924cf7c 51 #include <wolfcrypt/src/misc.c>
wolfSSL 15:117db924cf7c 52 #endif
wolfSSL 15:117db924cf7c 53
wolfSSL 15:117db924cf7c 54
wolfSSL 15:117db924cf7c 55 #if !defined(WC_NO_CACHE_RESISTANT) && \
wolfSSL 15:117db924cf7c 56 ((defined(HAVE_ECC) && defined(ECC_TIMING_RESISTANT)) || \
wolfSSL 15:117db924cf7c 57 (defined(USE_FAST_MATH) && defined(TFM_TIMING_RESISTANT)))
wolfSSL 15:117db924cf7c 58
wolfSSL 15:117db924cf7c 59 /* all off / all on pointer addresses for constant calculations */
wolfSSL 15:117db924cf7c 60 /* ecc.c uses same table */
wolfSSL 15:117db924cf7c 61 const wolfssl_word wc_off_on_addr[2] =
wolfSSL 15:117db924cf7c 62 {
wolfSSL 15:117db924cf7c 63 #if defined(WC_64BIT_CPU)
wolfSSL 15:117db924cf7c 64 W64LIT(0x0000000000000000),
wolfSSL 15:117db924cf7c 65 W64LIT(0xffffffffffffffff)
wolfSSL 15:117db924cf7c 66 #elif defined(WC_16BIT_CPU)
wolfSSL 15:117db924cf7c 67 0x0000U,
wolfSSL 15:117db924cf7c 68 0xffffU
wolfSSL 15:117db924cf7c 69 #else
wolfSSL 15:117db924cf7c 70 /* 32 bit */
wolfSSL 15:117db924cf7c 71 0x00000000U,
wolfSSL 15:117db924cf7c 72 0xffffffffU
wolfSSL 15:117db924cf7c 73 #endif
wolfSSL 15:117db924cf7c 74 };
wolfSSL 15:117db924cf7c 75 #endif
wolfSSL 15:117db924cf7c 76
wolfSSL 15:117db924cf7c 77
wolfSSL 15:117db924cf7c 78 int get_digit_count(mp_int* a)
wolfSSL 15:117db924cf7c 79 {
wolfSSL 15:117db924cf7c 80 if (a == NULL)
wolfSSL 15:117db924cf7c 81 return 0;
wolfSSL 15:117db924cf7c 82
wolfSSL 15:117db924cf7c 83 return a->used;
wolfSSL 15:117db924cf7c 84 }
wolfSSL 15:117db924cf7c 85
wolfSSL 15:117db924cf7c 86 mp_digit get_digit(mp_int* a, int n)
wolfSSL 15:117db924cf7c 87 {
wolfSSL 15:117db924cf7c 88 if (a == NULL)
wolfSSL 15:117db924cf7c 89 return 0;
wolfSSL 15:117db924cf7c 90
wolfSSL 15:117db924cf7c 91 return (n >= a->used || n < 0) ? 0 : a->dp[n];
wolfSSL 15:117db924cf7c 92 }
wolfSSL 15:117db924cf7c 93
wolfSSL 15:117db924cf7c 94 int get_rand_digit(WC_RNG* rng, mp_digit* d)
wolfSSL 15:117db924cf7c 95 {
wolfSSL 15:117db924cf7c 96 return wc_RNG_GenerateBlock(rng, (byte*)d, sizeof(mp_digit));
wolfSSL 15:117db924cf7c 97 }
wolfSSL 15:117db924cf7c 98
wolfSSL 15:117db924cf7c 99 #ifdef WC_RSA_BLINDING
wolfSSL 15:117db924cf7c 100 int mp_rand(mp_int* a, int digits, WC_RNG* rng)
wolfSSL 15:117db924cf7c 101 {
wolfSSL 15:117db924cf7c 102 int ret = 0;
wolfSSL 15:117db924cf7c 103 DECLARE_VAR(d, mp_digit, 1, rng->heap);
wolfSSL 15:117db924cf7c 104
wolfSSL 15:117db924cf7c 105 if (rng == NULL) {
wolfSSL 15:117db924cf7c 106 ret = MISSING_RNG_E; goto exit;
wolfSSL 15:117db924cf7c 107 }
wolfSSL 15:117db924cf7c 108
wolfSSL 15:117db924cf7c 109 if (a == NULL
wolfSSL 15:117db924cf7c 110 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 15:117db924cf7c 111 || d == NULL
wolfSSL 15:117db924cf7c 112 #endif
wolfSSL 15:117db924cf7c 113 ) {
wolfSSL 15:117db924cf7c 114 ret = BAD_FUNC_ARG; goto exit;
wolfSSL 15:117db924cf7c 115 }
wolfSSL 15:117db924cf7c 116
wolfSSL 15:117db924cf7c 117 mp_zero(a);
wolfSSL 15:117db924cf7c 118 if (digits <= 0) {
wolfSSL 15:117db924cf7c 119 ret = MP_OKAY; goto exit;
wolfSSL 15:117db924cf7c 120 }
wolfSSL 15:117db924cf7c 121
wolfSSL 15:117db924cf7c 122 /* first place a random non-zero digit */
wolfSSL 15:117db924cf7c 123 do {
wolfSSL 15:117db924cf7c 124 ret = get_rand_digit(rng, d);
wolfSSL 15:117db924cf7c 125 if (ret != 0) {
wolfSSL 15:117db924cf7c 126 goto exit;
wolfSSL 15:117db924cf7c 127 }
wolfSSL 15:117db924cf7c 128 } while (*d == 0);
wolfSSL 15:117db924cf7c 129
wolfSSL 15:117db924cf7c 130 if ((ret = mp_add_d(a, *d, a)) != MP_OKAY) {
wolfSSL 15:117db924cf7c 131 goto exit;
wolfSSL 15:117db924cf7c 132 }
wolfSSL 15:117db924cf7c 133
wolfSSL 15:117db924cf7c 134 while (--digits > 0) {
wolfSSL 15:117db924cf7c 135 if ((ret = mp_lshd(a, 1)) != MP_OKAY) {
wolfSSL 15:117db924cf7c 136 goto exit;
wolfSSL 15:117db924cf7c 137 }
wolfSSL 15:117db924cf7c 138 if ((ret = get_rand_digit(rng, d)) != 0) {
wolfSSL 15:117db924cf7c 139 goto exit;
wolfSSL 15:117db924cf7c 140 }
wolfSSL 15:117db924cf7c 141 if ((ret = mp_add_d(a, *d, a)) != MP_OKAY) {
wolfSSL 15:117db924cf7c 142 goto exit;
wolfSSL 15:117db924cf7c 143 }
wolfSSL 15:117db924cf7c 144 }
wolfSSL 15:117db924cf7c 145
wolfSSL 15:117db924cf7c 146 exit:
wolfSSL 15:117db924cf7c 147 FREE_VAR(d, rng->heap);
wolfSSL 15:117db924cf7c 148
wolfSSL 15:117db924cf7c 149 return ret;
wolfSSL 15:117db924cf7c 150 }
wolfSSL 15:117db924cf7c 151 #endif /* WC_RSA_BLINDING */
wolfSSL 15:117db924cf7c 152
wolfSSL 15:117db924cf7c 153
wolfSSL 15:117db924cf7c 154 #ifdef HAVE_WOLF_BIGINT
wolfSSL 15:117db924cf7c 155 void wc_bigint_init(WC_BIGINT* a)
wolfSSL 15:117db924cf7c 156 {
wolfSSL 15:117db924cf7c 157 if (a != NULL) {
wolfSSL 15:117db924cf7c 158 a->buf = NULL;
wolfSSL 15:117db924cf7c 159 a->len = 0;
wolfSSL 15:117db924cf7c 160 a->heap = NULL;
wolfSSL 15:117db924cf7c 161 }
wolfSSL 15:117db924cf7c 162 }
wolfSSL 15:117db924cf7c 163
wolfSSL 15:117db924cf7c 164 int wc_bigint_alloc(WC_BIGINT* a, word32 sz)
wolfSSL 15:117db924cf7c 165 {
wolfSSL 15:117db924cf7c 166 int err = MP_OKAY;
wolfSSL 15:117db924cf7c 167
wolfSSL 15:117db924cf7c 168 if (a == NULL)
wolfSSL 15:117db924cf7c 169 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 170
wolfSSL 15:117db924cf7c 171 if (sz > 0) {
wolfSSL 15:117db924cf7c 172 if (a->buf && sz > a->len) {
wolfSSL 15:117db924cf7c 173 wc_bigint_free(a);
wolfSSL 15:117db924cf7c 174 }
wolfSSL 15:117db924cf7c 175 if (a->buf == NULL) {
wolfSSL 15:117db924cf7c 176 a->buf = (byte*)XMALLOC(sz, a->heap, DYNAMIC_TYPE_WOLF_BIGINT);
wolfSSL 15:117db924cf7c 177 }
wolfSSL 15:117db924cf7c 178 if (a->buf == NULL) {
wolfSSL 15:117db924cf7c 179 err = MP_MEM;
wolfSSL 15:117db924cf7c 180 }
wolfSSL 15:117db924cf7c 181 else {
wolfSSL 15:117db924cf7c 182 XMEMSET(a->buf, 0, sz);
wolfSSL 15:117db924cf7c 183 }
wolfSSL 15:117db924cf7c 184 }
wolfSSL 15:117db924cf7c 185 a->len = sz;
wolfSSL 15:117db924cf7c 186
wolfSSL 15:117db924cf7c 187 return err;
wolfSSL 15:117db924cf7c 188 }
wolfSSL 15:117db924cf7c 189
wolfSSL 15:117db924cf7c 190 /* assumes input is big endian format */
wolfSSL 15:117db924cf7c 191 int wc_bigint_from_unsigned_bin(WC_BIGINT* a, const byte* in, word32 inlen)
wolfSSL 15:117db924cf7c 192 {
wolfSSL 15:117db924cf7c 193 int err;
wolfSSL 15:117db924cf7c 194
wolfSSL 15:117db924cf7c 195 if (a == NULL || in == NULL || inlen == 0)
wolfSSL 15:117db924cf7c 196 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 197
wolfSSL 15:117db924cf7c 198 err = wc_bigint_alloc(a, inlen);
wolfSSL 15:117db924cf7c 199 if (err == 0) {
wolfSSL 15:117db924cf7c 200 XMEMCPY(a->buf, in, inlen);
wolfSSL 15:117db924cf7c 201 }
wolfSSL 15:117db924cf7c 202
wolfSSL 15:117db924cf7c 203 return err;
wolfSSL 15:117db924cf7c 204 }
wolfSSL 15:117db924cf7c 205
wolfSSL 15:117db924cf7c 206 int wc_bigint_to_unsigned_bin(WC_BIGINT* a, byte* out, word32* outlen)
wolfSSL 15:117db924cf7c 207 {
wolfSSL 15:117db924cf7c 208 word32 sz;
wolfSSL 15:117db924cf7c 209
wolfSSL 15:117db924cf7c 210 if (a == NULL || out == NULL || outlen == NULL || *outlen == 0)
wolfSSL 15:117db924cf7c 211 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 212
wolfSSL 15:117db924cf7c 213 /* trim to fit into output buffer */
wolfSSL 15:117db924cf7c 214 sz = a->len;
wolfSSL 15:117db924cf7c 215 if (a->len > *outlen) {
wolfSSL 15:117db924cf7c 216 WOLFSSL_MSG("wc_bigint_export: Truncating output");
wolfSSL 15:117db924cf7c 217 sz = *outlen;
wolfSSL 15:117db924cf7c 218 }
wolfSSL 15:117db924cf7c 219
wolfSSL 15:117db924cf7c 220 if (a->buf) {
wolfSSL 15:117db924cf7c 221 XMEMCPY(out, a->buf, sz);
wolfSSL 15:117db924cf7c 222 }
wolfSSL 15:117db924cf7c 223
wolfSSL 15:117db924cf7c 224 *outlen = sz;
wolfSSL 15:117db924cf7c 225
wolfSSL 15:117db924cf7c 226 return MP_OKAY;
wolfSSL 15:117db924cf7c 227 }
wolfSSL 15:117db924cf7c 228
wolfSSL 15:117db924cf7c 229 void wc_bigint_zero(WC_BIGINT* a)
wolfSSL 15:117db924cf7c 230 {
wolfSSL 15:117db924cf7c 231 if (a && a->buf) {
wolfSSL 15:117db924cf7c 232 ForceZero(a->buf, a->len);
wolfSSL 15:117db924cf7c 233 }
wolfSSL 15:117db924cf7c 234 }
wolfSSL 15:117db924cf7c 235
wolfSSL 15:117db924cf7c 236 void wc_bigint_free(WC_BIGINT* a)
wolfSSL 15:117db924cf7c 237 {
wolfSSL 15:117db924cf7c 238 if (a) {
wolfSSL 15:117db924cf7c 239 if (a->buf) {
wolfSSL 15:117db924cf7c 240 XFREE(a->buf, a->heap, DYNAMIC_TYPE_WOLF_BIGINT);
wolfSSL 15:117db924cf7c 241 }
wolfSSL 15:117db924cf7c 242 a->buf = NULL;
wolfSSL 15:117db924cf7c 243 a->len = 0;
wolfSSL 15:117db924cf7c 244 }
wolfSSL 15:117db924cf7c 245 }
wolfSSL 15:117db924cf7c 246
wolfSSL 15:117db924cf7c 247 /* sz: make sure the buffer is at least that size and zero padded.
wolfSSL 15:117db924cf7c 248 * A `sz == 0` will use the size of `src`.
wolfSSL 15:117db924cf7c 249 * The calulcates sz is stored into dst->len in `wc_bigint_alloc`.
wolfSSL 15:117db924cf7c 250 */
wolfSSL 15:117db924cf7c 251 int wc_mp_to_bigint_sz(mp_int* src, WC_BIGINT* dst, word32 sz)
wolfSSL 15:117db924cf7c 252 {
wolfSSL 15:117db924cf7c 253 int err;
wolfSSL 15:117db924cf7c 254 word32 x, y;
wolfSSL 15:117db924cf7c 255
wolfSSL 15:117db924cf7c 256 if (src == NULL || dst == NULL)
wolfSSL 15:117db924cf7c 257 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 258
wolfSSL 15:117db924cf7c 259 /* get size of source */
wolfSSL 15:117db924cf7c 260 x = mp_unsigned_bin_size(src);
wolfSSL 15:117db924cf7c 261 if (sz < x)
wolfSSL 15:117db924cf7c 262 sz = x;
wolfSSL 15:117db924cf7c 263
wolfSSL 15:117db924cf7c 264 /* make sure destination is allocated and large enough */
wolfSSL 15:117db924cf7c 265 err = wc_bigint_alloc(dst, sz);
wolfSSL 15:117db924cf7c 266 if (err == MP_OKAY) {
wolfSSL 15:117db924cf7c 267
wolfSSL 15:117db924cf7c 268 /* leading zero pad */
wolfSSL 15:117db924cf7c 269 y = sz - x;
wolfSSL 15:117db924cf7c 270 XMEMSET(dst->buf, 0, y);
wolfSSL 15:117db924cf7c 271
wolfSSL 15:117db924cf7c 272 /* export src as unsigned bin to destination buf */
wolfSSL 15:117db924cf7c 273 err = mp_to_unsigned_bin(src, dst->buf + y);
wolfSSL 15:117db924cf7c 274 }
wolfSSL 15:117db924cf7c 275
wolfSSL 15:117db924cf7c 276 return err;
wolfSSL 15:117db924cf7c 277 }
wolfSSL 15:117db924cf7c 278
wolfSSL 15:117db924cf7c 279 int wc_mp_to_bigint(mp_int* src, WC_BIGINT* dst)
wolfSSL 15:117db924cf7c 280 {
wolfSSL 15:117db924cf7c 281 if (src == NULL || dst == NULL)
wolfSSL 15:117db924cf7c 282 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 283
wolfSSL 15:117db924cf7c 284 return wc_mp_to_bigint_sz(src, dst, 0);
wolfSSL 15:117db924cf7c 285 }
wolfSSL 15:117db924cf7c 286
wolfSSL 15:117db924cf7c 287 int wc_bigint_to_mp(WC_BIGINT* src, mp_int* dst)
wolfSSL 15:117db924cf7c 288 {
wolfSSL 15:117db924cf7c 289 int err;
wolfSSL 15:117db924cf7c 290
wolfSSL 15:117db924cf7c 291 if (src == NULL || dst == NULL)
wolfSSL 15:117db924cf7c 292 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 293
wolfSSL 15:117db924cf7c 294 if (src->buf == NULL)
wolfSSL 15:117db924cf7c 295 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 296
wolfSSL 15:117db924cf7c 297 err = mp_read_unsigned_bin(dst, src->buf, src->len);
wolfSSL 15:117db924cf7c 298 wc_bigint_free(src);
wolfSSL 15:117db924cf7c 299
wolfSSL 15:117db924cf7c 300 return err;
wolfSSL 15:117db924cf7c 301 }
wolfSSL 15:117db924cf7c 302
wolfSSL 15:117db924cf7c 303 #endif /* HAVE_WOLF_BIGINT */
wolfSSL 15:117db924cf7c 304
wolfSSL 15:117db924cf7c 305 #endif /* USE_FAST_MATH || !NO_BIG_INT */
wolfSSL 15:117db924cf7c 306