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