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