Modify AES and 3DES selftests to use EVP.
authorDr. Stephen Henson <steve@openssl.org>
Sun, 1 Jul 2007 23:19:15 +0000 (23:19 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 1 Jul 2007 23:19:15 +0000 (23:19 +0000)
CHANGES
fips-1.0/aes/fips_aes_selftest.c
fips-1.0/des/fips_des_selftest.c
fips-1.0/fips.c
fips-1.0/fips.h
fips-1.0/fips_locl.h

diff --git a/CHANGES b/CHANGES
index 5f4ea05d0a16513039768042d702738346973875..5cb29ca5fd7fbfa6c068e635c1b364af8217c6fc 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -8,7 +8,7 @@
      automatically use EVP_CIPHER_{get,set}_asn1_iv and avoid the
      need for any ASN1 dependencies in FIPS library. Move AES and 3DES
      cipher definitions to fips library and modify AES and 3DES algorithm
-     tests to use EVP.
+     tests and self tests to use EVP.
      [Steve Henson]
 
   *) Move EVP cipher code into enc_min.c to support a minimal implementation
index 0e53d21bd0d17878eac440ef9aae57d170712141..441bbc18e7d8dccafc58bcbd829dc1bcb0375e92 100644 (file)
@@ -50,7 +50,7 @@
 #include <string.h>
 #include <openssl/err.h>
 #include <openssl/fips.h>
-#include <openssl/aes.h>
+#include <openssl/evp.h>
 
 #ifdef OPENSSL_FIPS
 static struct
@@ -78,35 +78,24 @@ void FIPS_corrupt_aes()
 int FIPS_selftest_aes()
     {
     int n;
+    int ret = 0;
+    EVP_CIPHER_CTX ctx;
+    EVP_CIPHER_CTX_init(&ctx);
 
-    /* Encrypt and check against known ciphertext */
     for(n=0 ; n < 1 ; ++n)
        {
-       AES_KEY key;
-       unsigned char buf[16];
-
-       AES_set_encrypt_key(tests[n].key,128,&key);
-       AES_encrypt(tests[n].plaintext,buf,&key);
-       if(memcmp(buf,tests[n].ciphertext,sizeof buf))
-           {
-           FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED);
-           return 0;
-           }
+       if (fips_cipher_test(&ctx, EVP_aes_128_ecb(),
+                               tests[n].key, NULL,
+                               tests[n].plaintext,
+                               tests[n].ciphertext,
+                               16) <= 0)
+               goto err;
        }
-    /* Decrypt and check against known plaintext */
-    for(n=0 ; n < 1 ; ++n)
-       {
-       AES_KEY key;
-       unsigned char buf[16];
-
-       AES_set_decrypt_key(tests[n].key,128,&key);
-       AES_decrypt(tests[n].ciphertext,buf,&key);
-       if(memcmp(buf,tests[n].plaintext,sizeof buf))
-           {
+    ret = 1;
+    err:
+    EVP_CIPHER_CTX_cleanup(&ctx);
+    if (ret == 0)
            FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED);
-           return 0;
-           }
-       }
-    return 1;
+    return ret;
     }
 #endif
index 7dd01465a195aa6b278fc50c6d490ef5eb57563f..8ae215f131fbc7806fa1e16255af319e0f39ce00 100644 (file)
 #include <string.h>
 #include <openssl/err.h>
 #include <openssl/fips.h>
-#include <openssl/des.h>
+#include <openssl/evp.h>
 #include <openssl/opensslconf.h>
 
 #ifdef OPENSSL_FIPS
 static struct
     {
-    DES_cblock key;
+    unsigned char key[8];
     unsigned char plaintext[8];
     unsigned char ciphertext[8];
     } tests[]=
