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 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 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