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