8#include <botan/internal/commoncrypto.h>
10#include <botan/block_cipher.h>
12#include <botan/internal/commoncrypto_utils.h>
14#include <CommonCrypto/CommonCrypto.h>
20class CommonCrypto_BlockCipher final :
public BlockCipher {
22 CommonCrypto_BlockCipher(std::string_view name,
const CommonCryptor_Opts& opts);
24 ~CommonCrypto_BlockCipher();
26 void clear()
override;
28 std::string provider()
const override {
return "commoncrypto"; }
30 std::string name()
const override {
return m_cipher_name; }
32 std::unique_ptr<BlockCipher> new_object()
const override;
34 size_t block_size()
const override {
return m_opts.block_size; }
36 Key_Length_Specification key_spec()
const override {
return m_opts.key_spec; }
38 bool has_keying_material()
const override {
return m_key_set; }
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;
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);
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;
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);
62 void key_schedule(std::span<const uint8_t> key)
override;
64 std::string m_cipher_name;
65 CommonCryptor_Opts m_opts;
67 CCCryptorRef m_encrypt =
nullptr;
68 CCCryptorRef m_decrypt =
nullptr;
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) {}
75CommonCrypto_BlockCipher::~CommonCrypto_BlockCipher() {
77 CCCryptorRelease(m_encrypt);
80 CCCryptorRelease(m_decrypt);
87void CommonCrypto_BlockCipher::key_schedule(std::span<const uint8_t> key) {
88 secure_vector<uint8_t> full_key(key.begin(), key.end());
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);
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);
111std::unique_ptr<BlockCipher> CommonCrypto_BlockCipher::new_object()
const {
112 return std::make_unique<CommonCrypto_BlockCipher>(m_cipher_name, m_opts);
118void CommonCrypto_BlockCipher::clear() {
122 CCCryptorRelease(m_encrypt);
127 CCCryptorRelease(m_decrypt);
136 return std::make_unique<CommonCrypto_BlockCipher>(name, opts);
std::unique_ptr< BlockCipher > make_commoncrypto_block_cipher(std::string_view name)
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)