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