@@ -75,21 +75,20 @@ static struct
 
 static struct
     {
-    DES_cblock key1;
-    DES_cblock key2;
+    unsigned char key[16];
     unsigned char plaintext[8];
     unsigned char ciphertext[8];
     } tests2[]=
        {
        {
-       { 0x7c,0x4f,0x6e,0xf7,0xa2,0x04,0x16,0xec },
-       { 0x0b,0x6b,0x7c,0x9e,0x5e,0x19,0xa7,0xc4 },
+       { 0x7c,0x4f,0x6e,0xf7,0xa2,0x04,0x16,0xec,
+         0x0b,0x6b,0x7c,0x9e,0x5e,0x19,0xa7,0xc4 },
        { 0x06,0xa7,0xd8,0x79,0xaa,0xce,0x69,0xef },
        { 0x4c,0x11,0x17,0x55,0xbf,0xc4,0x4e,0xfd }
        },
        {
-       { 0x5d,0x9e,0x01,0xd3,0x25,0xc7,0x3e,0x34 },
-       { 0x01,0x16,0x7c,0x85,0x23,0xdf,0xe0,0x68 },
+       { 0x5d,0x9e,0x01,0xd3,0x25,0xc7,0x3e,0x34,
+         0x01,0x16,0x7c,0x85,0x23,0xdf,0xe0,0x68 },
        { 0x9c,0x50,0x09,0x0f,0x5e,0x7d,0x69,0x7e },
        { 0xd2,0x0b,0x18,0xdf,0xd9,0x0d,0x9e,0xff },
        }
@@ -97,24 +96,22 @@ static struct
 
 static struct
     {
-    DES_cblock key1;
-    DES_cblock key2;
-    DES_cblock key3;
+    unsigned char key[24];
     unsigned char plaintext[8];
     unsigned char ciphertext[8];
     } tests3[]=
        {
        {
-       { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
-       { 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10 },
-       { 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0 },
-       { 0x8f,0x8f,0xbf,0x9b,0x5d,0x48,0xb4,0x1c},
-       { 0x59,0x8c,0xe5,0xd3,0x6c,0xa2,0xea,0x1b},
+       { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+         0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,
+         0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0 },
+       { 0x8f,0x8f,0xbf,0x9b,0x5d,0x48,0xb4,0x1c },
+       { 0x59,0x8c,0xe5,0xd3,0x6c,0xa2,0xea,0x1b },
        },
        {
-       { 0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xFE },
-       { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF },
-       { 0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4 },
+       { 0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xFE,
+         0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+         0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4 },
        { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF },
        { 0x11,0x25,0xb0,0x35,0xbe,0xa0,0x82,0x86 },
        },
@@ -127,78 +124,42 @@ void FIPS_corrupt_des()
 
 int FIPS_selftest_des()
     {
-    int n;
-
+    int n, ret = 0;
+    EVP_CIPHER_CTX ctx;
+    EVP_CIPHER_CTX_init(&ctx);
+#if 0
     /* Encrypt/decrypt with DES and compare to known answers */
     for(n=0 ; n < 2 ; ++n)
        {
-       DES_key_schedule key;
-       DES_cblock buf;
-
-       DES_set_key(&tests[n].key,&key);
-       DES_ecb_encrypt(&tests[n].plaintext,&buf,&key,1);
-       if(memcmp(buf,tests[n].ciphertext,sizeof buf))
-           {
-           FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
-           return 0;
-           }
-       DES_ecb_encrypt(&tests[n].ciphertext,&buf,&key,0);
-       if(memcmp(buf,tests[n].plaintext,sizeof buf))
-           {
-           FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
-           return 0;
-           }
+       if (!fips_cipher_test(&ctx, EVP_des_ecb(),
+                               tests[n].key, NULL,
+                               tests[n].plaintext, tests[n].ciphertext, 8))
+               goto err;
        }
-
+#endif
     /* Encrypt/decrypt with 2-key 3DES and compare to known answers */
     for(n=0 ; n < 2 ; ++n)
        {
-       DES_key_schedule key1, key2;
-       unsigned char buf[8];
-
-       DES_set_key(&tests2[n].key1,&key1);
-       DES_set_key(&tests2[n].key2,&key2);
-       DES_ecb2_encrypt((const_DES_cblock *)tests2[n].plaintext,
-                               (DES_cblock *)buf,&key1,&key2,1);
-       if(memcmp(buf,tests2[n].ciphertext,sizeof buf))
-           {
-           FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
-           return 0;
-           }
-       DES_ecb2_encrypt((const_DES_cblock *)tests2[n].ciphertext,
-                               (DES_cblock *)buf,&key1,&key2,0);
-       if(memcmp(buf,tests2[n].plaintext,sizeof buf))
-           {
-           FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
-           return 0;
-           }
+       if (!fips_cipher_test(&ctx, EVP_des_ede_ecb(),
+                               tests2[n].key, NULL,
+                               tests2[n].plaintext, tests2[n].ciphertext, 8))
+               goto err;
        }
 
     /* Encrypt/decrypt with 3DES and compare to known answers */
     for(n=0 ; n < 2 ; ++n)
        {
-       DES_key_schedule key1, key2, key3;
-       unsigned char buf[8];
-
-       DES_set_key(&tests3[n].key1,&key1);
-       DES_set_key(&tests3[n].key2,&key2);
-       DES_set_key(&tests3[n].key3,&key3);
-       DES_ecb3_encrypt((const_DES_cblock *)tests3[n].plaintext,
-                               (DES_cblock *)buf,&key1,&key2,&key3,1);
-       if(memcmp(buf,tests3[n].ciphertext,sizeof buf))
-           {
-           FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
-           return 0;
-           }
-       DES_ecb3_encrypt((const_DES_cblock *)tests3[n].ciphertext,
-                               (DES_cblock *)buf,&key1,&key2,&key3,0);
-       if(memcmp(buf,tests3[n].plaintext,sizeof buf))
-           {
-           FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
-           return 0;
-           }
+       if (!fips_cipher_test(&ctx, EVP_des_ede3_ecb(),
+                               tests3[n].key, NULL,
+                               tests3[n].plaintext, tests3[n].ciphertext, 8))
+               goto err;
        }
+    ret = 1;
+    err:
+    EVP_CIPHER_CTX_cleanup(&ctx);
+    if (ret == 0)
+           FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
 
-    return 1;
+    return ret;
     }
 #endif
index f524bf1eb843c322f50b1013ea4ce87c96ca1adf..372aa59377261664e40a72b7fa97724812a5bb48 100644 (file)
@@ -462,4 +462,32 @@ int fips_pkey_signature_test(EVP_PKEY *pkey,
        return 1;
        }
 
+/* Generalized symmetric cipher test routine. Encrypt data, verify result
+ * against known answer, decrypt and compare with original plaintext.
+ */
+
+int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                       const unsigned char *key,
+                       const unsigned char *iv,
+                       const unsigned char *plaintext,
+                       const unsigned char *ciphertext,
+                       int len)
+       {
+       unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE];
+       unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE];
+       OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE);
+       if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1) <= 0)
+               return 0;
+       EVP_Cipher(ctx, citmp, plaintext, len);
+       if (memcmp(citmp, ciphertext, len))
+               return 0;
+       if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0) <= 0)
+               return 0;
+       EVP_Cipher(ctx, pltmp, citmp, len);
+       if (memcmp(pltmp, plaintext, len))
+               return 0;
+       return 1;
+       }
+
+
 #endif
