Botan 3.3.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
10#include <botan/block_cipher.h>
11#include <botan/hex.h>
12#include <botan/internal/commoncrypto_utils.h>
13
14#include <CommonCrypto/CommonCrypto.h>
15
16namespace Botan {
17
18namespace {
19
20class CommonCrypto_BlockCipher final : public BlockCipher {
21 public:
22 CommonCrypto_BlockCipher(std::string_view name, const CommonCryptor_Opts& opts);
23
24 ~CommonCrypto_BlockCipher();
25
26 void clear() override;
27
28 std::string provider() const override { return "commoncrypto"; }
29
30 std::string name() const override { return m_cipher_name; }
31
32 std::unique_ptr<BlockCipher> new_object() const override;
33
34 size_t block_size() const override { return m_opts.block_size; }
35
36 Key_Length_Specification key_spec() const override { return m_opts.key_spec; }
37
38 bool has_keying_material() const override { return m_key_set; }
39
40 void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override {
41 assert_key_material_set();
42 size_t total_len = blocks * m_opts.block_size;
43 size_t out_len = 0;
44
45 CCCryptorStatus status = CCCryptorUpdate(m_encrypt, in, total_len, out, total_len, &out_len);
46 if(status != kCCSuccess) {
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 assert_key_material_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, out, total_len, &out_len);
57 if(status != kCCSuccess) {
58 throw CommonCrypto_Error("CCCryptorUpdate decrypt", status);
59 }
60 }
61
62 void key_schedule(std::span<const uint8_t> key) override;
63
64 std::string m_cipher_name;
65 CommonCryptor_Opts m_opts;
66
67 CCCryptorRef m_encrypt = nullptr;
68 CCCryptorRef m_decrypt = nullptr;
70};
71
72CommonCrypto_BlockCipher::CommonCrypto_BlockCipher(std::string_view algo_name, const CommonCryptor_Opts& opts) :
73 m_cipher_name(algo_name), m_opts(opts), m_key_set(false) {}
74
75CommonCrypto_BlockCipher::~CommonCrypto_BlockCipher() {
76 if(m_encrypt) {
77 CCCryptorRelease(m_encrypt);
78 }
79 if(m_decrypt) {
80 CCCryptorRelease(m_decrypt);
81 }
82}
83
84/*
85* Set the key
86*/
87void CommonCrypto_BlockCipher::key_schedule(std::span<const uint8_t> key) {
88 secure_vector<uint8_t> full_key(key.begin(), key.end());
89
90 clear();
91 commoncrypto_adjust_key_size(key.data(), key.size(), m_opts, full_key);
92
93 CCCryptorStatus status;
94 status =
95 CCCryptorCreate(kCCEncrypt, m_opts.algo, kCCOptionECBMode, full_key.data(), full_key.size(), nullptr, &m_encrypt);
96 if(status != kCCSuccess) {
97 throw CommonCrypto_Error("CCCryptorCreate encrypt", status);
98 }
99 status =
100 CCCryptorCreate(kCCDecrypt, m_opts.algo, kCCOptionECBMode, full_key.data(), full_key.size(), nullptr, &m_decrypt);
101 if(status != kCCSuccess) {
102 throw CommonCrypto_Error("CCCryptorCreate decrypt", status);
103 }
104
105 m_key_set = true;
106}
107
108/*
109* Return a clone of this object
110*/
111std::unique_ptr<BlockCipher> CommonCrypto_BlockCipher::new_object() const {
112 return std::make_unique<CommonCrypto_BlockCipher>(m_cipher_name, m_opts);
113}
114
115/*
116* Clear memory of sensitive data
117*/
118void CommonCrypto_BlockCipher::clear() {
119 m_key_set = false;
120
121 if(m_encrypt) {
122 CCCryptorRelease(m_encrypt);
123 m_encrypt = nullptr;
124 }
125
126 if(m_decrypt) {
127 CCCryptorRelease(m_decrypt);
128 m_decrypt = nullptr;
129 }
130}
131} // namespace
132
133std::unique_ptr<BlockCipher> make_commoncrypto_block_cipher(std::string_view name) {
134 try {
136 return std::make_unique<CommonCrypto_BlockCipher>(name, opts);
137 } catch(CommonCrypto_Error& e) {
138 return nullptr;
139 }
140}
141} // namespace Botan
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 *)
std::unique_ptr< BlockCipher > make_commoncrypto_block_cipher(std::string_view name)
int32_t CCCryptorStatus
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)