8#include <botan/cryptobox.h>
9#include <botan/cipher_mode.h>
12#include <botan/pbkdf.h>
13#include <botan/data_src.h>
15#include <botan/loadstor.h>
16#include <botan/mem_ops.h>
28const uint32_t CRYPTOBOX_VERSION_CODE = 0xEFC22400;
30const size_t VERSION_CODE_LEN = 4;
31const size_t CIPHER_KEY_LEN = 32;
32const size_t CIPHER_IV_LEN = 16;
33const size_t MAC_KEY_LEN = 32;
34const size_t MAC_OUTPUT_LEN = 20;
35const size_t PBKDF_SALT_LEN = 10;
36const size_t PBKDF_ITERATIONS = 8 * 1024;
38const size_t PBKDF_OUTPUT_LEN = CIPHER_KEY_LEN + MAC_KEY_LEN + CIPHER_IV_LEN;
39const size_t CRYPTOBOX_HEADER_LEN = VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN;
43std::string
encrypt(
const uint8_t input[],
size_t input_len,
44 const std::string& passphrase,
55 for(
size_t i = 0; i != VERSION_CODE_LEN; ++i)
56 out_buf[i] =
get_byte(i, CRYPTOBOX_VERSION_CODE);
57 rng.
randomize(&out_buf[VERSION_CODE_LEN], PBKDF_SALT_LEN);
60 copy_mem(&out_buf[CRYPTOBOX_HEADER_LEN], input, input_len);
67 CIPHER_KEY_LEN + MAC_KEY_LEN + CIPHER_IV_LEN,
69 &out_buf[VERSION_CODE_LEN],
73 const uint8_t* mk = master_key.
begin();
74 const uint8_t* cipher_key = mk;
75 const uint8_t* mac_key = mk + CIPHER_KEY_LEN;
76 const uint8_t* iv = mk + CIPHER_KEY_LEN + MAC_KEY_LEN;
80 ctr->set_key(cipher_key, CIPHER_KEY_LEN);
81 ctr->start(iv, CIPHER_IV_LEN);
82 ctr->finish(out_buf, CRYPTOBOX_HEADER_LEN);
84 std::unique_ptr<MessageAuthenticationCode> hmac =
86 hmac->set_key(mac_key, MAC_KEY_LEN);
88 hmac->update(&out_buf[CRYPTOBOX_HEADER_LEN], input_len);
92 copy_mem(&out_buf[VERSION_CODE_LEN + PBKDF_SALT_LEN], mac.data(), MAC_OUTPUT_LEN);
99 const std::string& passphrase)
104 "BOTAN CRYPTOBOX MESSAGE");
106 if(ciphertext.size() < CRYPTOBOX_HEADER_LEN)
109 for(
size_t i = 0; i != VERSION_CODE_LEN; ++i)
110 if(ciphertext[i] !=
get_byte(i, CRYPTOBOX_VERSION_CODE))
113 const uint8_t* pbkdf_salt = &ciphertext[VERSION_CODE_LEN];
114 const uint8_t* box_mac = &ciphertext[VERSION_CODE_LEN + PBKDF_SALT_LEN];
125 const uint8_t* mk = master_key.
begin();
126 const uint8_t* cipher_key = mk;
127 const uint8_t* mac_key = mk + CIPHER_KEY_LEN;
128 const uint8_t* iv = mk + CIPHER_KEY_LEN + MAC_KEY_LEN;
131 std::unique_ptr<MessageAuthenticationCode> hmac =
133 hmac->set_key(mac_key, MAC_KEY_LEN);
135 if(ciphertext.size() > CRYPTOBOX_HEADER_LEN)
137 hmac->update(&ciphertext[CRYPTOBOX_HEADER_LEN],
138 ciphertext.size() - CRYPTOBOX_HEADER_LEN);
146 ctr->set_key(cipher_key, CIPHER_KEY_LEN);
147 ctr->start(iv, CIPHER_IV_LEN);
148 ctr->finish(ciphertext, CRYPTOBOX_HEADER_LEN);
150 ciphertext.erase(ciphertext.begin(), ciphertext.begin() + CRYPTOBOX_HEADER_LEN);
155 const std::string& passphrase)
162std::string
decrypt(
const uint8_t input[],
size_t input_len,
163 const std::string& passphrase)
172 const std::string& passphrase)
175 input.size(), passphrase);
static std::unique_ptr< Cipher_Mode > create_or_throw(const std::string &algo, Cipher_Dir direction, const std::string &provider="")
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(const std::string &algo_spec, const std::string &provider="")
const uint8_t * begin() const
static std::unique_ptr< PBKDF > create_or_throw(const std::string &algo_spec, const std::string &provider="")
virtual void randomize(uint8_t output[], size_t length)=0
std::string decrypt(const uint8_t input[], size_t input_len, const std::string &passphrase)
std::string encrypt(const uint8_t input[], size_t input_len, const std::string &passphrase, RandomNumberGenerator &rng)
secure_vector< uint8_t > decrypt_bin(const uint8_t input[], size_t input_len, const std::string &passphrase)
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
secure_vector< uint8_t > decode_check_label(DataSource &source, const std::string &label_want)
void copy_mem(T *out, const T *in, size_t n)
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
const char * cast_uint8_ptr_to_char(const uint8_t *b)
constexpr uint8_t get_byte(size_t byte_num, T input)
std::vector< T, secure_allocator< T > > secure_vector
const uint8_t * cast_char_ptr_to_uint8(const char *s)