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_cmd_d - Compare bignum to standard integer 123 * @a: Bignum from bignum_init() 124 * @b: Small integer 125 * Returns: 0 on success, -1 on failure 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