12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* 22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Big number math 32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (c) 2006, Jouni Malinen <j@w1.fi> 42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * This software may be distributed under the terms of the BSD license. 62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * See README for more details. 72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "includes.h" 102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "common.h" 122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "bignum.h" 132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef CONFIG_INTERNAL_LIBTOMMATH 152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "libtommath.c" 162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#else /* CONFIG_INTERNAL_LIBTOMMATH */ 172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <tommath.h> 182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif /* CONFIG_INTERNAL_LIBTOMMATH */ 192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* 222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * The current version is just a wrapper for LibTomMath library, so 232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * struct bignum is just typecast to mp_int. 242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/** 272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * bignum_init - Allocate memory for bignum 282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Returns: Pointer to allocated bignum or %NULL on failure 292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstruct bignum * bignum_init(void) 312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project struct bignum *n = os_zalloc(sizeof(mp_int)); 332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (n == NULL) 342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return NULL; 352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (mp_init((mp_int *) n) != MP_OKAY) { 362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project os_free(n); 372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project n = NULL; 382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return n; 402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/** 442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * bignum_deinit - Free bignum 452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @n: Bignum from bignum_init() 462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid bignum_deinit(struct bignum *n) 482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (n) { 502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project mp_clear((mp_int *) n); 512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project os_free(n); 522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/** 572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * bignum_get_unsigned_bin - Get length of bignum as an unsigned binary buffer 582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @n: Bignum from bignum_init() 592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Returns: Length of n if written to a binary buffer 602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectsize_t bignum_get_unsigned_bin_len(struct bignum *n) 622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return mp_unsigned_bin_size((mp_int *) n); 642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/** 682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * bignum_get_unsigned_bin - Set binary buffer to unsigned bignum 692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @n: Bignum from bignum_init() 702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @buf: Buffer for the binary number 712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @len: Length of the buffer, can be %NULL if buffer is known to be long 722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * enough. Set to used buffer length on success if not %NULL. 732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Returns: 0 on success, -1 on failure 742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len) 762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 7753f17a9db278d33517d9888dd77848f554522a38JP Abgrall size_t need = mp_unsigned_bin_size((mp_int *) n); 7853f17a9db278d33517d9888dd77848f554522a38JP Abgrall if (len && need > *len) { 7953f17a9db278d33517d9888dd77848f554522a38JP Abgrall *len = need; 802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return -1; 812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (mp_to_unsigned_bin((mp_int *) n, buf) != MP_OKAY) { 832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); 842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return -1; 852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (len) 872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *len = need; 882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return 0; 892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/** 932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * bignum_set_unsigned_bin - Set bignum based on unsigned binary buffer 942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @n: Bignum from bignum_init(); to be set to the given value 952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @buf: Buffer with unsigned binary value 962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @len: Length of buf in octets 972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Returns: 0 on success, -1 on failure 982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len) 1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 10153f17a9db278d33517d9888dd77848f554522a38JP Abgrall if (mp_read_unsigned_bin((mp_int *) n, (u8 *) buf, len) != MP_OKAY) { 10253f17a9db278d33517d9888dd77848f554522a38JP Abgrall wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); 10353f17a9db278d33517d9888dd77848f554522a38JP Abgrall return -1; 1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return 0; 1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 10753f17a9db278d33517d9888dd77848f554522a38JP Abgrall 10853f17a9db278d33517d9888dd77848f554522a38JP Abgrall 10953f17a9db278d33517d9888dd77848f554522a38JP Abgrall/** 11053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * bignum_cmp - Signed comparison 11153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * @a: Bignum from bignum_init() 11253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * @b: Bignum from bignum_init() 11353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Returns: 0 on success, -1 on failure 11453f17a9db278d33517d9888dd77848f554522a38JP Abgrall */ 11553f17a9db278d33517d9888dd77848f554522a38JP Abgrallint bignum_cmp(const struct bignum *a, const struct bignum *b) 11653f17a9db278d33517d9888dd77848f554522a38JP Abgrall{ 11753f17a9db278d33517d9888dd77848f554522a38JP Abgrall return mp_cmp((mp_int *) a, (mp_int *) b); 11853f17a9db278d33517d9888dd77848f554522a38JP Abgrall} 11953f17a9db278d33517d9888dd77848f554522a38JP Abgrall 12053f17a9db278d33517d9888dd77848f554522a38JP Abgrall 1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/** 1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * bignum_cmd_d - Compare bignum to standard integer 1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @a: Bignum from bignum_init() 1242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @b: Small integer 1252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Returns: 0 on success, -1 on failure 1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint bignum_cmp_d(const struct bignum *a, unsigned long b) 1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return mp_cmp_d((mp_int *) a, b); 13053f17a9db278d33517d9888dd77848f554522a38JP Abgrall} 13153f17a9db278d33517d9888dd77848f554522a38JP Abgrall 13253f17a9db278d33517d9888dd77848f554522a38JP Abgrall 1332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/** 1342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * bignum_add - c = a + b 1352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @a: Bignum from bignum_init() 1362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @b: Bignum from bignum_init() 1372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @c: Bignum from bignum_init(); used to store the result of a + b 1382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Returns: 0 on success, -1 on failure 1392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint bignum_add(const struct bignum *a, const struct bignum *b, 1412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project struct bignum *c) 1422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 1432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (mp_add((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { 1442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); 1452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return -1; 1462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return 0; 14853f17a9db278d33517d9888dd77848f554522a38JP Abgrall} 14953f17a9db278d33517d9888dd77848f554522a38JP Abgrall 15053f17a9db278d33517d9888dd77848f554522a38JP Abgrall 15153f17a9db278d33517d9888dd77848f554522a38JP Abgrall/** 15253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * bignum_sub - c = a - b 15353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * @a: Bignum from bignum_init() 15453f17a9db278d33517d9888dd77848f554522a38JP Abgrall * @b: Bignum from bignum_init() 15553f17a9db278d33517d9888dd77848f554522a38JP Abgrall * @c: Bignum from bignum_init(); used to store the result of a - b 15653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Returns: 0 on success, -1 on failure 1572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 1582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint bignum_sub(const struct bignum *a, const struct bignum *b, 1592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project struct bignum *c) 16053f17a9db278d33517d9888dd77848f554522a38JP Abgrall{ 16153f17a9db278d33517d9888dd77848f554522a38JP Abgrall if (mp_sub((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { 16253f17a9db278d33517d9888dd77848f554522a38JP Abgrall wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); 1632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return -1; 1642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return 0; 16653f17a9db278d33517d9888dd77848f554522a38JP Abgrall} 16753f17a9db278d33517d9888dd77848f554522a38JP Abgrall 16853f17a9db278d33517d9888dd77848f554522a38JP Abgrall 169892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes/** 170892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * bignum_mul - c = a * b 171892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * @a: Bignum from bignum_init() 1722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @b: Bignum from bignum_init() 1732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @c: Bignum from bignum_init(); used to store the result of a * b 1742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Returns: 0 on success, -1 on failure 1752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 176892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesint bignum_mul(const struct bignum *a, const struct bignum *b, 1772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project struct bignum *c) 17853f17a9db278d33517d9888dd77848f554522a38JP Abgrall{ 17953f17a9db278d33517d9888dd77848f554522a38JP Abgrall if (mp_mul((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { 18053f17a9db278d33517d9888dd77848f554522a38JP Abgrall wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); 18153f17a9db278d33517d9888dd77848f554522a38JP Abgrall return -1; 18253f17a9db278d33517d9888dd77848f554522a38JP Abgrall } 18353f17a9db278d33517d9888dd77848f554522a38JP Abgrall return 0; 184892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes} 185892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes 186892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes 1872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/** 1882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * bignum_mulmod - d = a * b (mod c) 1892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * @a: Bignum from bignum_init() 19053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * @b: Bignum from bignum_init() 19153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * @c: Bignum from bignum_init(); modulus 19253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * @d: Bignum from bignum_init(); used to store the result of a * b (mod c) 19353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Returns: 0 on success, -1 on failure 19453f17a9db278d33517d9888dd77848f554522a38JP Abgrall */ 19553f17a9db278d33517d9888dd77848f554522a38JP Abgrallint bignum_mulmod(const struct bignum *a, const struct bignum *b, 19653f17a9db278d33517d9888dd77848f554522a38JP Abgrall const struct bignum *c, struct bignum *d) 19753f17a9db278d33517d9888dd77848f554522a38JP Abgrall{ 19853f17a9db278d33517d9888dd77848f554522a38JP Abgrall if (mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d) 1992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project != MP_OKAY) { 2002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 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 */ 215int 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