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