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