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