aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/engine/def_engine/def_eng.h5
-rw-r--r--src/engine/def_engine/def_mode.cpp183
2 files changed, 104 insertions, 84 deletions
diff --git a/src/engine/def_engine/def_eng.h b/src/engine/def_engine/def_eng.h
index 2d7145480..ba5bee8ef 100644
--- a/src/engine/def_engine/def_eng.h
+++ b/src/engine/def_engine/def_eng.h
@@ -78,6 +78,11 @@ class BOTAN_DLL Default_Engine : public Engine
Algorithm_Factory&) const;
};
+Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher,
+ Cipher_Dir direction,
+ const std::string& mode,
+ const std::string& padding);
+
}
#endif
diff --git a/src/engine/def_engine/def_mode.cpp b/src/engine/def_engine/def_mode.cpp
index 2b093a0a3..0c7a1a2e2 100644
--- a/src/engine/def_engine/def_mode.cpp
+++ b/src/engine/def_engine/def_mode.cpp
@@ -51,22 +51,22 @@ namespace {
/**
* Get a block cipher padding method by name
*/
-BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec)
+BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec,
+ const std::string& def_if_empty)
{
- SCAN_Name request(algo_spec);
-
#if defined(BOTAN_HAS_CIPHER_MODE_PADDING)
- if(request.algo_name() == "PKCS7")
+ if(algo_spec == "NoPadding" || (algo_spec == "" && def_if_empty == "NoPadding"))
+ return new Null_Padding;
+
+ if(algo_spec == "PKCS7" || (algo_spec == "" && def_if_empty == "PKCS7"))
return new PKCS7_Padding;
- if(request.algo_name() == "OneAndZeros")
+ if(algo_spec == "OneAndZeros")
return new OneAndZeros_Padding;
- if(request.algo_name() == "X9.23")
+ if(algo_spec == "X9.23")
return new ANSI_X923_Padding;
- if(request.algo_name() == "NoPadding")
- return new Null_Padding;
#endif
throw Algorithm_Not_Found(algo_spec);
@@ -74,58 +74,11 @@ BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec)
}
-/*
-* Get a cipher object
-*/
-Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec,
- Cipher_Dir direction,
- Algorithm_Factory& af)
+Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher,
+ Cipher_Dir direction,
+ const std::string& mode,
+ const std::string& padding)
{
- std::vector<std::string> algo_parts = split_on(algo_spec, '/');
- if(algo_parts.empty())
- throw Invalid_Algorithm_Name(algo_spec);
-
- const std::string cipher_name = algo_parts[0];
-
- // check if it is a stream cipher first (easy case)
- const StreamCipher* stream_cipher = af.prototype_stream_cipher(cipher_name);
- if(stream_cipher)
- return new StreamCipher_Filter(stream_cipher->clone());
-
- const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_name);
- if(!block_cipher)
- return 0;
-
- if(algo_parts.size() != 2 && algo_parts.size() != 3)
- return 0;
-
- std::string mode = algo_parts[1];
- u32bit bits = 0;
-
- if(mode.find("CFB") != std::string::npos ||
- mode.find("EAX") != std::string::npos)
- {
- std::vector<std::string> algo_info = parse_algorithm_name(mode);
- mode = algo_info[0];
- if(algo_info.size() == 1)
- bits = 8*block_cipher->BLOCK_SIZE;
- else if(algo_info.size() == 2)
- bits = to_u32bit(algo_info[1]);
- else
- throw Invalid_Algorithm_Name(algo_spec);
- }
-
- std::string padding;
- if(algo_parts.size() == 3)
- padding = algo_parts[2];
- else
- padding = (mode == "CBC") ? "PKCS7" : "NoPadding";
-
- if(mode == "ECB" && padding == "CTS")
- return 0;
- else if((mode != "CBC" && mode != "ECB") && padding != "NoPadding")
- throw Invalid_Algorithm_Name(algo_spec);
-
#if defined(BOTAN_HAS_OFB)
if(mode == "OFB")
return new OFB(block_cipher->clone());
@@ -137,22 +90,14 @@ Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec,
#endif
#if defined(BOTAN_HAS_ECB)
- if(mode == "ECB")
- {
- if(direction == ENCRYPTION)
- return new ECB_Encryption(block_cipher->clone(), get_bc_pad(padding));
- else
- return new ECB_Decryption(block_cipher->clone(), get_bc_pad(padding));
- }
-#endif
-
-#if defined(BOTAN_HAS_CFB)
- if(mode == "CFB")
+ if(mode == "ECB" || mode == "")
{
if(direction == ENCRYPTION)
- return new CFB_Encryption(block_cipher->clone(), bits);
+ return new ECB_Encryption(block_cipher->clone(),
+ get_bc_pad(padding, "NoPadding"));
else
- return new CFB_Decryption(block_cipher->clone(), bits);
+ return new ECB_Decryption(block_cipher->clone(),
+ get_bc_pad(padding, "NoPadding"));
}
#endif
@@ -173,25 +118,15 @@ Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec,
#if defined(BOTAN_HAS_CBC)
if(direction == ENCRYPTION)
return new CBC_Encryption(block_cipher->clone(),
- get_bc_pad(padding));
+ get_bc_pad(padding, "PKCS7"));
else
return new CBC_Decryption(block_cipher->clone(),
- get_bc_pad(padding));
+ get_bc_pad(padding, "PKCS7"));
#else
return 0;
#endif
}
-#if defined(BOTAN_HAS_EAX)
- if(mode == "EAX")
- {
- if(direction == ENCRYPTION)
- return new EAX_Encryption(block_cipher->clone(), bits);
- else
- return new EAX_Decryption(block_cipher->clone(), bits);
- }
-#endif
-
#if defined(BOTAN_HAS_XTS)
if(mode == "XTS")
{
@@ -202,6 +137,86 @@ Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec,
}
#endif
+ if(mode.find("CFB") != std::string::npos ||
+ mode.find("EAX") != std::string::npos)
+ {
+ u32bit bits = 0;
+
+ std::vector<std::string> algo_info = parse_algorithm_name(mode);
+ std::string mode_name = algo_info[0];
+ if(algo_info.size() == 1)
+ bits = 8*block_cipher->BLOCK_SIZE;
+ else if(algo_info.size() == 2)
+ bits = to_u32bit(algo_info[1]);
+ else
+ return 0;
+
+#if defined(BOTAN_HAS_CFB)
+ if(mode_name == "CFB")
+ {
+ if(direction == ENCRYPTION)
+ return new CFB_Encryption(block_cipher->clone(), bits);
+ else
+ return new CFB_Decryption(block_cipher->clone(), bits);
+ }
+#endif
+
+#if defined(BOTAN_HAS_EAX)
+ if(mode_name == "EAX")
+ {
+ if(direction == ENCRYPTION)
+ return new EAX_Encryption(block_cipher->clone(), bits);
+ else
+ return new EAX_Decryption(block_cipher->clone(), bits);
+ }
+#endif
+ }
+
+ return 0;
+ }
+
+/*
+* Get a cipher object
+*/
+Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec,
+ Cipher_Dir direction,
+ Algorithm_Factory& af)
+ {
+ std::vector<std::string> algo_parts = split_on(algo_spec, '/');
+ if(algo_parts.empty())
+ throw Invalid_Algorithm_Name(algo_spec);
+
+ const std::string cipher_name = algo_parts[0];
+
+ // check if it is a stream cipher first (easy case)
+ const StreamCipher* stream_cipher = af.prototype_stream_cipher(cipher_name);
+ if(stream_cipher)
+ return new StreamCipher_Filter(stream_cipher->clone());
+
+ const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_name);
+ if(!block_cipher)
+ return 0;
+
+ if(algo_parts.size() != 2 && algo_parts.size() != 3)
+ return 0;
+
+ std::string mode = algo_parts[1];
+
+ std::string padding;
+ if(algo_parts.size() == 3)
+ padding = algo_parts[2];
+ else
+ padding = (mode == "CBC") ? "PKCS7" : "NoPadding";
+
+ if(mode == "ECB" && padding == "CTS")
+ return 0;
+ else if((mode != "CBC" && mode != "ECB") && padding != "NoPadding")
+ throw Invalid_Algorithm_Name(algo_spec);
+
+ Keyed_Filter* filt = get_cipher_mode(block_cipher, direction, mode, padding);
+ if(filt)
+ return filt;
+
throw Algorithm_Not_Found("get_mode: " + cipher_name + "/" +
mode + "/" + padding);
}