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