Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
wolfmath.c
00001 /* wolfmath.c 00002 * 00003 * Copyright (C) 2006-2017 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 /* common functions for either math library */ 00024 00025 #ifdef HAVE_CONFIG_H 00026 #include <config.h> 00027 #endif 00028 00029 /* in case user set USE_FAST_MATH there */ 00030 #include <wolfcrypt/settings.h> 00031 00032 #ifdef USE_FAST_MATH 00033 #include <wolfcrypt/tfm.h> 00034 #else 00035 #include <wolfcrypt/integer.h> 00036 #endif 00037 00038 #include <wolfcrypt/error-crypt.h> 00039 #include <wolfcrypt/logging.h> 00040 00041 #if defined(USE_FAST_MATH) || !defined(NO_BIG_INT) 00042 00043 #ifdef WOLFSSL_ASYNC_CRYPT 00044 #include <wolfcrypt/async.h> 00045 #endif 00046 00047 #ifdef NO_INLINE 00048 #include <wolfcrypt/misc.h> 00049 #else 00050 #define WOLFSSL_MISC_INCLUDED 00051 #include <wolfcrypt/src/misc.c> 00052 #endif 00053 00054 00055 #if !defined(WC_NO_CACHE_RESISTANT) && \ 00056 ((defined(HAVE_ECC) && defined(ECC_TIMING_RESISTANT)) || \ 00057 (defined(USE_FAST_MATH) && defined(TFM_TIMING_RESISTANT))) 00058 00059 /* all off / all on pointer addresses for constant calculations */ 00060 /* ecc.c uses same table */ 00061 const wolfssl_word wc_off_on_addr[2] = 00062 { 00063 #if defined(WC_64BIT_CPU) 00064 W64LIT(0x0000000000000000), 00065 W64LIT(0xffffffffffffffff) 00066 #elif defined(WC_16BIT_CPU) 00067 0x0000U, 00068 0xffffU 00069 #else 00070 /* 32 bit */ 00071 0x00000000U, 00072 0xffffffffU 00073 #endif 00074 }; 00075 #endif 00076 00077 00078 int get_digit_count(mp_int* a) 00079 { 00080 if (a == NULL) 00081 return 0; 00082 00083 return a->used; 00084 } 00085 00086 mp_digit get_digit(mp_int* a, int n) 00087 { 00088 if (a == NULL) 00089 return 0; 00090 00091 return (n >= a->used || n < 0) ? 0 : a->dp[n]; 00092 } 00093 00094 int get_rand_digit(WC_RNG* rng, mp_digit* d) 00095 { 00096 return wc_RNG_GenerateBlock(rng, (byte*)d, sizeof(mp_digit)); 00097 } 00098 00099 #ifdef WC_RSA_BLINDING 00100 int mp_rand(mp_int* a, int digits, WC_RNG* rng) 00101 { 00102 int ret = 0; 00103 DECLARE_VAR(d, mp_digit, 1, rng->heap); 00104 00105 if (rng == NULL) { 00106 ret = MISSING_RNG_E; goto exit; 00107 } 00108 00109 if (a == NULL 00110 #ifdef WOLFSSL_ASYNC_CRYPT 00111 || d == NULL 00112 #endif 00113 ) { 00114 ret = BAD_FUNC_ARG; goto exit; 00115 } 00116 00117 mp_zero(a); 00118 if (digits <= 0) { 00119 ret = MP_OKAY; goto exit; 00120 } 00121 00122 /* first place a random non-zero digit */ 00123 do { 00124 ret = get_rand_digit(rng, d); 00125 if (ret != 0) { 00126 goto exit; 00127 } 00128 } while (*d == 0); 00129 00130 if ((ret = mp_add_d(a, *d, a)) != MP_OKAY) { 00131 goto exit; 00132 } 00133 00134 while (--digits > 0) { 00135 if ((ret = mp_lshd(a, 1)) != MP_OKAY) { 00136 goto exit; 00137 } 00138 if ((ret = get_rand_digit(rng, d)) != 0) { 00139 goto exit; 00140 } 00141 if ((ret = mp_add_d(a, *d, a)) != MP_OKAY) { 00142 goto exit; 00143 } 00144 } 00145 00146 exit: 00147 FREE_VAR(d, rng->heap); 00148 00149 return ret; 00150 } 00151 #endif /* WC_RSA_BLINDING */ 00152 00153 00154 #ifdef HAVE_WOLF_BIGINT 00155 void wc_bigint_init(WC_BIGINT* a) 00156 { 00157 if (a != NULL) { 00158 a->buf = NULL; 00159 a->len = 0; 00160 a->heap = NULL; 00161 } 00162 } 00163 00164 int wc_bigint_alloc(WC_BIGINT* a, word32 sz) 00165 { 00166 int err = MP_OKAY; 00167 00168 if (a == NULL) 00169 return BAD_FUNC_ARG; 00170 00171 if (sz > 0) { 00172 if (a->buf && sz > a->len) { 00173 wc_bigint_free(a); 00174 } 00175 if (a->buf == NULL) { 00176 a->buf = (byte*)XMALLOC(sz, a->heap, DYNAMIC_TYPE_WOLF_BIGINT); 00177 } 00178 if (a->buf == NULL) { 00179 err = MP_MEM; 00180 } 00181 else { 00182 XMEMSET(a->buf, 0, sz); 00183 } 00184 } 00185 a->len = sz; 00186 00187 return err; 00188 } 00189 00190 /* assumes input is big endian format */ 00191 int wc_bigint_from_unsigned_bin(WC_BIGINT* a, const byte* in, word32 inlen) 00192 { 00193 int err; 00194 00195 if (a == NULL || in == NULL || inlen == 0) 00196 return BAD_FUNC_ARG; 00197 00198 err = wc_bigint_alloc(a, inlen); 00199 if (err == 0) { 00200 XMEMCPY(a->buf, in, inlen); 00201 } 00202 00203 return err; 00204 } 00205 00206 int wc_bigint_to_unsigned_bin(WC_BIGINT* a, byte* out, word32* outlen) 00207 { 00208 word32 sz; 00209 00210 if (a == NULL || out == NULL || outlen == NULL || *outlen == 0) 00211 return BAD_FUNC_ARG; 00212 00213 /* trim to fit into output buffer */ 00214 sz = a->len; 00215 if (a->len > *outlen) { 00216 WOLFSSL_MSG("wc_bigint_export: Truncating output"); 00217 sz = *outlen; 00218 } 00219 00220 if (a->buf) { 00221 XMEMCPY(out, a->buf, sz); 00222 } 00223 00224 *outlen = sz; 00225 00226 return MP_OKAY; 00227 } 00228 00229 void wc_bigint_zero(WC_BIGINT* a) 00230 { 00231 if (a && a->buf) { 00232 ForceZero(a->buf, a->len); 00233 } 00234 } 00235 00236 void wc_bigint_free(WC_BIGINT* a) 00237 { 00238 if (a) { 00239 if (a->buf) { 00240 XFREE(a->buf, a->heap, DYNAMIC_TYPE_WOLF_BIGINT); 00241 } 00242 a->buf = NULL; 00243 a->len = 0; 00244 } 00245 } 00246 00247 /* sz: make sure the buffer is at least that size and zero padded. 00248 * A `sz == 0` will use the size of `src`. 00249 * The calulcates sz is stored into dst->len in `wc_bigint_alloc`. 00250 */ 00251 int wc_mp_to_bigint_sz(mp_int* src, WC_BIGINT* dst, word32 sz) 00252 { 00253 int err; 00254 word32 x, y; 00255 00256 if (src == NULL || dst == NULL) 00257 return BAD_FUNC_ARG; 00258 00259 /* get size of source */ 00260 x = mp_unsigned_bin_size(src); 00261 if (sz < x) 00262 sz = x; 00263 00264 /* make sure destination is allocated and large enough */ 00265 err = wc_bigint_alloc(dst, sz); 00266 if (err == MP_OKAY) { 00267 00268 /* leading zero pad */ 00269 y = sz - x; 00270 XMEMSET(dst->buf, 0, y); 00271 00272 /* export src as unsigned bin to destination buf */ 00273 err = mp_to_unsigned_bin(src, dst->buf + y); 00274 } 00275 00276 return err; 00277 } 00278 00279 int wc_mp_to_bigint(mp_int* src, WC_BIGINT* dst) 00280 { 00281 if (src == NULL || dst == NULL) 00282 return BAD_FUNC_ARG; 00283 00284 return wc_mp_to_bigint_sz(src, dst, 0); 00285 } 00286 00287 int wc_bigint_to_mp(WC_BIGINT* src, mp_int* dst) 00288 { 00289 int err; 00290 00291 if (src == NULL || dst == NULL) 00292 return BAD_FUNC_ARG; 00293 00294 if (src->buf == NULL) 00295 return BAD_FUNC_ARG; 00296 00297 err = mp_read_unsigned_bin(dst, src->buf, src->len); 00298 wc_bigint_free(src); 00299 00300 return err; 00301 } 00302 00303 #endif /* HAVE_WOLF_BIGINT */ 00304 00305 #endif /* USE_FAST_MATH || !NO_BIG_INT */ 00306
Generated on Tue Jul 12 2022 16:58:12 by
1.7.2