• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2017 The BoringSSL Authors
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 /* test_fips exercises various cryptographic primitives for demonstration
16  * purposes in the validation process only. */
17 
18 #include <stdio.h>
19 
20 #include <openssl/aead.h>
21 #include <openssl/aes.h>
22 #include <openssl/bn.h>
23 #include <openssl/bytestring.h>
24 #include <openssl/crypto.h>
25 #include <openssl/ctrdrbg.h>
26 #include <openssl/des.h>
27 #include <openssl/dh.h>
28 #include <openssl/ec_key.h>
29 #include <openssl/ecdsa.h>
30 #include <openssl/err.h>
31 #include <openssl/hkdf.h>
32 #include <openssl/hmac.h>
33 #include <openssl/nid.h>
34 #include <openssl/rsa.h>
35 #include <openssl/sha.h>
36 
37 #include "../../crypto/fipsmodule/bcm_interface.h"
38 #include "../../crypto/fipsmodule/rand/internal.h"
39 #include "../../crypto/fipsmodule/tls/internal.h"
40 #include "../../crypto/internal.h"
41 
42 OPENSSL_MSVC_PRAGMA(warning(disable : 4295))
43 
44 #if defined(BORINGSSL_FIPS)
hexdump(const void * a,size_t len)45 static void hexdump(const void *a, size_t len) {
46   const unsigned char *in = (const unsigned char *)a;
47   for (size_t i = 0; i < len; i++) {
48     printf("%02x", in[i]);
49   }
50 
51   printf("\n");
52 }
53 #endif
54 
run_test()55 static int run_test() {
56   // Ensure that the output is line-buffered rather than fully buffered. When
57   // some of the tests fail, some of the output can otherwise be lost.
58   setvbuf(stdout, NULL, _IOLBF, 0);
59   setvbuf(stderr, NULL, _IOLBF, 0);
60 
61   if (!FIPS_mode()) {
62     printf("Module not in FIPS mode\n");
63     return 0;
64   }
65   printf("Module is in FIPS mode\n");
66 
67   const uint32_t module_version = FIPS_version();
68   if (module_version == 0) {
69     printf("No module version set\n");
70     // return 0;
71   }
72   printf("Module: '%s', version: %" PRIu32 " hash:\n", FIPS_module_name(),
73          module_version);
74 
75 #if !defined(BORINGSSL_FIPS)
76   // |module_version| will be zero, so the non-FIPS build will never get
77   // this far.
78   printf("Non zero module version in non-FIPS build - should not happen!\n");
79   return 0;
80 #else
81 #if defined(OPENSSL_ASAN)
82   printf("(not available when compiled for ASAN)");
83 #else
84   hexdump(FIPS_module_hash(), SHA256_DIGEST_LENGTH);
85 #endif
86 
87   static const uint8_t kAESKey[16] = "BoringCrypto Ky";
88   static const uint8_t kPlaintext[64] =
89       "BoringCryptoModule FIPS KAT Encryption and Decryption Plaintext";
90   static const DES_cblock kDESKey1 = {"BCMDES1"};
91   static const DES_cblock kDESKey2 = {"BCMDES2"};
92   static const DES_cblock kDESKey3 = {"BCMDES3"};
93   static const DES_cblock kDESIV = {"BCMDESI"};
94   static const uint8_t kPlaintextSHA256[32] = {
95       0x37, 0xbd, 0x70, 0x53, 0x72, 0xfc, 0xd4, 0x03, 0x79, 0x70, 0xfb,
96       0x06, 0x95, 0xb1, 0x2a, 0x82, 0x48, 0xe1, 0x3e, 0xf2, 0x33, 0xfb,
97       0xef, 0x29, 0x81, 0x22, 0x45, 0x40, 0x43, 0x70, 0xce, 0x0f};
98   const uint8_t kDRBGEntropy[48] =
99       "DBRG Initial Entropy                           ";
100   const uint8_t kDRBGPersonalization[19] = "BCMPersonalization";
101   const uint8_t kDRBGAD[16] = "BCM DRBG AD    ";
102   const uint8_t kDRBGEntropy2[48] =
103       "DBRG Reseed Entropy                            ";
104 
105   AES_KEY aes_key;
106   uint8_t aes_iv[16];
107   uint8_t output[256];
108 
109   /* AES-CBC Encryption */
110   memset(aes_iv, 0, sizeof(aes_iv));
111   if (AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) {
112     printf("AES_set_encrypt_key failed\n");
113     return 0;
114   }
115 
116   printf("About to AES-CBC encrypt ");
117   hexdump(kPlaintext, sizeof(kPlaintext));
118   AES_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &aes_key, aes_iv,
119                   AES_ENCRYPT);
120   printf("  got ");
121   hexdump(output, sizeof(kPlaintext));
122 
123   /* AES-CBC Decryption */
124   memset(aes_iv, 0, sizeof(aes_iv));
125   if (AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) {
126     printf("AES decrypt failed\n");
127     return 0;
128   }
129   printf("About to AES-CBC decrypt ");
130   hexdump(output, sizeof(kPlaintext));
131   AES_cbc_encrypt(output, output, sizeof(kPlaintext), &aes_key, aes_iv,
132                   AES_DECRYPT);
133   printf("  got ");
134   hexdump(output, sizeof(kPlaintext));
135 
136   size_t out_len;
137   uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
138   OPENSSL_memset(nonce, 0, sizeof(nonce));
139   EVP_AEAD_CTX aead_ctx;
140   if (!EVP_AEAD_CTX_init(&aead_ctx, EVP_aead_aes_128_gcm(), kAESKey,
141                          sizeof(kAESKey), 0, NULL)) {
142     printf("EVP_AEAD_CTX_init failed\n");
143     return 0;
144   }
145 
146   /* AES-GCM Encryption */
147   printf("About to AES-GCM seal ");
148   hexdump(output, sizeof(kPlaintext));
149   if (!EVP_AEAD_CTX_seal(&aead_ctx, output, &out_len, sizeof(output), nonce,
150                          EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()),
151                          kPlaintext, sizeof(kPlaintext), NULL, 0)) {
152     printf("AES-GCM encrypt failed\n");
153     return 0;
154   }
155   printf("  got ");
156   hexdump(output, out_len);
157 
158   /* AES-GCM Decryption */
159   printf("About to AES-GCM open ");
160   hexdump(output, out_len);
161   if (!EVP_AEAD_CTX_open(&aead_ctx, output, &out_len, sizeof(output), nonce,
162                          EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()), output,
163                          out_len, NULL, 0)) {
164     printf("AES-GCM decrypt failed\n");
165     return 0;
166   }
167   printf("  got ");
168   hexdump(output, out_len);
169 
170   EVP_AEAD_CTX_cleanup(&aead_ctx);
171 
172   DES_key_schedule des1, des2, des3;
173   DES_cblock des_iv;
174   DES_set_key(&kDESKey1, &des1);
175   DES_set_key(&kDESKey2, &des2);
176   DES_set_key(&kDESKey3, &des3);
177 
178   /* 3DES Encryption */
179   memcpy(&des_iv, &kDESIV, sizeof(des_iv));
180   printf("About to 3DES-CBC encrypt ");
181   hexdump(kPlaintext, sizeof(kPlaintext));
182   DES_ede3_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &des1, &des2,
183                        &des3, &des_iv, DES_ENCRYPT);
184   printf("  got ");
185   hexdump(output, sizeof(kPlaintext));
186 
187   /* 3DES Decryption */
188   memcpy(&des_iv, &kDESIV, sizeof(des_iv));
189   printf("About to 3DES-CBC decrypt ");
190   hexdump(kPlaintext, sizeof(kPlaintext));
191   DES_ede3_cbc_encrypt(output, output, sizeof(kPlaintext), &des1, &des2, &des3,
192                        &des_iv, DES_DECRYPT);
193   printf("  got ");
194   hexdump(output, sizeof(kPlaintext));
195 
196   /* SHA-1 */
197   printf("About to SHA-1 hash ");
198   hexdump(kPlaintext, sizeof(kPlaintext));
199   SHA1(kPlaintext, sizeof(kPlaintext), output);
200   printf("  got ");
201   hexdump(output, SHA_DIGEST_LENGTH);
202 
203   /* SHA-256 */
204   printf("About to SHA-256 hash ");
205   hexdump(kPlaintext, sizeof(kPlaintext));
206   SHA256(kPlaintext, sizeof(kPlaintext), output);
207   printf("  got ");
208   hexdump(output, SHA256_DIGEST_LENGTH);
209 
210   /* SHA-512 */
211   printf("About to SHA-512 hash ");
212   hexdump(kPlaintext, sizeof(kPlaintext));
213   SHA512(kPlaintext, sizeof(kPlaintext), output);
214   printf("  got ");
215   hexdump(output, SHA512_DIGEST_LENGTH);
216 
217   RSA *rsa_key = RSA_new();
218   printf("About to generate RSA key\n");
219   if (!RSA_generate_key_fips(rsa_key, 2048, NULL)) {
220     printf("RSA_generate_key_fips failed\n");
221     return 0;
222   }
223 
224   /* RSA Sign */
225   unsigned sig_len;
226   printf("About to RSA sign ");
227   hexdump(kPlaintextSHA256, sizeof(kPlaintextSHA256));
228   if (!RSA_sign(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256), output,
229                 &sig_len, rsa_key)) {
230     printf("RSA Sign failed\n");
231     return 0;
232   }
233   printf("  got ");
234   hexdump(output, sig_len);
235 
236   /* RSA Verify */
237   printf("About to RSA verify ");
238   hexdump(output, sig_len);
239   if (!RSA_verify(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256),
240                   output, sig_len, rsa_key)) {
241     printf("RSA Verify failed.\n");
242     return 0;
243   }
244 
245   RSA_free(rsa_key);
246 
247   /* Generating a key with a null output parameter. */
248   printf("About to generate RSA key with null output\n");
249   if (!RSA_generate_key_fips(NULL, 2048, NULL)) {
250     printf("RSA_generate_key_fips failed with null output parameter\n");
251     ERR_clear_error();
252   } else {
253     printf(
254         "RSA_generate_key_fips unexpectedly succeeded with null output "
255         "parameter\n");
256     return 0;
257   }
258 
259   EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
260   if (ec_key == NULL) {
261     printf("invalid ECDSA key\n");
262     return 0;
263   }
264 
265   printf("About to generate P-256 key\n");
266   if (!EC_KEY_generate_key_fips(ec_key)) {
267     printf("EC_KEY_generate_key_fips failed\n");
268     return 0;
269   }
270 
271   /* Primitive Z Computation */
272   const EC_GROUP *const ec_group = EC_KEY_get0_group(ec_key);
273   EC_POINT *z_point = EC_POINT_new(ec_group);
274   uint8_t z_result[65];
275   printf("About to compute key-agreement Z with P-256:\n");
276   if (!EC_POINT_mul(ec_group, z_point, NULL, EC_KEY_get0_public_key(ec_key),
277                     EC_KEY_get0_private_key(ec_key), NULL) ||
278       EC_POINT_point2oct(ec_group, z_point, POINT_CONVERSION_UNCOMPRESSED,
279                          z_result, sizeof(z_result),
280                          NULL) != sizeof(z_result)) {
281     fprintf(stderr, "EC_POINT_mul failed.\n");
282     return 0;
283   }
284   EC_POINT_free(z_point);
285 
286   printf("  got ");
287   hexdump(z_result, sizeof(z_result));
288 
289   /* ECDSA Sign/Verify PWCT */
290   printf("About to ECDSA sign ");
291   hexdump(kPlaintextSHA256, sizeof(kPlaintextSHA256));
292   ECDSA_SIG *sig =
293       ECDSA_do_sign(kPlaintextSHA256, sizeof(kPlaintextSHA256), ec_key);
294   if (sig == NULL || !ECDSA_do_verify(kPlaintextSHA256,
295                                       sizeof(kPlaintextSHA256), sig, ec_key)) {
296     printf("ECDSA Sign/Verify PWCT failed.\n");
297     return 0;
298   }
299 
300   ECDSA_SIG_free(sig);
301   EC_KEY_free(ec_key);
302 
303   /* Generating a key with a null output pointer. */
304   printf("About to generate P-256 key with NULL output\n");
305   if (!EC_KEY_generate_key_fips(NULL)) {
306     printf("EC_KEY_generate_key_fips failed with a NULL output pointer.\n");
307     ERR_clear_error();
308   } else {
309     printf(
310         "EC_KEY_generate_key_fips unexpectedly succeeded with a NULL output "
311         "pointer.\n");
312     return 0;
313   }
314 
315   /* ECDSA with an invalid public key. */
316   ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
317   static const uint8_t kNotValidX926[] = {1, 2, 3, 4, 5, 6};
318   if (!EC_KEY_oct2key(ec_key, kNotValidX926, sizeof(kNotValidX926),
319                       /*ctx=*/NULL)) {
320     printf("Error while parsing invalid ECDSA public key\n");
321   } else {
322     printf("Unexpected success while parsing invalid ECDSA public key\n");
323     return 0;
324   }
325   EC_KEY_free(ec_key);
326 
327   /* DBRG */
328   CTR_DRBG_STATE drbg;
329   printf("About to seed CTR-DRBG with ");
330   hexdump(kDRBGEntropy, sizeof(kDRBGEntropy));
331   if (!CTR_DRBG_init(&drbg, kDRBGEntropy, kDRBGPersonalization,
332                      sizeof(kDRBGPersonalization)) ||
333       !CTR_DRBG_generate(&drbg, output, sizeof(output), kDRBGAD,
334                          sizeof(kDRBGAD)) ||
335       !CTR_DRBG_reseed(&drbg, kDRBGEntropy2, kDRBGAD, sizeof(kDRBGAD)) ||
336       !CTR_DRBG_generate(&drbg, output, sizeof(output), kDRBGAD,
337                          sizeof(kDRBGAD))) {
338     printf("DRBG failed\n");
339     return 0;
340   }
341   printf("  generated ");
342   hexdump(output, sizeof(output));
343   CTR_DRBG_clear(&drbg);
344 
345   /* HKDF */
346   printf("About to run HKDF\n");
347   uint8_t hkdf_output[32];
348   if (!HKDF(hkdf_output, sizeof(hkdf_output), EVP_sha256(), kAESKey,
349             sizeof(kAESKey), (const uint8_t *)"salt", 4, kPlaintextSHA256,
350             sizeof(kPlaintextSHA256))) {
351     fprintf(stderr, "HKDF failed.\n");
352     return 0;
353   }
354   printf("  got ");
355   hexdump(hkdf_output, sizeof(hkdf_output));
356 
357   /* TLS v1.0 KDF */
358   printf("About to run TLS v1.0 KDF\n");
359   uint8_t tls10_output[32];
360   if (!CRYPTO_tls1_prf(EVP_md5_sha1(), tls10_output, sizeof(tls10_output),
361                        kAESKey, sizeof(kAESKey), "foo", 3, kPlaintextSHA256,
362                        sizeof(kPlaintextSHA256), kPlaintextSHA256,
363                        sizeof(kPlaintextSHA256))) {
364     fprintf(stderr, "TLS v1.0 KDF failed.\n");
365     return 0;
366   }
367   printf("  got ");
368   hexdump(tls10_output, sizeof(tls10_output));
369 
370   /* TLS v1.2 KDF */
371   printf("About to run TLS v1.2 KDF\n");
372   uint8_t tls12_output[32];
373   if (!CRYPTO_tls1_prf(EVP_sha256(), tls12_output, sizeof(tls12_output),
374                        kAESKey, sizeof(kAESKey), "foo", 3, kPlaintextSHA256,
375                        sizeof(kPlaintextSHA256), kPlaintextSHA256,
376                        sizeof(kPlaintextSHA256))) {
377     fprintf(stderr, "TLS v1.2 KDF failed.\n");
378     return 0;
379   }
380   printf("  got ");
381   hexdump(tls12_output, sizeof(tls12_output));
382 
383   /* TLS v1.3 KDF */
384   printf("About to run TLS v1.3 KDF\n");
385   uint8_t tls13_output[32];
386   if (!CRYPTO_tls13_hkdf_expand_label(
387           tls13_output, sizeof(tls13_output), EVP_sha256(), kAESKey,
388           sizeof(kAESKey), (const uint8_t *)"foo", 3, kPlaintextSHA256,
389           sizeof(kPlaintextSHA256))) {
390     fprintf(stderr, "TLS v1.3 KDF failed.\n");
391     return 0;
392   }
393   printf("  got ");
394   hexdump(tls13_output, sizeof(tls13_output));
395 
396   /* FFDH */
397   printf("About to compute FFDH key-agreement:\n");
398   DH *dh = DH_get_rfc7919_2048();
399   uint8_t dh_result[2048 / 8];
400   if (!dh || !DH_generate_key(dh) || sizeof(dh_result) != DH_size(dh) ||
401       DH_compute_key_padded(dh_result, DH_get0_pub_key(dh), dh) !=
402           sizeof(dh_result)) {
403     fprintf(stderr, "FFDH failed.\n");
404     return 0;
405   }
406   DH_free(dh);
407 
408   printf("  got ");
409   hexdump(dh_result, sizeof(dh_result));
410 
411   /* ML-KEM */
412   printf("About to generate ML-KEM key:\n");
413   auto mlkem_public_key_bytes =
414       std::make_unique<uint8_t[]>(BCM_MLKEM768_PUBLIC_KEY_BYTES);
415   auto mlkem_private_key = std::make_unique<BCM_mlkem768_private_key>();
416   if (BCM_mlkem768_generate_key_fips(mlkem_public_key_bytes.get(), nullptr,
417                                      mlkem_private_key.get()) !=
418       bcm_status::approved) {
419     fprintf(stderr, "ML-KEM generation failed");
420     return 0;
421   }
422   printf("  got ");
423   hexdump(mlkem_public_key_bytes.get(), BCM_MLKEM768_PUBLIC_KEY_BYTES);
424 
425   printf("About to do ML-KEM encap:\n");
426   auto mlkem_ciphertext =
427       std::make_unique<uint8_t[]>(BCM_MLKEM768_CIPHERTEXT_BYTES);
428   uint8_t mlkem_shared_secret[BCM_MLKEM_SHARED_SECRET_BYTES];
429   auto mlkem_public_key = std::make_unique<BCM_mlkem768_public_key>();
430   BCM_mlkem768_public_from_private(mlkem_public_key.get(),
431                                    mlkem_private_key.get());
432   if (BCM_mlkem768_encap(mlkem_ciphertext.get(), mlkem_shared_secret,
433                          mlkem_public_key.get()) != bcm_infallible::approved) {
434     fprintf(stderr, "ML-KEM encap failed");
435     return 0;
436   }
437   printf("  got ");
438   hexdump(mlkem_shared_secret, sizeof(mlkem_shared_secret));
439 
440   printf("About to do ML-KEM decap:\n");
441   if (BCM_mlkem768_decap(mlkem_shared_secret, mlkem_ciphertext.get(),
442                          BCM_MLKEM768_CIPHERTEXT_BYTES,
443                          mlkem_private_key.get()) != bcm_status::approved) {
444     fprintf(stderr, "ML-KEM decap failed");
445     return 0;
446   }
447   printf("  got ");
448   hexdump(mlkem_shared_secret, sizeof(mlkem_shared_secret));
449 
450   /* ML-DSA */
451   printf("About to generate ML-DSA key:\n");
452   auto mldsa_public_key_bytes =
453       std::make_unique<uint8_t[]>(BCM_MLDSA65_PUBLIC_KEY_BYTES);
454   uint8_t mldsa_seed[BCM_MLDSA_SEED_BYTES];
455   auto mldsa_priv = std::make_unique<BCM_mldsa65_private_key>();
456   if (BCM_mldsa65_generate_key_fips(mldsa_public_key_bytes.get(), mldsa_seed,
457                                     mldsa_priv.get()) != bcm_status::approved) {
458     fprintf(stderr, "ML-DSA keygen failed");
459     return 0;
460   }
461   printf("  got ");
462   hexdump(mldsa_public_key_bytes.get(), BCM_MLDSA65_PUBLIC_KEY_BYTES);
463 
464   printf("About to ML-DSA sign:\n");
465   auto mldsa_sig = std::make_unique<uint8_t[]>(BCM_MLDSA65_SIGNATURE_BYTES);
466   if (BCM_mldsa65_sign(mldsa_sig.get(), mldsa_priv.get(), nullptr, 0, nullptr,
467                        0) != bcm_status::approved) {
468     fprintf(stderr, "ML-DSA sign failed");
469     return 0;
470   }
471   printf("  got ");
472   hexdump(mldsa_sig.get(), BCM_MLDSA65_SIGNATURE_BYTES);
473 
474   printf("About to ML-DSA verify:\n");
475   auto mldsa_pub = std::make_unique<BCM_mldsa65_public_key>();
476   if (BCM_mldsa65_public_from_private(mldsa_pub.get(), mldsa_priv.get()) !=
477           bcm_status::approved ||
478       BCM_mldsa65_verify(mldsa_pub.get(), mldsa_sig.get(), nullptr, 0, nullptr,
479                          0) != bcm_status::approved) {
480     fprintf(stderr, "ML-DSA verify failed");
481     return 0;
482   }
483 
484   /* SLH-DSA */
485   printf("About to generate SLH-DSA key:\n");
486   uint8_t slhdsa_seed[3 * BCM_SLHDSA_SHA2_128S_N] = {0};
487   uint8_t slhdsa_pub[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES];
488   uint8_t slhdsa_priv[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES];
489   BCM_slhdsa_sha2_128s_generate_key_from_seed(slhdsa_pub, slhdsa_priv,
490                                               slhdsa_seed);
491   printf("  got ");
492   hexdump(slhdsa_pub, sizeof(slhdsa_pub));
493 
494   printf("About to SLH-DSA sign:\n");
495   auto slhdsa_sig =
496       std::make_unique<uint8_t[]>(BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES);
497   if (BCM_slhdsa_sha2_128s_sign(slhdsa_sig.get(), slhdsa_priv, nullptr, 0,
498                                 nullptr, 0) != bcm_status::approved) {
499     fprintf(stderr, "SLH-DSA sign failed");
500     return 0;
501   }
502   printf("  got ");
503   hexdump(slhdsa_sig.get(), 128);  // value too long to fully print
504 
505   printf("About to SLH-DSA verify:\n");
506   if (BCM_slhdsa_sha2_128s_verify(
507           slhdsa_sig.get(), BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES, slhdsa_pub,
508           nullptr, 0, nullptr, 0) != bcm_status::approved) {
509     fprintf(stderr, "SLH-DSA verify failed");
510     return 0;
511   }
512 
513   printf("PASS\n");
514   return 1;
515 #endif  // !defined(BORINGSSL_FIPS)
516 }
517 
main(int argc,char ** argv)518 int main(int argc, char **argv) {
519   if (!run_test()) {
520     printf("FAIL\n");
521     fflush(stdout);
522     abort();
523   }
524   return 0;
525 }
526