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