ef020f7899ac7bf55d357d538f93802f191197ab
[openssl.git] / test / testutil / tests.c
1 /*
2  * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include "../testutil.h"
11 #include "output.h"
12 #include "tu_local.h"
13
14 #include <string.h>
15 #include <ctype.h>
16 #include "../../e_os.h"
17
18 /* The size of memory buffers to display on failure */
19 #define MEM_BUFFER_SIZE     (2000)
20 #define MAX_STRING_WIDTH    (80)
21 #define BN_OUTPUT_SIZE      (8)
22
23 /* Output a failed test first line */
24 static void test_fail_message_prefix(const char *prefix, const char *file,
25                                      int line, const char *type,
26                                      const char *left, const char *right,
27                                      const char *op)
28 {
29     test_printf_stderr("%*s# %s: ", subtest_level(), "",
30                        prefix != NULL ? prefix : "ERROR");
31     if (type)
32         test_printf_stderr("(%s) ", type);
33     if (op != NULL)
34         test_printf_stderr("'%s %s %s' failed", left, op, right);
35     if (file != NULL) {
36         test_printf_stderr(" @ %s:%d", file, line);
37     }
38     test_printf_stderr("\n");
39 }
40
41 /* Output a diff header */
42 static void test_diff_header(const char *left, const char *right)
43 {
44     test_printf_stderr("%*s# --- %s\n", subtest_level(), "", left);
45     test_printf_stderr("%*s# +++ %s\n", subtest_level(), "", right);
46 }
47
48 /*
49  * A common routine to output test failure messages.  Generally this should not
50  * be called directly, rather it should be called by the following functions.
51  *
52  * |desc| is a printf formatted description with arguments |args| that is
53  * supplied by the user and |desc| can be NULL.  |type| is the data type
54  * that was tested (int, char, ptr, ...).  |fmt| is a system provided
55  * printf format with following arguments that spell out the failure
56  * details i.e. the actual values compared and the operator used.
57  *
58  * The typical use for this is from an utility test function:
59  *
60  * int test6(const char *file, int line, int n) {
61  *     if (n != 6) {
62  *         test_fail_message(1, file, line, "int", "value %d is not %d", n, 6);
63  *         return 0;
64  *     }
65  *     return 1;
66  * }
67  *
68  * calling test6(3, "oops") will return 0 and produce out along the lines of:
69  *      FAIL oops: (int) value 3 is not 6\n
70  */
71 static void test_fail_message(const char *prefix, const char *file, int line,
72                               const char *type, const char *left,
73                               const char *right, const char *op,
74                               const char *fmt, ...)
75             PRINTF_FORMAT(8, 9);
76
77 static void test_fail_message_va(const char *prefix, const char *file,
78                                  int line, const char *type,
79                                  const char *left, const char *right,
80                                  const char *op, const char *fmt, va_list ap)
81 {
82     test_fail_message_prefix(prefix, file, line, type, left, right, op);
83     if (fmt != NULL) {
84         test_printf_stderr("%*s# ", subtest_level(), "");
85         test_vprintf_stderr(fmt, ap);
86         test_printf_stderr("\n");
87     }
88     test_printf_stderr("\n");
89     test_flush_stderr();
90 }
91
92 static void test_fail_string_message(const char *prefix, const char *file,
93                                      int line, const char *type,
94                                      const char *left, const char *right,
95                                      const char *op, const char *m1, size_t l1,
96                                      const char *m2, size_t l2)
97 {
98     const int indent = subtest_level();
99     const size_t width = (MAX_STRING_WIDTH - indent - 12) / 16 * 16;
100     char b1[MAX_STRING_WIDTH + 1], b2[MAX_STRING_WIDTH + 1];
101     char bdiff[MAX_STRING_WIDTH + 1];
102     size_t n1, n2, i;
103     unsigned int cnt = 0, diff;
104
105     test_fail_message_prefix(prefix, file, line, type, left, right, op);
106     if (m1 == NULL)
107         l1 = 0;
108     if (m2 == NULL)
109         l2 = 0;
110     if (l1 == 0 && l2 == 0) {
111         if ((m1 == NULL) == (m2 == NULL)) {
112             test_printf_stderr("%*s# % 4s   %s\n", indent, "", "",
113                                m1 == NULL ? "NULL" : "''");
114         } else {
115             test_diff_header(left, right);
116             test_printf_stderr("%*s# % 4s - %s\n", indent, "", "",
117                                m1 == NULL ? "NULL" : "''");
118             test_printf_stderr("%*s# % 4s + %s\n", indent, "", "",
119                                m2 == NULL ? "NULL" : "''");
120         }
121         goto fin;
122     }
123
124     if (l1 != l2 || strcmp(m1, m2) != 0)
125         test_diff_header(left, right);
126
127     while (l1 > 0 || l2 > 0) {
128         n1 = n2 = 0;
129         if (l1 > 0) {
130             b1[n1 = l1 > width ? width : l1] = 0;
131             for (i = 0; i < n1; i++)
132                 b1[i] = isprint(m1[i]) ? m1[i] : '.';
133         }
134         if (l2 > 0) {
135             b2[n2 = l2 > width ? width : l2] = 0;
136             for (i = 0; i < n2; i++)
137                 b2[i] = isprint(m2[i]) ? m2[i] : '.';
138         }
139         diff = n1 != n2;
140         i = 0;
141         if (n1 > 0 && n2 > 0) {
142             const size_t j = n1 < n2 ? n1 : n2;
143             const size_t k = n1 > n2 ? n1 : n2;
144
145             for (; i < j; i++)
146                 if (m1[i] == m2[i]) {
147                     bdiff[i] = ' ';
148                 } else {
149                     bdiff[i] = '^';
150                     diff = 1;
151                 }
152             for (; i < k; i++)
153                 bdiff[i] = '^';
154             bdiff[i] = '\0';
155         }
156         if (!diff) {
157             test_printf_stderr("%*s# % 4u:  '%s'\n", indent, "", cnt, b1);
158         } else {
159             if (cnt == 0 && m1 == NULL)
160                 test_printf_stderr("%*s# % 4s - NULL\n", indent, "", "");
161             else if (cnt == 0 && *m1 == '\0')
162                 test_printf_stderr("%*s# % 4s - ''\n", indent, "", "");
163             else if (n1 > 0)
164                 test_printf_stderr("%*s# % 4u:- '%s'\n", indent, "", cnt, b1);
165             if (cnt == 0 && m2 == NULL)
166                 test_printf_stderr("%*s# % 4s + NULL\n", indent, "", "");
167             else if (cnt == 0 && *m2 == '\0')
168                 test_printf_stderr("%*s# % 4s + ''\n", indent, "", "");
169             else if (n2 > 0)
170                 test_printf_stderr("%*s# % 4u:+ '%s'\n", indent, "", cnt, b2);
171             if (i > 0)
172                 test_printf_stderr("%*s# % 4s    %s\n", indent, "", "", bdiff);
173         }
174         m1 += n1;
175         m2 += n2;
176         l1 -= n1;
177         l2 -= n2;
178         cnt += width;
179     }
180 fin:
181     test_printf_stderr("\n");
182     test_flush_stderr();
183 }
184
185 static void hex_convert_memory(const unsigned char *m, size_t n, char *b,
186                                size_t width)
187 {
188     size_t i;
189
190     for (i = 0; i < n; i++) {
191         const unsigned char c = *m++;
192
193         *b++ = "0123456789abcdef"[c >> 4];
194         *b++ = "0123456789abcdef"[c & 15];
195         if (i % width == width - 1 && i != n - 1)
196             *b++ = ' ';
197     }
198     *b = '\0';
199 }
200
201 static const int bn_bytes = (MAX_STRING_WIDTH - 9) / (BN_OUTPUT_SIZE * 2 + 1)
202                             * BN_OUTPUT_SIZE;
203 static const int bn_chars = (MAX_STRING_WIDTH - 9) / (BN_OUTPUT_SIZE * 2 + 1)
204                             * (BN_OUTPUT_SIZE * 2 + 1) - 1;
205
206 static void test_bignum_header_line(void)
207 {
208     test_printf_stderr("%*s#  %*s\n", subtest_level(), "", bn_chars + 6,
209                        "bit position");
210 }
211
212 static void test_bignum_zero_print(const BIGNUM *bn, char sep)
213 {
214     const char *v = "NULL", *suf = "";
215     if (bn != NULL) {
216         suf = ":    0";
217         v = BN_is_negative(bn) ? "-0" : "0";
218     }
219     test_printf_stderr("%*s# %c%*s%s\n", subtest_level(), "", sep, bn_chars,
220                        v, suf);
221 }
222
223 static int convert_bn_memory(const unsigned char *in, size_t bytes,
224                              char *out, int *lz, const BIGNUM *bn)
225 {
226     int n = bytes * 2, i;
227     char *p = out, *q = NULL;
228
229     if (bn != NULL && !BN_is_zero(bn)) {
230         hex_convert_memory(in, bytes, out, BN_OUTPUT_SIZE);
231         if (*lz) {
232             for (; *p == '0' || *p == ' '; p++)
233                 if (*p == '0') {
234                     q = p;
235                     *p = ' ';
236                     n--;
237                 }
238             if (*p == '\0') {
239                 /*
240                  * in[bytes] is defined because we're converting a non-zero
241                  * number and we've not seen a non-zero yet.
242                  */
243                 if ((in[bytes] & 0xf0) != 0 && BN_is_negative(bn)) {
244                     *lz = 0;
245                     *q = '-';
246                     n++;
247                 }
248             } else {
249                 *lz = 0;
250                 if (BN_is_negative(bn)) {
251                     /*
252                      * This is valid because we always convert more digits than
253                      * the number holds.
254                      */
255                     *q = '-';
256                     n++;
257                 }
258             }
259         }
260        return n;
261     }
262
263     for (i = 0; i < n; i++) {
264         *p++ = ' ';
265         if (i % (2 * BN_OUTPUT_SIZE) == 2 * BN_OUTPUT_SIZE - 1 && i != n - 1)
266             *p++ = ' ';
267     }
268     *p = '\0';
269     if (bn == NULL)
270         q = "NULL";
271     else
272         q = BN_is_negative(bn) ? "-0" : "0";
273     strcpy(p - strlen(q), q);
274     return 0;
275 }
276
277 static void test_fail_bignum_common(const char *prefix, const char *file,
278                                     int line, const char *type,
279                                     const char *left, const char *right,
280                                     const char *op,
281                                     const BIGNUM *bn1, const BIGNUM *bn2)
282 {
283     const int indent = subtest_level();
284     const size_t bytes = bn_bytes;
285     char b1[MAX_STRING_WIDTH + 1], b2[MAX_STRING_WIDTH + 1];
286     char *p, bdiff[MAX_STRING_WIDTH + 1];
287     size_t l1, l2, n1, n2, i, len;
288     unsigned int cnt, diff, real_diff;
289     unsigned char *m1 = NULL, *m2 = NULL;
290     int lz1 = 1, lz2 = 1;
291     unsigned char buffer[MEM_BUFFER_SIZE * 2], *bufp = buffer;
292
293     l1 = bn1 == NULL ? 0 : (BN_num_bytes(bn1) + (BN_is_negative(bn1) ? 1 : 0));
294     l2 = bn2 == NULL ? 0 : (BN_num_bytes(bn2) + (BN_is_negative(bn2) ? 1 : 0));
295     if (l1 == 0 && l2 == 0) {
296         if ((bn1 == NULL) == (bn2 == NULL)) {
297             test_bignum_header_line();
298             test_bignum_zero_print(bn1, ' ');
299         } else {
300             test_diff_header(left, right);
301             test_bignum_header_line();
302             test_bignum_zero_print(bn1, '-');
303             test_bignum_zero_print(bn2, '+');
304         }
305         goto fin;
306     }
307
308     if (l1 != l2 || bn1 == NULL || bn2 == NULL || BN_cmp(bn1, bn2) != 0)
309         test_diff_header(left, right);
310     test_bignum_header_line();
311
312     len = ((l1 > l2 ? l1 : l2) + bytes - 1) / bytes * bytes;
313
314     if (len > MEM_BUFFER_SIZE && (bufp = OPENSSL_malloc(len * 2)) == NULL) {
315         bufp = buffer;
316         len = MEM_BUFFER_SIZE;
317         test_printf_stderr("%*s# WARNING: these BIGNUMs have been truncated",
318                            indent, "");
319     }
320
321     if (bn1 != NULL) {
322         m1 = bufp;
323         BN_bn2binpad(bn1, m1, len);
324     }
325     if (bn2 != NULL) {
326         m2 = bufp + len;
327         BN_bn2binpad(bn2, m2, len);
328     }
329
330     while (len > 0) {
331         cnt = 8 * (len - bytes);
332         n1 = convert_bn_memory(m1, bytes, b1, &lz1, bn1);
333         n2 = convert_bn_memory(m2, bytes, b2, &lz2, bn2);
334
335         diff = real_diff = 0;
336         i = 0;
337         p = bdiff;
338         for (i=0; b1[i] != '\0'; i++)
339             if (b1[i] == b2[i] || b1[i] == ' ' || b2[i] == ' ') {
340                 *p++ = ' ';
341                 diff |= b1[i] != b2[i];
342             } else {
343                 *p++ = '^';
344                 real_diff = diff = 1;
345             }
346         *p++ = '\0';
347         if (!diff) {
348             test_printf_stderr("%*s#  %s:% 5d\n", indent, "",
349                                n2 > n1 ? b2 : b1, cnt);
350         } else {
351             if (cnt == 0 && bn1 == NULL)
352                 test_printf_stderr("%*s# -%s\n", indent, "", b1);
353             else if (cnt == 0 || n1 > 0)
354                 test_printf_stderr("%*s# -%s:% 5d\n", indent, "", b1, cnt);
355             if (cnt == 0 && bn2 == NULL)
356                 test_printf_stderr("%*s# +%s\n", indent, "", b2);
357             else if (cnt == 0 || n2 > 0)
358                 test_printf_stderr("%*s# +%s:% 5d\n", indent, "", b2, cnt);
359             if (real_diff && (cnt == 0 || (n1 > 0 && n2 > 0))
360                     && bn1 != NULL && bn2 != NULL)
361                 test_printf_stderr("%*s#  %s\n", indent, "", bdiff);
362         }
363         if (m1 != NULL)
364             m1 += bytes;
365         if (m2 != NULL)
366             m2 += bytes;
367         len -= bytes;
368     }
369 fin:
370     test_printf_stderr("\n");
371     test_flush_stderr();
372     if (bufp != buffer)
373         OPENSSL_free(bufp);
374 }
375
376 static void test_fail_bignum_message(const char *prefix, const char *file,
377                                      int line, const char *type,
378                                      const char *left, const char *right,
379                                      const char *op,
380                                      const BIGNUM *bn1, const BIGNUM *bn2)
381 {
382     test_fail_message_prefix(prefix, file, line, type, left, right, op);
383     test_fail_bignum_common(prefix, file, line, type, left, right, op, bn1, bn2);
384 }
385
386 static void test_fail_bignum_mono_message(const char *prefix, const char *file,
387                                           int line, const char *type,
388                                           const char *left, const char *right,
389                                           const char *op, const BIGNUM *bn)
390 {
391     test_fail_message_prefix(prefix, file, line, type, left, right, op);
392     test_fail_bignum_common(prefix, file, line, type, left, right, op, bn, bn);
393 }
394
395 static void test_fail_memory_message(const char *prefix, const char *file,
396                                      int line, const char *type,
397                                      const char *left, const char *right,
398                                      const char *op,
399                                      const unsigned char *m1, size_t l1,
400                                      const unsigned char *m2, size_t l2)
401 {
402     const int indent = subtest_level();
403     const size_t bytes = (MAX_STRING_WIDTH - 9) / 17 * 8;
404     char b1[MAX_STRING_WIDTH + 1], b2[MAX_STRING_WIDTH + 1];
405     char *p, bdiff[MAX_STRING_WIDTH + 1];
406     size_t n1, n2, i;
407     unsigned int cnt = 0, diff;
408
409     test_fail_message_prefix(prefix, file, line, type, left, right, op);
410     if (m1 == NULL)
411         l1 = 0;
412     if (m2 == NULL)
413         l2 = 0;
414     if (l1 == 0 && l2 == 0) {
415         if ((m1 == NULL) == (m2 == NULL)) {
416             test_printf_stderr("%*s# %04s  %s\n", indent, "", "",
417                                m1 == NULL ? "NULL" : "empty");
418         } else {
419             test_diff_header(left, right);
420             test_printf_stderr("%*s# %04s -%s\n", indent, "", "",
421                                m1 == NULL ? "NULL" : "empty");
422             test_printf_stderr("%*s# %04s +%s\n", indent, "", "",
423                                m2 == NULL ? "NULL" : "empty");
424         }
425         goto fin;
426     }
427
428     if (l1 != l2 || memcmp(m1, m2, l1) != 0)
429         test_diff_header(left, right);
430
431     while (l1 > 0 || l2 > 0) {
432         n1 = n2 = 0;
433         if (l1 > 0) {
434             n1 = l1 > bytes ? bytes : l1;
435             hex_convert_memory(m1, n1, b1, 8);
436         }
437         if (l2 > 0) {
438             n2 = l2 > bytes ? bytes : l2;
439             hex_convert_memory(m2, n2, b2, 8);
440         }
441
442         diff = n1 != n2;
443         i = 0;
444         p = bdiff;
445         if (n1 > 0 && n2 > 0) {
446             const size_t j = n1 < n2 ? n1 : n2;
447             const size_t k = n1 > n2 ? n1 : n2;
448
449             for (; i < j; i++) {
450                 if (m1[i] == m2[i]) {
451                     *p++ = ' ';
452                     *p++ = ' ';
453                 } else {
454                     *p++ = '^';
455                     *p++ = '^';
456                     diff = 1;
457                 }
458                 if ((i % 8) == 7 && (i != j - 1 || j != k))
459                     *p++ = ' ';
460             }
461
462             for (; i < k; i++) {
463                 *p++ = '^';
464                 *p++ = '^';
465                 if ((i % 8) == 7 && i != k - 1)
466                     *p++ = ' ';
467             }
468             *p++ = '\0';
469         }
470
471         if (!diff) {
472             test_printf_stderr("%*s# %04x: %s\n", indent, "", cnt, b1);
473         } else {
474             if (cnt == 0 && m1 == NULL)
475                 test_printf_stderr("%*s# %04s -NULL\n", indent, "", "");
476             else if (cnt == 0 && l1 == 0)
477                 test_printf_stderr("%*s# %04s -empty\n", indent, "", "");
478             else if (n1 > 0)
479                 test_printf_stderr("%*s# %04x:-%s\n", indent, "", cnt, b1);
480             if (cnt == 0 && m2 == NULL)
481                 test_printf_stderr("%*s# %04s +NULL\n", indent, "", "");
482             else if (cnt == 0 && l2 == 0)
483                 test_printf_stderr("%*s# %04s +empty\n", indent, "", "");
484             else if (n2 > 0)
485                 test_printf_stderr("%*s# %04x:+%s\n", indent, "", cnt, b2);
486             if (i > 0)
487                 test_printf_stderr("%*s# % 4s  %s\n", indent, "", "", bdiff);
488         }
489         m1 += n1;
490         m2 += n2;
491         l1 -= n1;
492         l2 -= n2;
493         cnt += bytes;
494     }
495 fin:
496     test_printf_stderr("\n");
497     test_flush_stderr();
498 }
499
500 static void test_fail_message(const char *prefix, const char *file,
501                               int line, const char *type,
502                               const char *left, const char *right,
503                               const char *op, const char *fmt, ...)
504 {
505     va_list ap;
506
507     va_start(ap, fmt);
508     test_fail_message_va(prefix, file, line, type, left, right, op, fmt, ap);
509     va_end(ap);
510 }
511
512 void test_info_c90(const char *desc, ...)
513 {
514     va_list ap;
515
516     va_start(ap, desc);
517     test_fail_message_va("INFO", NULL, -1, NULL, NULL, NULL, NULL, desc, ap);
518     va_end(ap);
519 }
520
521 void test_info(const char *file, int line, const char *desc, ...)
522 {
523     va_list ap;
524
525     va_start(ap, desc);
526     test_fail_message_va("INFO", file, line, NULL, NULL, NULL, NULL, desc, ap);
527     va_end(ap);
528 }
529
530 void test_error_c90(const char *desc, ...)
531 {
532     va_list ap;
533
534     va_start(ap, desc);
535     test_fail_message(NULL, NULL, -1, NULL, NULL, NULL, NULL, desc, ap);
536     va_end(ap);
537 }
538
539 void test_error(const char *file, int line, const char *desc, ...)
540 {
541     va_list ap;
542
543     va_start(ap, desc);
544     test_fail_message_va(NULL, file, line, NULL, NULL, NULL, NULL, desc, ap);
545     va_end(ap);
546 }
547
548 void test_openssl_errors(void)
549 {
550     ERR_print_errors_cb(openssl_error_cb, NULL);
551 }
552
553 /*
554  * Define some comparisons between pairs of various types.
555  * These functions return 1 if the test is true.
556  * Otherwise, they return 0 and pretty-print diagnostics.
557  *
558  * In each case the functions produced are:
559  *  int test_name_eq(const type t1, const type t2, const char *desc, ...);
560  *  int test_name_ne(const type t1, const type t2, const char *desc, ...);
561  *  int test_name_lt(const type t1, const type t2, const char *desc, ...);
562  *  int test_name_le(const type t1, const type t2, const char *desc, ...);
563  *  int test_name_gt(const type t1, const type t2, const char *desc, ...);
564  *  int test_name_ge(const type t1, const type t2, const char *desc, ...);
565  *
566  * The t1 and t2 arguments are to be compared for equality, inequality,
567  * less than, less than or equal to, greater than and greater than or
568  * equal to respectively.  If the specified condition holds, the functions
569  * return 1.  If the condition does not hold, the functions print a diagnostic
570  * message and return 0.
571  *
572  * The desc argument is a printf format string followed by its arguments and
573  * this is included in the output if the condition being tested for is false.
574  */
575 #define DEFINE_COMPARISON(type, name, opname, op, fmt)                  \
576     int test_ ## name ## _ ## opname(const char *file, int line,        \
577                                      const char *s1, const char *s2,    \
578                                      const type t1, const type t2)      \
579     {                                                                   \
580         if (t1 op t2)                                                   \
581             return 1;                                                   \
582         test_fail_message(NULL, file, line, #type, s1, s2, #op,         \
583                           "[" fmt "] compared to [" fmt "]",            \
584                           t1, t2);                                      \
585         return 0;                                                       \
586     }
587
588 #define DEFINE_COMPARISONS(type, name, fmt)                             \
589     DEFINE_COMPARISON(type, name, eq, ==, fmt)                          \
590     DEFINE_COMPARISON(type, name, ne, !=, fmt)                          \
591     DEFINE_COMPARISON(type, name, lt, <, fmt)                           \
592     DEFINE_COMPARISON(type, name, le, <=, fmt)                          \
593     DEFINE_COMPARISON(type, name, gt, >, fmt)                           \
594     DEFINE_COMPARISON(type, name, ge, >=, fmt)
595
596 DEFINE_COMPARISONS(int, int, "%d")
597 DEFINE_COMPARISONS(unsigned int, uint, "%u")
598 DEFINE_COMPARISONS(char, char, "%c")
599 DEFINE_COMPARISONS(unsigned char, uchar, "%u")
600 DEFINE_COMPARISONS(long, long, "%ld")
601 DEFINE_COMPARISONS(unsigned long, ulong, "%lu")
602 DEFINE_COMPARISONS(size_t, size_t, "%zu")
603
604 DEFINE_COMPARISON(void *, ptr, eq, ==, "%p")
605 DEFINE_COMPARISON(void *, ptr, ne, !=, "%p")
606
607 int test_ptr_null(const char *file, int line, const char *s, const void *p)
608 {
609     if (p == NULL)
610         return 1;
611     test_fail_message(NULL, file, line, "ptr", s, "NULL", "==", "%p", p);
612     return 0;
613 }
614
615 int test_ptr(const char *file, int line, const char *s, const void *p)
616 {
617     if (p != NULL)
618         return 1;
619     test_fail_message(NULL, file, line, "ptr", s, "NULL", "!=", "%p", p);
620     return 0;
621 }
622
623 int test_true(const char *file, int line, const char *s, int b)
624 {
625     if (b)
626         return 1;
627     test_fail_message(NULL, file, line, "bool", s, "true", "==", "false");
628     return 0;
629 }
630
631 int test_false(const char *file, int line, const char *s, int b)
632 {
633     if (!b)
634         return 1;
635     test_fail_message(NULL, file, line, "bool", s, "false", "==", "true");
636     return 0;
637 }
638
639 int test_str_eq(const char *file, int line, const char *st1, const char *st2,
640                 const char *s1, const char *s2)
641 {
642     if (s1 == NULL && s2 == NULL)
643       return 1;
644     if (s1 == NULL || s2 == NULL || strcmp(s1, s2) != 0) {
645         test_fail_string_message(NULL, file, line, "string", st1, st2, "==",
646                                  s1, s1 == NULL ? 0 : strlen(s1),
647                                  s2, s2 == NULL ? 0 : strlen(s2));
648         return 0;
649     }
650     return 1;
651 }
652
653 int test_str_ne(const char *file, int line, const char *st1, const char *st2,
654                 const char *s1, const char *s2)
655 {
656     if ((s1 == NULL) ^ (s2 == NULL))
657       return 1;
658     if (s1 == NULL || strcmp(s1, s2) == 0) {
659         test_fail_string_message(NULL, file, line, "string", st1, st2, "!=",
660                                  s1, s1 == NULL ? 0 : strlen(s1),
661                                  s2, s2 == NULL ? 0 : strlen(s2));
662         return 0;
663     }
664     return 1;
665 }
666
667 int test_strn_eq(const char *file, int line, const char *st1, const char *st2,
668                  const char *s1, const char *s2, size_t len)
669 {
670     if (s1 == NULL && s2 == NULL)
671       return 1;
672     if (s1 == NULL || s2 == NULL || strncmp(s1, s2, len) != 0) {
673         test_fail_string_message(NULL, file, line, "string", st1, st2, "==",
674                                  s1, s1 == NULL ? 0 : OPENSSL_strnlen(s1, len),
675                                  s2, s2 == NULL ? 0 : OPENSSL_strnlen(s2, len));
676         return 0;
677     }
678     return 1;
679 }
680
681 int test_strn_ne(const char *file, int line, const char *st1, const char *st2,
682                  const char *s1, const char *s2, size_t len)
683 {
684     if ((s1 == NULL) ^ (s2 == NULL))
685       return 1;
686     if (s1 == NULL || strncmp(s1, s2, len) == 0) {
687         test_fail_string_message(NULL, file, line, "string", st1, st2, "!=",
688                                  s1, s1 == NULL ? 0 : OPENSSL_strnlen(s1, len),
689                                  s2, s2 == NULL ? 0 : OPENSSL_strnlen(s2, len));
690         return 0;
691     }
692     return 1;
693 }
694
695 int test_mem_eq(const char *file, int line, const char *st1, const char *st2,
696                 const void *s1, size_t n1, const void *s2, size_t n2)
697 {
698     if (s1 == NULL && s2 == NULL)
699         return 1;
700     if (n1 != n2 || s1 == NULL || s2 == NULL || memcmp(s1, s2, n1) != 0) {
701         test_fail_memory_message(NULL, file, line, "memory", st1, st2, "==",
702                                  s1, n1, s2, n2);
703         return 0;
704     }
705     return 1;
706 }
707
708 int test_mem_ne(const char *file, int line, const char *st1, const char *st2,
709                 const void *s1, size_t n1, const void *s2, size_t n2)
710 {
711     if ((s1 == NULL) ^ (s2 == NULL))
712         return 1;
713     if (n1 != n2)
714         return 1;
715     if (s1 == NULL || memcmp(s1, s2, n1) == 0) {
716         test_fail_memory_message(NULL, file, line, "memory", st1, st2, "!=",
717                                  s1, n1, s2, n2);
718         return 0;
719     }
720     return 1;
721 }
722
723 #define DEFINE_BN_COMPARISONS(opname, op, zero_cond)                    \
724     int test_BN_ ## opname(const char *file, int line,                  \
725                            const char *s1, const char *s2,              \
726                            const BIGNUM *t1, const BIGNUM *t2)          \
727     {                                                                   \
728         if (BN_cmp(t1, t2) op 0)                                        \
729             return 1;                                                   \
730         test_fail_bignum_message(NULL, file, line, "BIGNUM", s1, s2,    \
731                                  #op, t1, t2);                          \
732         return 0;                                                       \
733     }                                                                   \
734     int test_BN_ ## opname ## _zero(const char *file, int line,         \
735                                     const char *s, const BIGNUM *a)     \
736     {                                                                   \
737         if (a != NULL &&(zero_cond))                                    \
738             return 1;                                                   \
739         test_fail_bignum_mono_message(NULL, file, line, "BIGNUM",       \
740                                       s, "0", #op, a);                  \
741         return 0;                                                       \
742     }
743
744 DEFINE_BN_COMPARISONS(eq, ==, BN_is_zero(a))
745 DEFINE_BN_COMPARISONS(ne, !=, !BN_is_zero(a))
746 DEFINE_BN_COMPARISONS(gt, >,  !BN_is_negative(a) && !BN_is_zero(a))
747 DEFINE_BN_COMPARISONS(ge, >=, !BN_is_negative(a) || BN_is_zero(a))
748 DEFINE_BN_COMPARISONS(lt, <,  BN_is_negative(a) && !BN_is_zero(a))
749 DEFINE_BN_COMPARISONS(le, <=, BN_is_negative(a) || BN_is_zero(a))
750
751 int test_BN_eq_one(const char *file, int line, const char *s, const BIGNUM *a)
752 {
753     if (a != NULL && BN_is_one(a))
754         return 1;
755     test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", s, "1", "==", a);
756     return 0;
757 }
758
759 int test_BN_odd(const char *file, int line, const char *s, const BIGNUM *a)
760 {
761     if (a != NULL && BN_is_odd(a))
762         return 1;
763     test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", "ODD(", ")", s, a);
764     return 0;
765 }
766
767 int test_BN_even(const char *file, int line, const char *s, const BIGNUM *a)
768 {
769     if (a != NULL && !BN_is_odd(a))
770         return 1;
771     test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", "EVEN(", ")", s,
772                                   a);
773     return 0;
774 }
775
776 int test_BN_eq_word(const char *file, int line, const char *bns, const char *ws,
777                     const BIGNUM *a, BN_ULONG w)
778 {
779     BIGNUM *bw;
780
781     if (a != NULL && BN_is_word(a, w))
782         return 1;
783     bw = BN_new();
784     BN_set_word(bw, w);
785     test_fail_bignum_message(NULL, file, line, "BIGNUM", bns, ws, "==", a, bw);
786     BN_free(bw);
787     return 0;
788 }
789
790 int test_BN_abs_eq_word(const char *file, int line, const char *bns,
791                         const char *ws, const BIGNUM *a, BN_ULONG w)
792 {
793     BIGNUM *bw, *aa;
794
795     if (a != NULL && BN_abs_is_word(a, w))
796         return 1;
797     bw = BN_new();
798     aa = BN_dup(a);
799     BN_set_negative(aa, 0);
800     BN_set_word(bw, w);
801     test_fail_bignum_message(NULL, file, line, "BIGNUM", bns, ws, "abs==",
802                              aa, bw);
803     BN_free(bw);
804     BN_free(aa);
805     return 0;
806 }