Botan 3.0.0
Crypto and TLS for C&
Functions
ffi_cipher.cpp File Reference
#include <botan/ffi.h>
#include <botan/internal/ffi_util.h>
#include <botan/aead.h>

Go to the source code of this file.

Functions

int botan_cipher_clear (botan_cipher_t cipher)
 
int botan_cipher_destroy (botan_cipher_t cipher)
 
int botan_cipher_get_default_nonce_length (botan_cipher_t cipher, size_t *nl)
 
int botan_cipher_get_ideal_update_granularity (botan_cipher_t cipher, size_t *ug)
 
int botan_cipher_get_keyspec (botan_cipher_t cipher, size_t *out_minimum_keylength, size_t *out_maximum_keylength, size_t *out_keylength_modulo)
 
int botan_cipher_get_tag_length (botan_cipher_t cipher, size_t *tl)
 
int botan_cipher_get_update_granularity (botan_cipher_t cipher, size_t *ug)
 
int botan_cipher_init (botan_cipher_t *cipher, const char *cipher_name, uint32_t flags)
 
int botan_cipher_name (botan_cipher_t cipher, char *name, size_t *name_len)
 
int botan_cipher_output_length (botan_cipher_t cipher, size_t in_len, size_t *out_len)
 
int botan_cipher_query_keylen (botan_cipher_t cipher, size_t *out_minimum_keylength, size_t *out_maximum_keylength)
 
int botan_cipher_reset (botan_cipher_t cipher)
 
int botan_cipher_set_associated_data (botan_cipher_t cipher, const uint8_t *ad, size_t ad_len)
 
int botan_cipher_set_key (botan_cipher_t cipher, const uint8_t *key, size_t key_len)
 
int botan_cipher_start (botan_cipher_t cipher_obj, const uint8_t *nonce, size_t nonce_len)
 
int botan_cipher_update (botan_cipher_t cipher_obj, uint32_t flags, uint8_t output_ptr[], size_t orig_output_size, size_t *output_written, const uint8_t input_ptr[], size_t orig_input_size, size_t *input_consumed)
 
int botan_cipher_valid_nonce_length (botan_cipher_t cipher, size_t nl)
 

Function Documentation

◆ botan_cipher_clear()

int botan_cipher_clear ( botan_cipher_t  hash)

Reset the key, nonce, AD and all other state on this cipher object

Definition at line 88 of file ffi_cipher.cpp.

89 {
90 return BOTAN_FFI_VISIT(cipher, [](auto &c) { c.clear(); });
91 }
#define BOTAN_FFI_VISIT(obj, lambda)
Definition: ffi_util.h:126

References BOTAN_FFI_VISIT.

◆ botan_cipher_destroy()

int botan_cipher_destroy ( botan_cipher_t  cipher)

Destroy the cipher object

Returns
0 if success, error if invalid object handle

Definition at line 83 of file ffi_cipher.cpp.

84 {
85 return BOTAN_FFI_CHECKED_DELETE(cipher);
86 }
#define BOTAN_FFI_CHECKED_DELETE(o)
Definition: ffi_util.h:145

References BOTAN_FFI_CHECKED_DELETE.

◆ botan_cipher_get_default_nonce_length()

int botan_cipher_get_default_nonce_length ( botan_cipher_t  cipher,
size_t *  nl 
)

Get the default nonce length of this cipher

Definition at line 259 of file ffi_cipher.cpp.

260 {
261 return BOTAN_FFI_VISIT(cipher, [=](const auto& c) { *nl = c.default_nonce_length(); });
262 }

References BOTAN_FFI_VISIT.

◆ botan_cipher_get_ideal_update_granularity()

int botan_cipher_get_ideal_update_granularity ( botan_cipher_t  cipher,
size_t *  ug 
)

Return the ideal update granularity of the cipher. This is some multiple of the update granularity, reflecting possibilities for optimization.

Definition at line 269 of file ffi_cipher.cpp.

270 {
271 return BOTAN_FFI_VISIT(cipher, [=](const auto& c) { *ug = c.ideal_granularity(); });
272 }

