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