aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/prov/commoncrypto/commoncrypto_utils.cpp
diff options
context:
space:
mode:
authorJose Pereira <[email protected]>2018-09-06 23:18:45 -0700
committerJose Pereira <[email protected]>2018-09-09 14:04:13 -0700
commit77e5fed44b3e24445b06ed80eaa31978081469b5 (patch)
tree9edf0c3e13980937395f1d96587fc28496f6dd78 /src/lib/prov/commoncrypto/commoncrypto_utils.cpp
parentd3b55672f63621c82d5a9d5b7be2e6af319006d6 (diff)
Add CommonCrypto cipher modes support
Diffstat (limited to 'src/lib/prov/commoncrypto/commoncrypto_utils.cpp')
-rw-r--r--src/lib/prov/commoncrypto/commoncrypto_utils.cpp149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/lib/prov/commoncrypto/commoncrypto_utils.cpp b/src/lib/prov/commoncrypto/commoncrypto_utils.cpp
new file mode 100644
index 000000000..fc841f45c
--- /dev/null
+++ b/src/lib/prov/commoncrypto/commoncrypto_utils.cpp
@@ -0,0 +1,149 @@
+/*
+* Cipher Modes via CommonCrypto
+* (C) 2018 Jose Pereira
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/cipher_mode.h>
+#include <botan/parsing.h>
+#include <botan/internal/commoncrypto.h>
+#include <botan/internal/rounding.h>
+#include <botan/scan_name.h>
+
+#include "commoncrypto_utils.h"
+
+namespace Botan {
+
+std::string CommonCrypto_Error::ccryptorstatus_to_string(CCCryptorStatus status)
+ {
+ switch(status)
+ {
+ case kCCSuccess:
+ return "Success";
+ case kCCParamError:
+ return "ParamError";
+ case kCCBufferTooSmall:
+ return "BufferTooSmall";
+ case kCCMemoryFailure:
+ return "MemoryFailure";
+ case kCCAlignmentError:
+ return "AlignmentError";
+ case kCCDecodeError:
+ return "DecodeError";
+ case kCCUnimplemented:
+ return "Unimplemented";
+ case kCCOverflow:
+ return "Overflow";
+ case kCCRNGFailure:
+ return "RNGFailure";
+ case kCCUnspecifiedError:
+ return "UnspecifiedError";
+ case kCCCallSequenceError:
+ return "CallSequenceError";
+ case kCCKeySizeError:
+ return "KeySizeError";
+ default:
+ return "Unknown";
+ }
+ };
+
+
+CommonCryptor_Opts commoncrypto_opts_from_algo(const std::string& algo)
+ {
+ SCAN_Name spec(algo);
+
+ std::string algo_name = spec.algo_name();
+ std::string cipher_mode = spec.cipher_mode();
+ std::string cipher_mode_padding = spec.cipher_mode_pad();
+
+ CommonCryptor_Opts opts;
+
+ if(algo_name.compare(0, 3, "AES") == 0)
+ {
+ opts.algo = kCCAlgorithmAES;
+ opts.block_size = kCCBlockSizeAES128;
+ if(algo_name == "AES-128")
+ {
+ opts.key_spec = Key_Length_Specification(kCCKeySizeAES128);
+ }
+ else if(algo_name == "AES-192")
+ {
+ opts.key_spec = Key_Length_Specification(kCCKeySizeAES192);
+ }
+ else if(algo_name == "AES-256")
+ {
+ opts.key_spec = Key_Length_Specification(kCCKeySizeAES256);
+ }
+ else
+ {
+ throw CommonCrypto_Error("Unknown AES algorithm");
+ }
+ }
+ else if(algo_name == "DES")
+ {
+ opts.algo = kCCAlgorithmDES;
+ opts.block_size = kCCBlockSizeDES;
+ opts.key_spec = Key_Length_Specification(kCCKeySizeDES);
+ }
+ else if(algo_name == "TripleDES")
+ {
+ opts.algo = kCCAlgorithm3DES;
+ opts.block_size = kCCBlockSize3DES;
+ opts.key_spec = Key_Length_Specification(kCCKeySize3DES);//, 16, 24, 8);
+ }
+ else if(algo_name == "Blowfish")
+ {
+ opts.algo = kCCAlgorithmBlowfish;
+ opts.block_size = kCCBlockSizeBlowfish;
+ opts.key_spec = Key_Length_Specification(kCCKeySizeMinBlowfish, kCCKeySizeMaxBlowfish);//, 1, 56, 1);
+ }
+ else if(algo_name == "CAST-128")
+ {
+ opts.algo = kCCAlgorithmCAST;
+ opts.block_size = kCCBlockSizeCAST;
+ opts.key_spec = Key_Length_Specification(kCCKeySizeMinCAST, kCCKeySizeMaxCAST);//, 1, 16, 1);
+ }
+ else
+ {
+ throw CommonCrypto_Error("Unsupported cipher");
+ }
+
+ //TODO add CFB and XTS support
+ if(cipher_mode.empty() || cipher_mode == "ECB")
+ {
+ opts.mode = kCCModeECB;
+ }
+ else if(cipher_mode == "CBC")
+ {
+ opts.mode = kCCModeCBC;
+ }
+ else if(cipher_mode == "CTR")
+ {
+ opts.mode = kCCModeCTR;
+ }
+ else if(cipher_mode == "OFB")
+ {
+ opts.mode = kCCModeOFB;
+ }
+ else
+ {
+ throw CommonCrypto_Error("Unsupported cipher mode!");
+ }
+
+ if(cipher_mode_padding.empty() || cipher_mode_padding == "PKCS7")
+ {
+ opts.padding = ccPKCS7Padding;
+ }
+ else if(cipher_mode_padding == "NoPadding")
+ {
+ opts.padding = ccNoPadding;
+ }
+ else
+ {
+ throw CommonCrypto_Error("Unsupported cipher mode padding!");
+ }
+
+ return opts;
+ }
+}