Botan  2.9.0
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/hex.h>
9 
10 #include <botan/block_cipher.h>
11 #include <botan/internal/commoncrypto.h>
12 #include <CommonCrypto/CommonCrypto.h>
13 
14 #include "commoncrypto_utils.h"
15 
16 namespace Botan {
17 
18 namespace {
19 
20 class CommonCrypto_BlockCipher final : public BlockCipher
21  {
22  public:
23  CommonCrypto_BlockCipher(const std::string& name, const CommonCryptor_Opts& opts);
24 
25  ~CommonCrypto_BlockCipher();
26 
27  void clear() override;
28  std::string provider() const override { return "commoncrypto"; }
29  std::string name() const override { return m_cipher_name; }
30  BlockCipher* clone() const override;
31 
32  size_t block_size() const override { return m_opts.block_size; }
33 
34  Key_Length_Specification key_spec() const override { return m_opts.key_spec; }
35 
36  void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
37  {
38  verify_key_set(m_key_set);
39  size_t total_len = blocks * m_opts.block_size;
40  size_t out_len = 0;
41 
42  CCCryptorStatus status = CCCryptorUpdate(m_encrypt, in, total_len,
43  out, total_len, &out_len);
44  if(status != kCCSuccess)
45  {
46  throw CommonCrypto_Error("CCCryptorUpdate encrypt", status);
47  }
48  }
49 
50  void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
51  {
52  verify_key_set(m_key_set);
53  size_t total_len = blocks * m_opts.block_size;
54  size_t out_len = 0;
55 
56  CCCryptorStatus status = CCCryptorUpdate(m_decrypt, in, total_len,
57  out, total_len, &out_len);
58  if(status != kCCSuccess)
59  {
60  throw CommonCrypto_Error("CCCryptorUpdate decrypt", status);
61  }
62  }
63 
64  void key_schedule(const uint8_t key[], size_t key_len) override;
65 
66  std::string m_cipher_name;
67  CommonCryptor_Opts m_opts;
68 
69  CCCryptorRef m_encrypt = nullptr;
70  CCCryptorRef m_decrypt = nullptr;
71  bool m_key_set;
72  };
73 
74 CommonCrypto_BlockCipher::CommonCrypto_BlockCipher(const std::string& algo_name,
75  const CommonCryptor_Opts& opts) :
76  m_cipher_name(algo_name),
77  m_opts(opts),
78  m_key_set(false)
79  {
80  }
81 
82 CommonCrypto_BlockCipher::~CommonCrypto_BlockCipher()
83  {
84  if(m_encrypt)
85  {
86  CCCryptorRelease(m_encrypt);
87  }
88  if(m_decrypt)
89  {
90  CCCryptorRelease(m_decrypt);
91  }
92  }
93 
94 /*
95 * Set the key
96 */
97 void CommonCrypto_BlockCipher::key_schedule(const uint8_t key[], size_t length)
98  {
99  secure_vector<uint8_t> full_key(key, key + length);
100 
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 }
136 
137 std::unique_ptr<BlockCipher>
139  {
140 
141  try
142  {
144  return std::unique_ptr<BlockCipher>(new CommonCrypto_BlockCipher(name, opts));
145  }
146  catch(CommonCrypto_Error& e)
147  {
148  return nullptr;
149  }
150  }
151 }
152 
CommonCryptor_Opts commoncrypto_opts_from_algo(const std::string &algo)
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)