Botan 2.19.1
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(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;
71 };
72
73CommonCrypto_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
81CommonCrypto_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*/
96void 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*/
123BlockCipher* 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*/
131void 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
149std::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
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:13
std::unique_ptr< BlockCipher > make_commoncrypto_block_cipher(const std::string &name)
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)