xref: /aosp_15_r20/external/boringssl/src/util/fipstools/test_fips.c (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1 /* Copyright (c) 2017, Google Inc.
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/crypto.h>
24 #include <openssl/ctrdrbg.h>
25 #include <openssl/des.h>
26 #include <openssl/dh.h>
27 #include <openssl/ec_key.h>
28 #include <openssl/ecdsa.h>
29 #include <openssl/err.h>
30 #include <openssl/hkdf.h>
31 #include <openssl/hmac.h>
32 #include <openssl/nid.h>
33 #include <openssl/rsa.h>
34 #include <openssl/sha.h>
35 
36 #include "../../crypto/fipsmodule/rand/internal.h"
37 #include "../../crypto/fipsmodule/tls/internal.h"
38 #include "../../crypto/internal.h"
39 
40 OPENSSL_MSVC_PRAGMA(warning(disable : 4295))
41 
42 #if defined(BORINGSSL_FIPS)
hexdump(const void * a,size_t len)43 static void hexdump(const void *a, size_t len) {
44   const unsigned char *in = (const unsigned char *)a;
45   for (size_t i = 0; i < len; i++) {
46     printf("%02x", in[i]);
47   }
48 
49   printf("\n");
50 }
51 #endif
52 
main(int argc,char ** argv)53 int main(int argc, char **argv) {
54   // Ensure that the output is line-buffered rather than fully buffered. When
55   // some of the tests fail, some of the output can otherwise be lost.
56   setvbuf(stdout, NULL, _IOLBF, 0);
57   setvbuf(stderr, NULL, _IOLBF, 0);
58 
59   if (!FIPS_mode()) {
60     printf("Module not in FIPS mode\n");
61     goto err;
62   }
63   printf("Module is in FIPS mode\n");
64 
65   const uint32_t module_version = FIPS_version();
66   if (module_version == 0) {
67     printf("No module version set\n");
68     goto err;
69   }
70   printf("Module: '%s', version: %" PRIu32 " hash:\n", FIPS_module_name(),
71          module_version);
72 
73 #if !defined(BORINGSSL_FIPS)
74   // |module_version| will be zero, so the non-FIPS build will never get
75   // this far.
76   printf("Non zero module version in non-FIPS build - should not happen!\n");
77   goto err;
78 #else
79 #if defined(OPENSSL_ASAN)
80   printf("(not available when compiled for ASAN)");
81 #else
82   hexdump(FIPS_module_hash(), SHA256_DIGEST_LENGTH);
83 #endif
84 
85   static const uint8_t kAESKey[16] = "BoringCrypto Key";
86   static const uint8_t kPlaintext[64] =
87       "BoringCryptoModule FIPS KAT Encryption and Decryption Plaintext!";
88   static const DES_cblock kDESKey1 = {"BCMDESK1"};
89   static const DES_cblock kDESKey2 = {"BCMDESK2"};
90   static const DES_cblock kDESKey3 = {"BCMDESK3"};
91   static const DES_cblock kDESIV = {"BCMDESIV"};
92   static const uint8_t kPlaintextSHA256[32] = {
93       0x37, 0xbd, 0x70, 0x53, 0x72, 0xfc, 0xd4, 0x03, 0x79, 0x70, 0xfb,
94       0x06, 0x95, 0xb1, 0x2a, 0x82, 0x48, 0xe1, 0x3e, 0xf2, 0x33, 0xfb,
95       0xef, 0x29, 0x81, 0x22, 0x45, 0x40, 0x43, 0x70, 0xce, 0x0f};
96   const uint8_t kDRBGEntropy[48] =
97       "DBRG Initial Entropy                            ";
98   const uint8_t kDRBGPersonalization[18] = "BCMPersonalization";
99   const uint8_t kDRBGAD[16] = "BCM DRBG AD     ";
100   const uint8_t kDRBGEntropy2[48] =
101       "DBRG Reseed Entropy                             ";
102 
103   AES_KEY aes_key;
104   uint8_t aes_iv[16];
105   uint8_t output[256];
106 
107   /* AES-CBC Encryption */
108   memset(aes_iv, 0, sizeof(aes_iv));
109   if (AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) {
110     printf("AES_set_encrypt_key failed\n");
111     goto err;
112   }
113 
114   printf("About to AES-CBC encrypt ");
115   hexdump(kPlaintext, sizeof(kPlaintext));
116   AES_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &aes_key, aes_iv,
117                   AES_ENCRYPT);
118   printf("  got ");
119   hexdump(output, sizeof(kPlaintext));
120 
121   /* AES-CBC Decryption */
122   memset(aes_iv, 0, sizeof(aes_iv));
123   if (AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) {
124     printf("AES decrypt failed\n");
125     goto err;
126   }
127   printf("About to AES-CBC decrypt ");
128   hexdump(output, sizeof(kPlaintext));
129   AES_cbc_encrypt(output, output, sizeof(kPlaintext), &aes_key, aes_iv,
130                   AES_DECRYPT);
131   printf("  got ");
132   hexdump(output, sizeof(kPlaintext));
133 
134   size_t out_len;
135   uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
136   OPENSSL_memset(nonce, 0, sizeof(nonce));
137   EVP_AEAD_CTX aead_ctx;
138   if (!EVP_AEAD_CTX_init(&aead_ctx, EVP_aead_aes_128_gcm(), kAESKey,
139                          sizeof(kAESKey), 0, NULL)) {
140     printf("EVP_AEAD_CTX_init failed\n");
141     goto err;
142   }
143 
144   /* AES-GCM Encryption */
145   printf("About to AES-GCM seal ");
146   hexdump(output, sizeof(kPlaintext));
147   if (!EVP_AEAD_CTX_seal(&aead_ctx, output, &out_len, sizeof(output), nonce,
148                          EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()),
149                          kPlaintext, sizeof(kPlaintext), NULL, 0)) {
150     printf("AES-GCM encrypt failed\n");
151     goto err;
152   }
153   printf("  got ");
154   hexdump(output, out_len);
155 
156   /* AES-GCM Decryption */
157   printf("About to AES-GCM open ");
158   hexdump(output, out_len);
159   if (!EVP_AEAD_CTX_open(&aead_ctx, output, &out_len, sizeof(output), nonce,
160                          EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()), output,
161                          out_len, NULL, 0)) {
162     printf("AES-GCM decrypt failed\n");
163     goto err;
164   }
165   printf("  got ");
166   hexdump(output, out_len);
167 
168   EVP_AEAD_CTX_cleanup(&aead_ctx);
169 
170   DES_key_schedule des1, des2, des3;
171   DES_cblock des_iv;
172   DES_set_key(&kDESKey1, &des1);
173   DES_set_key(&kDESKey2, &des2);
174   DES_set_key(&kDESKey3, &des3);
175 
176   /* 3DES Encryption */
177   memcpy(&des_iv, &kDESIV, sizeof(des_iv));
178   printf("About to 3DES-CBC encrypt ");
179   hexdump(kPlaintext, sizeof(kPlaintext));
180   DES_ede3_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &des1, &des2,
181                        &des3, &des_iv, DES_ENCRYPT);
182   printf("  got ");
183   hexdump(output, sizeof(kPlaintext));
184 
185   /* 3DES Decryption */
186   memcpy(&des_iv, &kDESIV, sizeof(des_iv));
187   printf("About to 3DES-CBC decrypt ");
188   hexdump(kPlaintext, sizeof(kPlaintext));
189   DES_ede3_cbc_encrypt(output, output, sizeof(kPlaintext), &des1, &des2, &des3,
190                        &des_iv, DES_DECRYPT);
191   printf("  got ");
192   hexdump(output, sizeof(kPlaintext));
193 
194   /* SHA-1 */
195   printf("About to SHA-1 hash ");
196   hexdump(kPlaintext, sizeof(kPlaintext));
197   SHA1(kPlaintext, sizeof(kPlaintext), output);
198   printf("  got ");
199   hexdump(output, SHA_DIGEST_LENGTH);
200 
201   /* SHA-256 */
202   printf("About to SHA-256 hash ");
203   hexdump(kPlaintext, sizeof(kPlaintext));
204   SHA256(kPlaintext, sizeof(kPlaintext), output);
205   printf("  got ");
206   hexdump(output, SHA256_DIGEST_LENGTH);
207 
208   /* SHA-512 */
209   printf("About to SHA-512 hash ");
210   hexdump(kPlaintext, sizeof(kPlaintext));
211   SHA512(kPlaintext, sizeof(kPlaintext), output);
212   printf("  got ");
213   hexdump(output, SHA512_DIGEST_LENGTH);
214 
215   RSA *rsa_key = RSA_new();
216   printf("About to generate RSA key\n");
217   if (!RSA_generate_key_fips(rsa_key, 2048, NULL)) {
218     printf("RSA_generate_key_fips failed\n");
219     goto err;
220   }
221 
222   /* RSA Sign */
223   unsigned sig_len;
224   printf("About to RSA sign ");
225   hexdump(kPlaintextSHA256, sizeof(kPlaintextSHA256));
226   if (!RSA_sign(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256), output,
227                 &sig_len, rsa_key)) {
228     printf("RSA Sign failed\n");
229     goto err;
230   }
231   printf("  got ");
232   hexdump(output, sig_len);
233 
234   /* RSA Verify */
235   printf("About to RSA verify ");
236   hexdump(output, sig_len);
237   if (!RSA_verify(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256),
238                   output, sig_len, rsa_key)) {
239     printf("RSA Verify failed.\n");
240     goto err;
241   }
242 
243   RSA_free(rsa_key);
244 
245   /* Generating a key with a null output parameter. */
246   printf("About to generate RSA key with null output\n");
247   if (!RSA_generate_key_fips(NULL, 2048, NULL)) {
248     printf("RSA_generate_key_fips failed with null output parameter\n");
249     ERR_clear_error();
250   } else {
251     printf(
252         "RSA_generate_key_fips unexpectedly succeeded with null output "
253         "parameter\n");
254     goto err;
255   }
256 
257   EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
258   if (ec_key == NULL) {
259     printf("invalid ECDSA key\n");
260     goto err;
261   }
262 
263   printf("About to generate P-256 key\n");
264   if (!EC_KEY_generate_key_fips(ec_key)) {
265     printf("EC_KEY_generate_key_fips failed\n");
266     goto err;
267   }
268 
269   /* Primitive Z Computation */
270   const EC_GROUP *const ec_group = EC_KEY_get0_group(ec_key);
271   EC_POINT *z_point = EC_POINT_new(ec_group);
272   uint8_t z_result[65];
273   printf("About to compute key-agreement Z with P-256:\n");
274   if (!EC_POINT_mul(ec_group, z_point, NULL, EC_KEY_get0_public_key(ec_key),
275                     EC_KEY_get0_private_key(ec_key), NULL) ||
276       EC_POINT_point2oct(ec_group, z_point, POINT_CONVERSION_UNCOMPRESSED,
277                          z_result, sizeof(z_result),
278                          NULL) != sizeof(z_result)) {
279     fprintf(stderr, "EC_POINT_mul failed.\n");
280     goto err;
281   }
282   EC_POINT_free(z_point);
283 
284   printf("  got ");
285   hexdump(z_result, sizeof(z_result));
286 
287   /* ECDSA Sign/Verify PWCT */
288   printf("About to ECDSA sign ");
289   hexdump(kPlaintextSHA256, sizeof(kPlaintextSHA256));
290   ECDSA_SIG *sig =
291       ECDSA_do_sign(kPlaintextSHA256, sizeof(kPlaintextSHA256), ec_key);
292   if (sig == NULL || !ECDSA_do_verify(kPlaintextSHA256,
293                                       sizeof(kPlaintextSHA256), sig, ec_key)) {
294     printf("ECDSA Sign/Verify PWCT failed.\n");
295     goto err;
296   }
297 
298   ECDSA_SIG_free(sig);
299   EC_KEY_free(ec_key);
300 
301   /* Generating a key with a null output pointer. */
302   printf("About to generate P-256 key with NULL output\n");
303   if (!EC_KEY_generate_key_fips(NULL)) {
304     printf("EC_KEY_generate_key_fips failed with a NULL output pointer.\n");
305     ERR_clear_error();
306   } else {
307     printf(
308         "EC_KEY_generate_key_fips unexpectedly succeeded with a NULL output "
309         "pointer.\n");
310     goto err;
311   }
312 
313   /* ECDSA with an invalid public key. */
314   ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
315   static const uint8_t kNotValidX926[] = {1, 2, 3, 4, 5, 6};
316   if (!EC_KEY_oct2key(ec_key, kNotValidX926, sizeof(kNotValidX926),
317                       /*ctx=*/NULL)) {
318     printf("Error while parsing invalid ECDSA public key\n");
319   } else {
320     printf("Unexpected success while parsing invalid ECDSA public key\n");
321     goto err;
322   }
323   EC_KEY_free(ec_key);
324 
325   /* DBRG */
326   CTR_DRBG_STATE drbg;
327   printf("About to seed CTR-DRBG with ");
328   hexdump(kDRBGEntropy, sizeof(kDRBGEntropy));
329   if (!CTR_DRBG_init(&drbg, kDRBGEntropy, kDRBGPersonalization,
330                      sizeof(kDRBGPersonalization)) ||
331       !CTR_DRBG_generate(&drbg, output, sizeof(output), kDRBGAD,
332                          sizeof(kDRBGAD)) ||
333       !CTR_DRBG_reseed(&drbg, kDRBGEntropy2, kDRBGAD, sizeof(kDRBGAD)) ||
334       !CTR_DRBG_generate(&drbg, output, sizeof(output), kDRBGAD,
335                          sizeof(kDRBGAD))) {
336     printf("DRBG failed\n");
337     goto err;
338   }
339   printf("  generated ");
340   hexdump(output, sizeof(output));
341   CTR_DRBG_clear(&drbg);
342 
343   /* HKDF */
344   printf("About to run HKDF\n");
345   uint8_t hkdf_output[32];
346   if (!HKDF(hkdf_output, sizeof(hkdf_output), EVP_sha256(), kAESKey,
347             sizeof(kAESKey), (const uint8_t *)"salt", 4, kPlaintextSHA256,
348             sizeof(kPlaintextSHA256))) {
349     fprintf(stderr, "HKDF failed.\n");
350     goto err;
351   }
352   printf("  got ");
353   hexdump(hkdf_output, sizeof(hkdf_output));
354 
355   /* TLS v1.0 KDF */
356   printf("About to run TLS v1.0 KDF\n");
357   uint8_t tls10_output[32];
358   if (!CRYPTO_tls1_prf(EVP_md5_sha1(), tls10_output, sizeof(tls10_output),
359                        kAESKey, sizeof(kAESKey), "foo", 3, kPlaintextSHA256,
360                        sizeof(kPlaintextSHA256), kPlaintextSHA256,
361                        sizeof(kPlaintextSHA256))) {
362     fprintf(stderr, "TLS v1.0 KDF failed.\n");
363     goto err;
364   }
365   printf("  got ");
366   hexdump(tls10_output, sizeof(tls10_output));
367 
368   /* TLS v1.2 KDF */
369   printf("About to run TLS v1.2 KDF\n");
370   uint8_t tls12_output[32];
371   if (!CRYPTO_tls1_prf(EVP_sha256(), tls12_output, sizeof(tls12_output),
372                        kAESKey, sizeof(kAESKey), "foo", 3, kPlaintextSHA256,
373                        sizeof(kPlaintextSHA256), kPlaintextSHA256,
374                        sizeof(kPlaintextSHA256))) {
375     fprintf(stderr, "TLS v1.2 KDF failed.\n");
376     goto err;
377   }
378   printf("  got ");
379   hexdump(tls12_output, sizeof(tls12_output));
380 
381   /* TLS v1.3 KDF */
382   printf("About to run TLS v1.3 KDF\n");
383   uint8_t tls13_output[32];
384   if (!CRYPTO_tls13_hkdf_expand_label(
385           tls13_output, sizeof(tls13_output), EVP_sha256(), kAESKey,
386           sizeof(kAESKey), (const uint8_t *)"foo", 3, kPlaintextSHA256,
387           sizeof(kPlaintextSHA256))) {
388     fprintf(stderr, "TLS v1.3 KDF failed.\n");
389     goto err;
390   }
391   printf("  got ");
392   hexdump(tls13_output, sizeof(tls13_output));
393 
394   /* FFDH */
395   printf("About to compute FFDH key-agreement:\n");
396   DH *dh = DH_get_rfc7919_2048();
397   uint8_t dh_result[2048 / 8];
398   if (!dh || !DH_generate_key(dh) || sizeof(dh_result) != DH_size(dh) ||
399       DH_compute_key_padded(dh_result, DH_get0_pub_key(dh), dh) !=
400           sizeof(dh_result)) {
401     fprintf(stderr, "FFDH failed.\n");
402     goto err;
403   }
404   DH_free(dh);
405 
406   printf("  got ");
407   hexdump(dh_result, sizeof(dh_result));
408 
409   printf("PASS\n");
410   return 0;
411 #endif // !defined(BORINGSSL_FIPS)
412 
413 err:
414   printf("FAIL\n");
415   fflush(stdout);
416   abort();
417 }
418