Loading CHANGES +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading fips-1.0/aes/fips_aes_selftest.c +15 −26 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 fips-1.0/des/fips_des_selftest.c +39 −78 Original line number Diff line number Diff line Loading @@ -50,13 +50,13 @@ #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[]= Loading @@ -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 }, } Loading @@ -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 }, { 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 }, }, Loading @@ -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; if (!fips_cipher_test(&ctx, EVP_des_ede3_ecb(), tests3[n].key, NULL, tests3[n].plaintext, tests3[n].ciphertext, 8)) goto err; } DES_ecb3_encrypt((const_DES_cblock *)tests3[n].ciphertext, (DES_cblock *)buf,&key1,&key2,&key3,0); if(memcmp(buf,tests3[n].plaintext,sizeof buf)) { ret = 1; err: EVP_CIPHER_CTX_cleanup(&ctx); if (ret == 0) FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED); return 0; } } return 1; return ret; } #endif fips-1.0/fips.c +28 −0 Original line number Diff line number Diff line Loading @@ -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 fips-1.0/fips.h +10 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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. Loading Loading
CHANGES +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
fips-1.0/aes/fips_aes_selftest.c +15 −26 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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
fips-1.0/des/fips_des_selftest.c +39 −78 Original line number Diff line number Diff line Loading @@ -50,13 +50,13 @@ #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[]= Loading @@ -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 }, } Loading @@ -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 }, { 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 }, }, Loading @@ -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; if (!fips_cipher_test(&ctx, EVP_des_ede3_ecb(), tests3[n].key, NULL, tests3[n].plaintext, tests3[n].ciphertext, 8)) goto err; } DES_ecb3_encrypt((const_DES_cblock *)tests3[n].ciphertext, (DES_cblock *)buf,&key1,&key2,&key3,0); if(memcmp(buf,tests3[n].plaintext,sizeof buf)) { ret = 1; err: EVP_CIPHER_CTX_cleanup(&ctx); if (ret == 0) FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED); return 0; } } return 1; return ret; } #endif
fips-1.0/fips.c +28 −0 Original line number Diff line number Diff line Loading @@ -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
fips-1.0/fips.h +10 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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. Loading