Home | History | Annotate | Download | only in fipstools
      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