154820Speter/* 254820Speter * Big number math 354820Speter * Copyright (c) 2006, Jouni Malinen <j@w1.fi> 454820Speter * 554820Speter * This software may be distributed under the terms of the BSD license. 654820Speter * See README for more details. 754820Speter */ 854820Speter 954820Speter#include "includes.h" 1054820Speter 1154820Speter#include "common.h" 1254820Speter#include "bignum.h" 1354820Speter 1454820Speter#ifdef CONFIG_INTERNAL_LIBTOMMATH 1554820Speter#include "libtommath.c" 1654820Speter#else /* CONFIG_INTERNAL_LIBTOMMATH */ 1754820Speter#include <tommath.h> 1854820Speter#endif /* CONFIG_INTERNAL_LIBTOMMATH */ 1954820Speter 2054820Speter 2154820Speter/* 2254820Speter * The current version is just a wrapper for LibTomMath library, so 2354820Speter * struct bignum is just typecast to mp_int. 2454820Speter */ 2554820Speter 2654820Speter/** 2754820Speter * bignum_init - Allocate memory for bignum 2854820Speter * Returns: Pointer to allocated bignum or %NULL on failure 2954820Speter */ 3054820Speterstruct bignum * bignum_init(void) 3154820Speter{ 3254820Speter struct bignum *n = os_zalloc(sizeof(mp_int)); 3354820Speter if (n == NULL) 3454820Speter return NULL; 3554820Speter if (mp_init((mp_int *) n) != MP_OKAY) { 3654820Speter os_free(n); 3754820Speter n = NULL; 3854820Speter } 3954820Speter return n; 4054820Speter} 4154820Speter 4254820Speter 4354820Speter/** 4454820Speter * bignum_deinit - Free bignum 4554820Speter * @n: Bignum from bignum_init() 4654820Speter */ 4754820Spetervoid bignum_deinit(struct bignum *n) 4854820Speter{ 4954820Speter if (n) { 5054820Speter mp_clear((mp_int *) n); 5154820Speter os_free(n); 5254820Speter } 5354820Speter} 5454820Speter 5554820Speter 5654820Speter/** 5754820Speter * bignum_get_unsigned_bin - Get length of bignum as an unsigned binary buffer 5854820Speter * @n: Bignum from bignum_init() 5954820Speter * Returns: Length of n if written to a binary buffer 6054820Speter */ 6154820Spetersize_t bignum_get_unsigned_bin_len(struct bignum *n) 6254820Speter{ 6354820Speter return mp_unsigned_bin_size((mp_int *) n); 6454820Speter} 6554820Speter 6654820Speter 6754820Speter/** 6854820Speter * bignum_get_unsigned_bin - Set binary buffer to unsigned bignum 6954820Speter * @n: Bignum from bignum_init() 7054820Speter * @buf: Buffer for the binary number 7154820Speter * @len: Length of the buffer, can be %NULL if buffer is known to be long 7254820Speter * enough. Set to used buffer length on success if not %NULL. 7354820Speter * Returns: 0 on success, -1 on failure 7454820Speter */ 7554820Speterint bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len) 7654820Speter{ 7754820Speter size_t need = mp_unsigned_bin_size((mp_int *) n); 7854820Speter if (len && need > *len) { 7954820Speter *len = need; 8054820Speter return -1; 8154820Speter } 8254820Speter if (mp_to_unsigned_bin((mp_int *) n, buf) != MP_OKAY) { 8354820Speter wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); 8454820Speter return -1; 8554820Speter } 8654820Speter if (len) 8754820Speter *len = need; 8854820Speter return 0; 8954820Speter} 9054820Speter 9154820Speter 9254820Speter/** 9354820Speter * bignum_set_unsigned_bin - Set bignum based on unsigned binary buffer 9454820Speter * @n: Bignum from bignum_init(); to be set to the given value 9554820Speter * @buf: Buffer with unsigned binary value 9654820Speter * @len: Length of buf in octets 9754820Speter * Returns: 0 on success, -1 on failure 9854820Speter */ 9954820Speterint bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len) 10054820Speter{ 10154820Speter if (mp_read_unsigned_bin((mp_int *) n, (u8 *) buf, len) != MP_OKAY) { 10254820Speter wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); 10354820Speter return -1; 10454820Speter } 10554820Speter return 0; 10654820Speter} 10754820Speter 10854820Speter 10954820Speter/** 11054820Speter * bignum_cmp - Signed comparison 11154820Speter * @a: Bignum from bignum_init() 11254820Speter * @b: Bignum from bignum_init() 11354820Speter * Returns: 0 on success, -1 on failure 11454820Speter */ 11554820Speterint bignum_cmp(const struct bignum *a, const struct bignum *b) 11654820Speter{ 11754820Speter return mp_cmp((mp_int *) a, (mp_int *) b); 11854820Speter} 11954820Speter 12054820Speter 12154820Speter/** 12254820Speter * bignum_cmd_d - Compare bignum to standard integer 12354820Speter * @a: Bignum from bignum_init() 12454820Speter * @b: Small integer 12554820Speter * Returns: 0 on success, -1 on failure 12654820Speter */ 12754820Speterint bignum_cmp_d(const struct bignum *a, unsigned long b) 12854820Speter{ 12954820Speter return mp_cmp_d((mp_int *) a, b); 13054820Speter} 13154820Speter 13254820Speter 13354820Speter/** 13454820Speter * bignum_add - c = a + b 13554820Speter * @a: Bignum from bignum_init() 13654820Speter * @b: Bignum from bignum_init() 13754820Speter * @c: Bignum from bignum_init(); used to store the result of a + b 13854820Speter * Returns: 0 on success, -1 on failure 13954820Speter */ 14054820Speterint bignum_add(const struct bignum *a, const struct bignum *b, 14154820Speter struct bignum *c) 14254820Speter{ 14354820Speter if (mp_add((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { 14454820Speter wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); 14554820Speter return -1; 14654820Speter } 14754820Speter return 0; 14854820Speter} 14954820Speter 15054820Speter 15154820Speter/** 15254820Speter * bignum_sub - c = a - b 15354820Speter * @a: Bignum from bignum_init() 15454820Speter * @b: Bignum from bignum_init() 15554820Speter * @c: Bignum from bignum_init(); used to store the result of a - b 15654820Speter * Returns: 0 on success, -1 on failure 15754820Speter */ 15854820Speterint bignum_sub(const struct bignum *a, const struct bignum *b, 15954820Speter struct bignum *c) 16054820Speter{ 16154820Speter if (mp_sub((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { 16254820Speter wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); 16354820Speter return -1; 16454820Speter } 16554820Speter return 0; 16654820Speter} 16754820Speter 16854820Speter 16954820Speter/** 17054820Speter * bignum_mul - c = a * b 17154820Speter * @a: Bignum from bignum_init() 17254820Speter * @b: Bignum from bignum_init() 17354820Speter * @c: Bignum from bignum_init(); used to store the result of a * b 17454820Speter * Returns: 0 on success, -1 on failure 17554820Speter */ 17654820Speterint bignum_mul(const struct bignum *a, const struct bignum *b, 17754820Speter struct bignum *c) 17854820Speter{ 17954820Speter if (mp_mul((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { 18054820Speter wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); 18154820Speter return -1; 18254820Speter } 18354820Speter return 0; 18454820Speter} 18554820Speter 18654820Speter 18754820Speter/** 18854820Speter * bignum_mulmod - d = a * b (mod c) 18954820Speter * @a: Bignum from bignum_init() 19054820Speter * @b: Bignum from bignum_init() 19154820Speter * @c: Bignum from bignum_init(); modulus 19254820Speter * @d: Bignum from bignum_init(); used to store the result of a * b (mod c) 19354820Speter * Returns: 0 on success, -1 on failure 19454820Speter */ 19554820Speterint bignum_mulmod(const struct bignum *a, const struct bignum *b, 19654820Speter const struct bignum *c, struct bignum *d) 19754820Speter{ 19854820Speter if (mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d) 19954820Speter != MP_OKAY) { 20054820Speter wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); 20154820Speter return -1; 20254820Speter } 20354820Speter return 0; 20454820Speter} 20554820Speter 20654820Speter 20754820Speter/** 20854820Speter * bignum_exptmod - Modular exponentiation: d = a^b (mod c) 20954820Speter * @a: Bignum from bignum_init(); base 21054820Speter * @b: Bignum from bignum_init(); exponent 21154820Speter * @c: Bignum from bignum_init(); modulus 21254820Speter * @d: Bignum from bignum_init(); used to store the result of a^b (mod c) 21354820Speter * Returns: 0 on success, -1 on failure 21454820Speter */ 21554820Speterint bignum_exptmod(const struct bignum *a, const struct bignum *b, 21654820Speter const struct bignum *c, struct bignum *d) 21754820Speter{ 21854820Speter if (mp_exptmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d) 21954820Speter != MP_OKAY) { 22054820Speter wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); 22154820Speter return -1; 22254820Speter } 22354820Speter return 0; 22454820Speter} 22554820Speter