Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

commoncrypto_utils.cpp
Go to the documentation of this file.
1 /*
2 * Cipher Modes via CommonCrypto
3 * (C) 2018 Jose Pereira
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/cipher_mode.h>
9 #include <botan/parsing.h>
10 #include <botan/internal/commoncrypto.h>
11 #include <botan/internal/rounding.h>
12 #include <botan/scan_name.h>
13
14 #include "commoncrypto_utils.h"
15
16 namespace Botan {
17
18 std::string CommonCrypto_Error::ccryptorstatus_to_string(CCCryptorStatus status)
19 {
20 switch(status)
21 {
22 case kCCSuccess:
23 return "Success";
24 case kCCParamError:
25 return "ParamError";
26 case kCCBufferTooSmall:
27 return "BufferTooSmall";
28 case kCCMemoryFailure:
29 return "MemoryFailure";
30 case kCCAlignmentError:
31 return "AlignmentError";
32 case kCCDecodeError:
33 return "DecodeError";
34 case kCCUnimplemented:
35 return "Unimplemented";
36 case kCCOverflow:
37 return "Overflow";
38 case kCCRNGFailure:
39 return "RNGFailure";
40 case kCCUnspecifiedError:
41 return "UnspecifiedError";
42 case kCCCallSequenceError:
43 return "CallSequenceError";
44 case kCCKeySizeError:
45 return "KeySizeError";
46 default:
47 return "Unknown";
48 }
49 };
50
51
52 CommonCryptor_Opts commoncrypto_opts_from_algo(const std::string& algo)
53 {
54 SCAN_Name spec(algo);
55
56 std::string algo_name = spec.algo_name();
57 std::string cipher_mode = spec.cipher_mode();
58 std::string cipher_mode_padding = spec.cipher_mode_pad();
59
60 CommonCryptor_Opts opts;
61
62 if(algo_name.compare(0, 3, "AES") == 0)
63 {
64 opts.algo = kCCAlgorithmAES;
65 opts.block_size = kCCBlockSizeAES128;
66 if(algo_name == "AES-128")
67 {
68 opts.key_spec = Key_Length_Specification(kCCKeySizeAES128);
69 }
70 else if(algo_name == "AES-192")
71 {
72 opts.key_spec = Key_Length_Specification(kCCKeySizeAES192);
73 }
74 else if(algo_name == "AES-256")
75 {
76 opts.key_spec = Key_Length_Specification(kCCKeySizeAES256);
77 }
78 else
79 {
80 throw CommonCrypto_Error("Unknown AES algorithm");
81 }
82 }
83 else if(algo_name == "DES")
84 {
85 opts.algo = kCCAlgorithmDES;
86 opts.block_size = kCCBlockSizeDES;
87 opts.key_spec = Key_Length_Specification(kCCKeySizeDES);
88 }
89 else if(algo_name == "TripleDES")
90 {
91 opts.algo = kCCAlgorithm3DES;
92 opts.block_size = kCCBlockSize3DES;
93 opts.key_spec = Key_Length_Specification(16, kCCKeySize3DES, 8);
94 }
95 else if(algo_name == "Blowfish")
96 {
97 opts.algo = kCCAlgorithmBlowfish;
98 opts.block_size = kCCBlockSizeBlowfish;
99 opts.key_spec = Key_Length_Specification(1, kCCKeySizeMaxBlowfish, 1);
100 }
101 else if(algo_name == "CAST-128")
102 {
103 opts.algo = kCCAlgorithmCAST;
104 opts.block_size = kCCBlockSizeCAST;
105 // Botan's base implementation of CAST does not support shorter keys
106 // so we limit its minimum key size to 11 here.
107 opts.key_spec = Key_Length_Specification(11, kCCKeySizeMaxCAST, 1);
108 }
109 else
110 {
111 throw CommonCrypto_Error("Unsupported cipher");
112 }
113
114 //TODO add CFB and XTS support
115 if(cipher_mode.empty() || cipher_mode == "ECB")
116 {
117 opts.mode = kCCModeECB;
118 }
119 else if(cipher_mode == "CBC")
120 {
121 opts.mode = kCCModeCBC;
122 }
123 else if(cipher_mode == "CTR")
124 {
125 opts.mode = kCCModeCTR;
126 }
127 else if(cipher_mode == "OFB")
128 {
129 opts.mode = kCCModeOFB;
130 }
131 else
132 {
133 throw CommonCrypto_Error("Unsupported cipher mode!");
134 }
135
136 if(cipher_mode_padding == "NoPadding")
137 {
138 opts.padding = ccNoPadding;
139 }
140 /*
141 else if(cipher_mode_padding.empty() || cipher_mode_padding == "PKCS7")
142 {
143 opts.padding = ccPKCS7Padding;
144 }
145 */
146 else
147 {
148 throw CommonCrypto_Error("Unsupported cipher mode padding!");
149 }
150
151 return opts;
152 }
153
154
155 void commoncrypto_adjust_key_size(const uint8_t key[], size_t length,
156 const CommonCryptor_Opts& opts, secure_vector<uint8_t>& full_key)
157 {
158
159 if(opts.algo == kCCAlgorithmBlowfish && length < 8)
160 {
161 size_t repeat;
162 switch(length)
163 {
164 case 1:
165 repeat = 8;
166 break;
167 case 2:
168 repeat = 4;
169 break;
170 case 3:
171 repeat = 3;
172 break;
173 default:
174 repeat = 2;
175 break;
176 }
177
178 full_key.resize(length * repeat);
179 for(size_t i = 0; i < repeat; i++)
180 {
181 copy_mem(full_key.data() + i * length, key, length);
182 }
183 }
184 else if(opts.algo == kCCAlgorithm3DES && length == 16)
185 {
186 full_key += std::make_pair(key, 8);
187 }
188 }
189 }
Botan::SCAN_Name::cipher_mode
std::string cipher_mode() const
Definition: scan_name.h:89
Botan::commoncrypto_opts_from_algo
CommonCryptor_Opts commoncrypto_opts_from_algo(const std::string &algo)
Definition: commoncrypto_utils.cpp:52
Botan::CommonCryptor_Opts::algo
CCAlgorithm algo
Definition: commoncrypto_utils.h:21
commoncrypto_utils.h
Botan::Key_Length_Specification
Definition: key_spec.h:18
Botan::CommonCrypto_Error
Definition: commoncrypto.h:25
Botan::CommonCryptor_Opts::padding
CCPadding padding
Definition: commoncrypto_utils.h:23
Botan::CommonCryptor_Opts::block_size
size_t block_size
Definition: commoncrypto_utils.h:24
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
Botan::CommonCryptor_Opts::mode
CCMode mode
Definition: commoncrypto_utils.h:22
Botan::SCAN_Name::cipher_mode_pad
std::string cipher_mode_pad() const
Definition: scan_name.h:95
Botan::CommonCryptor_Opts::key_spec
Key_Length_Specification key_spec
Definition: commoncrypto_utils.h:25
Botan::CommonCryptor_Opts
Definition: commoncrypto_utils.h:19
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:132
Botan
Definition: alg_id.cpp:13
Botan::SCAN_Name
Definition: scan_name.h:23
Botan::SCAN_Name::algo_name
const std::string & algo_name() const
Definition: scan_name.h:51
Botan::commoncrypto_adjust_key_size
void commoncrypto_adjust_key_size(const uint8_t key[], size_t length, const CommonCryptor_Opts &opts, secure_vector< uint8_t > &full_key)
Definition: commoncrypto_utils.cpp:155