References BOTAN_FFI_VISIT.

◆ botan_cipher_get_keyspec()

int botan_cipher_get_keyspec ( botan_cipher_t  cipher,
size_t *  min_keylen,
size_t *  max_keylen,
size_t *  mod_keylen 
)

Get information about the supported key lengths.

Definition at line 116 of file ffi_cipher.cpp.

120 {
121 return BOTAN_FFI_VISIT(cipher, [=](const auto& c) {
122 if(out_minimum_keylength)
123 *out_minimum_keylength = c.key_spec().minimum_keylength();
124 if(out_maximum_keylength)
125 *out_maximum_keylength = c.key_spec().maximum_keylength();
126 if(out_keylength_modulo)
127 *out_keylength_modulo = c.key_spec().keylength_multiple();
128 });
129 }

References BOTAN_FFI_VISIT.

◆ botan_cipher_get_tag_length()

int botan_cipher_get_tag_length ( botan_cipher_t  cipher,
size_t *  tag_size 
)

Get the tag length of the cipher (0 for non-AEAD modes)

Definition at line 274 of file ffi_cipher.cpp.

275 {
276 return BOTAN_FFI_VISIT(cipher, [=](const auto& c) { *tl = c.tag_size(); });
277 }

References BOTAN_FFI_VISIT.

◆ botan_cipher_get_update_granularity()

int botan_cipher_get_update_granularity ( botan_cipher_t  cipher,
size_t *  ug 
)

Return the update granularity of the cipher; botan_cipher_update must be called with blocks of this size, except for the final.

Definition at line 264 of file ffi_cipher.cpp.

265 {
266 return BOTAN_FFI_VISIT(cipher, [=](const auto& /*c*/) { *ug = cipher->update_size(); });
267 }

References BOTAN_FFI_VISIT.

◆ botan_cipher_init()

int botan_cipher_init ( botan_cipher_t cipher,
const char *  name,
uint32_t  flags 
)

Initialize a cipher object

Definition at line 65 of file ffi_cipher.cpp.

