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