fips_test_suite.c revision 296465
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#include <stdio.h>
15#include <assert.h>
16#include <ctype.h>
17#include <string.h>
18#include <stdlib.h>
19#include <openssl/aes.h>
20#include <openssl/des.h>
21#include <openssl/hmac.h>
22#include <openssl/err.h>
23
24#include <openssl/bn.h>
25#include <openssl/rand.h>
26#include <openssl/sha.h>
27
28#ifndef OPENSSL_FIPS
29int main(int argc, char *argv[])
30{
31    printf("No FIPS support\n");
32    return (0);
33}
34#else
35
36# include <openssl/rsa.h>
37# include <openssl/dsa.h>
38# include <openssl/dh.h>
39
40# include <openssl/fips.h>
41# include "fips_utl.h"
42
43/*
44 * AES: encrypt and decrypt known plaintext, verify result matches original
45 * plaintext
46 */
47static int FIPS_aes_test(void)
48{
49    int ret = 0;
50    unsigned char pltmp[16];
51    unsigned char citmp[16];
52    unsigned char key[16] =
53        { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
54    unsigned char plaintext[16] = "etaonrishdlcu";
55    EVP_CIPHER_CTX ctx;
56    EVP_CIPHER_CTX_init(&ctx);
57    if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, key, NULL, 1) <= 0)
58        goto err;
59    EVP_Cipher(&ctx, citmp, plaintext, 16);
60    if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, key, NULL, 0) <= 0)
61        goto err;
62    EVP_Cipher(&ctx, pltmp, citmp, 16);
63    if (memcmp(pltmp, plaintext, 16))
64        goto err;
65    ret = 1;
66 err:
67    EVP_CIPHER_CTX_cleanup(&ctx);
68    return ret;
69}
70
71static int FIPS_des3_test(void)
72{
73    int ret = 0;
74    unsigned char pltmp[8];
75    unsigned char citmp[8];
76    unsigned char key[] =
77        { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
78        19, 20, 21, 22, 23, 24
79    };
80    unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' };
81    EVP_CIPHER_CTX ctx;
82    EVP_CIPHER_CTX_init(&ctx);
83    if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(), NULL, key, NULL, 1) <= 0)
84        goto err;
85    EVP_Cipher(&ctx, citmp, plaintext, 8);
86    if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(), NULL, key, NULL, 0) <= 0)
87        goto err;
88    EVP_Cipher(&ctx, pltmp, citmp, 8);
89    if (memcmp(pltmp, plaintext, 8))
90        goto err;
91    ret = 1;
92 err:
93    EVP_CIPHER_CTX_cleanup(&ctx);
94    return ret;
95}
96
97/*
98 * DSA: generate keys and sign, verify input plaintext.
99 */
100static int FIPS_dsa_test(int bad)
101{
102    DSA *dsa = NULL;
103    EVP_PKEY pk;
104    unsigned char dgst[] = "etaonrishdlc";
105    unsigned char buf[60];
106    unsigned int slen;
107    int r = 0;
108    EVP_MD_CTX mctx;
109
110    ERR_clear_error();
111    EVP_MD_CTX_init(&mctx);
112    dsa = FIPS_dsa_new();
113    if (!dsa)
114        goto end;
115    if (!DSA_generate_parameters_ex(dsa, 1024, NULL, 0, NULL, NULL, NULL))
116        goto end;
117    if (!DSA_generate_key(dsa))
118        goto end;
119    if (bad)
120        BN_add_word(dsa->pub_key, 1);
121
122    pk.type = EVP_PKEY_DSA;
123    pk.pkey.dsa = dsa;
124
125    if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
126        goto end;
127    if (!EVP_SignUpdate(&mctx, dgst, sizeof(dgst) - 1))
128        goto end;
129    if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
130        goto end;
131
132    if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
133        goto end;
134    if (!EVP_VerifyUpdate(&mctx, dgst, sizeof(dgst) - 1))
135        goto end;
136    r = EVP_VerifyFinal(&mctx, buf, slen, &pk);
137 end:
138    EVP_MD_CTX_cleanup(&mctx);
139    if (dsa)
140        FIPS_dsa_free(dsa);
141    if (r != 1)
142        return 0;
143    return 1;
144}
145
146/*
147 * RSA: generate keys and sign, verify input plaintext.
148 */
149static int FIPS_rsa_test(int bad)
150{
151    RSA *key;
152    unsigned char input_ptext[] = "etaonrishdlc";
153    unsigned char buf[256];
154    unsigned int slen;
155    BIGNUM *bn;
156    EVP_MD_CTX mctx;
157    EVP_PKEY pk;
158    int r = 0;
159
160    ERR_clear_error();
161    EVP_MD_CTX_init(&mctx);
162    key = FIPS_rsa_new();
163    bn = BN_new();
164    if (!key || !bn)
165        return 0;
166    BN_set_word(bn, 65537);
167    if (!RSA_generate_key_ex(key, 1024, bn, NULL))
168        return 0;
169    BN_free(bn);
170    if (bad)
171        BN_add_word(key->n, 1);
172
173    pk.type = EVP_PKEY_RSA;
174    pk.pkey.rsa = key;
175
176    if (!EVP_SignInit_ex(&mctx, EVP_sha1(), NULL))
177        goto end;
178    if (!EVP_SignUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
179        goto end;
180    if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
181        goto end;
182
183    if (!EVP_VerifyInit_ex(&mctx, EVP_sha1(), NULL))
184        goto end;
185    if (!EVP_VerifyUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
186        goto end;
187    r = EVP_VerifyFinal(&mctx, buf, slen, &pk);
188 end:
189    EVP_MD_CTX_cleanup(&mctx);
190    if (key)
191        FIPS_rsa_free(key);
192    if (r != 1)
193        return 0;
194    return 1;
195}
196
197/*
198 * SHA1: generate hash of known digest value and compare to known precomputed
199 * correct hash
200 */
201static int FIPS_sha1_test()
202{
203    unsigned char digest[SHA_DIGEST_LENGTH] =
204        { 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a,
205        0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18
206    };
207    unsigned char str[] = "etaonrishd";
208
209    unsigned char md[SHA_DIGEST_LENGTH];
210
211    ERR_clear_error();
212    if (!EVP_Digest(str, sizeof(str) - 1, md, NULL, EVP_sha1(), NULL))
213        return 0;
214    if (memcmp(md, digest, sizeof(md)))
215        return 0;
216    return 1;
217}
218
219/*
220 * SHA256: generate hash of known digest value and compare to known
221 * precomputed correct hash
222 */
223static int FIPS_sha256_test()
224{
225    unsigned char digest[SHA256_DIGEST_LENGTH] =
226        { 0xf5, 0x53, 0xcd, 0xb8, 0xcf, 0x1, 0xee, 0x17, 0x9b, 0x93, 0xc9,
227        0x68, 0xc0, 0xea, 0x40, 0x91,
228        0x6, 0xec, 0x8e, 0x11, 0x96, 0xc8, 0x5d, 0x1c, 0xaf, 0x64, 0x22, 0xe6,
229        0x50, 0x4f, 0x47, 0x57
230    };
231    unsigned char str[] = "etaonrishd";
232
233    unsigned char md[SHA256_DIGEST_LENGTH];
234
235    ERR_clear_error();
236    if (!EVP_Digest(str, sizeof(str) - 1, md, NULL, EVP_sha256(), NULL))
237        return 0;
238    if (memcmp(md, digest, sizeof(md)))
239        return 0;
240    return 1;
241}
242
243/*
244 * SHA512: generate hash of known digest value and compare to known
245 * precomputed correct hash
246 */
247static int FIPS_sha512_test()
248{
249    unsigned char digest[SHA512_DIGEST_LENGTH] =
250        { 0x99, 0xc9, 0xe9, 0x5b, 0x88, 0xd4, 0x78, 0x88, 0xdf, 0x88, 0x5f,
251        0x94, 0x71, 0x64, 0x28, 0xca,
252        0x16, 0x1f, 0x3d, 0xf4, 0x1f, 0xf3, 0x0f, 0xc5, 0x03, 0x99, 0xb2,
253        0xd0, 0xe7, 0x0b, 0x94, 0x4a,
254        0x45, 0xd2, 0x6c, 0x4f, 0x20, 0x06, 0xef, 0x71, 0xa9, 0x25, 0x7f,
255        0x24, 0xb1, 0xd9, 0x40, 0x22,
256        0x49, 0x54, 0x10, 0xc2, 0x22, 0x9d, 0x27, 0xfe, 0xbd, 0xd6, 0xd6,
257        0xeb, 0x2d, 0x42, 0x1d, 0xa3
258    };
259    unsigned char str[] = "etaonrishd";
260
261    unsigned char md[SHA512_DIGEST_LENGTH];
262
263    ERR_clear_error();
264    if (!EVP_Digest(str, sizeof(str) - 1, md, NULL, EVP_sha512(), NULL))
265        return 0;
266    if (memcmp(md, digest, sizeof(md)))
267        return 0;
268    return 1;
269}
270
271/*
272 * HMAC-SHA1: generate hash of known digest value and compare to known
273 * precomputed correct hash
274 */
275static int FIPS_hmac_sha1_test()
276{
277    unsigned char key[] = "etaonrishd";
278    unsigned char iv[] = "Sample text";
279    unsigned char kaval[EVP_MAX_MD_SIZE] =
280        { 0x73, 0xf7, 0xa0, 0x48, 0xf8, 0x94, 0xed, 0xdd, 0x0a, 0xea, 0xea,
281        0x56, 0x1b, 0x61, 0x2e, 0x70,
282        0xb2, 0xfb, 0xec, 0xc6
283    };
284
285    unsigned char out[EVP_MAX_MD_SIZE];
286    unsigned int outlen;
287
288    ERR_clear_error();
289    if (!HMAC
290        (EVP_sha1(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out, &outlen))
291        return 0;
292    if (memcmp(out, kaval, outlen))
293        return 0;
294    return 1;
295}
296
297/*
298 * HMAC-SHA224: generate hash of known digest value and compare to known
299 * precomputed correct hash
300 */
301static int FIPS_hmac_sha224_test()
302{
303    unsigned char key[] = "etaonrishd";
304    unsigned char iv[] = "Sample text";
305    unsigned char kaval[EVP_MAX_MD_SIZE] =
306        { 0x75, 0x58, 0xd5, 0xbd, 0x55, 0x6d, 0x87, 0x0f, 0x75, 0xff, 0xbe,
307        0x1c, 0xb2, 0xf0, 0x20, 0x35,
308        0xe5, 0x62, 0x49, 0xb6, 0x94, 0xb9, 0xfc, 0x65, 0x34, 0x33, 0x3a, 0x19
309    };
310
311    unsigned char out[EVP_MAX_MD_SIZE];
312    unsigned int outlen;
313
314    ERR_clear_error();
315    if (!HMAC
316        (EVP_sha224(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out,
317         &outlen))
318        return 0;
319    if (memcmp(out, kaval, outlen))
320        return 0;
321    return 1;
322}
323
324/*
325 * HMAC-SHA256: generate hash of known digest value and compare to known
326 * precomputed correct hash
327 */
328static int FIPS_hmac_sha256_test()
329{
330    unsigned char key[] = "etaonrishd";
331    unsigned char iv[] = "Sample text";
332    unsigned char kaval[EVP_MAX_MD_SIZE] =
333        { 0xe9, 0x17, 0xc1, 0x7b, 0x4c, 0x6b, 0x77, 0xda, 0xd2, 0x30, 0x36,
334        0x02, 0xf5, 0x72, 0x33, 0x87,
335        0x9f, 0xc6, 0x6e, 0x7b, 0x7e, 0xa8, 0xea, 0xaa, 0x9f, 0xba, 0xee,
336        0x51, 0xff, 0xda, 0x24, 0xf4
337    };
338
339    unsigned char out[EVP_MAX_MD_SIZE];
340    unsigned int outlen;
341
342    ERR_clear_error();
343    if (!HMAC
344        (EVP_sha256(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out,
345         &outlen))
346        return 0;
347    if (memcmp(out, kaval, outlen))
348        return 0;
349    return 1;
350}
351
352/*
353 * HMAC-SHA384: generate hash of known digest value and compare to known
354 * precomputed correct hash
355 */
356static int FIPS_hmac_sha384_test()
357{
358    unsigned char key[] = "etaonrishd";
359    unsigned char iv[] = "Sample text";
360    unsigned char kaval[EVP_MAX_MD_SIZE] =
361        { 0xb2, 0x9d, 0x40, 0x58, 0x32, 0xc4, 0xe3, 0x31, 0xb6, 0x63, 0x08,
362        0x26, 0x99, 0xef, 0x3b, 0x10,
363        0xe2, 0xdf, 0xf8, 0xff, 0xc6, 0xe1, 0x03, 0x29, 0x81, 0x2a, 0x1b,
364        0xac, 0xb0, 0x07, 0x39, 0x08,
365        0xf3, 0x91, 0x35, 0x11, 0x76, 0xd6, 0x4c, 0x20, 0xfb, 0x4d, 0xc3,
366        0xf3, 0xb8, 0x9b, 0x88, 0x1c
367    };
368
369    unsigned char out[EVP_MAX_MD_SIZE];
370    unsigned int outlen;
371
372    ERR_clear_error();
373    if (!HMAC
374        (EVP_sha384(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out,
375         &outlen))
376        return 0;
377    if (memcmp(out, kaval, outlen))
378        return 0;
379    return 1;
380}
381
382/*
383 * HMAC-SHA512: generate hash of known digest value and compare to known
384 * precomputed correct hash
385 */
386static int FIPS_hmac_sha512_test()
387{
388    unsigned char key[] = "etaonrishd";
389    unsigned char iv[] = "Sample text";
390    unsigned char kaval[EVP_MAX_MD_SIZE] =
391        { 0xcd, 0x3e, 0xb9, 0x51, 0xb8, 0xbc, 0x7f, 0x9a, 0x23, 0xaf, 0xf3,
392        0x77, 0x59, 0x85, 0xa9, 0xe6,
393        0xf7, 0xd1, 0x51, 0x96, 0x17, 0xe0, 0x92, 0xd8, 0xa6, 0x3b, 0xc1,
394        0xad, 0x7e, 0x24, 0xca, 0xb1,
395        0xd7, 0x79, 0x0a, 0xa5, 0xea, 0x2c, 0x02, 0x58, 0x0b, 0xa6, 0x52,
396        0x6b, 0x61, 0x7f, 0xeb, 0x9c,
397        0x47, 0x86, 0x5d, 0x74, 0x2b, 0x88, 0xdf, 0xee, 0x46, 0x69, 0x96,
398        0x3d, 0xa6, 0xd9, 0x2a, 0x53
399    };
400
401    unsigned char out[EVP_MAX_MD_SIZE];
402    unsigned int outlen;
403
404    ERR_clear_error();
405    if (!HMAC
406        (EVP_sha512(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out,
407         &outlen))
408        return 0;
409    if (memcmp(out, kaval, outlen))
410        return 0;
411    return 1;
412}
413
414/*
415 * DH: generate shared parameters
416 */
417static int dh_test()
418{
419    DH *dh;
420    ERR_clear_error();
421    dh = FIPS_dh_new();
422    if (!dh)
423        return 0;
424    if (!DH_generate_parameters_ex(dh, 1024, 2, NULL))
425        return 0;
426    FIPS_dh_free(dh);
427    return 1;
428}
429
430/*
431 * Zeroize
432 */
433static int Zeroize()
434{
435    RSA *key;
436    BIGNUM *bn;
437    unsigned char userkey[16] =
438        { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f,
439        0x83, 0x02, 0xb1, 0x09, 0x68
440    };
441    size_t i;
442    int n;
443
444    key = FIPS_rsa_new();
445    bn = BN_new();
446    if (!key || !bn)
447        return 0;
448    BN_set_word(bn, 65537);
449    if (!RSA_generate_key_ex(key, 1024, bn, NULL))
450        return 0;
451    BN_free(bn);
452
453    n = BN_num_bytes(key->d);
454    printf(" Generated %d byte RSA private key\n", n);
455    printf("\tBN key before overwriting:\n");
456    do_bn_print(stdout, key->d);
457    BN_rand(key->d, n * 8, -1, 0);
458    printf("\tBN key after overwriting:\n");
459    do_bn_print(stdout, key->d);
460
461    printf("\tchar buffer key before overwriting: \n\t\t");
462    for (i = 0; i < sizeof(userkey); i++)
463        printf("%02x", userkey[i]);
464    printf("\n");
465    RAND_bytes(userkey, sizeof userkey);
466    printf("\tchar buffer key after overwriting: \n\t\t");
467    for (i = 0; i < sizeof(userkey); i++)
468        printf("%02x", userkey[i]);
469    printf("\n");
470
471    return 1;
472}
473
474static int Error;
475static const char *Fail(const char *msg)
476{
477    do_print_errors();
478    Error++;
479    return msg;
480}
481
482static void test_msg(const char *msg, int result)
483{
484    printf("%s...%s\n", msg, result ? "successful" : Fail("Failed!"));
485}
486
487int main(int argc, char **argv)
488{
489
490    int do_corrupt_rsa_keygen = 0, do_corrupt_dsa_keygen = 0;
491    int bad_rsa = 0, bad_dsa = 0;
492    int do_rng_stick = 0;
493    int no_exit = 0;
494
495    printf("\tFIPS-mode test application\n\n");
496
497    /* Load entropy from external file, if any */
498    RAND_load_file(".rnd", 1024);
499
500    if (argv[1]) {
501        /* Corrupted KAT tests */
502        if (!strcmp(argv[1], "aes")) {
503            FIPS_corrupt_aes();
504            printf("AES encryption/decryption with corrupted KAT...\n");
505        } else if (!strcmp(argv[1], "des")) {
506            FIPS_corrupt_des();
507            printf("DES3-ECB encryption/decryption with corrupted KAT...\n");
508        } else if (!strcmp(argv[1], "dsa")) {
509            FIPS_corrupt_dsa();
510            printf
511                ("DSA key generation and signature validation with corrupted KAT...\n");
512        } else if (!strcmp(argv[1], "rsa")) {
513            FIPS_corrupt_rsa();
514            printf
515                ("RSA key generation and signature validation with corrupted KAT...\n");
516        } else if (!strcmp(argv[1], "rsakey")) {
517            printf
518                ("RSA key generation and signature validation with corrupted key...\n");
519            bad_rsa = 1;
520            no_exit = 1;
521        } else if (!strcmp(argv[1], "rsakeygen")) {
522            do_corrupt_rsa_keygen = 1;
523            no_exit = 1;
524            printf
525                ("RSA key generation and signature validation with corrupted keygen...\n");
526        } else if (!strcmp(argv[1], "dsakey")) {
527            printf
528                ("DSA key generation and signature validation with corrupted key...\n");
529            bad_dsa = 1;
530            no_exit = 1;
531        } else if (!strcmp(argv[1], "dsakeygen")) {
532            do_corrupt_dsa_keygen = 1;
533            no_exit = 1;
534            printf
535                ("DSA key generation and signature validation with corrupted keygen...\n");
536        } else if (!strcmp(argv[1], "sha1")) {
537            FIPS_corrupt_sha1();
538            printf("SHA-1 hash with corrupted KAT...\n");
539        } else if (!strcmp(argv[1], "rng")) {
540            FIPS_corrupt_rng();
541        } else if (!strcmp(argv[1], "rngstick")) {
542            do_rng_stick = 1;
543            no_exit = 1;
544            printf("RNG test with stuck continuous test...\n");
545        } else {
546            printf("Bad argument \"%s\"\n", argv[1]);
547            exit(1);
548        }
549        if (!no_exit) {
550            if (!FIPS_mode_set(1)) {
551                do_print_errors();
552                printf("Power-up self test failed\n");
553                exit(1);
554            }
555            printf("Power-up self test successful\n");
556            exit(0);
557        }
558    }
559
560    /*
561     * Non-Approved cryptographic operation
562     */
563    printf("1. Non-Approved cryptographic operation test...\n");
564    test_msg("\ta. Included algorithm (D-H)...", dh_test());
565
566    /*
567     * Power-up self test
568     */
569    ERR_clear_error();
570    test_msg("2. Automatic power-up self test", FIPS_mode_set(1));
571    if (!FIPS_mode())
572        exit(1);
573    if (do_corrupt_dsa_keygen)
574        FIPS_corrupt_dsa_keygen();
575    if (do_corrupt_rsa_keygen)
576        FIPS_corrupt_rsa_keygen();
577    if (do_rng_stick)
578        FIPS_rng_stick();
579
580    /*
581     * AES encryption/decryption
582     */
583    test_msg("3. AES encryption/decryption", FIPS_aes_test());
584
585    /*
586     * RSA key generation and encryption/decryption
587     */
588    test_msg("4. RSA key generation and encryption/decryption",
589             FIPS_rsa_test(bad_rsa));
590
591    /*
592     * DES-CBC encryption/decryption
593     */
594    test_msg("5. DES-ECB encryption/decryption", FIPS_des3_test());
595
596    /*
597     * DSA key generation and signature validation
598     */
599    test_msg("6. DSA key generation and signature validation",
600             FIPS_dsa_test(bad_dsa));
601
602    /*
603     * SHA-1 hash
604     */
605    test_msg("7a. SHA-1 hash", FIPS_sha1_test());
606
607    /*
608     * SHA-256 hash
609     */
610    test_msg("7b. SHA-256 hash", FIPS_sha256_test());
611
612    /*
613     * SHA-512 hash
614     */
615    test_msg("7c. SHA-512 hash", FIPS_sha512_test());
616
617    /*
618     * HMAC-SHA-1 hash
619     */
620    test_msg("7d. HMAC-SHA-1 hash", FIPS_hmac_sha1_test());
621
622    /*
623     * HMAC-SHA-224 hash
624     */
625    test_msg("7e. HMAC-SHA-224 hash", FIPS_hmac_sha224_test());
626
627    /*
628     * HMAC-SHA-256 hash
629     */
630    test_msg("7f. HMAC-SHA-256 hash", FIPS_hmac_sha256_test());
631
632    /*
633     * HMAC-SHA-384 hash
634     */
635    test_msg("7g. HMAC-SHA-384 hash", FIPS_hmac_sha384_test());
636
637    /*
638     * HMAC-SHA-512 hash
639     */
640    test_msg("7h. HMAC-SHA-512 hash", FIPS_hmac_sha512_test());
641
642    /*
643     * Non-Approved cryptographic operation
644     */
645    printf("8. Non-Approved cryptographic operation test...\n");
646    printf("\ta. Included algorithm (D-H)...%s\n",
647           dh_test()? "successful as expected" : Fail("failed INCORRECTLY!"));
648
649    /*
650     * Zeroization
651     */
652    printf("9. Zero-ization...\n\t%s\n",
653           Zeroize()? "successful as expected" : Fail("failed INCORRECTLY!"));
654
655    printf("\nAll tests completed with %d errors\n", Error);
656    return Error ? 1 : 0;
657}
658
659#endif
660