Botan
1.11.15
|
00001 /* 00002 * OpenSSL Block Cipher 00003 * (C) 1999-2010,2015 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/internal/block_utils.h> 00009 #include <openssl/evp.h> 00010 00011 namespace Botan { 00012 00013 namespace { 00014 00015 class OpenSSL_BlockCipher : public BlockCipher 00016 { 00017 public: 00018 void clear(); 00019 std::string name() const { return cipher_name; } 00020 BlockCipher* clone() const; 00021 00022 size_t block_size() const { return block_sz; } 00023 00024 OpenSSL_BlockCipher(const EVP_CIPHER*, const std::string&); 00025 00026 OpenSSL_BlockCipher(const EVP_CIPHER*, const std::string&, 00027 size_t, size_t, size_t); 00028 00029 Key_Length_Specification key_spec() const { return cipher_key_spec; } 00030 00031 ~OpenSSL_BlockCipher(); 00032 private: 00033 void encrypt_n(const byte in[], byte out[], size_t blocks) const 00034 { 00035 int out_len = 0; 00036 EVP_EncryptUpdate(&encrypt, out, &out_len, in, blocks * block_sz); 00037 } 00038 00039 void decrypt_n(const byte in[], byte out[], size_t blocks) const 00040 { 00041 int out_len = 0; 00042 EVP_DecryptUpdate(&decrypt, out, &out_len, in, blocks * block_sz); 00043 } 00044 00045 void key_schedule(const byte[], size_t); 00046 00047 size_t block_sz; 00048 Key_Length_Specification cipher_key_spec; 00049 std::string cipher_name; 00050 mutable EVP_CIPHER_CTX encrypt, decrypt; 00051 }; 00052 00053 OpenSSL_BlockCipher::OpenSSL_BlockCipher(const EVP_CIPHER* algo, 00054 const std::string& algo_name) : 00055 block_sz(EVP_CIPHER_block_size(algo)), 00056 cipher_key_spec(EVP_CIPHER_key_length(algo)), 00057 cipher_name(algo_name) 00058 { 00059 if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE) 00060 throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in"); 00061 00062 EVP_CIPHER_CTX_init(&encrypt); 00063 EVP_CIPHER_CTX_init(&decrypt); 00064 00065 EVP_EncryptInit_ex(&encrypt, algo, nullptr, nullptr, nullptr); 00066 EVP_DecryptInit_ex(&decrypt, algo, nullptr, nullptr, nullptr); 00067 00068 EVP_CIPHER_CTX_set_padding(&encrypt, 0); 00069 EVP_CIPHER_CTX_set_padding(&decrypt, 0); 00070 } 00071 00072 OpenSSL_BlockCipher::OpenSSL_BlockCipher(const EVP_CIPHER* algo, 00073 const std::string& algo_name, 00074 size_t key_min, size_t key_max, 00075 size_t key_mod) : 00076 block_sz(EVP_CIPHER_block_size(algo)), 00077 cipher_key_spec(key_min, key_max, key_mod), 00078 cipher_name(algo_name) 00079 { 00080 if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE) 00081 throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in"); 00082 00083 EVP_CIPHER_CTX_init(&encrypt); 00084 EVP_CIPHER_CTX_init(&decrypt); 00085 00086 EVP_EncryptInit_ex(&encrypt, algo, nullptr, nullptr, nullptr); 00087 EVP_DecryptInit_ex(&decrypt, algo, nullptr, nullptr, nullptr); 00088 00089 EVP_CIPHER_CTX_set_padding(&encrypt, 0); 00090 EVP_CIPHER_CTX_set_padding(&decrypt, 0); 00091 } 00092 00093 OpenSSL_BlockCipher::~OpenSSL_BlockCipher() 00094 { 00095 EVP_CIPHER_CTX_cleanup(&encrypt); 00096 EVP_CIPHER_CTX_cleanup(&decrypt); 00097 } 00098 00099 /* 00100 * Set the key 00101 */ 00102 void OpenSSL_BlockCipher::key_schedule(const byte key[], size_t length) 00103 { 00104 secure_vector<byte> full_key(key, key + length); 00105 00106 if(cipher_name == "TripleDES" && length == 16) 00107 { 00108 full_key += std::make_pair(key, 8); 00109 } 00110 else 00111 if(EVP_CIPHER_CTX_set_key_length(&encrypt, length) == 0 || 00112 EVP_CIPHER_CTX_set_key_length(&decrypt, length) == 0) 00113 throw Invalid_Argument("OpenSSL_BlockCipher: Bad key length for " + 00114 cipher_name); 00115 00116 EVP_EncryptInit_ex(&encrypt, nullptr, nullptr, &full_key[0], nullptr); 00117 EVP_DecryptInit_ex(&decrypt, nullptr, nullptr, &full_key[0], nullptr); 00118 } 00119 00120 /* 00121 * Return a clone of this object 00122 */ 00123 BlockCipher* OpenSSL_BlockCipher::clone() const 00124 { 00125 return new OpenSSL_BlockCipher(EVP_CIPHER_CTX_cipher(&encrypt), 00126 cipher_name, 00127 cipher_key_spec.minimum_keylength(), 00128 cipher_key_spec.maximum_keylength(), 00129 cipher_key_spec.keylength_multiple()); 00130 } 00131 00132 /* 00133 * Clear memory of sensitive data 00134 */ 00135 void OpenSSL_BlockCipher::clear() 00136 { 00137 const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(&encrypt); 00138 00139 EVP_CIPHER_CTX_cleanup(&encrypt); 00140 EVP_CIPHER_CTX_cleanup(&decrypt); 00141 EVP_CIPHER_CTX_init(&encrypt); 00142 EVP_CIPHER_CTX_init(&decrypt); 00143 EVP_EncryptInit_ex(&encrypt, algo, nullptr, nullptr, nullptr); 00144 EVP_DecryptInit_ex(&decrypt, algo, nullptr, nullptr, nullptr); 00145 EVP_CIPHER_CTX_set_padding(&encrypt, 0); 00146 EVP_CIPHER_CTX_set_padding(&decrypt, 0); 00147 } 00148 00149 std::function<BlockCipher* (const BlockCipher::Spec&)> 00150 make_evp_block_maker(const EVP_CIPHER* cipher, const char* algo) 00151 { 00152 return [cipher,algo](const BlockCipher::Spec&) 00153 { 00154 return new OpenSSL_BlockCipher(cipher, algo); 00155 }; 00156 } 00157 00158 std::function<BlockCipher* (const BlockCipher::Spec&)> 00159 make_evp_block_maker_keylen(const EVP_CIPHER* cipher, const char* algo, 00160 size_t kmin, size_t kmax, size_t kmod) 00161 { 00162 return [cipher,algo,kmin,kmax,kmod](const BlockCipher::Spec&) 00163 { 00164 return new OpenSSL_BlockCipher(cipher, algo, kmin, kmax, kmod); 00165 }; 00166 } 00167 00168 #define BOTAN_REGISTER_OPENSSL_EVP_BLOCK(NAME, EVP) \ 00169 BOTAN_REGISTER_TYPE(BlockCipher, EVP_BlockCipher ## EVP, NAME, \ 00170 make_evp_block_maker(EVP(), NAME), "openssl", 96); 00171 00172 #define BOTAN_REGISTER_OPENSSL_EVP_BLOCK_KEYLEN(NAME, EVP, KMIN, KMAX, KMOD) \ 00173 BOTAN_REGISTER_TYPE(BlockCipher, OpenSSL_BlockCipher ## EVP, NAME, \ 00174 make_evp_block_maker_keylen(EVP(), NAME, KMIN, KMAX, KMOD), \ 00175 "openssl", 96); 00176 00177 #if !defined(OPENSSL_NO_AES) 00178 BOTAN_REGISTER_OPENSSL_EVP_BLOCK("AES-128", EVP_aes_128_ecb); 00179 BOTAN_REGISTER_OPENSSL_EVP_BLOCK("AES-192", EVP_aes_192_ecb); 00180 BOTAN_REGISTER_OPENSSL_EVP_BLOCK("AES-256", EVP_aes_256_ecb); 00181 #endif 00182 00183 #if !defined(OPENSSL_NO_DES) 00184 BOTAN_REGISTER_OPENSSL_EVP_BLOCK("DES", EVP_des_ecb); 00185 BOTAN_REGISTER_OPENSSL_EVP_BLOCK_KEYLEN("TripleDES", EVP_des_ede3_ecb, 16, 24, 8); 00186 #endif 00187 00188 #if !defined(OPENSSL_NO_BF) 00189 BOTAN_REGISTER_OPENSSL_EVP_BLOCK_KEYLEN("Blowfish", EVP_bf_ecb, 1, 56, 1); 00190 #endif 00191 00192 #if !defined(OPENSSL_NO_CAST) 00193 BOTAN_REGISTER_OPENSSL_EVP_BLOCK_KEYLEN("CAST-128", EVP_cast5_ecb, 1, 16, 1); 00194 #endif 00195 00196 #if !defined(OPENSSL_NO_CAMELLIA) 00197 BOTAN_REGISTER_OPENSSL_EVP_BLOCK("Camellia-128", EVP_camellia_128_ecb); 00198 BOTAN_REGISTER_OPENSSL_EVP_BLOCK("Camellia-192", EVP_camellia_192_ecb); 00199 BOTAN_REGISTER_OPENSSL_EVP_BLOCK("Camellia-256", EVP_camellia_256_ecb); 00200 #endif 00201 00202 #if !defined(OPENSSL_NO_IDEA) 00203 BOTAN_REGISTER_OPENSSL_EVP_BLOCK("IDEA", EVP_idea_ecb); 00204 #endif 00205 00206 #if !defined(OPENSSL_NO_SEED) 00207 BOTAN_REGISTER_OPENSSL_EVP_BLOCK("SEED", EVP_seed_ecb); 00208 #endif 00209 00210 } 00211 00212 }