1 /*
2 * FFI (C89 API)
3 * (C) 2015,2017 Jack Lloyd
4 * (C) 2021 René Fischer
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #ifndef BOTAN_FFI_H_
10 #define BOTAN_FFI_H_
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 /*
17 This header exports some of botan's functionality via a C89 interface. This API
18 is uesd by the Python, OCaml, Rust and Ruby bindings via those languages
19 respective ctypes/FFI libraries.
20 
21 The API is intended to be as easy as possible to call from other
22 languages, which often have easy ways to call C, because C. But some C
23 code is easier to deal with than others, so to make things easy this
24 API follows a few simple rules:
25 
26 - All interactions are via pointers to opaque structs. No need to worry about
27   structure padding issues and the like.
28 
29 - All functions return an int error code (except the version calls, which are
30   assumed to always have something to say).
31 
32 - Use simple types: size_t for lengths, const char* NULL terminated strings,
33   uint8_t for binary.
34 
35 - No ownership of memory transfers across the API boundary. The API will
36   consume data from const pointers, and will produce output by writing to
37   buffers provided by (and allocated by) the caller.
38 
39 - If exporting a value (a string or a blob) the function takes a pointer to the
40   output array and a read/write pointer to the length. If the length is insufficient, an
41   error is returned. So passing nullptr/0 allows querying the final value.
42 
43   Note this does not apply to all functions, like `botan_hash_final`
44   which is not idempotent and are documented specially. But it's a
45   general theory of operation.
46 
47  TODO:
48  - Doxygen comments for all functions/params
49  - TLS
50 */
51 
52 #include <botan/build.h>
53 #include <stdint.h>
54 #include <stddef.h>
55 
56 /**
57 * Error codes
58 *
59 * If you add a new value here be sure to also add it in
60 * botan_error_description
61 */
62 enum BOTAN_FFI_ERROR {
63    BOTAN_FFI_SUCCESS = 0,
64    BOTAN_FFI_INVALID_VERIFIER = 1,
65 
66    BOTAN_FFI_ERROR_INVALID_INPUT = -1,
67    BOTAN_FFI_ERROR_BAD_MAC = -2,
68 
69    BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE = -10,
70 
71    BOTAN_FFI_ERROR_EXCEPTION_THROWN = -20,
72    BOTAN_FFI_ERROR_OUT_OF_MEMORY = -21,
73    BOTAN_FFI_ERROR_SYSTEM_ERROR = -22,
74    BOTAN_FFI_ERROR_INTERNAL_ERROR = -23,
75 
76    BOTAN_FFI_ERROR_BAD_FLAG = -30,
77    BOTAN_FFI_ERROR_NULL_POINTER = -31,
78    BOTAN_FFI_ERROR_BAD_PARAMETER = -32,
79    BOTAN_FFI_ERROR_KEY_NOT_SET = -33,
80    BOTAN_FFI_ERROR_INVALID_KEY_LENGTH = -34,
81    BOTAN_FFI_ERROR_INVALID_OBJECT_STATE = -35,
82 
83    BOTAN_FFI_ERROR_NOT_IMPLEMENTED = -40,
84    BOTAN_FFI_ERROR_INVALID_OBJECT = -50,
85 
86    BOTAN_FFI_ERROR_TLS_ERROR = -75,
87    BOTAN_FFI_ERROR_HTTP_ERROR = -76,
88    BOTAN_FFI_ERROR_ROUGHTIME_ERROR = -77,
89 
90    BOTAN_FFI_ERROR_UNKNOWN_ERROR = -100,
91 };
92 
93 /**
94 * Convert an error code into a string. Returns "Unknown error"
95 * if the error code is not a known one.
96 */
97 BOTAN_PUBLIC_API(2,8) const char* botan_error_description(int err);
98 
99 /**
100 * Return the version of the currently supported FFI API. This is
101 * expressed in the form YYYYMMDD of the release date of this version
102 * of the API.
103 */
104 BOTAN_PUBLIC_API(2,0) uint32_t botan_ffi_api_version(void);
105 
106 /**
107 * Return 0 (ok) if the version given is one this library supports.
108 * botan_ffi_supports_api(botan_ffi_api_version()) will always return 0.
109 */
110 BOTAN_PUBLIC_API(2,0) int botan_ffi_supports_api(uint32_t api_version);
111 
112 /**
113 * Return a free-form version string, e.g., 2.0.0
114 */
115 BOTAN_PUBLIC_API(2,0) const char* botan_version_string(void);
116 
117 /**
118 * Return the major version of the library
119 */
120 BOTAN_PUBLIC_API(2,0) uint32_t botan_version_major(void);
121 
122 /**
123 * Return the minor version of the library
124 */
125 BOTAN_PUBLIC_API(2,0) uint32_t botan_version_minor(void);
126 
127 /**
128 * Return the patch version of the library
129 */
130 BOTAN_PUBLIC_API(2,0) uint32_t botan_version_patch(void);
131 
132 /**
133 * Return the date this version was released as
134 * an integer, or 0 if an unreleased version
135 */
136 BOTAN_PUBLIC_API(2,0) uint32_t botan_version_datestamp(void);
137 
138 /**
139 * Returns 0 if x[0..len] == y[0..len], or otherwise -1
140 */
141 BOTAN_PUBLIC_API(2,3) int botan_constant_time_compare(const uint8_t* x, const uint8_t* y, size_t len);
142 
143 /**
144 * Deprecated equivalent to botan_constant_time_compare
145 */
146 BOTAN_PUBLIC_API(2,0) int botan_same_mem(const uint8_t* x, const uint8_t* y, size_t len);
147 
148 /**
149 * Clear out memory using a system specific approach to bypass elision by the
150 * compiler (currently using RtlSecureZeroMemory or tricks with volatile pointers).
151 */
152 BOTAN_PUBLIC_API(2,2) int botan_scrub_mem(void* mem, size_t bytes);
153 
154 #define BOTAN_FFI_HEX_LOWER_CASE 1
155 
156 /**
157 * Perform hex encoding
158 * @param x is some binary data
159 * @param len length of x in bytes
160 * @param out an array of at least x*2 bytes
161 * @param flags flags out be upper or lower case?
162 * @return 0 on success, 1 on failure
163 */
164 BOTAN_PUBLIC_API(2,0) int botan_hex_encode(const uint8_t* x, size_t len, char* out, uint32_t flags);
165 
166 /**
167 * Perform hex decoding
168 * @param hex_str a string of hex chars (whitespace is ignored)
169 * @param in_len the length of hex_str
170 * @param out the output buffer should be at least strlen(hex_str)/2 bytes
171 * @param out_len the size of out
172 */
173 BOTAN_PUBLIC_API(2,3) int botan_hex_decode(const char* hex_str, size_t in_len, uint8_t* out, size_t* out_len);
174 
175 /**
176 * Perform base64 encoding
177 */
178 BOTAN_PUBLIC_API(2,3) int botan_base64_encode(const uint8_t* x, size_t len, char* out, size_t* out_len);
179 
180 
181 /**
182 * Perform base64 decoding
183 */
184 BOTAN_PUBLIC_API(2,3) int botan_base64_decode(const char* base64_str, size_t in_len,
185                                               uint8_t* out, size_t* out_len);
186 
187 /**
188 * RNG type
189 */
190 typedef struct botan_rng_struct* botan_rng_t;
191 
192 /**
193 * Initialize a random number generator object
194 * @param rng rng object
195 * @param rng_type type of the rng, possible values:
196 *    "system": system RNG
197 *    "user": userspace RNG
198 *    "user-threadsafe": userspace RNG, with internal locking
199 *    "rdrand": directly read RDRAND
200 * Set rng_type to null to let the library choose some default.
201 */
202 BOTAN_PUBLIC_API(2,0) int botan_rng_init(botan_rng_t* rng, const char* rng_type);
203 
204 /**
205 * Initialize a custom random number generator from a set of callback functions
206 * @param rng rng object
207 * @param rng_name name of the rng
208 * @param context An application-specific context passed to the callback functions
209 * @param get_cb Callback for getting random bytes from the rng, return 0 for success
210 * @param add_entry_cb Callback for adding entropy to the rng, return 0 for success, may be NULL
211 * @param destroy_cb Callback called when rng is destroyed, may be NULL
212 */
213 BOTAN_PUBLIC_API(2,18) int botan_rng_init_custom(botan_rng_t* rng_out, const char* rng_name, void* context,
214                                                  int(* get_cb)(void* context, uint8_t* out, size_t out_len),
215                                                  int(* add_entropy_cb)(void* context, const uint8_t input[], size_t length),
216                                                  void(* destroy_cb)(void* context));
217 
218 /**
219 * Get random bytes from a random number generator
220 * @param rng rng object
221 * @param out output buffer of size out_len
222 * @param out_len number of requested bytes
223 * @return 0 on success, negative on failure
224 */
225 BOTAN_PUBLIC_API(2,0) int botan_rng_get(botan_rng_t rng, uint8_t* out, size_t out_len);
226 
227 /**
228 * Reseed a random number generator
229 * Uses the System_RNG as a seed generator.
230 *
231 * @param rng rng object
232 * @param bits number of bits to to reseed with
233 * @return 0 on success, a negative value on failure
234 */
235 BOTAN_PUBLIC_API(2,0) int botan_rng_reseed(botan_rng_t rng, size_t bits);
236 
237 /**
238 * Reseed a random number generator
239 *
240 * @param rng rng object
241 * @param source_rng the rng that will be read from
242 * @param bits number of bits to to reseed with
243 * @return 0 on success, a negative value on failure
244 */
245 BOTAN_PUBLIC_API(2,8) int botan_rng_reseed_from_rng(botan_rng_t rng,
246                                                     botan_rng_t source_rng,
247                                                     size_t bits);
248 
249 /**
250 * Add some seed material to a random number generator
251 *
252 * @param rng rng object
253 * @param entropy the data to add
254 * @param entropy_len length of entropy buffer
255 * @return 0 on success, a negative value on failure
256 */
257 BOTAN_PUBLIC_API(2,8) int botan_rng_add_entropy(botan_rng_t rng,
258                                                 const uint8_t* entropy,
259                                                 size_t entropy_len);
260 
261 /**
262 * Frees all resources of the random number generator object
263 * @param rng rng object
264 * @return 0 if success, error if invalid object handle
265 */
266 BOTAN_PUBLIC_API(2,0) int botan_rng_destroy(botan_rng_t rng);
267 
268 /*
269 * Hash type
270 */
271 typedef struct botan_hash_struct* botan_hash_t;
272 
273 /**
274 * Initialize a hash function object
275 * @param hash hash object
276 * @param hash_name name of the hash function, e.g., "SHA-384"
277 * @param flags should be 0 in current API revision, all other uses are reserved
278 *       and return BOTAN_FFI_ERROR_BAD_FLAG
279 */
280 BOTAN_PUBLIC_API(2,0) int botan_hash_init(botan_hash_t* hash, const char* hash_name, uint32_t flags);
281 
282 /**
283 * Copy the state of a hash function object
284 * @param dest destination hash object
285 * @param source source hash object
286 * @return 0 on success, a negative value on failure
287 */
288 BOTAN_PUBLIC_API(2,2) int botan_hash_copy_state(botan_hash_t *dest, const botan_hash_t source);
289 
290 /**
291 * Writes the output length of the hash function to *output_length
292 * @param hash hash object
293 * @param output_length output buffer to hold the hash function output length
294 * @return 0 on success, a negative value on failure
295 */
296 BOTAN_PUBLIC_API(2,0) int botan_hash_output_length(botan_hash_t hash, size_t* output_length);
297 
298 /**
299 * Writes the block size of the hash function to *block_size
300 * @param hash hash object
301 * @param block_size output buffer to hold the hash function output length
302 * @return 0 on success, a negative value on failure
303 */
304 BOTAN_PUBLIC_API(2,2) int botan_hash_block_size(botan_hash_t hash, size_t* block_size);
305 
306 /**
307 * Send more input to the hash function
308 * @param hash hash object
309 * @param in input buffer
310 * @param in_len number of bytes to read from the input buffer
311 * @return 0 on success, a negative value on failure
312 */
313 BOTAN_PUBLIC_API(2,0) int botan_hash_update(botan_hash_t hash, const uint8_t* in, size_t in_len);
314 
315 /**
316 * Finalizes the hash computation and writes the output to
317 * out[0:botan_hash_output_length()] then reinitializes for computing
318 * another digest as if botan_hash_clear had been called.
319 * @param hash hash object
320 * @param out output buffer
321 * @return 0 on success, a negative value on failure
322 */
323 BOTAN_PUBLIC_API(2,0) int botan_hash_final(botan_hash_t hash, uint8_t out[]);
324 
325 /**
326 * Reinitializes the state of the hash computation. A hash can
327 * be computed (with update/final) immediately.
328 * @param hash hash object
329 * @return 0 on success, a negative value on failure
330 */
331 BOTAN_PUBLIC_API(2,0) int botan_hash_clear(botan_hash_t hash);
332 
333 /**
334 * Frees all resources of the hash object
335 * @param hash hash object
336 * @return 0 if success, error if invalid object handle
337 */
338 BOTAN_PUBLIC_API(2,0) int botan_hash_destroy(botan_hash_t hash);
339 
340 /**
341 * Get the name of this hash function
342 * @param hash the object to read
343 * @param name output buffer
344 * @param name_len on input, the length of buffer, on success the number of bytes written
345 */
346 BOTAN_PUBLIC_API(2,8) int botan_hash_name(botan_hash_t hash, char* name, size_t* name_len);
347 
348 /*
349 * Message Authentication type
350 */
351 typedef struct botan_mac_struct* botan_mac_t;
352 
353 /**
354 * Initialize a message authentication code object
355 * @param mac mac object
356 * @param mac_name name of the hash function, e.g., "HMAC(SHA-384)"
357 * @param flags should be 0 in current API revision, all other uses are reserved
358 *       and return a negative value (error code)
359 * @return 0 on success, a negative value on failure
360 */
361 BOTAN_PUBLIC_API(2,0) int botan_mac_init(botan_mac_t* mac, const char* mac_name, uint32_t flags);
362 
363 /**
364 * Writes the output length of the message authentication code to *output_length
365 * @param mac mac object
366 * @param output_length output buffer to hold the MAC output length
367 * @return 0 on success, a negative value on failure
368 */
369 BOTAN_PUBLIC_API(2,0) int botan_mac_output_length(botan_mac_t mac, size_t* output_length);
370 
371 /**
372 * Sets the key on the MAC
373 * @param mac mac object
374 * @param key buffer holding the key
375 * @param key_len size of the key buffer in bytes
376 * @return 0 on success, a negative value on failure
377 */
378 BOTAN_PUBLIC_API(2,0) int botan_mac_set_key(botan_mac_t mac, const uint8_t* key, size_t key_len);
379 
380 /**
381 * Send more input to the message authentication code
382 * @param mac mac object
383 * @param buf input buffer
384 * @param len number of bytes to read from the input buffer
385 * @return 0 on success, a negative value on failure
386 */
387 BOTAN_PUBLIC_API(2,0) int botan_mac_update(botan_mac_t mac, const uint8_t* buf, size_t len);
388 
389 /**
390 * Finalizes the MAC computation and writes the output to
391 * out[0:botan_mac_output_length()] then reinitializes for computing
392 * another MAC as if botan_mac_clear had been called.
393 * @param mac mac object
394 * @param out output buffer
395 * @return 0 on success, a negative value on failure
396 */
397 BOTAN_PUBLIC_API(2,0) int botan_mac_final(botan_mac_t mac, uint8_t out[]);
398 
399 /**
400 * Reinitializes the state of the MAC computation. A MAC can
401 * be computed (with update/final) immediately.
402 * @param mac mac object
403 * @return 0 on success, a negative value on failure
404 */
405 BOTAN_PUBLIC_API(2,0) int botan_mac_clear(botan_mac_t mac);
406 
407 /**
408 * Get the name of this MAC
409 * @param mac the object to read
410 * @param name output buffer
411 * @param name_len on input, the length of buffer, on success the number of bytes written
412 */
413 BOTAN_PUBLIC_API(2,8) int botan_mac_name(botan_mac_t mac, char* name, size_t* name_len);
414 
415 /**
416 * Get the key length limits of this auth code
417 * @param mac the object to read
418 * @param out_minimum_keylength if non-NULL, will be set to minimum keylength of MAC
419 * @param out_maximum_keylength if non-NULL, will be set to maximum keylength of MAC
420 * @param out_keylength_modulo if non-NULL will be set to byte multiple of valid keys
421 */
422 BOTAN_PUBLIC_API(2,8) int botan_mac_get_keyspec(botan_mac_t mac,
423                                                  size_t* out_minimum_keylength,
424                                                  size_t* out_maximum_keylength,
425                                                  size_t* out_keylength_modulo);
426 
427 /**
428 * Frees all resources of the MAC object
429 * @param mac mac object
430 * @return 0 if success, error if invalid object handle
431 */
432 BOTAN_PUBLIC_API(2,0) int botan_mac_destroy(botan_mac_t mac);
433 
434 /*
435 * Cipher modes
436 */
437 typedef struct botan_cipher_struct* botan_cipher_t;
438 
439 #define BOTAN_CIPHER_INIT_FLAG_MASK_DIRECTION 1
440 #define BOTAN_CIPHER_INIT_FLAG_ENCRYPT 0
441 #define BOTAN_CIPHER_INIT_FLAG_DECRYPT 1
442 
443 /**
444 * Initialize a cipher object
445 */
446 BOTAN_PUBLIC_API(2,0) int botan_cipher_init(botan_cipher_t* cipher, const char* name, uint32_t flags);
447 
448 /**
449 * Return the name of the cipher object
450 */
451 BOTAN_PUBLIC_API(2,8) int botan_cipher_name(botan_cipher_t cipher, char* name, size_t* name_len);
452 
453 /**
454 * Return the output length of this cipher, for a particular input length.
455 */
456 BOTAN_PUBLIC_API(2,8) int botan_cipher_output_length(botan_cipher_t cipher, size_t in_len, size_t* out_len);
457 
458 /**
459 * Return if the specified nonce length is valid for this cipher
460 */
461 BOTAN_PUBLIC_API(2,0) int botan_cipher_valid_nonce_length(botan_cipher_t cipher, size_t nl);
462 
463 /**
464 * Get the tag length of the cipher (0 for non-AEAD modes)
465 */
466 BOTAN_PUBLIC_API(2,0) int botan_cipher_get_tag_length(botan_cipher_t cipher, size_t* tag_size);
467 
468 /**
469 * Get the default nonce length of this cipher
470 */
471 BOTAN_PUBLIC_API(2,0) int botan_cipher_get_default_nonce_length(botan_cipher_t cipher, size_t* nl);
472 
473 /**
474 * Return the update granularity of the cipher; botan_cipher_update must be
475 * called with blocks of this size, except for the final.
476 */
477 BOTAN_PUBLIC_API(2,0) int botan_cipher_get_update_granularity(botan_cipher_t cipher, size_t* ug);
478 
479 /**
480 * Get information about the key lengths. Prefer botan_cipher_get_keyspec
481 */
482 BOTAN_PUBLIC_API(2,0) int botan_cipher_query_keylen(botan_cipher_t,
483                                         size_t* out_minimum_keylength,
484                                         size_t* out_maximum_keylength);
485 
486 /**
487 * Get information about the supported key lengths.
488 */
489 BOTAN_PUBLIC_API(2,8) int botan_cipher_get_keyspec(botan_cipher_t,
490                                                    size_t* min_keylen,
491                                                    size_t* max_keylen,
492                                                    size_t* mod_keylen);
493 
494 /**
495 * Set the key for this cipher object
496 */
497 BOTAN_PUBLIC_API(2,0) int botan_cipher_set_key(botan_cipher_t cipher,
498                                                const uint8_t* key, size_t key_len);
499 
500 /**
501 * Reset the message specific state for this cipher.
502 * Without resetting the keys, this resets the nonce, and any state
503 * associated with any message bits that have been processed so far.
504 *
505 * It is conceptually equivalent to calling botan_cipher_clear followed
506 * by botan_cipher_set_key with the original key.
507 */
508 BOTAN_PUBLIC_API(2,8) int botan_cipher_reset(botan_cipher_t cipher);
509 
510 /**
511 * Set the associated data. Will fail if cipher is not an AEAD
512 */
513 BOTAN_PUBLIC_API(2,0) int botan_cipher_set_associated_data(botan_cipher_t cipher,
514                                                const uint8_t* ad, size_t ad_len);
515 
516 /**
517 * Begin processing a new message using the provided nonce
518 */
519 BOTAN_PUBLIC_API(2,0) int botan_cipher_start(botan_cipher_t cipher,
520                                  const uint8_t* nonce, size_t nonce_len);
521 
522 #define BOTAN_CIPHER_UPDATE_FLAG_FINAL (1U << 0)
523 
524 /**
525 * Encrypt some data
526 */
527 BOTAN_PUBLIC_API(2,0) int botan_cipher_update(botan_cipher_t cipher,
528                                   uint32_t flags,
529                                   uint8_t output[],
530                                   size_t output_size,
531                                   size_t* output_written,
532                                   const uint8_t input_bytes[],
533                                   size_t input_size,
534                                   size_t* input_consumed);
535 
536 /**
537 * Reset the key, nonce, AD and all other state on this cipher object
538 */
539 BOTAN_PUBLIC_API(2,0) int botan_cipher_clear(botan_cipher_t hash);
540 
541 /**
542 * Destroy the cipher object
543 * @return 0 if success, error if invalid object handle
544 */
545 BOTAN_PUBLIC_API(2,0) int botan_cipher_destroy(botan_cipher_t cipher);
546 
547 /*
548 * Derive a key from a passphrase for a number of iterations
549 * @param pbkdf_algo PBKDF algorithm, e.g., "PBKDF2(SHA-256)"
550 * @param out buffer to store the derived key, must be of out_len bytes
551 * @param out_len the desired length of the key to produce
552 * @param passphrase the password to derive the key from
553 * @param salt a randomly chosen salt
554 * @param salt_len length of salt in bytes
555 * @param iterations the number of iterations to use (use 10K or more)
556 * @return 0 on success, a negative value on failure
557 *
558 * Deprecated: use
559 *  botan_pwdhash(pbkdf_algo, iterations, 0, 0, out, out_len,
560 *                passphrase, 0, salt, salt_len);
561 */
562 BOTAN_PUBLIC_API(2,0) int
563 BOTAN_DEPRECATED("Use botan_pwdhash")
564 botan_pbkdf(const char* pbkdf_algo,
565             uint8_t out[], size_t out_len,
566             const char* passphrase,
567             const uint8_t salt[], size_t salt_len,
568             size_t iterations);
569 
570 /**
571 * Derive a key from a passphrase, running until msec time has elapsed.
572 * @param pbkdf_algo PBKDF algorithm, e.g., "PBKDF2(SHA-256)"
573 * @param out buffer to store the derived key, must be of out_len bytes
574 * @param out_len the desired length of the key to produce
575 * @param passphrase the password to derive the key from
576 * @param salt a randomly chosen salt
577 * @param salt_len length of salt in bytes
578 * @param milliseconds_to_run if iterations is zero, then instead the PBKDF is
579 *        run until milliseconds_to_run milliseconds has passed
580 * @param out_iterations_used set to the number iterations executed
581 * @return 0 on success, a negative value on failure
582 *
583 * Deprecated: use
584 *
585 * botan_pwdhash_timed(pbkdf_algo,
586 *                     static_cast<uint32_t>(ms_to_run),
587 *                     iterations_used,
588 *                     nullptr,
589 *                     nullptr,
590 *                     out, out_len,
591 *                     password, 0,
592 *                     salt, salt_len);
593 */
594 BOTAN_PUBLIC_API(2,0) int botan_pbkdf_timed(const char* pbkdf_algo,
595                                 uint8_t out[], size_t out_len,
596                                 const char* passphrase,
597                                 const uint8_t salt[], size_t salt_len,
598                                 size_t milliseconds_to_run,
599                                 size_t* out_iterations_used);
600 
601 
602 /*
603 * Derive a key from a passphrase
604 * @param algo PBKDF algorithm, e.g., "PBKDF2(SHA-256)" or "Scrypt"
605 * @param param1 the first PBKDF algorithm parameter
606 * @param param2 the second PBKDF algorithm parameter (may be zero if unneeded)
607 * @param param3 the third PBKDF algorithm parameter (may be zero if unneeded)
608 * @param out buffer to store the derived key, must be of out_len bytes
609 * @param out_len the desired length of the key to produce
610 * @param passphrase the password to derive the key from
611 * @param passphrase_len if > 0, specifies length of password. If len == 0, then
612 *        strlen will be called on passphrase to compute the length.
613 * @param salt a randomly chosen salt
614 * @param salt_len length of salt in bytes
615 * @return 0 on success, a negative value on failure
616 */
617 int BOTAN_PUBLIC_API(2,8) botan_pwdhash(
618    const char* algo,
619    size_t param1,
620    size_t param2,
621    size_t param3,
622    uint8_t out[],
623    size_t out_len,
624    const char* passphrase,
625    size_t passphrase_len,
626    const uint8_t salt[],
627    size_t salt_len);
628 
629 /*
630 * Derive a key from a passphrase
631 * @param pbkdf_algo PBKDF algorithm, e.g., "Scrypt" or "PBKDF2(SHA-256)"
632 * @param msec the desired runtime in milliseconds
633 * @param param1 will be set to the first password hash parameter
634 * @param param2 will be set to the second password hash parameter
635 * @param param3 will be set to the third password hash parameter
636 * @param out buffer to store the derived key, must be of out_len bytes
637 * @param out_len the desired length of the key to produce
638 * @param passphrase the password to derive the key from
639 * @param passphrase_len if > 0, specifies length of password. If len == 0, then
640 *        strlen will be called on passphrase to compute the length.
641 * @param salt a randomly chosen salt
642 * @param salt_len length of salt in bytes
643 * @return 0 on success, a negative value on failure
644 */
645 int BOTAN_PUBLIC_API(2,8) botan_pwdhash_timed(
646    const char* algo,
647    uint32_t msec,
648    size_t* param1,
649    size_t* param2,
650    size_t* param3,
651    uint8_t out[],
652    size_t out_len,
653    const char* passphrase,
654    size_t passphrase_len,
655    const uint8_t salt[],
656    size_t salt_len);
657 
658 /**
659 * Derive a key using scrypt
660 * Deprecated; use
661 * botan_pwdhash("Scrypt", N, r, p, out, out_len, password, 0, salt, salt_len);
662 */
663 BOTAN_PUBLIC_API(2,8) int
664 BOTAN_DEPRECATED("Use botan_pwdhash")
665 botan_scrypt(uint8_t out[], size_t out_len,
666              const char* passphrase,
667              const uint8_t salt[], size_t salt_len,
668              size_t N, size_t r, size_t p);
669 
670 /**
671 * Derive a key
672 * @param kdf_algo KDF algorithm, e.g., "SP800-56C"
673 * @param out buffer holding the derived key, must be of length out_len
674 * @param out_len the desired output length in bytes
675 * @param secret the secret input
676 * @param secret_len size of secret in bytes
677 * @param salt a diversifier
678 * @param salt_len size of salt in bytes
679 * @param label purpose for the derived keying material
680 * @param label_len size of label in bytes
681 * @return 0 on success, a negative value on failure
682 */
683 BOTAN_PUBLIC_API(2,0) int botan_kdf(const char* kdf_algo,
684                         uint8_t out[], size_t out_len,
685                         const uint8_t secret[], size_t secret_len,
686                         const uint8_t salt[], size_t salt_len,
687                         const uint8_t label[], size_t label_len);
688 
689 /*
690 * Raw Block Cipher (PRP) interface
691 */
692 typedef struct botan_block_cipher_struct* botan_block_cipher_t;
693 
694 /**
695 * Initialize a block cipher object
696 */
697 BOTAN_PUBLIC_API(2,1) int botan_block_cipher_init(botan_block_cipher_t* bc,
698                                                   const char* cipher_name);
699 
700 /**
701 * Destroy a block cipher object
702 * @return 0 if success, error if invalid object handle
703 */
704 BOTAN_PUBLIC_API(2,1) int botan_block_cipher_destroy(botan_block_cipher_t bc);
705 
706 /**
707 * Reinitializes the block cipher
708 * @return 0 on success, a negative value on failure
709 */
710 BOTAN_PUBLIC_API(2,1) int botan_block_cipher_clear(botan_block_cipher_t bc);
711 
712 /**
713 * Set the key for a block cipher instance
714 */
715 BOTAN_PUBLIC_API(2,1) int botan_block_cipher_set_key(botan_block_cipher_t bc,
716                                                      const uint8_t key[], size_t len);
717 
718 /**
719 * Return the positive block size of this block cipher, or negative to
720 * indicate an error
721 */
722 BOTAN_PUBLIC_API(2,1) int botan_block_cipher_block_size(botan_block_cipher_t bc);
723 
724 /**
725 * Encrypt one or more blocks with the cipher
726 */
727 BOTAN_PUBLIC_API(2,1) int botan_block_cipher_encrypt_blocks(botan_block_cipher_t bc,
728                                                             const uint8_t in[],
729                                                             uint8_t out[],
730                                                             size_t blocks);
731 
732 /**
733 * Decrypt one or more blocks with the cipher
734 */
735 BOTAN_PUBLIC_API(2,1) int botan_block_cipher_decrypt_blocks(botan_block_cipher_t bc,
736                                                             const uint8_t in[],
737                                                             uint8_t out[],
738                                                             size_t blocks);
739 
740 /**
741 * Get the name of this block cipher
742 * @param cipher the object to read
743 * @param name output buffer
744 * @param name_len on input, the length of buffer, on success the number of bytes written
745 */
746 BOTAN_PUBLIC_API(2,8) int botan_block_cipher_name(botan_block_cipher_t cipher,
747                                                   char* name, size_t* name_len);
748 
749 
750 /**
751 * Get the key length limits of this block cipher
752 * @param cipher the object to read
753 * @param out_minimum_keylength if non-NULL, will be set to minimum keylength of cipher
754 * @param out_maximum_keylength if non-NULL, will be set to maximum keylength of cipher
755 * @param out_keylength_modulo if non-NULL will be set to byte multiple of valid keys
756 */
757 BOTAN_PUBLIC_API(2,8) int botan_block_cipher_get_keyspec(botan_block_cipher_t cipher,
758                                                          size_t* out_minimum_keylength,
759                                                          size_t* out_maximum_keylength,
760                                                          size_t* out_keylength_modulo);
761 
762 /*
763 * Multiple precision integers (MPI)
764 */
765 typedef struct botan_mp_struct* botan_mp_t;
766 
767 /**
768 * Initialize an MPI
769 */
770 BOTAN_PUBLIC_API(2,1) int botan_mp_init(botan_mp_t* mp);
771 
772 /**
773 * Destroy (deallocate) an MPI
774 * @return 0 if success, error if invalid object handle
775 */
776 BOTAN_PUBLIC_API(2,1) int botan_mp_destroy(botan_mp_t mp);
777 
778 /**
779 * Convert the MPI to a hex string. Writes botan_mp_num_bytes(mp)*2 + 1 bytes
780 */
781 BOTAN_PUBLIC_API(2,1) int botan_mp_to_hex(const botan_mp_t mp, char* out);
782 
783 /**
784 * Convert the MPI to a string. Currently base == 10 and base == 16 are supported.
785 */
786 BOTAN_PUBLIC_API(2,1) int botan_mp_to_str(const botan_mp_t mp, uint8_t base, char* out, size_t* out_len);
787 
788 /**
789 * Set the MPI to zero
790 */
791 BOTAN_PUBLIC_API(2,1) int botan_mp_clear(botan_mp_t mp);
792 
793 /**
794 * Set the MPI value from an int
795 */
796 BOTAN_PUBLIC_API(2,1) int botan_mp_set_from_int(botan_mp_t mp, int initial_value);
797 
798 /**
799 * Set the MPI value from another MP object
800 */
801 BOTAN_PUBLIC_API(2,1) int botan_mp_set_from_mp(botan_mp_t dest, const botan_mp_t source);
802 
803 /**
804 * Set the MPI value from a string
805 */
806 BOTAN_PUBLIC_API(2,1) int botan_mp_set_from_str(botan_mp_t dest, const char* str);
807 
808 /**
809 * Set the MPI value from a string with arbitrary radix.
810 * For arbitrary being 10 or 16.
811 */
812 BOTAN_PUBLIC_API(2,1) int botan_mp_set_from_radix_str(botan_mp_t dest, const char* str, size_t radix);
813 
814 /**
815 * Return the number of significant bits in the MPI
816 */
817 BOTAN_PUBLIC_API(2,1) int botan_mp_num_bits(const botan_mp_t n, size_t* bits);
818 
819 /**
820 * Return the number of significant bytes in the MPI
821 */
822 BOTAN_PUBLIC_API(2,1) int botan_mp_num_bytes(const botan_mp_t n, size_t* bytes);
823 
824 /*
825 * Convert the MPI to a big-endian binary string. Writes botan_mp_num_bytes to vec
826 */
827 BOTAN_PUBLIC_API(2,1) int botan_mp_to_bin(const botan_mp_t mp, uint8_t vec[]);
828 
829 /*
830 * Set an MP to the big-endian binary value
831 */
832 BOTAN_PUBLIC_API(2,1) int botan_mp_from_bin(const botan_mp_t mp, const uint8_t vec[], size_t vec_len);
833 
834 /*
835 * Convert the MPI to a uint32_t, if possible. Fails if MPI is negative or too large.
836 */
837 BOTAN_PUBLIC_API(2,1) int botan_mp_to_uint32(const botan_mp_t mp, uint32_t* val);
838 
839 /**
840 * This function should have been named mp_is_non_negative. Returns 1
841 * iff mp is greater than *or equal to* zero. Use botan_mp_is_negative
842 * to detect negative numbers, botan_mp_is_zero to check for zero.
843 */
844 BOTAN_PUBLIC_API(2,1) int botan_mp_is_positive(const botan_mp_t mp);
845 
846 /**
847 * Return 1 iff mp is less than 0
848 */
849 BOTAN_PUBLIC_API(2,1) int botan_mp_is_negative(const botan_mp_t mp);
850 
851 BOTAN_PUBLIC_API(2,1) int botan_mp_flip_sign(botan_mp_t mp);
852 
853 BOTAN_PUBLIC_API(2,1) int botan_mp_is_zero(const botan_mp_t mp);
854 
855 BOTAN_PUBLIC_API(2,1) BOTAN_DEPRECATED("Use botan_mp_get_bit(0)")
856 int botan_mp_is_odd(const botan_mp_t mp);
857 BOTAN_PUBLIC_API(2,1) BOTAN_DEPRECATED("Use botan_mp_get_bit(0)")
858 int botan_mp_is_even(const botan_mp_t mp);
859 
860 BOTAN_PUBLIC_API(2,8) int botan_mp_add_u32(botan_mp_t result, const botan_mp_t x, uint32_t y);
861 BOTAN_PUBLIC_API(2,8) int botan_mp_sub_u32(botan_mp_t result, const botan_mp_t x, uint32_t y);
862 
863 BOTAN_PUBLIC_API(2,1) int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y);
864 BOTAN_PUBLIC_API(2,1) int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y);
865 BOTAN_PUBLIC_API(2,1) int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y);
866 
867 BOTAN_PUBLIC_API(2,1) int botan_mp_div(botan_mp_t quotient,
868                                        botan_mp_t remainder,
869                                        const botan_mp_t x, const botan_mp_t y);
870 
871 BOTAN_PUBLIC_API(2,1) int botan_mp_mod_mul(botan_mp_t result, const botan_mp_t x,
872                                            const botan_mp_t y, const botan_mp_t mod);
873 
874 /*
875 * Returns 0 if x != y
876 * Returns 1 if x == y
877 * Returns negative number on error
878 */
879 BOTAN_PUBLIC_API(2,1) int botan_mp_equal(const botan_mp_t x, const botan_mp_t y);
880 
881 /*
882 * Sets *result to comparison result:
883 * -1 if x < y, 0 if x == y, 1 if x > y
884 * Returns negative number on error or zero on success
885 */
886 BOTAN_PUBLIC_API(2,1) int botan_mp_cmp(int* result, const botan_mp_t x, const botan_mp_t y);
887 
888 /*
889 * Swap two botan_mp_t
890 */
891 BOTAN_PUBLIC_API(2,1) int botan_mp_swap(botan_mp_t x, botan_mp_t y);
892 
893 /* Return (base^exponent) % modulus */
894 BOTAN_PUBLIC_API(2,1) int botan_mp_powmod(botan_mp_t out, const botan_mp_t base, const botan_mp_t exponent, const botan_mp_t modulus);
895 
896 BOTAN_PUBLIC_API(2,1) int botan_mp_lshift(botan_mp_t out, const botan_mp_t in, size_t shift);
897 BOTAN_PUBLIC_API(2,1) int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift);
898 
899 BOTAN_PUBLIC_API(2,1) int botan_mp_mod_inverse(botan_mp_t out, const botan_mp_t in, const botan_mp_t modulus);
900 
901 BOTAN_PUBLIC_API(2,1) int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits);
902 
903 BOTAN_PUBLIC_API(2,1) int botan_mp_rand_range(botan_mp_t rand_out, botan_rng_t rng,
904                                   const botan_mp_t lower_bound, const botan_mp_t upper_bound);
905 
906 BOTAN_PUBLIC_API(2,1) int botan_mp_gcd(botan_mp_t out, const botan_mp_t x, const botan_mp_t y);
907 
908 /**
909 * Returns 0 if n is not prime
910 * Returns 1 if n is prime
911 * Returns negative number on error
912 */
913 BOTAN_PUBLIC_API(2,1) int botan_mp_is_prime(const botan_mp_t n, botan_rng_t rng, size_t test_prob);
914 
915 /**
916 * Returns 0 if specified bit of n is not set
917 * Returns 1 if specified bit of n is set
918 * Returns negative number on error
919 */
920 BOTAN_PUBLIC_API(2,1) int botan_mp_get_bit(const botan_mp_t n, size_t bit);
921 
922 /**
923 * Set the specified bit
924 */
925 BOTAN_PUBLIC_API(2,1) int botan_mp_set_bit(botan_mp_t n, size_t bit);
926 
927 /**
928 * Clear the specified bit
929 */
930 BOTAN_PUBLIC_API(2,1) int botan_mp_clear_bit(botan_mp_t n, size_t bit);
931 
932 /* Bcrypt password hashing */
933 
934 /**
935 * Create a password hash using Bcrypt
936 * @param out buffer holding the password hash, should be of length 64 bytes
937 * @param out_len the desired output length in bytes
938 * @param password the password
939 * @param rng a random number generator
940 * @param work_factor how much work to do to slow down guessing attacks
941 * @param flags should be 0 in current API revision, all other uses are reserved
942 *       and return BOTAN_FFI_ERROR_BAD_FLAG
943 * @return 0 on success, a negative value on failure
944 
945 * Output is formatted bcrypt $2a$...
946 */
947 BOTAN_PUBLIC_API(2,0) int botan_bcrypt_generate(uint8_t* out, size_t* out_len,
948                                     const char* password,
949                                     botan_rng_t rng,
950                                     size_t work_factor,
951                                     uint32_t flags);
952 
953 /**
954 * Check a previously created password hash
955 * @param pass the password to check against
956 * @param hash the stored hash to check against
957 * @return 0 if if this password/hash combination is valid,
958 *       1 if the combination is not valid (but otherwise well formed),
959 *       negative on error
960 */
961 BOTAN_PUBLIC_API(2,0) int botan_bcrypt_is_valid(const char* pass, const char* hash);
962 
963 /*
964 * Public/private key creation, import, ...
965 */
966 typedef struct botan_privkey_struct* botan_privkey_t;
967 
968 /**
969 * Create a new private key
970 * @param key the new object will be placed here
971 * @param algo_name something like "RSA" or "ECDSA"
972 * @param algo_params is specific to the algorithm. For RSA, specifies
973 *        the modulus bit length. For ECC is the name of the curve.
974 * @param rng a random number generator
975 */
976 BOTAN_PUBLIC_API(2,0) int botan_privkey_create(botan_privkey_t* key,
977                                                const char* algo_name,
978                                                const char* algo_params,
979                                                botan_rng_t rng);
980 
981 #define BOTAN_CHECK_KEY_EXPENSIVE_TESTS 1
982 
983 BOTAN_PUBLIC_API(2,0) int botan_privkey_check_key(botan_privkey_t key, botan_rng_t rng, uint32_t flags);
984 
985 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_privkey_create")
986 int botan_privkey_create_rsa(botan_privkey_t* key, botan_rng_t rng, size_t n_bits);
987 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_privkey_create")
988 int botan_privkey_create_ecdsa(botan_privkey_t* key, botan_rng_t rng, const char* params);
989 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_privkey_create")
990 int botan_privkey_create_ecdh(botan_privkey_t* key, botan_rng_t rng, const char* params);
991 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_privkey_create")
992 int botan_privkey_create_mceliece(botan_privkey_t* key, botan_rng_t rng, size_t n, size_t t);
993 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_privkey_create")
994 int botan_privkey_create_dh(botan_privkey_t* key, botan_rng_t rng, const char* param);
995 
996 /**
997  * Generates DSA key pair. Gives to a caller control over key length
998  * and order of a subgroup 'q'.
999  *
1000  * @param   key   handler to the resulting key
1001  * @param   rng   initialized PRNG
1002  * @param   pbits length of the key in bits. Must be between in range (1024, 3072)
1003  *          and multiple of 64. Bit size of the prime 'p'
1004  * @param   qbits order of the subgroup. Must be in range (160, 256) and multiple
1005  *          of 8
1006  *
1007  * @returns BOTAN_FFI_SUCCESS Success, `key' initialized with DSA key
1008  * @returns BOTAN_FFI_ERROR_NULL_POINTER  either `key' or `rng' is NULL
1009  * @returns BOTAN_FFI_ERROR_BAD_PARAMETER unexpected value for either `pbits' or
1010  *          `qbits'
1011  * @returns BOTAN_FFI_ERROR_NOT_IMPLEMENTED functionality not implemented
1012  *
1013 */
1014 BOTAN_PUBLIC_API(2,5) int botan_privkey_create_dsa(
1015                                 botan_privkey_t* key,
1016                                 botan_rng_t rng,
1017                                 size_t pbits,
1018                                 size_t qbits);
1019 
1020 /**
1021  * Generates ElGamal key pair. Caller has a control over key length
1022  * and order of a subgroup 'q'. Function is able to use two types of
1023  * primes:
1024  *    * if pbits-1 == qbits then safe primes are used for key generation
1025  *    * otherwise generation uses group of prime order
1026  *
1027  * @param   key   handler to the resulting key
1028  * @param   rng   initialized PRNG
1029  * @param   pbits length of the key in bits. Must be at least 1024
1030  * @param   qbits order of the subgroup. Must be at least 160
1031  *
1032  * @returns BOTAN_FFI_SUCCESS Success, `key' initialized with DSA key
1033  * @returns BOTAN_FFI_ERROR_NULL_POINTER  either `key' or `rng' is NULL
1034  * @returns BOTAN_FFI_ERROR_BAD_PARAMETER unexpected value for either `pbits' or
1035  *          `qbits'
1036  * @returns BOTAN_FFI_ERROR_NOT_IMPLEMENTED functionality not implemented
1037  *
1038 */
1039 BOTAN_PUBLIC_API(2,5) int botan_privkey_create_elgamal(
1040                             botan_privkey_t* key,
1041                             botan_rng_t rng,
1042                             size_t pbits,
1043                             size_t qbits);
1044 
1045 /**
1046 * Input currently assumed to be PKCS #8 structure;
1047 * Set password to NULL to indicate no encryption expected
1048 * Starting in 2.8.0, the rng parameter is unused and may be set to null
1049 */
1050 BOTAN_PUBLIC_API(2,0) int botan_privkey_load(botan_privkey_t* key,
1051                                              botan_rng_t rng,
1052                                              const uint8_t bits[], size_t len,
1053                                              const char* password);
1054 
1055 /**
1056 * @return 0 if success, error if invalid object handle
1057 */
1058 BOTAN_PUBLIC_API(2,0) int botan_privkey_destroy(botan_privkey_t key);
1059 
1060 #define BOTAN_PRIVKEY_EXPORT_FLAG_DER 0
1061 #define BOTAN_PRIVKEY_EXPORT_FLAG_PEM 1
1062 
1063 /**
1064 * On input *out_len is number of bytes in out[]
1065 * On output *out_len is number of bytes written (or required)
1066 * If out is not big enough no output is written, *out_len is set and 1 is returned
1067 * Returns 0 on success and sets
1068 * If some other error occurs a negative integer is returned.
1069 */
1070 BOTAN_PUBLIC_API(2,0) int botan_privkey_export(botan_privkey_t key,
1071                                    uint8_t out[], size_t* out_len,
1072                                    uint32_t flags);
1073 
1074 BOTAN_PUBLIC_API(2,8) int botan_privkey_algo_name(botan_privkey_t key, char out[], size_t* out_len);
1075 
1076 /**
1077 * Set encryption_algo to NULL or "" to have the library choose a default (recommended)
1078 */
1079 BOTAN_DEPRECATED("Use botan_privkey_export_encrypted_pbkdf_{msec,iter}")
1080 BOTAN_PUBLIC_API(2,0) int botan_privkey_export_encrypted(botan_privkey_t key,
1081                                              uint8_t out[], size_t* out_len,
1082                                              botan_rng_t rng,
1083                                              const char* passphrase,
1084                                              const char* encryption_algo,
1085                                              uint32_t flags);
1086 
1087 /*
1088 * Export a private key, running PBKDF for specified amount of time
1089 * @param key the private key to export
1090 */
1091 BOTAN_PUBLIC_API(2,0) int botan_privkey_export_encrypted_pbkdf_msec(botan_privkey_t key,
1092                                                         uint8_t out[], size_t* out_len,
1093                                                         botan_rng_t rng,
1094                                                         const char* passphrase,
1095                                                         uint32_t pbkdf_msec_runtime,
1096                                                         size_t* pbkdf_iterations_out,
1097                                                         const char* cipher_algo,
1098                                                         const char* pbkdf_algo,
1099                                                         uint32_t flags);
1100 
1101 /**
1102 * Export a private key using the specified number of iterations.
1103 */
1104 BOTAN_PUBLIC_API(2,0) int botan_privkey_export_encrypted_pbkdf_iter(botan_privkey_t key,
1105                                                         uint8_t out[], size_t* out_len,
1106                                                         botan_rng_t rng,
1107                                                         const char* passphrase,
1108                                                         size_t pbkdf_iterations,
1109                                                         const char* cipher_algo,
1110                                                         const char* pbkdf_algo,
1111                                                         uint32_t flags);
1112 
1113 typedef struct botan_pubkey_struct* botan_pubkey_t;
1114 
1115 BOTAN_PUBLIC_API(2,0) int botan_pubkey_load(botan_pubkey_t* key, const uint8_t bits[], size_t len);
1116 
1117 BOTAN_PUBLIC_API(2,0) int botan_privkey_export_pubkey(botan_pubkey_t* out, botan_privkey_t in);
1118 
1119 BOTAN_PUBLIC_API(2,0) int botan_pubkey_export(botan_pubkey_t key, uint8_t out[], size_t* out_len, uint32_t flags);
1120 
1121 BOTAN_PUBLIC_API(2,0) int botan_pubkey_algo_name(botan_pubkey_t key, char out[], size_t* out_len);
1122 
1123 /**
1124 * Returns 0 if key is valid, negative if invalid key or some other error
1125 */
1126 BOTAN_PUBLIC_API(2,0) int botan_pubkey_check_key(botan_pubkey_t key, botan_rng_t rng, uint32_t flags);
1127 
1128 BOTAN_PUBLIC_API(2,0) int botan_pubkey_estimated_strength(botan_pubkey_t key, size_t* estimate);
1129 
1130 BOTAN_PUBLIC_API(2,0) int botan_pubkey_fingerprint(botan_pubkey_t key, const char* hash,
1131                                        uint8_t out[], size_t* out_len);
1132 
1133 /**
1134 * @return 0 if success, error if invalid object handle
1135 */
1136 BOTAN_PUBLIC_API(2,0) int botan_pubkey_destroy(botan_pubkey_t key);
1137 
1138 /*
1139 * Get arbitrary named fields from public or privat keys
1140 */
1141 BOTAN_PUBLIC_API(2,0) int botan_pubkey_get_field(botan_mp_t output,
1142                                      botan_pubkey_t key,
1143                                      const char* field_name);
1144 
1145 BOTAN_PUBLIC_API(2,0) int botan_privkey_get_field(botan_mp_t output,
1146                                       botan_privkey_t key,
1147                                       const char* field_name);
1148 
1149 /*
1150 * Algorithm specific key operations: RSA
1151 */
1152 BOTAN_PUBLIC_API(2,0) int botan_privkey_load_rsa(botan_privkey_t* key,
1153                                      botan_mp_t p,
1154                                      botan_mp_t q,
1155                                      botan_mp_t e);
1156 
1157 BOTAN_PUBLIC_API(2,8) int botan_privkey_load_rsa_pkcs1(botan_privkey_t* key,
1158                                                        const uint8_t bits[],
1159                                                        size_t len);
1160 
1161 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_privkey_get_field")
1162 int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t rsa_key);
1163 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_privkey_get_field")
1164 int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t rsa_key);
1165 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_privkey_get_field")
1166 int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t rsa_key);
1167 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_privkey_get_field")
1168 int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t rsa_key);
1169 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_privkey_get_field")
1170 int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t rsa_key);
1171 
1172 BOTAN_PUBLIC_API(2,8) int botan_privkey_rsa_get_privkey(botan_privkey_t rsa_key,
1173                                                         uint8_t out[], size_t* out_len,
1174                                                         uint32_t flags);
1175 
1176 BOTAN_PUBLIC_API(2,0) int botan_pubkey_load_rsa(botan_pubkey_t* key,
1177                                                 botan_mp_t n,
1178                                                 botan_mp_t e);
1179 
1180 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_pubkey_get_field")
1181 int botan_pubkey_rsa_get_e(botan_mp_t e, botan_pubkey_t rsa_key);
1182 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_pubkey_get_field")
1183 int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t rsa_key);
1184 
1185 /*
1186 * Algorithm specific key operations: DSA
1187 */
1188 BOTAN_PUBLIC_API(2,0) int botan_privkey_load_dsa(botan_privkey_t* key,
1189                                      botan_mp_t p,
1190                                      botan_mp_t q,
1191                                      botan_mp_t g,
1192                                      botan_mp_t x);
1193 
1194 BOTAN_PUBLIC_API(2,0) int botan_pubkey_load_dsa(botan_pubkey_t* key,
1195                                     botan_mp_t p,
1196                                     botan_mp_t q,
1197                                     botan_mp_t g,
1198                                     botan_mp_t y);
1199 
1200 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_privkey_get_field")
1201 int botan_privkey_dsa_get_x(botan_mp_t n, botan_privkey_t key);
1202 
1203 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_pubkey_get_field")
1204 int botan_pubkey_dsa_get_p(botan_mp_t p, botan_pubkey_t key);
1205 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_pubkey_get_field")
1206 int botan_pubkey_dsa_get_q(botan_mp_t q, botan_pubkey_t key);
1207 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_pubkey_get_field")
1208 int botan_pubkey_dsa_get_g(botan_mp_t d, botan_pubkey_t key);
1209 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Use botan_pubkey_get_field")
1210 int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key);
1211 
1212 /*
1213 * Loads Diffie Hellman private key
1214 *
1215 * @param key variable populated with key material
1216 * @param p prime order of a Z_p group
1217 * @param g group generator
1218 * @param x private key
1219 *
1220 * @pre key is NULL on input
1221 * @post function allocates memory and assigns to `key'
1222 *
1223 * @return 0 on success, a negative value on failure
1224 */
1225 BOTAN_PUBLIC_API(2,0) int botan_privkey_load_dh(botan_privkey_t* key,
1226                                          botan_mp_t p,
1227                                          botan_mp_t g,
1228                                          botan_mp_t x);
1229 /**
1230 * Loads Diffie Hellman public key
1231 *
1232 * @param key variable populated with key material
1233 * @param p prime order of a Z_p group
1234 * @param g group generator
1235 * @param y public key
1236 *
1237 * @pre key is NULL on input
1238 * @post function allocates memory and assigns to `key'
1239 *
1240 * @return 0 on success, a negative value on failure
1241 */
1242 BOTAN_PUBLIC_API(2,0) int botan_pubkey_load_dh(botan_pubkey_t* key,
1243                                         botan_mp_t p,
1244                                         botan_mp_t g,
1245                                         botan_mp_t y);
1246 
1247 /*
1248 * Algorithm specific key operations: ElGamal
1249 */
1250 
1251 /**
1252 * Loads ElGamal public key
1253 * @param key variable populated with key material
1254 * @param p prime order of a Z_p group
1255 * @param g group generator
1256 * @param y public key
1257 *
1258 * @pre key is NULL on input
1259 * @post function allocates memory and assigns to `key'
1260 *
1261 * @return 0 on success, a negative value on failure
1262 */
1263 BOTAN_PUBLIC_API(2,0) int botan_pubkey_load_elgamal(botan_pubkey_t* key,
1264                                         botan_mp_t p,
1265                                         botan_mp_t g,
1266                                         botan_mp_t y);
1267 
1268 /**
1269 * Loads ElGamal private key
1270 *
1271 * @param key variable populated with key material
1272 * @param p prime order of a Z_p group
1273 * @param g group generator
1274 * @param x private key
1275 *
1276 * @pre key is NULL on input
1277 * @post function allocates memory and assigns to `key'
1278 *
1279 * @return 0 on success, a negative value on failure
1280 */
1281 BOTAN_PUBLIC_API(2,0) int botan_privkey_load_elgamal(botan_privkey_t* key,
1282                                          botan_mp_t p,
1283                                          botan_mp_t g,
1284                                          botan_mp_t x);
1285 
1286 /*
1287 * Algorithm specific key operations: Ed25519
1288 */
1289 
1290 BOTAN_PUBLIC_API(2,2) int botan_privkey_load_ed25519(botan_privkey_t* key,
1291                                          const uint8_t privkey[32]);
1292 
1293 BOTAN_PUBLIC_API(2,2) int botan_pubkey_load_ed25519(botan_pubkey_t* key,
1294                                         const uint8_t pubkey[32]);
1295 
1296 BOTAN_PUBLIC_API(2,2) int botan_privkey_ed25519_get_privkey(botan_privkey_t key,
1297                                                 uint8_t output[64]);
1298 
1299 BOTAN_PUBLIC_API(2,2) int botan_pubkey_ed25519_get_pubkey(botan_pubkey_t key,
1300                                               uint8_t pubkey[32]);
1301 
1302 /*
1303 * Algorithm specific key operations: X25519
1304 */
1305 
1306 BOTAN_PUBLIC_API(2,8) int botan_privkey_load_x25519(botan_privkey_t* key,
1307                                                     const uint8_t privkey[32]);
1308 
1309 BOTAN_PUBLIC_API(2,8) int botan_pubkey_load_x25519(botan_pubkey_t* key,
1310                                                    const uint8_t pubkey[32]);
1311 
1312 BOTAN_PUBLIC_API(2,8) int botan_privkey_x25519_get_privkey(botan_privkey_t key,
1313                                                            uint8_t output[32]);
1314 
1315 BOTAN_PUBLIC_API(2,8) int botan_pubkey_x25519_get_pubkey(botan_pubkey_t key,
1316                                                          uint8_t pubkey[32]);
1317 
1318 /*
1319 * Algorithm specific key operations: ECDSA and ECDH
1320 */
1321 BOTAN_PUBLIC_API(2,2)
1322 int botan_privkey_load_ecdsa(botan_privkey_t* key,
1323                              const botan_mp_t scalar,
1324                              const char* curve_name);
1325 
1326 BOTAN_PUBLIC_API(2,2)
1327 int botan_pubkey_load_ecdsa(botan_pubkey_t* key,
1328                             const botan_mp_t public_x,
1329                             const botan_mp_t public_y,
1330                             const char* curve_name);
1331 
1332 BOTAN_PUBLIC_API(2,2)
1333 int botan_pubkey_load_ecdh(botan_pubkey_t* key,
1334                            const botan_mp_t public_x,
1335                            const botan_mp_t public_y,
1336                            const char* curve_name);
1337 
1338 BOTAN_PUBLIC_API(2,2)
1339 int botan_privkey_load_ecdh(botan_privkey_t* key,
1340                             const botan_mp_t scalar,
1341                             const char* curve_name);
1342 
1343 BOTAN_PUBLIC_API(2,2)
1344 int botan_pubkey_load_sm2(botan_pubkey_t* key,
1345                           const botan_mp_t public_x,
1346                           const botan_mp_t public_y,
1347                           const char* curve_name);
1348 
1349 BOTAN_PUBLIC_API(2,2)
1350 int botan_privkey_load_sm2(botan_privkey_t* key,
1351                            const botan_mp_t scalar,
1352                            const char* curve_name);
1353 
1354 BOTAN_PUBLIC_API(2,2) BOTAN_DEPRECATED("Use botan_pubkey_load_sm2")
1355 int botan_pubkey_load_sm2_enc(botan_pubkey_t* key,
1356                               const botan_mp_t public_x,
1357                               const botan_mp_t public_y,
1358                               const char* curve_name);
1359 
1360 BOTAN_PUBLIC_API(2,2) BOTAN_DEPRECATED("Use botan_privkey_load_sm2")
1361 int botan_privkey_load_sm2_enc(botan_privkey_t* key,
1362                                const botan_mp_t scalar,
1363                                const char* curve_name);
1364 
1365 BOTAN_PUBLIC_API(2,3)
1366 int botan_pubkey_sm2_compute_za(uint8_t out[],
1367                                 size_t* out_len,
1368                                 const char* ident,
1369                                 const char* hash_algo,
1370                                 const botan_pubkey_t key);
1371 
1372 /*
1373 * Public Key Encryption
1374 */
1375 typedef struct botan_pk_op_encrypt_struct* botan_pk_op_encrypt_t;
1376 
1377 BOTAN_PUBLIC_API(2,0) int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t* op,
1378                                          botan_pubkey_t key,
1379                                          const char* padding,
1380                                          uint32_t flags);
1381 
1382 /**
1383 * @return 0 if success, error if invalid object handle
1384 */
1385 BOTAN_PUBLIC_API(2,0) int botan_pk_op_encrypt_destroy(botan_pk_op_encrypt_t op);
1386 
1387 BOTAN_PUBLIC_API(2,8) int botan_pk_op_encrypt_output_length(botan_pk_op_encrypt_t op,
1388                                                             size_t ptext_len,
1389                                                             size_t* ctext_len);
1390 
1391 BOTAN_PUBLIC_API(2,0) int botan_pk_op_encrypt(botan_pk_op_encrypt_t op,
1392                                               botan_rng_t rng,
1393                                               uint8_t out[],
1394                                               size_t* out_len,
1395                                               const uint8_t plaintext[],
1396                                               size_t plaintext_len);
1397 
1398 /*
1399 * Public Key Decryption
1400 */
1401 typedef struct botan_pk_op_decrypt_struct* botan_pk_op_decrypt_t;
1402 
1403 BOTAN_PUBLIC_API(2,0) int botan_pk_op_decrypt_create(botan_pk_op_decrypt_t* op,
1404                                          botan_privkey_t key,
1405                                          const char* padding,
1406                                          uint32_t flags);
1407 
1408 /**
1409 * @return 0 if success, error if invalid object handle
1410 */
1411 BOTAN_PUBLIC_API(2,0) int botan_pk_op_decrypt_destroy(botan_pk_op_decrypt_t op);
1412 
1413 BOTAN_PUBLIC_API(2,8) int botan_pk_op_decrypt_output_length(botan_pk_op_decrypt_t op,
1414                                                             size_t ctext_len,
1415                                                             size_t* ptext_len);
1416 
1417 BOTAN_PUBLIC_API(2,0) int botan_pk_op_decrypt(botan_pk_op_decrypt_t op,
1418                                   uint8_t out[], size_t* out_len,
1419                                   const uint8_t ciphertext[], size_t ciphertext_len);
1420 
1421 /*
1422 * Signature Generation
1423 */
1424 
1425 #define BOTAN_PUBKEY_DER_FORMAT_SIGNATURE 1
1426 
1427 typedef struct botan_pk_op_sign_struct* botan_pk_op_sign_t;
1428 
1429 BOTAN_PUBLIC_API(2,0)
1430 int botan_pk_op_sign_create(botan_pk_op_sign_t* op,
1431                             botan_privkey_t key,
1432                             const char* hash_and_padding,
1433                             uint32_t flags);
1434 
1435 /**
1436 * @return 0 if success, error if invalid object handle
1437 */
1438 BOTAN_PUBLIC_API(2,0) int botan_pk_op_sign_destroy(botan_pk_op_sign_t op);
1439 
1440 BOTAN_PUBLIC_API(2,8) int botan_pk_op_sign_output_length(botan_pk_op_sign_t op, size_t* olen);
1441 
1442 BOTAN_PUBLIC_API(2,0) int botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], size_t in_len);
1443 
1444 BOTAN_PUBLIC_API(2,0)
1445 int botan_pk_op_sign_finish(botan_pk_op_sign_t op, botan_rng_t rng,
1446                             uint8_t sig[], size_t* sig_len);
1447 
1448 /*
1449 * Signature Verification
1450 */
1451 typedef struct botan_pk_op_verify_struct* botan_pk_op_verify_t;
1452 
1453 BOTAN_PUBLIC_API(2,0)
1454 int botan_pk_op_verify_create(botan_pk_op_verify_t* op,
1455                               botan_pubkey_t key,
1456                               const char* hash_and_padding,
1457                               uint32_t flags);
1458 
1459 /**
1460 * @return 0 if success, error if invalid object handle
1461 */
1462 BOTAN_PUBLIC_API(2,0) int botan_pk_op_verify_destroy(botan_pk_op_verify_t op);
1463 
1464 BOTAN_PUBLIC_API(2,0) int botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], size_t in_len);
1465 BOTAN_PUBLIC_API(2,0) int botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], size_t sig_len);
1466 
1467 /*
1468 * Key Agreement
1469 */
1470 typedef struct botan_pk_op_ka_struct* botan_pk_op_ka_t;
1471 
1472 BOTAN_PUBLIC_API(2,0)
1473 int botan_pk_op_key_agreement_create(botan_pk_op_ka_t* op,
1474                                      botan_privkey_t key,
1475                                      const char* kdf,
1476                                      uint32_t flags);
1477 
1478 /**
1479 * @return 0 if success, error if invalid object handle
1480 */
1481 BOTAN_PUBLIC_API(2,0) int botan_pk_op_key_agreement_destroy(botan_pk_op_ka_t op);
1482 
1483 BOTAN_PUBLIC_API(2,0) int botan_pk_op_key_agreement_export_public(botan_privkey_t key,
1484                                                       uint8_t out[], size_t* out_len);
1485 
1486 BOTAN_PUBLIC_API(2,8) int botan_pk_op_key_agreement_size(botan_pk_op_ka_t op, size_t* out_len);
1487 
1488 BOTAN_PUBLIC_API(2,0)
1489 int botan_pk_op_key_agreement(botan_pk_op_ka_t op,
1490                               uint8_t out[], size_t* out_len,
1491                               const uint8_t other_key[], size_t other_key_len,
1492                               const uint8_t salt[], size_t salt_len);
1493 
1494 BOTAN_PUBLIC_API(2,0) int botan_pkcs_hash_id(const char* hash_name, uint8_t pkcs_id[], size_t* pkcs_id_len);
1495 
1496 
1497 /*
1498 *
1499 * @param mce_key must be a McEliece key
1500 * ct_len should be pt_len + n/8 + a few?
1501 */
1502 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Poorly specified, avoid in new code")
1503 int botan_mceies_encrypt(botan_pubkey_t mce_key,
1504                          botan_rng_t rng,
1505                          const char* aead,
1506                          const uint8_t pt[], size_t pt_len,
1507                          const uint8_t ad[], size_t ad_len,
1508                          uint8_t ct[], size_t* ct_len);
1509 
1510 BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("Poorly specified, avoid in new code")
1511 int botan_mceies_decrypt(botan_privkey_t mce_key,
1512                          const char* aead,
1513                          const uint8_t ct[], size_t ct_len,
1514                          const uint8_t ad[], size_t ad_len,
1515                          uint8_t pt[], size_t* pt_len);
1516 
1517 /*
1518 * X.509 certificates
1519 **************************/
1520 
1521 typedef struct botan_x509_cert_struct* botan_x509_cert_t;
1522 
1523 BOTAN_PUBLIC_API(2,0) int botan_x509_cert_load(botan_x509_cert_t* cert_obj, const uint8_t cert[], size_t cert_len);
1524 BOTAN_PUBLIC_API(2,0) int botan_x509_cert_load_file(botan_x509_cert_t* cert_obj, const char* filename);
1525 
1526 /**
1527 * @return 0 if success, error if invalid object handle
1528 */
1529 BOTAN_PUBLIC_API(2,0) int botan_x509_cert_destroy(botan_x509_cert_t cert);
1530 
1531 BOTAN_PUBLIC_API(2,8) int botan_x509_cert_dup(botan_x509_cert_t* new_cert, botan_x509_cert_t cert);
1532 
1533 /* Prefer botan_x509_cert_not_before and botan_x509_cert_not_after */
1534 BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t* out_len);
1535 BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_time_expires(botan_x509_cert_t cert, char out[], size_t* out_len);
1536 
1537 BOTAN_PUBLIC_API(2,8) int botan_x509_cert_not_before(botan_x509_cert_t cert, uint64_t* time_since_epoch);
1538 BOTAN_PUBLIC_API(2,8) int botan_x509_cert_not_after(botan_x509_cert_t cert, uint64_t* time_since_epoch);
1539 
1540 BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_fingerprint(botan_x509_cert_t cert, const char* hash, uint8_t out[], size_t* out_len);
1541 
1542 BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_serial_number(botan_x509_cert_t cert, uint8_t out[], size_t* out_len);
1543 BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_authority_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len);
1544 BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len);
1545 
1546 BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_public_key_bits(botan_x509_cert_t cert,
1547                                                   uint8_t out[], size_t* out_len);
1548 
1549 BOTAN_PUBLIC_API(2,0) int botan_x509_cert_get_public_key(botan_x509_cert_t cert, botan_pubkey_t* key);
1550 
1551 BOTAN_PUBLIC_API(2,0)
1552 int botan_x509_cert_get_issuer_dn(botan_x509_cert_t cert,
1553                                   const char* key, size_t index,
1554                                   uint8_t out[], size_t* out_len);
1555 
1556 BOTAN_PUBLIC_API(2,0)
1557 int botan_x509_cert_get_subject_dn(botan_x509_cert_t cert,
1558                                    const char* key, size_t index,
1559                                    uint8_t out[], size_t* out_len);
1560 
1561 BOTAN_PUBLIC_API(2,0) int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t* out_len);
1562 
1563 /* Must match values of Key_Constraints in key_constraints.h */
1564 enum botan_x509_cert_key_constraints {
1565    NO_CONSTRAINTS     = 0,
1566    DIGITAL_SIGNATURE  = 32768,
1567    NON_REPUDIATION    = 16384,
1568    KEY_ENCIPHERMENT   = 8192,
1569    DATA_ENCIPHERMENT  = 4096,
1570    KEY_AGREEMENT      = 2048,
1571    KEY_CERT_SIGN      = 1024,
1572    CRL_SIGN           = 512,
1573    ENCIPHER_ONLY      = 256,
1574    DECIPHER_ONLY      = 128
1575 };
1576 
1577 BOTAN_PUBLIC_API(2,0) int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage);
1578 
1579 /**
1580 * Check if the certificate matches the specified hostname via alternative name or CN match.
1581 * RFC 5280 wildcards also supported.
1582 */
1583 BOTAN_PUBLIC_API(2,5) int botan_x509_cert_hostname_match(botan_x509_cert_t cert, const char* hostname);
1584 
1585 /**
1586 * Returns 0 if the validation was successful, 1 if validation failed,
1587 * and negative on error. A status code with details is written to
1588 * *validation_result
1589 *
1590 * Intermediates or trusted lists can be null
1591 * Trusted path can be null
1592 */
1593 BOTAN_PUBLIC_API(2,8) int botan_x509_cert_verify(
1594    int* validation_result,
1595    botan_x509_cert_t cert,
1596    const botan_x509_cert_t* intermediates,
1597    size_t intermediates_len,
1598    const botan_x509_cert_t* trusted,
1599    size_t trusted_len,
1600    const char* trusted_path,
1601    size_t required_strength,
1602    const char* hostname,
1603    uint64_t reference_time);
1604 
1605 /**
1606 * Returns a pointer to a static character string explaining the status code,
1607 * or else NULL if unknown.
1608 */
1609 BOTAN_PUBLIC_API(2,8) const char* botan_x509_cert_validation_status(int code);
1610 
1611 /*
1612 * X.509 CRL
1613 **************************/
1614 
1615 typedef struct botan_x509_crl_struct* botan_x509_crl_t;
1616 
1617 BOTAN_PUBLIC_API(2,13) int botan_x509_crl_load_file(botan_x509_crl_t* crl_obj, const char* crl_path);
1618 BOTAN_PUBLIC_API(2,13) int botan_x509_crl_load(botan_x509_crl_t* crl_obj, const uint8_t crl_bits[], size_t crl_bits_len);
1619 
1620 BOTAN_PUBLIC_API(2,13) int botan_x509_crl_destroy(botan_x509_crl_t crl);
1621 
1622 /**
1623  * Given a CRL and a certificate,
1624  * check if the certificate is revoked on that particular CRL
1625  */
1626 BOTAN_PUBLIC_API(2,13) int botan_x509_is_revoked(botan_x509_crl_t crl, botan_x509_cert_t cert);
1627 
1628 /**
1629  * Different flavor of `botan_x509_cert_verify`, supports revocation lists.
1630  * CRLs are passed as an array, same as intermediates and trusted CAs
1631  */
1632 BOTAN_PUBLIC_API(2,13) int botan_x509_cert_verify_with_crl(
1633    int* validation_result,
1634    botan_x509_cert_t cert,
1635    const botan_x509_cert_t* intermediates,
1636    size_t intermediates_len,
1637    const botan_x509_cert_t* trusted,
1638    size_t trusted_len,
1639    const botan_x509_crl_t* crls,
1640    size_t crls_len,
1641    const char* trusted_path,
1642    size_t required_strength,
1643    const char* hostname,
1644    uint64_t reference_time);
1645 
1646 /**
1647  * Key wrapping as per RFC 3394
1648  */
1649 BOTAN_PUBLIC_API(2,2)
1650 int botan_key_wrap3394(const uint8_t key[], size_t key_len,
1651                        const uint8_t kek[], size_t kek_len,
1652                        uint8_t wrapped_key[], size_t *wrapped_key_len);
1653 
1654 BOTAN_PUBLIC_API(2,2)
1655 int botan_key_unwrap3394(const uint8_t wrapped_key[], size_t wrapped_key_len,
1656                          const uint8_t kek[], size_t kek_len,
1657                          uint8_t key[], size_t *key_len);
1658 
1659 /**
1660 * HOTP
1661 */
1662 
1663 typedef struct botan_hotp_struct* botan_hotp_t;
1664 
1665 /**
1666 * Initialize a HOTP instance
1667 */
1668 BOTAN_PUBLIC_API(2,8)
1669 int botan_hotp_init(botan_hotp_t* hotp,
1670                     const uint8_t key[], size_t key_len,
1671                     const char* hash_algo,
1672                     size_t digits);
1673 
1674 /**
1675 * Destroy a HOTP instance
1676 * @return 0 if success, error if invalid object handle
1677 */
1678 BOTAN_PUBLIC_API(2,8)
1679 int botan_hotp_destroy(botan_hotp_t hotp);
1680 
1681 /**
1682 * Generate a HOTP code for the provided counter
1683 */
1684 BOTAN_PUBLIC_API(2,8)
1685 int botan_hotp_generate(botan_hotp_t hotp,
1686                         uint32_t* hotp_code,
1687                         uint64_t hotp_counter);
1688 
1689 /**
1690 * Verify a HOTP code
1691 */
1692 BOTAN_PUBLIC_API(2,8)
1693 int botan_hotp_check(botan_hotp_t hotp,
1694                      uint64_t* next_hotp_counter,
1695                      uint32_t hotp_code,
1696                      uint64_t hotp_counter,
1697                      size_t resync_range);
1698 
1699 
1700 /**
1701 * TOTP
1702 */
1703 
1704 typedef struct botan_totp_struct* botan_totp_t;
1705 
1706 /**
1707 * Initialize a TOTP instance
1708 */
1709 BOTAN_PUBLIC_API(2,8)
1710 int botan_totp_init(botan_totp_t* totp,
1711                     const uint8_t key[], size_t key_len,
1712                     const char* hash_algo,
1713                     size_t digits,
1714                     size_t time_step);
1715 
1716 /**
1717 * Destroy a TOTP instance
1718 * @return 0 if success, error if invalid object handle
1719 */
1720 BOTAN_PUBLIC_API(2,8)
1721 int botan_totp_destroy(botan_totp_t totp);
1722 
1723 /**
1724 * Generate a TOTP code for the provided timestamp
1725 * @param totp the TOTP object
1726 * @param totp_code the OTP code will be written here
1727 * @param timestamp the current local timestamp
1728 */
1729 BOTAN_PUBLIC_API(2,8)
1730 int botan_totp_generate(botan_totp_t totp,
1731                         uint32_t* totp_code,
1732                         uint64_t timestamp);
1733 
1734 /**
1735 * Verify a TOTP code
1736 * @param totp the TOTP object
1737 * @param totp_code the presented OTP
1738 * @param timestamp the current local timestamp
1739 * @param acceptable_clock_drift specifies the acceptable amount
1740 * of clock drift (in terms of time steps) between the two hosts.
1741 */
1742 BOTAN_PUBLIC_API(2,8)
1743 int botan_totp_check(botan_totp_t totp,
1744                      uint32_t totp_code,
1745                      uint64_t timestamp,
1746                      size_t acceptable_clock_drift);
1747 
1748 
1749 /**
1750 * Format Preserving Encryption
1751 */
1752 
1753 typedef struct botan_fpe_struct* botan_fpe_t;
1754 
1755 #define BOTAN_FPE_FLAG_FE1_COMPAT_MODE 1
1756 
1757 BOTAN_PUBLIC_API(2,8)
1758 int botan_fpe_fe1_init(botan_fpe_t* fpe, botan_mp_t n,
1759                        const uint8_t key[], size_t key_len,
1760                        size_t rounds, uint32_t flags);
1761 
1762 /**
1763 * @return 0 if success, error if invalid object handle
1764 */
1765 BOTAN_PUBLIC_API(2,8)
1766 int botan_fpe_destroy(botan_fpe_t fpe);
1767 
1768 BOTAN_PUBLIC_API(2,8)
1769 int botan_fpe_encrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], size_t tweak_len);
1770 
1771 BOTAN_PUBLIC_API(2,8)
1772 int botan_fpe_decrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], size_t tweak_len);
1773 
1774 #ifdef __cplusplus
1775 }
1776 #endif
1777 
1778 #endif
1779