index d77ff3a32df7c5ee4bbd5641bbf3de1cd1466f39..1ae60e39c1dbf63915eb9c76a9fd71986d74afd6 100644 (file)
@@ -58,6 +58,8 @@ extern "C" {
 struct dsa_st;
 struct evp_pkey_st;
 struct env_md_st;
+struct evp_cipher_st;
+struct evp_cipher_ctx_st;
 
 int FIPS_mode_set(int onoff);
 int FIPS_mode(void);
@@ -84,6 +86,14 @@ int fips_pkey_signature_test(struct evp_pkey_st *pkey,
                        const struct env_md_st *digest, unsigned int md_flags,
                        const char *fail_str);
 
+int fips_cipher_test(struct evp_cipher_ctx_st *ctx,
+                       const struct evp_cipher_st *cipher,
+                       const unsigned char *key,
+                       const unsigned char *iv,
+                       const unsigned char *plaintext,
+                       const unsigned char *ciphertext,
+                       int len);
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
index cc91341beed2a58f49d1e6abdf46e1c4f9f0a0ba..06cb64d8328990be2cfdf3d905382744a7315955 100644 (file)
@@ -64,6 +64,8 @@ int fips_set_owning_thread(void);
 int fips_clear_owning_thread(void);
 unsigned char *fips_signature_witness(void);
 
+#define FIPS_MAX_CIPHER_TEST_SIZE      16
+
 #ifdef  __cplusplus
 }
 #endif