/src/hostap/src/tls/bignum.c
Line | Count | Source (jump to first uncovered line) |
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 | | */ |
30 | | struct bignum * bignum_init(void) |
31 | 0 | { |
32 | 0 | struct bignum *n = os_zalloc(sizeof(mp_int)); |
33 | 0 | if (n == NULL) |
34 | 0 | return NULL; |
35 | 0 | if (mp_init((mp_int *) n) != MP_OKAY) { |
36 | 0 | os_free(n); |
37 | 0 | n = NULL; |
38 | 0 | } |
39 | 0 | return n; |
40 | 0 | } |
41 | | |
42 | | |
43 | | /** |
44 | | * bignum_deinit - Free bignum |
45 | | * @n: Bignum from bignum_init() |
46 | | */ |
47 | | void bignum_deinit(struct bignum *n) |
48 | 0 | { |
49 | 0 | if (n) { |
50 | 0 | mp_clear((mp_int *) n); |
51 | 0 | os_free(n); |
52 | 0 | } |
53 | 0 | } |
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 | | */ |
61 | | size_t bignum_get_unsigned_bin_len(struct bignum *n) |
62 | 0 | { |
63 | 0 | return mp_unsigned_bin_size((mp_int *) n); |
64 | 0 | } |
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 | | */ |
75 | | int bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len) |
76 | 0 | { |
77 | 0 | size_t need = mp_unsigned_bin_size((mp_int *) n); |
78 | 0 | if (len && need > *len) { |
79 | 0 | *len = need; |
80 | 0 | return -1; |
81 | 0 | } |
82 | 0 | if (mp_to_unsigned_bin((mp_int *) n, buf) != MP_OKAY) { |
83 | 0 | wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); |
84 | 0 | return -1; |
85 | 0 | } |
86 | 0 | if (len) |
87 | 0 | *len = need; |
88 | 0 | return 0; |
89 | 0 | } |
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 | | */ |
99 | | int bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len) |
100 | 0 | { |
101 | 0 | if (mp_read_unsigned_bin((mp_int *) n, (u8 *) buf, len) != MP_OKAY) { |
102 | 0 | wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); |
103 | 0 | return -1; |
104 | 0 | } |
105 | 0 | return 0; |
106 | 0 | } |
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 | | */ |
115 | | int bignum_cmp(const struct bignum *a, const struct bignum *b) |
116 | 0 | { |
117 | 0 | return mp_cmp((mp_int *) a, (mp_int *) b); |
118 | 0 | } |
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 | | */ |
127 | | int bignum_cmp_d(const struct bignum *a, unsigned long b) |
128 | 0 | { |
129 | 0 | return mp_cmp_d((mp_int *) a, b); |
130 | 0 | } |
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 | | */ |
140 | | int bignum_add(const struct bignum *a, const struct bignum *b, |
141 | | struct bignum *c) |
142 | 0 | { |
143 | 0 | if (mp_add((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { |
144 | 0 | wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); |
145 | 0 | return -1; |
146 | 0 | } |
147 | 0 | return 0; |
148 | 0 | } |
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 | | */ |
158 | | int bignum_sub(const struct bignum *a, const struct bignum *b, |
159 | | struct bignum *c) |
160 | 0 | { |
161 | 0 | if (mp_sub((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { |
162 | 0 | wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); |
163 | 0 | return -1; |
164 | 0 | } |
165 | 0 | return 0; |
166 | 0 | } |
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 | | */ |
176 | | int bignum_mul(const struct bignum *a, const struct bignum *b, |
177 | | struct bignum *c) |
178 | 0 | { |
179 | 0 | if (mp_mul((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { |
180 | 0 | wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); |
181 | 0 | return -1; |
182 | 0 | } |
183 | 0 | return 0; |
184 | 0 | } |
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 | | */ |
195 | | int bignum_mulmod(const struct bignum *a, const struct bignum *b, |
196 | | const struct bignum *c, struct bignum *d) |
197 | 0 | { |
198 | 0 | if (mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d) |
199 | 0 | != MP_OKAY) { |
200 | 0 | wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); |
201 | 0 | return -1; |
202 | 0 | } |
203 | 0 | return 0; |
204 | 0 | } |
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 | | */ |
215 | | int bignum_exptmod(const struct bignum *a, const struct bignum *b, |
216 | | const struct bignum *c, struct bignum *d) |
217 | 0 | { |
218 | 0 | if (mp_exptmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d) |
219 | 0 | != MP_OKAY) { |
220 | 0 | wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); |
221 | 0 | return -1; |
222 | 0 | } |
223 | 0 | return 0; |
224 | 0 | } |