Add single call public key sign and verify functions.
[openssl.git] / fips / fips_test_suite.c
1 /* ====================================================================
2  * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
3  *
4  *
5  * This command is intended as a test driver for the FIPS-140 testing
6  * lab performing FIPS-140 validation.  It demonstrates the use of the
7  * OpenSSL library ito perform a variety of common cryptographic
8  * functions.  A power-up self test is demonstrated by deliberately
9  * pointing to an invalid executable hash
10  *
11  * Contributed by Steve Marquess.
12  *
13  */
14
15 #define OPENSSL_FIPSAPI
16
17 #include <stdio.h>
18 #include <assert.h>
19 #include <ctype.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <openssl/evp.h>
23 #include <openssl/hmac.h>
24 #include <openssl/cmac.h>
25 #include <openssl/sha.h>
26 #include <openssl/err.h>
27
28 #include <openssl/bn.h>
29 #include <openssl/rand.h>
30
31 #ifndef OPENSSL_FIPS
32 int main(int argc, char *argv[])
33     {
34     printf("No FIPS support\n");
35     return(0);
36     }
37 #else
38
39 #define ERR_clear_error() while(0)
40
41 #include <openssl/rsa.h>
42 #include <openssl/dsa.h>
43 #include <openssl/dh.h>
44
45 #include <openssl/fips.h>
46 #include <openssl/fips_rand.h>
47 #include "fips_utl.h"
48
49 /* AES: encrypt and decrypt known plaintext, verify result matches original plaintext
50 */
51 static int FIPS_aes_test(void)
52         {
53         int ret = 0;
54         unsigned char pltmp[16];
55         unsigned char citmp[16];
56         unsigned char key[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
57         unsigned char plaintext[16] = "etaonrishdlcu";
58         EVP_CIPHER_CTX ctx;
59         FIPS_cipher_ctx_init(&ctx);
60         if (FIPS_cipherinit(&ctx, EVP_aes_128_ecb(), key, NULL, 1) <= 0)
61                 goto err;
62         FIPS_cipher(&ctx, citmp, plaintext, 16);
63         if (FIPS_cipherinit(&ctx, EVP_aes_128_ecb(), key, NULL, 0) <= 0)
64                 goto err;
65         FIPS_cipher(&ctx, pltmp, citmp, 16);
66         if (memcmp(pltmp, plaintext, 16))
67                 goto err;
68         ret = 1;
69         err:
70         FIPS_cipher_ctx_cleanup(&ctx);
71         return ret;
72         }
73
74 static int FIPS_aes_gcm_test(void)
75         {
76         int ret = 0;
77         unsigned char pltmp[16];
78         unsigned char citmp[16];
79         unsigned char tagtmp[16];
80         unsigned char key[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
81         unsigned char iv[16] = {21,22,23,24,25,26,27,28,29,30,31,32};
82         unsigned char aad[] = "Some text AAD";
83         unsigned char plaintext[16] = "etaonrishdlcu";
84         EVP_CIPHER_CTX ctx;
85         FIPS_cipher_ctx_init(&ctx);
86         if (FIPS_cipherinit(&ctx, EVP_aes_128_gcm(), key, iv, 1) <= 0)
87                 goto err;
88         FIPS_cipher(&ctx, NULL, aad, sizeof(aad));
89         FIPS_cipher(&ctx, citmp, plaintext, 16);
90         FIPS_cipher(&ctx, NULL, NULL, 0);
91         if (!FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, 16, tagtmp))
92                 goto err;
93
94         if (FIPS_cipherinit(&ctx, EVP_aes_128_gcm(), key, iv, 0) <= 0)
95                 goto err;
96         if (!FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, 16, tagtmp))
97                 goto err;
98
99         FIPS_cipher(&ctx, NULL, aad, sizeof(aad));
100
101         FIPS_cipher(&ctx, pltmp, citmp, 16);
102
103         if (FIPS_cipher(&ctx, NULL, NULL, 0) < 0)
104                 goto err;
105
106         if (memcmp(pltmp, plaintext, 16))
107                 goto err;
108
109         ret = 1;
110         err:
111         FIPS_cipher_ctx_cleanup(&ctx);
112         return ret;
113         }
114
115 static int FIPS_des3_test(void)
116         {
117         int ret = 0;
118         unsigned char pltmp[8];
119         unsigned char citmp[8];
120         unsigned char key[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
121                               19,20,21,22,23,24};
122         unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' };
123         EVP_CIPHER_CTX ctx;
124         FIPS_cipher_ctx_init(&ctx);
125         if (FIPS_cipherinit(&ctx, EVP_des_ede3_ecb(), key, NULL, 1) <= 0)
126                 goto err;
127         FIPS_cipher(&ctx, citmp, plaintext, 8);
128         if (FIPS_cipherinit(&ctx, EVP_des_ede3_ecb(), key, NULL, 0) <= 0)
129                 goto err;
130         FIPS_cipher(&ctx, pltmp, citmp, 8);
131         if (memcmp(pltmp, plaintext, 8))
132                 goto err;
133         ret = 1;
134         err:
135         FIPS_cipher_ctx_cleanup(&ctx);
136         return ret;
137         }
138
139 /*
140  * DSA: generate keys and sign, verify input plaintext.
141  */
142 static int FIPS_dsa_test(int bad)
143     {
144     DSA *dsa = NULL;
145     unsigned char dgst[] = "etaonrishdlc";
146     int r = 0;
147     DSA_SIG *sig = NULL;
148
149     ERR_clear_error();
150     dsa = FIPS_dsa_new();
151     if (!dsa)
152         goto end;
153     if (!DSA_generate_parameters_ex(dsa, 1024,NULL,0,NULL,NULL,NULL))
154         goto end;
155     if (!DSA_generate_key(dsa))
156         goto end;
157     if (bad)
158             BN_add_word(dsa->pub_key, 1);
159
160     sig = FIPS_dsa_sign(dsa, dgst, sizeof(dgst) -1, EVP_sha256());
161     if (!sig)
162         goto end;
163
164     r = FIPS_dsa_verify(dsa, dgst, sizeof(dgst) -1, EVP_sha256(), sig);
165     end:
166     if (sig)
167         FIPS_dsa_sig_free(sig);
168     if (dsa)
169           FIPS_dsa_free(dsa);
170     if (r != 1)
171         return 0;
172     return 1;
173     }
174
175 /*
176  * RSA: generate keys and sign, verify input plaintext.
177  */
178 static int FIPS_rsa_test(int bad)
179     {
180     RSA *key;
181     unsigned char input_ptext[] = "etaonrishdlc";
182     unsigned char buf[256];
183     unsigned int slen;
184     BIGNUM *bn;
185     int r = 0;
186
187     ERR_clear_error();
188     key = FIPS_rsa_new();
189     bn = BN_new();
190     if (!key || !bn)
191         return 0;
192     BN_set_word(bn, 65537);
193     if (!RSA_generate_key_ex(key, 2048,bn,NULL))
194         return 0;
195     BN_free(bn);
196     if (bad)
197             BN_add_word(key->n, 1);
198
199     if (!FIPS_rsa_sign(key, input_ptext, sizeof(input_ptext) - 1, EVP_sha256(),
200                         RSA_PKCS1_PADDING, 0, NULL, buf, &slen))
201         goto end;
202
203     r = FIPS_rsa_verify(key, input_ptext, sizeof(input_ptext) - 1, EVP_sha256(),
204                         RSA_PKCS1_PADDING, 0, NULL, buf, slen);
205     end:
206     if (key)
207           FIPS_rsa_free(key);
208     if (r != 1)
209         return 0;
210     return 1;
211     }
212
213 /* SHA1: generate hash of known digest value and compare to known
214    precomputed correct hash
215 */
216 static int FIPS_sha1_test()
217     {
218     unsigned char digest[SHA_DIGEST_LENGTH] =
219         { 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a, 0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18 };
220     unsigned char str[] = "etaonrishd";
221
222     unsigned char md[SHA_DIGEST_LENGTH];
223
224     ERR_clear_error();
225     if (!FIPS_digest(str,sizeof(str) - 1,md, NULL, EVP_sha1())) return 0;
226     if (memcmp(md,digest,sizeof(md)))
227         return 0;
228     return 1;
229     }
230
231 /* SHA256: generate hash of known digest value and compare to known
232    precomputed correct hash
233 */
234 static int FIPS_sha256_test()
235     {
236     unsigned char digest[SHA256_DIGEST_LENGTH] =
237         {0xf5, 0x53, 0xcd, 0xb8, 0xcf, 0x1, 0xee, 0x17, 0x9b, 0x93, 0xc9, 0x68, 0xc0, 0xea, 0x40, 0x91,
238          0x6, 0xec, 0x8e, 0x11, 0x96, 0xc8, 0x5d, 0x1c, 0xaf, 0x64, 0x22, 0xe6, 0x50, 0x4f, 0x47, 0x57};
239     unsigned char str[] = "etaonrishd";
240
241     unsigned char md[SHA256_DIGEST_LENGTH];
242
243     ERR_clear_error();
244     if (!FIPS_digest(str,sizeof(str) - 1,md, NULL, EVP_sha256())) return 0;
245     if (memcmp(md,digest,sizeof(md)))
246         return 0;
247     return 1;
248     }
249
250 /* SHA512: generate hash of known digest value and compare to known
251    precomputed correct hash
252 */
253 static int FIPS_sha512_test()
254     {
255     unsigned char digest[SHA512_DIGEST_LENGTH] =
256         {0x99, 0xc9, 0xe9, 0x5b, 0x88, 0xd4, 0x78, 0x88, 0xdf, 0x88, 0x5f, 0x94, 0x71, 0x64, 0x28, 0xca,
257          0x16, 0x1f, 0x3d, 0xf4, 0x1f, 0xf3, 0x0f, 0xc5, 0x03, 0x99, 0xb2, 0xd0, 0xe7, 0x0b, 0x94, 0x4a,
258          0x45, 0xd2, 0x6c, 0x4f, 0x20, 0x06, 0xef, 0x71, 0xa9, 0x25, 0x7f, 0x24, 0xb1, 0xd9, 0x40, 0x22,
259          0x49, 0x54, 0x10, 0xc2, 0x22, 0x9d, 0x27, 0xfe, 0xbd, 0xd6, 0xd6, 0xeb, 0x2d, 0x42, 0x1d, 0xa3};
260     unsigned char str[] = "etaonrishd";
261
262     unsigned char md[SHA512_DIGEST_LENGTH];
263
264     ERR_clear_error();
265     if (!FIPS_digest(str,sizeof(str) - 1,md, NULL, EVP_sha512())) return 0;
266     if (memcmp(md,digest,sizeof(md)))
267         return 0;
268     return 1;
269     }
270
271 /* HMAC-SHA1: generate hash of known digest value and compare to known
272    precomputed correct hash
273 */
274 static int FIPS_hmac_sha1_test()
275     {
276     unsigned char key[] = "etaonrishd";
277     unsigned char iv[] = "Sample text";
278     unsigned char kaval[EVP_MAX_MD_SIZE] =
279         {0x73, 0xf7, 0xa0, 0x48, 0xf8, 0x94, 0xed, 0xdd, 0x0a, 0xea, 0xea, 0x56, 0x1b, 0x61, 0x2e, 0x70,
280          0xb2, 0xfb, 0xec, 0xc6};
281
282     unsigned char out[EVP_MAX_MD_SIZE];
283     unsigned int outlen;
284
285     ERR_clear_error();
286     if (!HMAC(EVP_sha1(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
287     if (memcmp(out,kaval,outlen))
288         return 0;
289     return 1;
290     }
291
292 /* HMAC-SHA224: generate hash of known digest value and compare to known
293    precomputed correct hash
294 */
295 static int FIPS_hmac_sha224_test()
296     {
297     unsigned char key[] = "etaonrishd";
298     unsigned char iv[] = "Sample text";
299     unsigned char kaval[EVP_MAX_MD_SIZE] =
300         {0x75, 0x58, 0xd5, 0xbd, 0x55, 0x6d, 0x87, 0x0f, 0x75, 0xff, 0xbe, 0x1c, 0xb2, 0xf0, 0x20, 0x35,
301          0xe5, 0x62, 0x49, 0xb6, 0x94, 0xb9, 0xfc, 0x65, 0x34, 0x33, 0x3a, 0x19};
302
303     unsigned char out[EVP_MAX_MD_SIZE];
304     unsigned int outlen;
305
306     ERR_clear_error();
307     if (!HMAC(EVP_sha224(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
308     if (memcmp(out,kaval,outlen))
309         return 0;
310     return 1;
311     }
312
313 /* HMAC-SHA256: generate hash of known digest value and compare to known
314    precomputed correct hash
315 */
316 static int FIPS_hmac_sha256_test()
317     {
318     unsigned char key[] = "etaonrishd";
319     unsigned char iv[] = "Sample text";
320     unsigned char kaval[EVP_MAX_MD_SIZE] =
321         {0xe9, 0x17, 0xc1, 0x7b, 0x4c, 0x6b, 0x77, 0xda, 0xd2, 0x30, 0x36, 0x02, 0xf5, 0x72, 0x33, 0x87,
322          0x9f, 0xc6, 0x6e, 0x7b, 0x7e, 0xa8, 0xea, 0xaa, 0x9f, 0xba, 0xee, 0x51, 0xff, 0xda, 0x24, 0xf4};
323
324     unsigned char out[EVP_MAX_MD_SIZE];
325     unsigned int outlen;
326
327     ERR_clear_error();
328     if (!HMAC(EVP_sha256(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
329     if (memcmp(out,kaval,outlen))
330         return 0;
331     return 1;
332     }
333
334 /* HMAC-SHA384: generate hash of known digest value and compare to known
335    precomputed correct hash
336 */
337 static int FIPS_hmac_sha384_test()
338     {
339     unsigned char key[] = "etaonrishd";
340     unsigned char iv[] = "Sample text";
341     unsigned char kaval[EVP_MAX_MD_SIZE] =
342         {0xb2, 0x9d, 0x40, 0x58, 0x32, 0xc4, 0xe3, 0x31, 0xb6, 0x63, 0x08, 0x26, 0x99, 0xef, 0x3b, 0x10,
343          0xe2, 0xdf, 0xf8, 0xff, 0xc6, 0xe1, 0x03, 0x29, 0x81, 0x2a, 0x1b, 0xac, 0xb0, 0x07, 0x39, 0x08,
344          0xf3, 0x91, 0x35, 0x11, 0x76, 0xd6, 0x4c, 0x20, 0xfb, 0x4d, 0xc3, 0xf3, 0xb8, 0x9b, 0x88, 0x1c};
345
346     unsigned char out[EVP_MAX_MD_SIZE];
347     unsigned int outlen;
348
349     ERR_clear_error();
350     if (!HMAC(EVP_sha384(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
351     if (memcmp(out,kaval,outlen))
352         return 0;
353     return 1;
354     }
355
356 /* HMAC-SHA512: generate hash of known digest value and compare to known
357    precomputed correct hash
358 */
359 static int FIPS_hmac_sha512_test()
360     {
361     unsigned char key[] = "etaonrishd";
362     unsigned char iv[] = "Sample text";
363     unsigned char kaval[EVP_MAX_MD_SIZE] =
364         {0xcd, 0x3e, 0xb9, 0x51, 0xb8, 0xbc, 0x7f, 0x9a, 0x23, 0xaf, 0xf3, 0x77, 0x59, 0x85, 0xa9, 0xe6,
365          0xf7, 0xd1, 0x51, 0x96, 0x17, 0xe0, 0x92, 0xd8, 0xa6, 0x3b, 0xc1, 0xad, 0x7e, 0x24, 0xca, 0xb1,
366          0xd7, 0x79, 0x0a, 0xa5, 0xea, 0x2c, 0x02, 0x58, 0x0b, 0xa6, 0x52, 0x6b, 0x61, 0x7f, 0xeb, 0x9c,
367          0x47, 0x86, 0x5d, 0x74, 0x2b, 0x88, 0xdf, 0xee, 0x46, 0x69, 0x96, 0x3d, 0xa6, 0xd9, 0x2a, 0x53};
368
369     unsigned char out[EVP_MAX_MD_SIZE];
370     unsigned int outlen;
371
372     ERR_clear_error();
373     if (!HMAC(EVP_sha512(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
374     if (memcmp(out,kaval,outlen))
375         return 0;
376     return 1;
377     }
378
379 /* CMAC-AES128: generate hash of known digest value and compare to known
380    precomputed correct hash
381 */
382 static int FIPS_cmac_aes128_test()
383     {
384     unsigned char key[16] = { 0x2b,0x7e,0x15,0x16, 0x28,0xae,0xd2,0xa6,
385                               0xab,0xf7,0x15,0x88, 0x09,0xcf,0x4f,0x3c, };
386     unsigned char data[] = "Sample text";
387     unsigned char kaval[EVP_MAX_MD_SIZE] =
388             { 0x16,0x83,0xfe,0xac, 0x52,0x9b,0xae,0x23,
389               0xd7,0xd5,0x66,0xf5, 0xd2,0x8d,0xbd,0x2a, };
390
391     unsigned char *out = NULL;
392     size_t outlen;
393     CMAC_CTX *ctx = CMAC_CTX_new();
394     int r = 0;
395
396     ERR_clear_error();
397
398     if (!ctx)
399             goto end;
400     if (!CMAC_Init(ctx,key,sizeof(key),EVP_aes_128_cbc(),NULL))
401             goto end;
402     if (!CMAC_Update(ctx,data,sizeof(data)-1))
403             goto end;
404     /* This should return 1.  If not, there's a programming error... */
405     if (!CMAC_Final(ctx, out, &outlen))
406             goto end;
407     out = OPENSSL_malloc(outlen);
408     if (!CMAC_Final(ctx, out, &outlen))
409             goto end;
410 #if 0
411     {
412     char *hexout = OPENSSL_malloc(outlen * 2 + 1);
413     bin2hex(out, outlen, hexout);
414     printf("CMAC-AES128: res = %s\n", hexout);
415     OPENSSL_free(hexout);
416     }
417     r = 1;
418 #else
419     if (!memcmp(out,kaval,outlen))
420             r = 1;
421 #endif
422     end:
423     CMAC_CTX_free(ctx);
424     if (out)
425           OPENSSL_free(out);
426     return r;
427     }
428
429 /* CMAC-AES192: generate hash of known digest value and compare to known
430    precomputed correct hash
431 */
432 static int FIPS_cmac_aes192_test()
433     {
434     unsigned char key[] = { 0x8e,0x73,0xb0,0xf7, 0xda,0x0e,0x64,0x52,
435                             0xc8,0x10,0xf3,0x2b, 0x80,0x90,0x79,0xe5,
436                             0x62,0xf8,0xea,0xd2, 0x52,0x2c,0x6b,0x7b, };
437     unsigned char data[] = "Sample text";
438     unsigned char kaval[] =
439             { 0xd6,0x99,0x19,0x25, 0xe5,0x1d,0x95,0x48,
440               0xb1,0x4a,0x0b,0xf2, 0xc6,0x3c,0x47,0x1f, };
441
442     unsigned char *out = NULL;
443     size_t outlen;
444     CMAC_CTX *ctx = CMAC_CTX_new();
445     int r = 0;
446
447     ERR_clear_error();
448
449     if (!ctx)
450             goto end;
451     if (!CMAC_Init(ctx,key,sizeof(key),EVP_aes_192_cbc(),NULL))
452             goto end;
453     if (!CMAC_Update(ctx,data,sizeof(data)-1))
454             goto end;
455     /* This should return 1.  If not, there's a programming error... */
456     if (!CMAC_Final(ctx, out, &outlen))
457             goto end;
458     out = OPENSSL_malloc(outlen);
459     if (!CMAC_Final(ctx, out, &outlen))
460             goto end;
461 #if 0
462     {
463     char *hexout = OPENSSL_malloc(outlen * 2 + 1);
464     bin2hex(out, outlen, hexout);
465     printf("CMAC-AES192: res = %s\n", hexout);
466     OPENSSL_free(hexout);
467     }
468     r = 1;
469 #else
470     if (!memcmp(out,kaval,outlen))
471             r = 1;
472 #endif
473     end:
474     CMAC_CTX_free(ctx);
475     if (out)
476           OPENSSL_free(out);
477     return r;
478     }
479
480 /* CMAC-AES256: generate hash of known digest value and compare to known
481    precomputed correct hash
482 */
483 static int FIPS_cmac_aes256_test()
484     {
485     unsigned char key[] = { 0x60,0x3d,0xeb,0x10, 0x15,0xca,0x71,0xbe,
486                             0x2b,0x73,0xae,0xf0, 0x85,0x7d,0x77,0x81,
487                             0x1f,0x35,0x2c,0x07, 0x3b,0x61,0x08,0xd7,
488                             0x2d,0x98,0x10,0xa3, 0x09,0x14,0xdf,0xf4, };
489     unsigned char data[] = "Sample text";
490     unsigned char kaval[] =
491             { 0xec,0xc2,0xcf,0x63, 0xc7,0xce,0xfc,0xa4,
492               0xb0,0x86,0x37,0x5f, 0x15,0x60,0xba,0x1f, };
493
494     unsigned char *out = NULL;
495     size_t outlen;
496     CMAC_CTX *ctx = CMAC_CTX_new();
497     int r = 0;
498
499     ERR_clear_error();
500
501     if (!ctx)
502             goto end;
503     if (!CMAC_Init(ctx,key,sizeof(key),EVP_aes_256_cbc(),NULL))
504             goto end;
505     if (!CMAC_Update(ctx,data,sizeof(data)-1))
506             goto end;
507     /* This should return 1.  If not, there's a programming error... */
508     if (!CMAC_Final(ctx, out, &outlen))
509             goto end;
510     out = OPENSSL_malloc(outlen);
511     if (!CMAC_Final(ctx, out, &outlen))
512             goto end;
513 #if 0
514     {
515     char *hexout = OPENSSL_malloc(outlen * 2 + 1);
516     bin2hex(out, outlen, hexout);
517     printf("CMAC-AES256: res = %s\n", hexout);
518     OPENSSL_free(hexout);
519     }
520     r = 1;
521 #else
522     if (!memcmp(out,kaval,outlen))
523             r = 1;
524 #endif
525     end:
526     CMAC_CTX_free(ctx);
527     if (out)
528           OPENSSL_free(out);
529     return r;
530     }
531
532 /* CMAC-TDEA3: generate hash of known digest value and compare to known
533    precomputed correct hash
534 */
535 static int FIPS_cmac_tdea3_test()
536     {
537     unsigned char key[] = { 0x8a,0xa8,0x3b,0xf8, 0xcb,0xda,0x10,0x62,
538                             0x0b,0xc1,0xbf,0x19, 0xfb,0xb6,0xcd,0x58,
539                             0xbc,0x31,0x3d,0x4a, 0x37,0x1c,0xa8,0xb5, };
540     unsigned char data[] = "Sample text";
541     unsigned char kaval[EVP_MAX_MD_SIZE] =
542             { 0xb4,0x06,0x4e,0xbf, 0x59,0x89,0xba,0x68, };
543
544     unsigned char *out = NULL;
545     size_t outlen;
546     CMAC_CTX *ctx = CMAC_CTX_new();
547     int r = 0;
548
549     ERR_clear_error();
550
551     if (!ctx)
552             goto end;
553     if (!CMAC_Init(ctx,key,sizeof(key),EVP_des_ede3_cbc(),NULL))
554             goto end;
555     if (!CMAC_Update(ctx,data,sizeof(data)-1))
556             goto end;
557     /* This should return 1.  If not, there's a programming error... */
558     if (!CMAC_Final(ctx, out, &outlen))
559             goto end;
560     out = OPENSSL_malloc(outlen);
561     if (!CMAC_Final(ctx, out, &outlen))
562             goto end;
563 #if 0
564     {
565     char *hexout = OPENSSL_malloc(outlen * 2 + 1);
566     bin2hex(out, outlen, hexout);
567     printf("CMAC-TDEA3: res = %s\n", hexout);
568     OPENSSL_free(hexout);
569     }
570     r = 1;
571 #else
572     if (!memcmp(out,kaval,outlen))
573             r = 1;
574 #endif
575     end:
576     CMAC_CTX_free(ctx);
577     if (out)
578           OPENSSL_free(out);
579     return r;
580     }
581
582
583 /* DH: generate shared parameters
584 */
585 static int dh_test()
586     {
587     DH *dh;
588     ERR_clear_error();
589     dh = FIPS_dh_new();
590     if (!dh)
591         return 0;
592     if (!DH_generate_parameters_ex(dh, 1024, 2, NULL))
593         return 0;
594     FIPS_dh_free(dh);
595     return 1;
596     }
597
598 /* Zeroize
599 */
600 static int Zeroize()
601     {
602     RSA *key;
603     BIGNUM *bn;
604     unsigned char userkey[16] = 
605         { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 };
606     size_t i;
607     int n;
608
609     key = FIPS_rsa_new();
610     bn = BN_new();
611     if (!key || !bn)
612         return 0;
613     BN_set_word(bn, 65537);
614     if (!RSA_generate_key_ex(key, 1024,bn,NULL))
615         return 0;
616     BN_free(bn);
617     
618     n = BN_num_bytes(key->d);
619     printf(" Generated %d byte RSA private key\n", n);
620     printf("\tBN key before overwriting:\n");
621     do_bn_print(stdout, key->d);
622     BN_rand(key->d,n*8,-1,0);
623     printf("\tBN key after overwriting:\n");
624     do_bn_print(stdout, key->d);
625
626     printf("\tchar buffer key before overwriting: \n\t\t");
627     for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
628         printf("\n");
629     RAND_bytes(userkey, sizeof userkey);
630     printf("\tchar buffer key after overwriting: \n\t\t");
631     for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
632         printf("\n");
633
634     FIPS_rsa_free(key);
635
636     return 1;
637     }
638
639 /* Dummy Entropy for DRBG tests. WARNING: THIS IS TOTALLY BOGUS
640  * HAS ZERO SECURITY AND MUST NOT BE USED IN REAL APPLICATIONS.
641  */
642
643 static unsigned char dummy_drbg_entropy[1024];
644
645 static size_t drbg_test_cb(DRBG_CTX *ctx, unsigned char **pout,
646                                 int entropy, size_t min_len, size_t max_len)
647         {
648         *pout = dummy_drbg_entropy;
649         /* Round up to multiple of block size */
650         return (min_len + 0xf) & ~0xf;
651         }
652
653 /* DRBG test: just generate lots of data and trigger health checks */
654
655 static int do_drbg_test(int type, int flags)
656     {
657     DRBG_CTX *dctx;
658     int rv = 0;
659     size_t i;
660     unsigned char randout[1024];
661     dctx = FIPS_drbg_new(type, flags);
662     if (!dctx)
663         return 0;
664     FIPS_drbg_set_callbacks(dctx, drbg_test_cb, 0, 0x10, drbg_test_cb, 0);
665     for (i = 0; i < sizeof(dummy_drbg_entropy); i++)
666         {
667         dummy_drbg_entropy[i] = i & 0xff;
668         }
669     if (!FIPS_drbg_instantiate(dctx, dummy_drbg_entropy, 10))
670         goto err;
671     FIPS_drbg_set_check_interval(dctx, 10);
672     for (i = 0; i < 32; i++)
673         {
674         if (!FIPS_drbg_generate(dctx, randout, sizeof(randout), 0, NULL, 0))
675                 goto err;
676         if (!FIPS_drbg_generate(dctx, randout, sizeof(randout), 0, dummy_drbg_entropy, 1))
677                 goto err;
678         }
679     rv = 1;
680     err:
681     FIPS_drbg_free(dctx);
682     return rv;
683     }
684
685 typedef struct 
686     {
687     int type, flags;
688     } DRBG_LIST;
689
690 static int do_drbg_all(void)
691     {
692     static DRBG_LIST drbg_types[] =
693         {
694                 {NID_sha1, 0},
695                 {NID_sha224, 0},
696                 {NID_sha256, 0},
697                 {NID_sha384, 0},
698                 {NID_sha512, 0},
699                 {NID_hmacWithSHA1, 0},
700                 {NID_hmacWithSHA224, 0},
701                 {NID_hmacWithSHA256, 0},
702                 {NID_hmacWithSHA384, 0},
703                 {NID_hmacWithSHA512, 0},
704                 {NID_aes_128_ctr, 0},
705                 {NID_aes_192_ctr, 0},
706                 {NID_aes_256_ctr, 0},
707                 {NID_aes_128_ctr, DRBG_FLAG_CTR_USE_DF},
708                 {NID_aes_192_ctr, DRBG_FLAG_CTR_USE_DF},
709                 {NID_aes_256_ctr, DRBG_FLAG_CTR_USE_DF},
710                 {(NID_X9_62_prime256v1 << 16)|NID_sha1, 0},
711                 {(NID_X9_62_prime256v1 << 16)|NID_sha224, 0},
712                 {(NID_X9_62_prime256v1 << 16)|NID_sha256, 0},
713                 {(NID_X9_62_prime256v1 << 16)|NID_sha384, 0},
714                 {(NID_X9_62_prime256v1 << 16)|NID_sha512, 0},
715                 {(NID_secp384r1 << 16)|NID_sha224, 0},
716                 {(NID_secp384r1 << 16)|NID_sha256, 0},
717                 {(NID_secp384r1 << 16)|NID_sha384, 0},
718                 {(NID_secp384r1 << 16)|NID_sha512, 0},
719                 {(NID_secp521r1 << 16)|NID_sha256, 0},
720                 {(NID_secp521r1 << 16)|NID_sha384, 0},
721                 {(NID_secp521r1 << 16)|NID_sha512, 0},
722                 {0, 0}
723         };
724     DRBG_LIST *lst;
725     int rv = 1;
726     for (lst = drbg_types;; lst++)
727         {
728         if (lst->type == 0)
729                 break;
730         if (!do_drbg_test(lst->type, lst->flags))
731                 rv = 0;
732         }
733     return rv;
734     }
735
736 static int Error;
737 static const char * Fail(const char *msg)
738     {
739     Error++;
740     return msg; 
741     }
742
743 static void test_msg(const char *msg, int result)
744         {
745         printf("%s...%s\n", msg, result ? "successful" : Fail("Failed!"));
746         }
747
748 /* Table of IDs for POST translating between NIDs and names */
749
750 typedef struct 
751         {
752         int id;
753         const char *name;
754         } POST_ID;
755
756 POST_ID id_list[] = {
757         {NID_sha1, "SHA1"},
758         {NID_sha224, "SHA224"},
759         {NID_sha256, "SHA256"},
760         {NID_sha384, "SHA384"},
761         {NID_sha512, "SHA512"},
762         {NID_hmacWithSHA1, "HMAC-SHA1"},
763         {NID_hmacWithSHA224, "HMAC-SHA224"},
764         {NID_hmacWithSHA256, "HMAC-SHA256"},
765         {NID_hmacWithSHA384, "HMAC-SHA384"},
766         {NID_hmacWithSHA512, "HMAC-SHA512"},
767         {EVP_PKEY_RSA, "RSA"},
768         {EVP_PKEY_DSA, "DSA"},
769         {EVP_PKEY_EC, "ECDSA"},
770         {NID_aes_128_cbc, "AES-128-CBC"},
771         {NID_aes_192_cbc, "AES-192-CBC"},
772         {NID_aes_256_cbc, "AES-256-CBC"},
773         {NID_aes_128_ctr, "AES-128-CTR"},
774         {NID_aes_192_ctr, "AES-192-CTR"},
775         {NID_aes_256_ctr, "AES-256-CTR"},
776         {NID_aes_128_ecb, "AES-128-ECB"},
777         {NID_aes_128_xts, "AES-128-XTS"},
778         {NID_aes_256_xts, "AES-256-XTS"},
779         {NID_des_ede3_cbc, "DES-EDE3-CBC"},
780         {NID_des_ede3_ecb, "DES-EDE3-ECB"},
781         {NID_secp224r1, "P-224"},
782         {NID_sect233r1, "B-233"},
783         {NID_sect233k1, "K-233"},
784         {NID_X9_62_prime256v1, "P-256"},
785         {NID_secp384r1, "P-384"},
786         {NID_secp521r1, "P-521"},
787         {0, NULL}
788 };
789
790 static const char *lookup_id(int id)
791         {
792         POST_ID *n;
793         static char out[40];
794         for (n = id_list; n->name; n++)
795                 {
796                 if (n->id == id)
797                         return n->name;
798                 }
799         sprintf(out, "ID=%d", id);
800         return out;
801         }
802
803 static int fail_id = -1;
804 static int fail_sub = -1;
805 static int fail_key = -1;
806
807 static int post_cb(int op, int id, int subid, void *ex)
808         {
809         const char *idstr, *exstr = "";
810         char asctmp[20];
811         int keytype = -1;
812 #ifdef FIPS_POST_TIME
813         static struct timespec start, end, tstart, tend;
814 #endif
815         switch(id)
816                 {
817                 case FIPS_TEST_INTEGRITY:
818                 idstr = "Integrity";
819                 break;
820
821                 case FIPS_TEST_DIGEST:
822                 idstr = "Digest";
823                 exstr = lookup_id(subid);
824                 break;
825
826                 case FIPS_TEST_CIPHER:
827                 exstr = lookup_id(subid);
828                 idstr = "Cipher";
829                 break;
830
831                 case FIPS_TEST_SIGNATURE:
832                 if (ex)
833                         {
834                         EVP_PKEY *pkey = ex;
835                         keytype = pkey->type;
836                         if (keytype == EVP_PKEY_EC)
837                                 {
838                                 const EC_GROUP *grp;
839                                 int cnid;
840                                 grp = EC_KEY_get0_group(pkey->pkey.ec);
841                                 cnid = EC_GROUP_get_curve_name(grp);
842                                 sprintf(asctmp, "ECDSA %s", lookup_id(cnid));
843                                 exstr = asctmp;
844                                 }
845                         else
846                                 exstr = lookup_id(keytype);
847                         }
848                 idstr = "Signature";
849                 break;
850
851                 case FIPS_TEST_HMAC:
852                 exstr = lookup_id(subid);
853                 idstr = "HMAC";
854                 break;
855
856                 case FIPS_TEST_CMAC:
857                 idstr = "CMAC";
858                 exstr = lookup_id(subid);
859                 break;
860
861                 case FIPS_TEST_GCM:
862                 idstr = "GCM";
863                 break;
864
865                 case FIPS_TEST_XTS:
866                 idstr = "XTS";
867                 exstr = lookup_id(subid);
868                 break;
869
870                 case FIPS_TEST_CCM:
871                 idstr = "CCM";
872                 break;
873
874                 case FIPS_TEST_X931:
875                 idstr = "X9.31 PRNG";
876                 sprintf(asctmp, "keylen=%d", subid);
877                 exstr = asctmp;
878                 break;
879
880                 case FIPS_TEST_DRBG:
881                 idstr = "DRBG";
882                 if (*(int *)ex & DRBG_FLAG_CTR_USE_DF)
883                         {
884                         sprintf(asctmp, "%s DF", lookup_id(subid));
885                         exstr = asctmp;
886                         }
887                 else if (subid >> 16)
888                         {
889                         sprintf(asctmp, "%s %s",
890                                         lookup_id(subid >> 16),
891                                         lookup_id(subid & 0xFFFF));
892                         exstr = asctmp;
893                         }
894                 else
895                         exstr = lookup_id(subid);
896                 break;
897
898                 case FIPS_TEST_PAIRWISE:
899                 if (ex)
900                         {
901                         EVP_PKEY *pkey = ex;
902                         keytype = pkey->type;
903                         exstr = lookup_id(keytype);
904                         }
905                 idstr = "Pairwise Consistency";
906                 break;
907
908                 case FIPS_TEST_CONTINUOUS:
909                 idstr = "Continuous PRNG";
910                 break;
911
912                 case FIPS_TEST_ECDH:
913                 idstr = "ECDH";
914                 exstr = lookup_id(subid);
915                 break;
916
917                 default:
918                 idstr = "Unknown";
919                 break;
920
921                 }
922
923         switch(op)
924                 {
925                 case FIPS_POST_BEGIN:
926 #ifdef FIPS_POST_TIME
927                 clock_getres(CLOCK_REALTIME, &tstart);
928                 printf("\tTimer resolution %ld s, %ld ns\n",
929                                 (long)tstart.tv_sec, (long)tstart.tv_nsec);
930                 clock_gettime(CLOCK_REALTIME, &tstart);
931 #endif
932                 printf("\tPOST started\n");
933                 break;
934
935                 case FIPS_POST_END:
936                 printf("\tPOST %s\n", id ? "Success" : "Failed");
937 #ifdef FIPS_POST_TIME
938                 clock_gettime(CLOCK_REALTIME, &tend);
939                 printf("\t\tTook %f seconds\n",
940                         (double)((tend.tv_sec+tend.tv_nsec*1e-9)
941                         - (tstart.tv_sec+tstart.tv_nsec*1e-9)));
942 #endif
943                 break;
944
945                 case FIPS_POST_STARTED:
946                 printf("\t\t%s %s test started\n", idstr, exstr);
947 #ifdef FIPS_POST_TIME
948                 clock_gettime(CLOCK_REALTIME, &start);
949 #endif
950                 break;
951
952                 case FIPS_POST_SUCCESS:
953                 printf("\t\t%s %s test OK\n", idstr, exstr);
954 #ifdef FIPS_POST_TIME
955                 clock_gettime(CLOCK_REALTIME, &end);
956                 printf("\t\t\tTook %f seconds\n",
957                         (double)((end.tv_sec+end.tv_nsec*1e-9)
958                         - (start.tv_sec+start.tv_nsec*1e-9)));
959 #endif
960                 break;
961
962                 case FIPS_POST_FAIL:
963                 printf("\t\t%s %s test FAILED!!\n", idstr, exstr);
964                 break;
965
966                 case FIPS_POST_CORRUPT:
967                 if (fail_id == id
968                         && (fail_key == -1 || fail_key == keytype)
969                         && (fail_sub == -1 || fail_sub == subid))
970                         {
971                         printf("\t\t%s %s test failure induced\n", idstr, exstr);
972                         return 0;
973                         }
974                 break;
975
976                 }
977         return 1;
978         }
979
980 #ifdef FIPS_ALGVS
981 int fips_test_suite_main(int argc, char **argv)
982 #else
983 int main(int argc, char **argv)
984 #endif
985     {
986     int bad_rsa = 0, bad_dsa = 0;
987     int do_rng_stick = 0;
988     int do_drbg_stick = 0;
989     int no_exit = 0;
990     int no_dh = 0;
991     char *pass = FIPS_AUTH_USER_PASS;
992
993     FIPS_post_set_callback(post_cb);
994
995     printf("\tFIPS-mode test application\n");
996
997     printf("\t%s\n\n", FIPS_module_version_text());
998
999     if (argv[1]) {
1000         /* Corrupted KAT tests */
1001         if (!strcmp(argv[1], "integrity")) {
1002             fail_id = FIPS_TEST_INTEGRITY;
1003         } else if (!strcmp(argv[1], "aes")) {
1004             fail_id = FIPS_TEST_CIPHER;
1005             fail_sub = NID_aes_128_ecb; 
1006         } else if (!strcmp(argv[1], "aes-ccm")) {
1007             fail_id = FIPS_TEST_CCM;
1008         } else if (!strcmp(argv[1], "aes-gcm")) {
1009             fail_id = FIPS_TEST_GCM;
1010         } else if (!strcmp(argv[1], "aes-xts")) {
1011             fail_id = FIPS_TEST_XTS;
1012         } else if (!strcmp(argv[1], "des")) {
1013             fail_id = FIPS_TEST_CIPHER;
1014             fail_sub = NID_des_ede3_ecb;        
1015         } else if (!strcmp(argv[1], "dsa")) {
1016             fail_id = FIPS_TEST_SIGNATURE;
1017             fail_key = EVP_PKEY_DSA;    
1018         } else if (!strcmp(argv[1], "ecdh")) {
1019             fail_id = FIPS_TEST_ECDH;
1020         } else if (!strcmp(argv[1], "ecdsa")) {
1021             fail_id = FIPS_TEST_SIGNATURE;
1022             fail_key = EVP_PKEY_EC;     
1023         } else if (!strcmp(argv[1], "rsa")) {
1024             fail_id = FIPS_TEST_SIGNATURE;
1025             fail_key = EVP_PKEY_RSA;    
1026         } else if (!strcmp(argv[1], "rsakey")) {
1027             printf("RSA key generation and signature validation with corrupted key...\n");
1028             bad_rsa = 1;
1029             no_exit = 1;
1030         } else if (!strcmp(argv[1], "rsakeygen")) {
1031             fail_id = FIPS_TEST_PAIRWISE;
1032             fail_key = EVP_PKEY_RSA;
1033             no_exit = 1;
1034         } else if (!strcmp(argv[1], "dsakey")) {
1035             printf("DSA key generation and signature validation with corrupted key...\n");
1036             bad_dsa = 1;
1037             no_exit = 1;
1038         } else if (!strcmp(argv[1], "dsakeygen")) {
1039             fail_id = FIPS_TEST_PAIRWISE;
1040             fail_key = EVP_PKEY_DSA;
1041             no_exit = 1;
1042         } else if (!strcmp(argv[1], "sha1")) {
1043             fail_id = FIPS_TEST_DIGEST;
1044         } else if (!strcmp(argv[1], "hmac")) {
1045             fail_id = FIPS_TEST_HMAC;
1046         } else if (!strcmp(argv[1], "cmac")) {
1047             fail_id = FIPS_TEST_CMAC;
1048         } else if (!strcmp(argv[1], "drbg")) {
1049             fail_id = FIPS_TEST_DRBG;
1050         } else if (!strcmp(argv[1], "rng")) {
1051             fail_id = FIPS_TEST_X931;
1052         } else if (!strcmp(argv[1], "nodh")) {
1053             no_dh = 1;
1054             no_exit = 1;
1055         } else if (!strcmp(argv[1], "post")) {
1056             fail_id = -1;
1057         } else if (!strcmp(argv[1], "rngstick")) {
1058             do_rng_stick = 1;
1059             no_exit = 1;
1060             printf("RNG test with stuck continuous test...\n");
1061         } else if (!strcmp(argv[1], "drbgentstick")) {
1062                 do_entropy_stick();
1063         } else if (!strcmp(argv[1], "drbgstick")) {
1064             do_drbg_stick = 1;
1065             no_exit = 1;
1066             printf("DRBG test with stuck continuous test...\n");
1067         } else if (!strcmp(argv[1], "user")) {
1068                 pass = FIPS_AUTH_USER_PASS;
1069         } else if (!strcmp(argv[1], "officer")) {
1070                 pass = FIPS_AUTH_OFFICER_PASS;
1071         } else if (!strcmp(argv[1], "badpass")) {
1072                 pass = "bad invalid password";
1073         } else if (!strcmp(argv[1], "nopass")) {
1074                 pass = "";
1075         } else {
1076             printf("Bad argument \"%s\"\n", argv[1]);
1077             return 1;
1078         }
1079         if (!no_exit) {
1080                 fips_algtest_init_nofips();
1081                 if (!FIPS_module_mode_set(1, pass)) {
1082                     printf("Power-up self test failed\n");
1083                     return 1;
1084                 }
1085                 printf("Power-up self test successful\n");
1086                 return 0;
1087         }
1088     }
1089
1090     fips_algtest_init_nofips();
1091
1092     /* Non-Approved cryptographic operation
1093     */
1094     printf("1. Non-Approved cryptographic operation test...\n");
1095     if (no_dh)
1096         printf("\t D-H test skipped\n");
1097     else
1098         test_msg("\ta. Included algorithm (D-H)...", dh_test());
1099
1100     /* Power-up self test
1101     */
1102     ERR_clear_error();
1103     test_msg("2. Automatic power-up self test", FIPS_module_mode_set(1, pass));
1104     if (!FIPS_module_mode())
1105         return 1;
1106     if (do_drbg_stick)
1107             FIPS_drbg_stick();
1108     if (do_rng_stick)
1109             FIPS_x931_stick();
1110
1111     /* AES encryption/decryption
1112     */
1113     test_msg("3a. AES encryption/decryption", FIPS_aes_test());
1114     /* AES GCM encryption/decryption
1115     */
1116     test_msg("3b. AES-GCM encryption/decryption", FIPS_aes_gcm_test());
1117
1118     /* RSA key generation and encryption/decryption
1119     */
1120     test_msg("4. RSA key generation and encryption/decryption",
1121                                                 FIPS_rsa_test(bad_rsa));
1122
1123     /* DES-CBC encryption/decryption
1124     */
1125     test_msg("5. DES-ECB encryption/decryption", FIPS_des3_test());
1126
1127     /* DSA key generation and signature validation
1128     */
1129     test_msg("6. DSA key generation and signature validation",
1130                                                 FIPS_dsa_test(bad_dsa));
1131
1132     /* SHA-1 hash
1133     */
1134     test_msg("7a. SHA-1 hash", FIPS_sha1_test());
1135
1136     /* SHA-256 hash
1137     */
1138     test_msg("7b. SHA-256 hash", FIPS_sha256_test());
1139
1140     /* SHA-512 hash
1141     */
1142     test_msg("7c. SHA-512 hash", FIPS_sha512_test());
1143
1144     /* HMAC-SHA-1 hash
1145     */
1146     test_msg("7d. HMAC-SHA-1 hash", FIPS_hmac_sha1_test());
1147
1148     /* HMAC-SHA-224 hash
1149     */
1150     test_msg("7e. HMAC-SHA-224 hash", FIPS_hmac_sha224_test());
1151
1152     /* HMAC-SHA-256 hash
1153     */
1154     test_msg("7f. HMAC-SHA-256 hash", FIPS_hmac_sha256_test());
1155
1156     /* HMAC-SHA-384 hash
1157     */
1158     test_msg("7g. HMAC-SHA-384 hash", FIPS_hmac_sha384_test());
1159
1160     /* HMAC-SHA-512 hash
1161     */
1162     test_msg("7h. HMAC-SHA-512 hash", FIPS_hmac_sha512_test());
1163
1164     /* CMAC-AES-128 hash
1165     */
1166     test_msg("8a. CMAC-AES-128 hash", FIPS_cmac_aes128_test());
1167
1168     /* CMAC-AES-192 hash
1169     */
1170     test_msg("8b. CMAC-AES-192 hash", FIPS_cmac_aes192_test());
1171
1172     /* CMAC-AES-256 hash
1173     */
1174     test_msg("8c. CMAC-AES-256 hash", FIPS_cmac_aes256_test());
1175
1176 # if 0                          /* Not a FIPS algorithm */
1177     /* CMAC-TDEA-2 hash
1178     */
1179     test_msg("8d. CMAC-TDEA-2 hash", FIPS_cmac_tdea2_test());
1180 #endif
1181
1182     /* CMAC-TDEA-3 hash
1183     */
1184     test_msg("8e. CMAC-TDEA-3 hash", FIPS_cmac_tdea3_test());
1185
1186     /* Non-Approved cryptographic operation
1187     */
1188     printf("9. Non-Approved cryptographic operation test...\n");
1189     printf("\ta. Included algorithm (D-H)...%s\n",
1190                 no_dh ? "skipped" :
1191                 dh_test() ? "successful as expected"
1192                                                 : Fail("failed INCORRECTLY!") );
1193
1194     /* Zeroization
1195     */
1196     printf("10. Zero-ization...\n\t%s\n",
1197                 Zeroize() ? "successful as expected"
1198                                         : Fail("failed INCORRECTLY!") );
1199
1200     printf("11. Complete DRBG health check...\n");
1201     printf("\t%s\n", FIPS_selftest_drbg_all() ? "successful as expected"
1202                                         : Fail("failed INCORRECTLY!") );
1203
1204     printf("12. DRBG generation check...\n");
1205     printf("\t%s\n", do_drbg_all() ? "successful as expected"
1206                                         : Fail("failed INCORRECTLY!") );
1207
1208     printf("\nAll tests completed with %d errors\n", Error);
1209     return Error ? 1 : 0;
1210     }
1211
1212 #endif