Botan  2.18.1
Crypto and TLS for C++11
commoncrypto_block.cpp
Go to the documentation of this file.
1 /*
2 * Block Ciphers via CommonCrypto
3 * (C) 2018 Jose Luis 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/hex.h>
11 #include <botan/block_cipher.h>
12 
13 #include <CommonCrypto/CommonCrypto.h>
14 
15 namespace Botan {
16 
17 namespace {
18 
19 class CommonCrypto_BlockCipher final : public BlockCipher
20  {
21  public:
22  CommonCrypto_BlockCipher(const std::string& name, const CommonCryptor_Opts& opts);
23 
24  ~CommonCrypto_BlockCipher();
25 
26  void clear() override;
27  std::string provider() const override { return "commoncrypto"; }
28  std::string name() const override { return m_cipher_name; }
29  BlockCipher* clone() const override;
30 
31  size_t block_size() const override { return m_opts.block_size; }
32 
33  Key_Length_Specification key_spec() const override { return m_opts.key_spec; }
34 
35  void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
36  {
37  verify_key_set(m_key_set);
38  size_t total_len = blocks * m_opts.block_size;
39  size_t out_len = 0;
40 
41  CCCryptorStatus status = CCCryptorUpdate(m_encrypt, in, total_len,
42  out, total_len, &out_len);
43  if(status != kCCSuccess)
44  {
45  throw CommonCrypto_Error("CCCryptorUpdate encrypt", status);
46  }
47  }
48 
49  void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
50  {
51  verify_key_set(m_key_set);
52  size_t total_len = blocks * m_opts.block_size;
53  size_t out_len = 0;
54 
55  CCCryptorStatus status = CCCryptorUpdate(m_decrypt, in, total_len,
56  out, total_len, &out_len);
57  if(status != kCCSuccess)
58  {
59  throw CommonCrypto_Error("CCCryptorUpdate decrypt", status);
60  }
61  }
62 
63  void key_schedule(const uint8_t key[], size_t key_len) override;
64 
65  std::string m_cipher_name;
66  CommonCryptor_Opts m_opts;
67 
68  CCCryptorRef m_encrypt = nullptr;
69  CCCryptorRef m_decrypt = nullptr;
70  bool m_key_set;
71  };
72 
73 CommonCrypto_BlockCipher::CommonCrypto_BlockCipher(const std::string& algo_name,
74  const CommonCryptor_Opts& opts) :
75  m_cipher_name(algo_name),
76  m_opts(opts),
77  m_key_set(false)
78  {
79  }
80 
81 CommonCrypto_BlockCipher::~CommonCrypto_BlockCipher()
82  {
83  if(m_encrypt)
84  {
85  CCCryptorRelease(m_encrypt);
86  }
87  if(m_decrypt)
88  {
89  CCCryptorRelease(m_decrypt);
90  }
91  }
92 
93 /*
94 * Set the key
95 */
96 void CommonCrypto_BlockCipher::key_schedule(const uint8_t key[], size_t length)
97  {
98  secure_vector<uint8_t> full_key(key, key + length);
99 
100  clear();
101  commoncrypto_adjust_key_size(key, length, m_opts, full_key);
102 
103  CCCryptorStatus status;
104  status = CCCryptorCreate(kCCEncrypt, m_opts.algo, kCCOptionECBMode,
105  full_key.data(), full_key.size(), nullptr, &m_encrypt);
106  if(status != kCCSuccess)
107  {
108  throw CommonCrypto_Error("CCCryptorCreate encrypt", status);
109  }
110  status = CCCryptorCreate(kCCDecrypt, m_opts.algo, kCCOptionECBMode,
111  full_key.data(), full_key.size(), nullptr, &m_decrypt);
112  if(status != kCCSuccess)
113  {
114  throw CommonCrypto_Error("CCCryptorCreate decrypt", status);
115  }
116 
117  m_key_set = true;
118  }
119 
120 /*
121 * Return a clone of this object
122 */
123 BlockCipher* CommonCrypto_BlockCipher::clone() const
124  {
125  return new CommonCrypto_BlockCipher(m_cipher_name, m_opts);
126  }
127 
128 /*
129 * Clear memory of sensitive data
130 */
131 void CommonCrypto_BlockCipher::clear()
132  {
133  m_key_set = false;
134 
135  if(m_encrypt)
136  {
137  CCCryptorRelease(m_encrypt);
138  m_encrypt = nullptr;
139  }
140 
141  if(m_decrypt)
142  {
143  CCCryptorRelease(m_decrypt);
144  m_decrypt = nullptr;
145  }
146  }
147 }
148 
149 std::unique_ptr<BlockCipher>
151  {
152 
153  try
154  {
156  return std::unique_ptr<BlockCipher>(new CommonCrypto_BlockCipher(name, opts));
157  }
158  catch(CommonCrypto_Error& e)
159  {
160  return nullptr;
161  }
162  }
163 }
164 
CommonCryptor_Opts commoncrypto_opts_from_algo_name(const std::string &algo_name)
std::unique_ptr< BlockCipher > make_commoncrypto_block_cipher(const std::string &name)
int(* final)(unsigned char *, CTX *)
CommonCryptor_Opts m_opts
CCCryptorRef m_encrypt
std::string m_cipher_name
std::string name
Definition: alg_id.cpp:13
CCCryptorRef m_decrypt
bool m_key_set
void commoncrypto_adjust_key_size(const uint8_t key[], size_t length, const CommonCryptor_Opts &opts, secure_vector< uint8_t > &full_key)