66 {
67 return ffi_guard_thunk(__func__, [=]() -> int {
69 const Botan::Cipher_Dir dir = encrypt_p ?
71
72 std::unique_ptr<Botan::Cipher_Mode> mode(Botan::Cipher_Mode::create(cipher_name, dir));
73 if(!mode)
75
76 const size_t update_size = ffi_choose_update_size(*mode);
77
78 *cipher = new botan_cipher_struct(std::move(mode), update_size);
79 return BOTAN_FFI_SUCCESS;
80 });
81 }
static std::unique_ptr< Cipher_Mode > create(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
Definition: cipher_mode.cpp:50
#define BOTAN_CIPHER_INIT_FLAG_ENCRYPT
Definition: ffi.h:496
#define BOTAN_CIPHER_INIT_FLAG_MASK_DIRECTION
Definition: ffi.h:495
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition: ffi.h:91
@ BOTAN_FFI_SUCCESS
Definition: ffi.h:70
Flags flags(Flag flags)
Definition: p11.h:860
int ffi_guard_thunk(const char *func_name, const std::function< int()> &thunk)
Definition: ffi.cpp:120
Cipher_Dir
Definition: cipher_mode.h:26

References BOTAN_CIPHER_INIT_FLAG_ENCRYPT, BOTAN_CIPHER_INIT_FLAG_MASK_DIRECTION, BOTAN_FFI_ERROR_NOT_IMPLEMENTED, BOTAN_FFI_SUCCESS, Botan::Cipher_Mode::create(), Botan::Decryption, Botan::Encryption, and Botan_FFI::ffi_guard_thunk().

◆ botan_cipher_name()

int botan_cipher_name ( botan_cipher_t  cipher,
char *  name,
size_t *  name_len 
)

Return the name of the cipher object

Definition at line 279 of file ffi_cipher.cpp.

280 {
281 return BOTAN_FFI_VISIT(cipher, [=](const auto& c) {
282 return write_str_output(name, name_len, c.name()); });
283 }
std::string name
int write_str_output(uint8_t out[], size_t *out_len, std::string_view str)
Definition: ffi_util.h:219

References BOTAN_FFI_VISIT, name, and Botan_FFI::write_str_output().

◆ botan_cipher_output_length()

int botan_cipher_output_length ( botan_cipher_t  cipher,
size_t  in_len,
size_t *  out_len 
)

Return the output length of this cipher, for a particular input length.

Definition at line 98 of file ffi_cipher.cpp.

99 {
100 if(out_len == nullptr)
102
103 return BOTAN_FFI_VISIT(cipher, [=](const auto& c) { *out_len = c.output_length(in_len); });
104 }
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition: ffi.h:85

References BOTAN_FFI_ERROR_NULL_POINTER, and BOTAN_FFI_VISIT.

◆ botan_cipher_query_keylen()

int botan_cipher_query_keylen ( botan_cipher_t  cipher,
size_t *  out_minimum_keylength,
size_t *  out_maximum_keylength 
)

Get information about the key lengths. Prefer botan_cipher_get_keyspec

Definition at line 106 of file ffi_cipher.cpp.

109 {
110 return BOTAN_FFI_VISIT(cipher, [=](const auto& c) {
111 *out_minimum_keylength = c.key_spec().minimum_keylength();
112 *out_maximum_keylength = c.key_spec().maximum_keylength();
113 });
114 }

References BOTAN_FFI_VISIT.

◆ botan_cipher_reset()

int botan_cipher_reset ( botan_cipher_t  cipher)

Reset the message specific state for this cipher. Without resetting the keys, this resets the nonce, and any state associated with any message bits that have been processed so far.

It is conceptually equivalent to calling botan_cipher_clear followed by botan_cipher_set_key with the original key.

Definition at line 93 of file ffi_cipher.cpp.

94 {
95 return BOTAN_FFI_VISIT(cipher, [](auto &c) { c.reset(); });
96 }

References BOTAN_FFI_VISIT.

◆ botan_cipher_set_associated_data()

int botan_cipher_set_associated_data ( botan_cipher_t  cipher,
const uint8_t *  ad,
size_t  ad_len 
)

Set the associated data. Will fail if cipher is not an AEAD

Definition at line 238 of file ffi_cipher.cpp.

241 {
242 return BOTAN_FFI_VISIT(cipher, [=](auto& c) {
243 if(Botan::AEAD_Mode* aead = dynamic_cast<Botan::AEAD_Mode*>(&c))
244 {
245 aead->set_associated_data(ad, ad_len);
246 return BOTAN_FFI_SUCCESS;
247 }
249 });
250 }
@ BOTAN_FFI_ERROR_BAD_PARAMETER
Definition: ffi.h:86

References BOTAN_FFI_ERROR_BAD_PARAMETER, BOTAN_FFI_SUCCESS, and BOTAN_FFI_VISIT.

◆ botan_cipher_set_key()

int botan_cipher_set_key ( botan_cipher_t  cipher,
const uint8_t *  key,
size_t  key_len 
)

Set the key for this cipher object

Definition at line 131 of file ffi_cipher.cpp.

133 {
134 return BOTAN_FFI_VISIT(cipher, [=](auto& c) { c.set_key(key, key_len); });
135 }

References BOTAN_FFI_VISIT.

◆ botan_cipher_start()

int botan_cipher_start ( botan_cipher_t  cipher,
const uint8_t *  nonce,
size_t  nonce_len 
)

Begin processing a new message using the provided nonce

Definition at line 137 of file ffi_cipher.cpp.

139 {
140 return ffi_guard_thunk(__func__, [=]() -> int {
141 Botan::Cipher_Mode& cipher = safe_get(cipher_obj);
142 cipher.start(nonce, nonce_len);
143 return BOTAN_FFI_SUCCESS;
144 });
145 }
void start(std::span< const uint8_t > nonce)
Definition: cipher_mode.h:90
T & safe_get(botan_struct< T, M > *p)
Definition: ffi_util.h:69

References BOTAN_FFI_SUCCESS, Botan_FFI::ffi_guard_thunk(), Botan_FFI::safe_get(), and Botan::Cipher_Mode::start().

◆ botan_cipher_update()

int botan_cipher_update ( botan_cipher_t  cipher,
uint32_t  flags,
uint8_t  output[],
size_t  output_size,
size_t *  output_written,
const uint8_t  input_bytes[],
size_t  input_size,
size_t *  input_consumed 
)

Encrypt some data

Definition at line 147 of file ffi_cipher.cpp.

155 {
156 return ffi_guard_thunk(__func__, [=]() -> int {
157
158 size_t input_size = orig_input_size;
159 size_t output_size = orig_output_size;
160 const uint8_t* input = input_ptr;
161 uint8_t* output = output_ptr;
162
163 using namespace Botan;
164 Cipher_Mode& cipher = safe_get(cipher_obj);
165 secure_vector<uint8_t>& mbuf = cipher_obj->buf();
166
167 const bool final_input = (flags & BOTAN_CIPHER_UPDATE_FLAG_FINAL);
168
169 if(final_input)
170 {
171 mbuf.assign(input, input + input_size);
172 *input_consumed = input_size;
173 *output_written = 0;
174
175 try
176 {
177 cipher.finish(mbuf);
178 }
180 {
182 }
183
184 *output_written = mbuf.size();
185
186 if(mbuf.size() <= output_size)
187 {
188 copy_mem(output, mbuf.data(), mbuf.size());
189 mbuf.clear();
190 return BOTAN_FFI_SUCCESS;
191 }
192
193 return -1;
194 }
195
196 if(input_size == 0)
197 {
198 // Currently must take entire buffer in this case
199 *output_written = mbuf.size();
200 if(output_size >= mbuf.size())
201 {
202 copy_mem(output, mbuf.data(), mbuf.size());
203 mbuf.clear();
204 return BOTAN_FFI_SUCCESS;
205 }
206
207 return -1;
208 }
209
210 const size_t ud = cipher_obj->update_size();
211
212 mbuf.resize(ud);
213 size_t taken = 0, written = 0;
214
215 while(input_size >= ud && output_size >= ud)
216 {
217 // FIXME we can use process here and avoid the copy
218 copy_mem(mbuf.data(), input, ud);
219 cipher.update(mbuf);
220
221 input_size -= ud;
222 copy_mem(output, mbuf.data(), ud);
223 input += ud;
224 taken += ud;
225
226 output_size -= ud;
227 output += ud;
228 written += ud;
229 }
230
231 *output_written = written;
232 *input_consumed = taken;
233
234 return BOTAN_FFI_SUCCESS;
235 });
236 }
void finish(secure_vector< uint8_t > &final_block, size_t offset=0)
Definition: cipher_mode.h:158
void update(T &buffer, size_t offset=0)
Definition: cipher_mode.h:144
#define BOTAN_CIPHER_UPDATE_FLAG_FINAL
Definition: ffi.h:584
@ BOTAN_FFI_ERROR_BAD_MAC
Definition: ffi.h:74
Definition: alg_id.cpp:12
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:126
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:64

References BOTAN_CIPHER_UPDATE_FLAG_FINAL, BOTAN_FFI_ERROR_BAD_MAC, BOTAN_FFI_SUCCESS, Botan_FFI::ffi_guard_thunk(), Botan::Cipher_Mode::finish(), Botan_FFI::safe_get(), and Botan::Cipher_Mode::update().

◆ botan_cipher_valid_nonce_length()

int botan_cipher_valid_nonce_length ( botan_cipher_t  cipher,
size_t  nl 
)

Return if the specified nonce length is valid for this cipher

Definition at line 252 of file ffi_cipher.cpp.

253 {
254 return BOTAN_FFI_VISIT(cipher, [=](const auto& c) {
255 return c.valid_nonce_length(nl) ? 1 : 0;
256 });
257 }

References BOTAN_FFI_VISIT.