8 #include <botan/cipher_mode.h>
9 #include <botan/internal/rounding.h>
10 #include <botan/internal/commoncrypto.h>
20 class CommonCrypto_Cipher_Mode
final :
public Cipher_Mode
23 CommonCrypto_Cipher_Mode(
const std::string&
name,
25 const CommonCryptor_Opts& opts);
27 ~CommonCrypto_Cipher_Mode();
29 std::string provider()
const override {
return "commoncrypto"; }
32 void start_msg(
const uint8_t nonce[],
size_t nonce_len)
override;
33 size_t process(uint8_t msg[],
size_t msg_len)
override;
34 void finish(secure_vector<uint8_t>& final_block,
size_t offset0)
override;
35 size_t output_length(
size_t input_length)
const override;
36 size_t update_granularity()
const override;
37 size_t minimum_final_size()
const override;
38 size_t default_nonce_length()
const override;
39 bool valid_nonce_length(
size_t nonce_len)
const override;
40 void clear()
override;
41 void reset()
override;
42 Key_Length_Specification key_spec()
const override;
45 void key_schedule(
const uint8_t key[],
size_t length)
override;
55 CommonCrypto_Cipher_Mode::CommonCrypto_Cipher_Mode(
const std::string&
name,
56 Cipher_Dir direction,
const CommonCryptor_Opts& opts) :
65 CommonCrypto_Cipher_Mode::~CommonCrypto_Cipher_Mode()
73 void CommonCrypto_Cipher_Mode::start_msg(
const uint8_t nonce[],
size_t nonce_len)
77 if(!valid_nonce_length(nonce_len))
78 {
throw Invalid_IV_Length(
name(), nonce_len); }
81 CCCryptorStatus status = CCCryptorReset(
m_cipher, nonce);
82 if(status != kCCSuccess)
84 throw CommonCrypto_Error(
"CCCryptorReset on start_msg", status);
90 size_t CommonCrypto_Cipher_Mode::process(uint8_t msg[],
size_t msg_len)
99 size_t outl = CCCryptorGetOutputLength(
m_cipher, msg_len,
false);
101 secure_vector<uint8_t> out(outl);
103 if(
m_opts.padding == ccNoPadding && msg_len %
m_opts.block_size)
108 CCCryptorStatus status = CCCryptorUpdate(
m_cipher, msg, msg_len,
109 out.data(), outl, &outl);
110 if(status != kCCSuccess)
112 throw CommonCrypto_Error(
"CCCryptorUpdate", status);
119 void CommonCrypto_Cipher_Mode::finish(secure_vector<uint8_t>& buffer,
126 uint8_t* buf = buffer.data() + offset;
127 const size_t buf_size = buffer.size() - offset;
129 size_t written = process(buf, buf_size);
131 size_t outl = CCCryptorGetOutputLength(
m_cipher, buf_size - written,
true);
132 secure_vector<uint8_t> out(outl);
134 CCCryptorStatus status = CCCryptorFinal(
136 if(status != kCCSuccess)
138 throw CommonCrypto_Error(
"CCCryptorFinal", status);
141 size_t new_len = offset + written + outl;
142 if(
m_opts.padding != ccNoPadding || buffer.size() < new_len)
144 buffer.resize(new_len);
146 copy_mem(buffer.data() - offset + written, out.data(), outl);
150 size_t CommonCrypto_Cipher_Mode::update_granularity()
const
152 return m_opts.block_size * BOTAN_BLOCK_CIPHER_PAR_MULT;
155 size_t CommonCrypto_Cipher_Mode::minimum_final_size()
const
163 size_t CommonCrypto_Cipher_Mode::default_nonce_length()
const
168 bool CommonCrypto_Cipher_Mode::valid_nonce_length(
size_t nonce_len)
const
170 return (nonce_len == 0 || nonce_len ==
m_opts.block_size);
173 size_t CommonCrypto_Cipher_Mode::output_length(
size_t input_length)
const
175 if(input_length == 0)
176 {
return m_opts.block_size; }
181 void CommonCrypto_Cipher_Mode::clear()
197 void CommonCrypto_Cipher_Mode::reset()
206 CCCryptorStatus status = CCCryptorReset(
m_cipher,
nullptr);
207 if(status != kCCSuccess)
209 throw CommonCrypto_Error(
"CCCryptorReset", status);
213 Key_Length_Specification CommonCrypto_Cipher_Mode::key_spec()
const
218 void CommonCrypto_Cipher_Mode::key_schedule(
const uint8_t key[],
size_t length)
220 CCCryptorStatus status;
223 nullptr, key, length,
nullptr, 0, 0, 0, &
m_cipher);
224 if(status != kCCSuccess)
226 throw CommonCrypto_Error(
"CCCryptorCreate", status);
241 return new CommonCrypto_Cipher_Mode(name, direction, opts);
CommonCryptor_Opts commoncrypto_opts_from_algo(const std::string &algo)
CommonCryptor_Opts m_opts
const std::string m_mode_name
int(* final)(unsigned char *, CTX *)
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ASSERT(expr, assertion_made)
void copy_mem(T *out, const T *in, size_t n)
size_t round_up(size_t n, size_t align_to)
Cipher_Mode * make_commoncrypto_cipher_mode(const std::string &name, Cipher_Dir direction)