8 #include <botan/internal/commoncrypto.h>
9 #include <botan/internal/commoncrypto_utils.h>
10 #include <botan/cipher_mode.h>
11 #include <botan/internal/rounding.h>
19 class CommonCrypto_Cipher_Mode
final :
public Cipher_Mode
22 CommonCrypto_Cipher_Mode(
const std::string&
name,
24 const CommonCryptor_Opts& opts);
26 ~CommonCrypto_Cipher_Mode();
28 std::string provider()
const override {
return "commoncrypto"; }
31 void start_msg(
const uint8_t nonce[],
size_t nonce_len)
override;
32 size_t process(uint8_t msg[],
size_t msg_len)
override;
33 void finish(secure_vector<uint8_t>& final_block,
size_t offset0)
override;
34 size_t output_length(
size_t input_length)
const override;
35 size_t update_granularity()
const override;
36 size_t minimum_final_size()
const override;
37 size_t default_nonce_length()
const override;
38 bool valid_nonce_length(
size_t nonce_len)
const override;
39 void clear()
override;
40 void reset()
override;
41 Key_Length_Specification key_spec()
const override;
44 void key_schedule(
const uint8_t key[],
size_t length)
override;
54 CommonCrypto_Cipher_Mode::CommonCrypto_Cipher_Mode(
const std::string&
name,
55 Cipher_Dir direction,
const CommonCryptor_Opts& opts) :
64 CommonCrypto_Cipher_Mode::~CommonCrypto_Cipher_Mode()
72 void CommonCrypto_Cipher_Mode::start_msg(
const uint8_t nonce[],
size_t nonce_len)
76 if(!valid_nonce_length(nonce_len))
77 {
throw Invalid_IV_Length(
name(), nonce_len); }
80 CCCryptorStatus status = CCCryptorReset(
m_cipher, nonce);
81 if(status != kCCSuccess)
83 throw CommonCrypto_Error(
"CCCryptorReset on start_msg", status);
89 size_t CommonCrypto_Cipher_Mode::process(uint8_t msg[],
size_t msg_len)
98 size_t outl = CCCryptorGetOutputLength(
m_cipher, msg_len,
false);
100 secure_vector<uint8_t> out(outl);
102 if(
m_opts.padding == ccNoPadding && msg_len %
m_opts.block_size)
107 CCCryptorStatus status = CCCryptorUpdate(
m_cipher, msg, msg_len,
108 out.data(), outl, &outl);
109 if(status != kCCSuccess)
111 throw CommonCrypto_Error(
"CCCryptorUpdate", status);
118 void CommonCrypto_Cipher_Mode::finish(secure_vector<uint8_t>& buffer,
125 uint8_t* buf = buffer.data() + offset;
126 const size_t buf_size = buffer.size() - offset;
128 size_t written = process(buf, buf_size);
130 size_t outl = CCCryptorGetOutputLength(
m_cipher, buf_size - written,
true);
131 secure_vector<uint8_t> out(outl);
133 CCCryptorStatus status = CCCryptorFinal(
135 if(status != kCCSuccess)
137 throw CommonCrypto_Error(
"CCCryptorFinal", status);
140 size_t new_len = offset + written + outl;
141 if(
m_opts.padding != ccNoPadding || buffer.size() < new_len)
143 buffer.resize(new_len);
145 copy_mem(buffer.data() - offset + written, out.data(), outl);
149 size_t CommonCrypto_Cipher_Mode::update_granularity()
const
151 return m_opts.block_size * BOTAN_BLOCK_CIPHER_PAR_MULT;
154 size_t CommonCrypto_Cipher_Mode::minimum_final_size()
const
162 size_t CommonCrypto_Cipher_Mode::default_nonce_length()
const
167 bool CommonCrypto_Cipher_Mode::valid_nonce_length(
size_t nonce_len)
const
169 return (nonce_len == 0 || nonce_len ==
m_opts.block_size);
172 size_t CommonCrypto_Cipher_Mode::output_length(
size_t input_length)
const
174 if(input_length == 0)
175 {
return m_opts.block_size; }
180 void CommonCrypto_Cipher_Mode::clear()
196 void CommonCrypto_Cipher_Mode::reset()
205 CCCryptorStatus status = CCCryptorReset(
m_cipher,
nullptr);
206 if(status != kCCSuccess)
208 throw CommonCrypto_Error(
"CCCryptorReset", status);
212 Key_Length_Specification CommonCrypto_Cipher_Mode::key_spec()
const
217 void CommonCrypto_Cipher_Mode::key_schedule(
const uint8_t key[],
size_t length)
219 CCCryptorStatus status;
222 nullptr, key, length,
nullptr, 0, 0, 0, &
m_cipher);
223 if(status != kCCSuccess)
225 throw CommonCrypto_Error(
"CCCryptorCreate", status);
240 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)