s4:torture: Adapt KDC canon test to Heimdal upstream changes
[samba.git] / source4 / heimdal / lib / hcrypto / test_bn.c
1 /*
2  * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #include <config.h>
35 #include <roken.h>
36
37 #include <bn.h>
38 #include <rand.h>
39
40 static int
41 set_get(unsigned long num)
42 {
43     BIGNUM *bn;
44
45     bn = BN_new();
46     if (!BN_set_word(bn, num))
47         return 1;
48
49     if (BN_get_word(bn) != num)
50         return 1;
51
52     BN_free(bn);
53     return 0;
54 }
55
56 #define CHECK(x) do { ret += x; } while(0)
57
58 static int
59 test_BN_set_get(void)
60 {
61     int ret = 0;
62     CHECK(set_get(0));
63     CHECK(set_get(1));
64     CHECK(set_get(0xff));
65     CHECK(set_get(0x1ff));
66     CHECK(set_get(0xffff));
67     CHECK(set_get(0xf000));
68     CHECK(set_get(ULONG_MAX / 2));
69     CHECK(set_get(ULONG_MAX - 1));
70
71     return ret;
72 }
73
74 static int
75 test_BN_bit(void)
76 {
77     BIGNUM *bn;
78     int ret = 0;
79
80     bn = BN_new();
81
82     /* test setting and getting of "word" */
83     if (!BN_set_word(bn, 1))
84         return 1;
85     if (!BN_is_bit_set(bn, 0))
86         ret += 1;
87     if (!BN_is_bit_set(bn, 0))
88         ret += 1;
89
90     if (!BN_set_word(bn, 2))
91         return 1;
92     if (!BN_is_bit_set(bn, 1))
93         ret += 1;
94
95     if (!BN_set_word(bn, 3))
96         return 1;
97     if (!BN_is_bit_set(bn, 0))
98         ret += 1;
99     if (!BN_is_bit_set(bn, 1))
100         ret += 1;
101
102     if (!BN_set_word(bn, 0x100))
103         return 1;
104     if (!BN_is_bit_set(bn, 8))
105         ret += 1;
106
107     if (!BN_set_word(bn, 0x1000))
108         return 1;
109     if (!BN_is_bit_set(bn, 12))
110         ret += 1;
111
112     /* test bitsetting */
113     if (!BN_set_word(bn, 1))
114         return 1;
115     if (!BN_set_bit(bn, 1))
116         return 1;
117     if (BN_get_word(bn) != 3)
118         return 1;
119     if (!BN_clear_bit(bn, 0))
120         return 1;
121     if (BN_get_word(bn) != 2)
122         return 1;
123
124     /* test bitsetting past end of current end */
125     BN_clear(bn);
126     if (!BN_set_bit(bn, 12))
127         return 1;
128     if (BN_get_word(bn) != 0x1000)
129         return 1;
130
131     /* test bit and byte counting functions */
132     if (BN_num_bits(bn) != 13)
133         return 1;
134     if (BN_num_bytes(bn) != 2)
135         return 1;
136
137     BN_free(bn);
138     return ret;
139 }
140
141 struct ietest {
142     char *data;
143     size_t len;
144     unsigned long num;
145 } ietests[] = {
146     { "", 0, 0 },
147     { "\x01", 1, 1 },
148     { "\x02", 1, 2 },
149     { "\xf2", 1, 0xf2 },
150     { "\x01\x00", 2, 256 }
151 };
152
153 static int
154 test_BN_import_export(void)
155 {
156     BIGNUM *bn;
157     int ret = 0;
158     int i;
159
160     bn = BN_new();
161
162     for (i = 0; i < sizeof(ietests)/sizeof(ietests[0]); i++) {
163         size_t len;
164         unsigned char *p;
165         if (!BN_bin2bn((unsigned char*)ietests[i].data, ietests[i].len, bn))
166             return 1;
167         if (BN_get_word(bn) != ietests[i].num)
168             return 1;
169         len = BN_num_bytes(bn);
170         if (len != ietests[i].len)
171             return 1;
172         p = malloc(len + 1);
173         p[len] = 0xf4;
174         BN_bn2bin(bn, p);
175         if (p[len] != 0xf4)
176             return 1;
177         if (memcmp(p, ietests[i].data, ietests[i].len) != 0)
178             return 1;
179         free(p);
180     }
181
182     BN_free(bn);
183     return ret;
184 }
185
186 static int
187 test_BN_uadd(void)
188 {
189     BIGNUM *a, *b, *c;
190     char *p;
191
192     a = BN_new();
193     b = BN_new();
194     c = BN_new();
195
196     BN_set_word(a, 1);
197     BN_set_word(b, 2);
198
199     BN_uadd(c, a, b);
200
201     if (BN_get_word(c) != 3)
202         return 1;
203
204     BN_uadd(c, b, a);
205
206     if (BN_get_word(c) != 3)
207         return 1;
208
209     BN_set_word(b, 0xff);
210
211     BN_uadd(c, a, b);
212     if (BN_get_word(c) != 0x100)
213         return 1;
214
215     BN_uadd(c, b, a);
216     if (BN_get_word(c) != 0x100)
217         return 1;
218
219     BN_set_word(a, 0xff);
220
221     BN_uadd(c, a, b);
222     if (BN_get_word(c) != 0x1fe)
223         return 1;
224
225     BN_uadd(c, b, a);
226     if (BN_get_word(c) != 0x1fe)
227         return 1;
228
229
230     BN_free(a);
231     BN_free(b);
232
233     BN_hex2bn(&a, "50212A3B611D46642C825A16A354CE0FD4D85DD2");
234     BN_hex2bn(&b, "84B6C7E8D28ACA1614954DA");
235
236     BN_uadd(c, b, a);
237     p = BN_bn2hex(c);
238     if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) {
239         free(p);
240         return 1;
241     }
242     free(p);
243
244     BN_uadd(c, a, b);
245     p = BN_bn2hex(c);
246     if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) {
247         free(p);
248         return 1;
249     }
250     free(p);
251
252     BN_free(a);
253     BN_free(b);
254     BN_free(c);
255
256     return 0;
257 }
258
259 static int
260 test_BN_cmp(void)
261 {
262     BIGNUM *a, *b;
263
264     a = BN_new();
265     b = BN_new();
266
267     if (!BN_set_word(a, 1))
268         return 1;
269     if (!BN_set_word(b, 1))
270         return 1;
271
272     if (BN_cmp(a, b) != 0)
273         return 1;
274     if (BN_cmp(b, a) != 0)
275         return 1;
276
277     if (!BN_set_word(b, 2))
278         return 1;
279
280     if (BN_cmp(a, b) >= 0)
281         return 1;
282     if (BN_cmp(b, a) <= 0)
283         return 1;
284
285     BN_set_negative(b, 1);
286
287     if (BN_cmp(a, b) <= 0)
288         return 1;
289     if (BN_cmp(b, a) >= 0)
290         return 1;
291
292     BN_free(a);
293     BN_free(b);
294
295     BN_hex2bn(&a, "50212A3B611D46642C825A16A354CE0FD4D85DD1");
296     BN_hex2bn(&b, "50212A3B611D46642C825A16A354CE0FD4D85DD2");
297
298     if (BN_cmp(a, b) >= 0)
299         return 1;
300     if (BN_cmp(b, a) <= 0)
301         return 1;
302
303     BN_set_negative(b, 1);
304
305     if (BN_cmp(a, b) <= 0)
306         return 1;
307     if (BN_cmp(b, a) >= 0)
308         return 1;
309
310     BN_free(a);
311     BN_free(b);
312     return 0;
313 }
314
315 static int
316 test_BN_rand(void)
317 {
318     BIGNUM *bn;
319
320     if (RAND_status() != 1)
321         return 0;
322
323     bn = BN_new();
324     if (bn == NULL)
325         return 1;
326
327     if (!BN_rand(bn, 1024, 0, 0))
328         return 1;
329
330     BN_free(bn);
331     return 0;
332 }
333
334 #define testnum 100
335 #define testnum2 10
336
337 static int
338 test_BN_CTX(void)
339 {
340     unsigned int i, j;
341     BIGNUM *bn;
342     BN_CTX *c;
343
344     if ((c = BN_CTX_new()) == NULL)
345         return 1;
346
347     for (i = 0; i < testnum; i++) {
348         BN_CTX_start(c);
349         BN_CTX_end(c);
350     }
351
352     for (i = 0; i < testnum; i++)
353         BN_CTX_start(c);
354     for (i = 0; i < testnum; i++)
355         BN_CTX_end(c);
356
357     for (i = 0; i < testnum; i++) {
358         BN_CTX_start(c);
359         if ((bn = BN_CTX_get(c)) == NULL)
360             return 1;
361         BN_CTX_end(c);
362     }
363
364     for (i = 0; i < testnum; i++) {
365         BN_CTX_start(c);
366         for (j = 0; j < testnum2; j++)
367             if ((bn = BN_CTX_get(c)) == NULL)
368                 return 1;
369     }
370     for (i = 0; i < testnum; i++)
371         BN_CTX_end(c);
372
373     BN_CTX_free(c);
374     return 0;
375 }
376
377
378 int
379 main(int argc, char **argv)
380 {
381     int ret = 0;
382
383     ret += test_BN_set_get();
384     ret += test_BN_bit();
385     ret += test_BN_import_export();
386     ret += test_BN_uadd();
387     ret += test_BN_cmp();
388     ret += test_BN_rand();
389     ret += test_BN_CTX();
390
391     return ret;
392 }