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