wolf SSL / wolfSSL-TLS13-Beta

Fork of wolfSSL by wolf SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers wolfmath.c Source File

wolfmath.c

00001 /* wolfmath.c
00002  *
00003  * Copyright (C) 2006-2016 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 <wolfssl/wolfcrypt/settings.h>
00031 
00032 #ifdef USE_FAST_MATH
00033     #include <wolfssl/wolfcrypt/tfm.h>
00034 #else
00035     #include <wolfssl/wolfcrypt/integer.h>
00036 #endif
00037 
00038 #include <wolfssl/wolfcrypt/error-crypt.h>
00039 #include <wolfssl/wolfcrypt/logging.h>
00040 
00041 #if defined(USE_FAST_MATH) || !defined(NO_BIG_INT)
00042 
00043 #ifdef WOLFSSL_ASYNC_CRYPT
00044     #include <wolfssl/wolfcrypt/async.h>
00045 #endif
00046 
00047 #ifdef NO_INLINE
00048     #include <wolfssl/wolfcrypt/misc.h>
00049 #else
00050     #define WOLFSSL_MISC_INCLUDED
00051     #include <wolfcrypt/src/misc.c>
00052 #endif
00053 
00054 
00055 int get_digit_count(mp_int* a)
00056 {
00057     if (a == NULL)
00058         return 0;
00059 
00060     return a->used;
00061 }
00062 
00063 mp_digit get_digit(mp_int* a, int n)
00064 {
00065     if (a == NULL)
00066         return 0;
00067 
00068     return (n >= a->used || n < 0) ? 0 : a->dp[n];
00069 }
00070 
00071 int get_rand_digit(WC_RNG* rng, mp_digit* d)
00072 {
00073     return wc_RNG_GenerateBlock(rng, (byte*)d, sizeof(mp_digit));
00074 }
00075 
00076 #ifdef WC_RSA_BLINDING
00077 int mp_rand(mp_int* a, int digits, WC_RNG* rng)
00078 {
00079     int ret;
00080     mp_digit d;
00081 
00082     if (rng == NULL)
00083         return MISSING_RNG_E;
00084 
00085     if (a == NULL)
00086         return BAD_FUNC_ARG;
00087 
00088     mp_zero(a);
00089     if (digits <= 0) {
00090         return MP_OKAY;
00091     }
00092 
00093     /* first place a random non-zero digit */
00094     do {
00095         ret = get_rand_digit(rng, &d);
00096         if (ret != 0) {
00097             return ret;
00098         }
00099     } while (d == 0);
00100 
00101     if ((ret = mp_add_d(a, d, a)) != MP_OKAY) {
00102         return ret;
00103     }
00104 
00105     while (--digits > 0) {
00106         if ((ret = mp_lshd(a, 1)) != MP_OKAY) {
00107             return ret;
00108         }
00109         if ((ret = get_rand_digit(rng, &d)) != 0) {
00110             return ret;
00111         }
00112         if ((ret = mp_add_d(a, d, a)) != MP_OKAY) {
00113             return ret;
00114         }
00115     }
00116 
00117     return ret;
00118 }
00119 #endif /* WC_RSA_BLINDING */
00120 
00121 
00122 #ifdef HAVE_WOLF_BIGINT
00123 void wc_bigint_init(WC_BIGINT* a)
00124 {
00125     if (a != NULL) {
00126         a->buf = NULL;
00127         a->len = 0;
00128         a->heap = NULL;
00129     }
00130 }
00131 
00132 int wc_bigint_alloc(WC_BIGINT* a, word32 sz)
00133 {
00134     int err = MP_OKAY;
00135 
00136     if (a == NULL)
00137         return BAD_FUNC_ARG;
00138 
00139     if (sz > 0) {
00140         if (a->buf && sz > a->len) {
00141             wc_bigint_free(a);
00142         }
00143         if (a->buf == NULL) {
00144             a->buf = (byte*)XMALLOC(sz, a->heap, DYNAMIC_TYPE_WOLF_BIGINT);
00145         }
00146         if (a->buf == NULL) {
00147             err = MP_MEM;
00148         }
00149         else {
00150             XMEMSET(a->buf, 0, sz);
00151         }
00152     }
00153     a->len = sz;
00154 
00155     return err;
00156 }
00157 
00158 /* assumes input is big endian format */
00159 int wc_bigint_from_unsigned_bin(WC_BIGINT* a, const byte* in, word32 inlen)
00160 {
00161     int err;
00162 
00163     if (a == NULL || in == NULL || inlen == 0)
00164         return BAD_FUNC_ARG;
00165 
00166     err = wc_bigint_alloc(a, inlen);
00167     if (err == 0) {
00168         XMEMCPY(a->buf, in, inlen);
00169     }
00170 
00171     return err;
00172 }
00173 
00174 int wc_bigint_to_unsigned_bin(WC_BIGINT* a, byte* out, word32* outlen)
00175 {
00176     word32 sz;
00177 
00178     if (a == NULL || out == NULL || outlen == NULL || *outlen == 0)
00179         return BAD_FUNC_ARG;
00180 
00181     /* trim to fit into output buffer */
00182     sz = a->len;
00183     if (a->len > *outlen) {
00184         WOLFSSL_MSG("wc_bigint_export: Truncating output");
00185         sz = *outlen;
00186     }
00187 
00188     if (a->buf) {
00189         XMEMCPY(out, a->buf, sz);
00190     }
00191 
00192     *outlen = sz;
00193 
00194     return MP_OKAY;
00195 }
00196 
00197 void wc_bigint_zero(WC_BIGINT* a)
00198 {
00199     if (a && a->buf) {
00200         ForceZero(a->buf, a->len);
00201     }
00202 }
00203 
00204 void wc_bigint_free(WC_BIGINT* a)
00205 {
00206     if (a) {
00207         if (a->buf) {
00208           XFREE(a->buf, a->heap, DYNAMIC_TYPE_WOLF_BIGINT);
00209         }
00210         a->buf = NULL;
00211         a->len = 0;
00212     }
00213 }
00214 
00215 int wc_mp_to_bigint(mp_int* src, WC_BIGINT* dst)
00216 {
00217     int err;
00218     word32 sz;
00219 
00220     if (src == NULL || dst == NULL)
00221         return BAD_FUNC_ARG;
00222 
00223     sz = mp_unsigned_bin_size(src);
00224     err = wc_bigint_alloc(dst, sz);
00225     if (err == MP_OKAY)
00226         err = mp_to_unsigned_bin(src, dst->buf);
00227 
00228     return err;
00229 }
00230 
00231 int wc_bigint_to_mp(WC_BIGINT* src, mp_int* dst)
00232 {
00233     int err;
00234 
00235     if (src == NULL || dst == NULL)
00236         return BAD_FUNC_ARG;
00237 
00238     if (src->buf == NULL)
00239         return BAD_FUNC_ARG;
00240 
00241     err = mp_read_unsigned_bin(dst, src->buf, src->len);
00242     wc_bigint_free(src);
00243 
00244     return err;
00245 }
00246 
00247 #endif /* HAVE_WOLF_BIGINT */
00248 
00249 #endif /* USE_FAST_MATH || !NO_BIG_INT */
00250