1/*
2 * Copyright (c) 2011-12 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24/*
25 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
26 * (Royal Institute of Technology, Stockholm, Sweden).
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * 1. Redistributions of source code must retain the above copyright
34 *    notice, this list of conditions and the following disclaimer.
35 *
36 * 2. Redistributions in binary form must reproduce the above copyright
37 *    notice, this list of conditions and the following disclaimer in the
38 *    documentation and/or other materials provided with the distribution.
39 *
40 * 3. Neither the name of the Institute nor the names of its contributors
41 *    may be used to endorse or promote products derived from this software
42 *    without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 */
56
57#include "ossl-config.h"
58
59#include <sys/types.h>
60#include <limits.h>
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64
65#include "ossl-bn.h"
66#include "ossl-rand.h"
67
68#include "test_common.h"
69
70static int verbose = 1;
71
72static int
73set_get(unsigned long num)
74{
75	BIGNUM *bn;
76
77	bn = BN_new();
78	if (!BN_set_word(bn, num)) {
79		return (1);
80	}
81
82	if (BN_get_word(bn) != num) {
83		return (1);
84	}
85
86	BN_free(bn);
87	return (0);
88}
89
90
91#define CHECK(x)	 \
92	do { ret += x; } \
93	while (0)
94
95static int
96test_BN_set_get(void)
97{
98	int ret = 0;
99
100	CHECK(set_get(0));
101	CHECK(set_get(1));
102	CHECK(set_get(0xff));
103	CHECK(set_get(0x1ff));
104	CHECK(set_get(0xffff));
105	CHECK(set_get(0xf000));
106	CHECK(set_get(ULONG_MAX / 2));
107	CHECK(set_get(ULONG_MAX - 1));
108
109	return (ret);
110}
111
112
113static int
114test_BN_bit(void)
115{
116	BIGNUM *bn;
117	int ret = 0;
118
119	bn = BN_new();
120
121	/* test setting and getting of "word" */
122	if (!BN_set_word(bn, 1)) {
123		return (1);
124	}
125	if (!BN_is_bit_set(bn, 0)) {
126		ret += 1;
127	}
128	if (!BN_is_bit_set(bn, 0)) {
129		ret += 1;
130	}
131
132	if (!BN_set_word(bn, 2)) {
133		return (1);
134	}
135	if (!BN_is_bit_set(bn, 1)) {
136		ret += 1;
137	}
138
139	if (!BN_set_word(bn, 3)) {
140		return (1);
141	}
142	if (!BN_is_bit_set(bn, 0)) {
143		ret += 1;
144	}
145	if (!BN_is_bit_set(bn, 1)) {
146		ret += 1;
147	}
148
149	if (!BN_set_word(bn, 0x100)) {
150		return (1);
151	}
152	if (!BN_is_bit_set(bn, 8)) {
153		ret += 1;
154	}
155
156	if (!BN_set_word(bn, 0x1000)) {
157		return (1);
158	}
159	if (!BN_is_bit_set(bn, 12)) {
160		ret += 1;
161	}
162
163	/* test bitsetting */
164	if (!BN_set_word(bn, 1)) {
165		return (1);
166	}
167	if (!BN_set_bit(bn, 1)) {
168		return (1);
169	}
170	if (BN_get_word(bn) != 3) {
171		return (1);
172	}
173	if (!BN_clear_bit(bn, 0)) {
174		return (1);
175	}
176	if (BN_get_word(bn) != 2) {
177		return (1);
178	}
179
180	/* test bitsetting past end of current end */
181	BN_clear(bn);
182	if (!BN_set_bit(bn, 12)) {
183		return (1);
184	}
185	if (BN_get_word(bn) != 0x1000) {
186		return (1);
187	}
188
189	/* test bit and byte counting functions */
190	if (BN_num_bits(bn) != 13) {
191		return (1);
192	}
193	if (BN_num_bytes(bn) != 2) {
194		return (1);
195	}
196
197	BN_free(bn);
198	return (ret);
199}
200
201
202struct ietest {
203	char *		data;
204	size_t		len;
205	unsigned long	num;
206}
207ietests[] =
208{
209	{ "",	      0,    0 },
210	{ "\x01",     1,    1 },
211	{ "\x02",     1,    2 },
212	{ "\xf2",     1, 0xf2 },
213	{ "\x01\x00", 2,  256 }
214};
215
216static int
217test_BN_import_export(void)
218{
219	BIGNUM *bn;
220	int ret = 0;
221	int i;
222
223	bn = BN_new();
224
225	for (i = 0; i < sizeof(ietests)/sizeof(ietests[0]); i++) {
226		size_t len;
227		unsigned char *p;
228		if (!BN_bin2bn((unsigned char *)ietests[i].data, ietests[i].len, bn)) {
229			return (1);
230		}
231		if (BN_get_word(bn) != ietests[i].num) {
232			return (1);
233		}
234		len = BN_num_bytes(bn);
235		if (len != ietests[i].len) {
236			return (1);
237		}
238		p = malloc(len + 1);
239		p[len] = 0xf4;
240		BN_bn2bin(bn, p);
241		if (p[len] != 0xf4) {
242			return (1);
243		}
244		if (memcmp(p, ietests[i].data, ietests[i].len) != 0) {
245			return (1);
246		}
247		free(p);
248	}
249
250	BN_free(bn);
251	return (ret);
252}
253
254
255static int
256test_BN_uadd(void)
257{
258	BIGNUM *a, *b, *c;
259	char *p;
260
261	a = BN_new();
262	b = BN_new();
263	c = BN_new();
264
265	BN_set_word(a, 1);
266	BN_set_word(b, 2);
267
268	BN_uadd(c, a, b);
269
270	if (BN_get_word(c) != 3) {
271		return (1);
272	}
273
274	BN_uadd(c, b, a);
275
276	if (BN_get_word(c) != 3) {
277		return (1);
278	}
279
280	BN_set_word(b, 0xff);
281
282	BN_uadd(c, a, b);
283	if (BN_get_word(c) != 0x100) {
284		return (1);
285	}
286
287	BN_uadd(c, b, a);
288	if (BN_get_word(c) != 0x100) {
289		return (1);
290	}
291
292	BN_set_word(a, 0xff);
293
294	BN_uadd(c, a, b);
295	if (BN_get_word(c) != 0x1fe) {
296		return (1);
297	}
298
299	BN_uadd(c, b, a);
300	if (BN_get_word(c) != 0x1fe) {
301		return (1);
302	}
303
304
305	/*
306	BN_free(a);
307	BN_free(b);
308	*/
309
310	BN_hex2bn(&a, "50212A3B611D46642C825A16A354CE0FD4D85DD2");
311	BN_hex2bn(&b, "84B6C7E8D28ACA1614954DA");
312
313	BN_uadd(c, b, a);
314	p = BN_bn2hex(c);
315	if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) {
316		free(p);
317		return (1);
318	}
319	free(p);
320
321	BN_uadd(c, a, b);
322	p = BN_bn2hex(c);
323	if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) {
324		free(p);
325		return (1);
326	}
327	free(p);
328
329	BN_free(a);
330	BN_free(b);
331	BN_free(c);
332
333	return (0);
334}
335
336
337static int
338test_BN_cmp(void)
339{
340	BIGNUM *a, *b;
341
342	a = BN_new();
343	b = BN_new();
344
345	if (!BN_set_word(a, 1)) {
346		return (1);
347	}
348	if (!BN_set_word(b, 1)) {
349		return (1);
350	}
351
352	if (BN_cmp(a, b) != 0) {
353		return (1);
354	}
355	if (BN_cmp(b, a) != 0) {
356		return (1);
357	}
358
359	if (!BN_set_word(b, 2)) {
360		return (1);
361	}
362
363	if (BN_cmp(a, b) >= 0) {
364		return (1);
365	}
366	if (BN_cmp(b, a) <= 0) {
367		return (1);
368	}
369
370	BN_set_negative(b, 1);
371
372	if (BN_cmp(a, b) <= 0) {
373		return (1);
374	}
375	if (BN_cmp(b, a) >= 0) {
376		return (1);
377	}
378
379	/*
380	BN_free(a);
381	BN_free(b);
382	*/
383
384	BN_hex2bn(&a, "50212A3B611D46642C825A16A354CE0FD4D85DD1");
385	BN_hex2bn(&b, "50212A3B611D46642C825A16A354CE0FD4D85DD2");
386
387	if (BN_cmp(a, b) >= 0) {
388		return (1);
389	}
390	if (BN_cmp(b, a) <= 0) {
391		return (1);
392	}
393
394	BN_set_negative(b, 1);
395
396	if (BN_cmp(a, b) <= 0) {
397		return (1);
398	}
399	if (BN_cmp(b, a) >= 0) {
400		return (1);
401	}
402
403	BN_free(a);
404	BN_free(b);
405	return (0);
406}
407
408
409static int
410test_BN_rand(void)
411{
412	BIGNUM *bn;
413
414	if (RAND_status() != 1) {
415		return (0);
416	}
417
418	bn = BN_new();
419	if (bn == NULL) {
420		return (1);
421	}
422
423	if (!BN_rand(bn, 1024, 0, 0)) {
424		return (1);
425	}
426
427	BN_free(bn);
428	return (0);
429}
430
431
432#define testnum		100
433#define testnum2	10
434
435static int
436test_BN_CTX(void)
437{
438	unsigned int i, j;
439	BIGNUM *bn;
440	BN_CTX *c;
441
442	if ((c = BN_CTX_new()) == NULL) {
443		return (1);
444	}
445
446	for (i = 0; i < testnum; i++) {
447		BN_CTX_start(c);
448		BN_CTX_end(c);
449	}
450
451	for (i = 0; i < testnum; i++) {
452		BN_CTX_start(c);
453	}
454	for (i = 0; i < testnum; i++) {
455		BN_CTX_end(c);
456	}
457
458	for (i = 0; i < testnum; i++) {
459		BN_CTX_start(c);
460		if ((bn = BN_CTX_get(c)) == NULL) {
461			return (1);
462		}
463		BN_CTX_end(c);
464	}
465
466	for (i = 0; i < testnum; i++) {
467		BN_CTX_start(c);
468		for (j = 0; j < testnum2; j++) {
469			if ((bn = BN_CTX_get(c)) == NULL) {
470				return (1);
471			}
472		}
473	}
474	for (i = 0; i < testnum; i++) {
475		BN_CTX_end(c);
476	}
477
478	BN_CTX_free(c);
479	return (0);
480}
481
482
483static testFunction_t bnTestFunctions[] = {
484	{ test_BN_set_get, "BN_set_get" },
485	{ test_BN_bit, "BN_bit" },
486	{ test_BN_import_export, "BN_import_export" },
487	{ test_BN_uadd, "BN_uadd" },
488	{ test_BN_rand, "BN_rand" },
489	{ test_BN_CTX, "BN_CTX" },
490};
491#define numBnumTestFunctions    (sizeof(bnTestFunctions) / sizeof(bnTestFunctions[0]))
492
493int
494main(int argc, char **argv)
495{
496	int i, err;
497	int total = 0, pass = 0, fail = 0;
498
499	if (verbose) printf("[TEST] Big Num\n");
500
501	for (i = 0; i < numBnumTestFunctions; i++) {
502		if (NULL == bnTestFunctions[i].description) continue;
503		if (verbose) printf("[BEGIN] %s\n", bnTestFunctions[i].description);
504		err = bnTestFunctions[i].funcptr();
505		total++;
506		if (err) {
507			fail++;
508			if (verbose) printf("[FAIL] %s\n", bnTestFunctions[i].description);
509		} else {
510			pass++;
511			if (verbose) printf("[PASS] %s\n", bnTestFunctions[i].description);
512		}
513	}
514
515	if (verbose) {
516		printf("[SUMMARY]\n");
517		printf("Total: %d\n", total);
518		printf("passed: %d\n", pass);
519		printf("failed: %d\n", fail);
520	}
521
522	return (fail);
523}
524