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