Home | History | Annotate | Download | only in tls
      1 /*
      2  * Big number math
      3  * Copyright (c) 2006, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "includes.h"
     10 
     11 #include "common.h"
     12 #include "bignum.h"
     13 
     14 #ifdef CONFIG_INTERNAL_LIBTOMMATH
     15 #include "libtommath.c"
     16 #else /* CONFIG_INTERNAL_LIBTOMMATH */
     17 #include <tommath.h>
     18 #endif /* CONFIG_INTERNAL_LIBTOMMATH */
     19 
     20 
     21 /*
     22  * The current version is just a wrapper for LibTomMath library, so
     23  * struct bignum is just typecast to mp_int.
     24  */
     25 
     26 /**
     27  * bignum_init - Allocate memory for bignum
     28  * Returns: Pointer to allocated bignum or %NULL on failure
     29  */
     30 struct bignum * bignum_init(void)
     31 {
     32 	struct bignum *n = os_zalloc(sizeof(mp_int));
     33 	if (n == NULL)
     34 		return NULL;
     35 	if (mp_init((mp_int *) n) != MP_OKAY) {
     36 		os_free(n);
     37 		n = NULL;
     38 	}
     39 	return n;
     40 }
     41 
     42 
     43 /**
     44  * bignum_deinit - Free bignum
     45  * @n: Bignum from bignum_init()
     46  */
     47 void bignum_deinit(struct bignum *n)
     48 {
     49 	if (n) {
     50 		mp_clear((mp_int *) n);
     51 		os_free(n);
     52 	}
     53 }
     54 
     55 
     56 /**
     57  * bignum_get_unsigned_bin - Get length of bignum as an unsigned binary buffer
     58  * @n: Bignum from bignum_init()
     59  * Returns: Length of n if written to a binary buffer
     60  */
     61 size_t bignum_get_unsigned_bin_len(struct bignum *n)
     62 {
     63 	return mp_unsigned_bin_size((mp_int *) n);
     64 }
     65 
     66 
     67 /**
     68  * bignum_get_unsigned_bin - Set binary buffer to unsigned bignum
     69  * @n: Bignum from bignum_init()
     70  * @buf: Buffer for the binary number
     71  * @len: Length of the buffer, can be %NULL if buffer is known to be long
     72  * enough. Set to used buffer length on success if not %NULL.
     73  * Returns: 0 on success, -1 on failure
     74  */
     75 int bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len)
     76 {
     77 	size_t need = mp_unsigned_bin_size((mp_int *) n);
     78 	if (len && need > *len) {
     79 		*len = need;
     80 		return -1;
     81 	}
     82 	if (mp_to_unsigned_bin((mp_int *) n, buf) != MP_OKAY) {
     83 		wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
     84 		return -1;
     85 	}
     86 	if (len)
     87 		*len = need;
     88 	return 0;
     89 }
     90 
     91 
     92 /**
     93  * bignum_set_unsigned_bin - Set bignum based on unsigned binary buffer
     94  * @n: Bignum from bignum_init(); to be set to the given value
     95  * @buf: Buffer with unsigned binary value
     96  * @len: Length of buf in octets
     97  * Returns: 0 on success, -1 on failure
     98  */
     99 int bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len)
    100 {
    101 	if (mp_read_unsigned_bin((mp_int *) n, (u8 *) buf, len) != MP_OKAY) {
    102 		wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
    103 		return -1;
    104 	}
    105 	return 0;
    106 }
    107 
    108 
    109 /**
    110  * bignum_cmp - Signed comparison
    111  * @a: Bignum from bignum_init()
    112  * @b: Bignum from bignum_init()
    113  * Returns: 0 on success, -1 on failure
    114  */
    115 int bignum_cmp(const struct bignum *a, const struct bignum *b)
    116 {
    117 	return mp_cmp((mp_int *) a, (mp_int *) b);
    118 }
    119 
    120 
    121 /**
    122  * bignum_cmp_d - Compare bignum to standard integer
    123  * @a: Bignum from bignum_init()
    124  * @b: Small integer
    125  * Returns: -1 if a < b, 0 if a == b, 1 if a > b
    126  */
    127 int bignum_cmp_d(const struct bignum *a, unsigned long b)
    128 {
    129 	return mp_cmp_d((mp_int *) a, b);
    130 }
    131 
    132 
    133 /**
    134  * bignum_add - c = a + b
    135  * @a: Bignum from bignum_init()
    136  * @b: Bignum from bignum_init()
    137  * @c: Bignum from bignum_init(); used to store the result of a + b
    138  * Returns: 0 on success, -1 on failure
    139  */
    140 int bignum_add(const struct bignum *a, const struct bignum *b,
    141 	       struct bignum *c)
    142 {
    143 	if (mp_add((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) {
    144 		wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
    145 		return -1;
    146 	}
    147 	return 0;
    148 }
    149 
    150 
    151 /**
    152  * bignum_sub - c = a - b
    153  * @a: Bignum from bignum_init()
    154  * @b: Bignum from bignum_init()
    155  * @c: Bignum from bignum_init(); used to store the result of a - b
    156  * Returns: 0 on success, -1 on failure
    157  */
    158 int bignum_sub(const struct bignum *a, const struct bignum *b,
    159 	       struct bignum *c)
    160 {
    161 	if (mp_sub((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) {
    162 		wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
    163 		return -1;
    164 	}
    165 	return 0;
    166 }
    167 
    168 
    169 /**
    170  * bignum_mul - c = a * b
    171  * @a: Bignum from bignum_init()
    172  * @b: Bignum from bignum_init()
    173  * @c: Bignum from bignum_init(); used to store the result of a * b
    174  * Returns: 0 on success, -1 on failure
    175  */
    176 int bignum_mul(const struct bignum *a, const struct bignum *b,
    177 	       struct bignum *c)
    178 {
    179 	if (mp_mul((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) {
    180 		wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
    181 		return -1;
    182 	}
    183 	return 0;
    184 }
    185 
    186 
    187 /**
    188  * bignum_mulmod - d = a * b (mod c)
    189  * @a: Bignum from bignum_init()
    190  * @b: Bignum from bignum_init()
    191  * @c: Bignum from bignum_init(); modulus
    192  * @d: Bignum from bignum_init(); used to store the result of a * b (mod c)
    193  * Returns: 0 on success, -1 on failure
    194  */
    195 int bignum_mulmod(const struct bignum *a, const struct bignum *b,
    196 		  const struct bignum *c, struct bignum *d)
    197 {
    198 	if (mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d)
    199 	    != MP_OKAY) {
    200 		wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
    201 		return -1;
    202 	}
    203 	return 0;
    204 }
    205 
    206 
    207 /**
    208  * bignum_exptmod - Modular exponentiation: d = a^b (mod c)
    209  * @a: Bignum from bignum_init(); base
    210  * @b: Bignum from bignum_init(); exponent
    211  * @c: Bignum from bignum_init(); modulus
    212  * @d: Bignum from bignum_init(); used to store the result of a^b (mod c)
    213  * Returns: 0 on success, -1 on failure
    214  */
    215 int bignum_exptmod(const struct bignum *a, const struct bignum *b,
    216 		   const struct bignum *c, struct bignum *d)
    217 {
    218 	if (mp_exptmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d)
    219 	    != MP_OKAY) {
    220 		wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
    221 		return -1;
    222 	}
    223 	return 0;
    224 }
    225