8#include <botan/cryptobox.h>
9#include <botan/cipher_mode.h>
12#include <botan/pwdhash.h>
13#include <botan/data_src.h>
15#include <botan/internal/loadstor.h>
16#include <botan/mem_ops.h>
26const uint32_t CRYPTOBOX_VERSION_CODE = 0xEFC22400;
28const size_t VERSION_CODE_LEN = 4;
29const size_t CIPHER_KEY_LEN = 32;
30const size_t CIPHER_IV_LEN = 16;
31const size_t MAC_KEY_LEN = 32;
32const size_t MAC_OUTPUT_LEN = 20;
33const size_t PBKDF_SALT_LEN = 10;
34const size_t PBKDF_ITERATIONS = 8 * 1024;
36const size_t CRYPTOBOX_HEADER_LEN = VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN;
40std::string
encrypt(
const uint8_t input[],
size_t input_len,
41 std::string_view passphrase,
52 store_be(CRYPTOBOX_VERSION_CODE, out_buf.data());
53 rng.
randomize(&out_buf[VERSION_CODE_LEN], PBKDF_SALT_LEN);
56 copy_mem(&out_buf[CRYPTOBOX_HEADER_LEN], input, input_len);
61 auto pbkdf = pbkdf_fam->from_params(PBKDF_ITERATIONS);
66 master_key.data(), master_key.size(),
67 passphrase.data(), passphrase.size(),
68 &out_buf[VERSION_CODE_LEN], PBKDF_SALT_LEN);
70 const uint8_t* mk = master_key.data();
71 const uint8_t* cipher_key = mk;
72 const uint8_t* mac_key = mk + CIPHER_KEY_LEN;
73 const uint8_t* iv = mk + CIPHER_KEY_LEN + MAC_KEY_LEN;
77 ctr->set_key(cipher_key, CIPHER_KEY_LEN);
78 ctr->start(iv, CIPHER_IV_LEN);
79 ctr->finish(out_buf, CRYPTOBOX_HEADER_LEN);
81 std::unique_ptr<MessageAuthenticationCode> hmac =
83 hmac->set_key(mac_key, MAC_KEY_LEN);
85 hmac->update(&out_buf[CRYPTOBOX_HEADER_LEN], input_len);
89 copy_mem(&out_buf[VERSION_CODE_LEN + PBKDF_SALT_LEN], mac.data(), MAC_OUTPUT_LEN);
96 std::string_view passphrase)
101 "BOTAN CRYPTOBOX MESSAGE");
103 if(ciphertext.size() < CRYPTOBOX_HEADER_LEN)
106 for(
size_t i = 0; i != VERSION_CODE_LEN; ++i)
109 if(version != 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];
117 auto pbkdf = pbkdf_fam->from_params(PBKDF_ITERATIONS);
122 master_key.data(), master_key.size(),
123 passphrase.data(), passphrase.size(),
124 pbkdf_salt, PBKDF_SALT_LEN);
126 const uint8_t* mk = master_key.data();
127 const uint8_t* cipher_key = mk;
128 const uint8_t* mac_key = mk + CIPHER_KEY_LEN;
129 const uint8_t* iv = mk + CIPHER_KEY_LEN + MAC_KEY_LEN;
132 std::unique_ptr<MessageAuthenticationCode> hmac =
134 hmac->set_key(mac_key, MAC_KEY_LEN);
136 if(ciphertext.size() > CRYPTOBOX_HEADER_LEN)
138 hmac->update(&ciphertext[CRYPTOBOX_HEADER_LEN],
139 ciphertext.size() - CRYPTOBOX_HEADER_LEN);
147 ctr->set_key(cipher_key, CIPHER_KEY_LEN);
148 ctr->start(iv, CIPHER_IV_LEN);
149 ctr->finish(ciphertext, CRYPTOBOX_HEADER_LEN);
151 ciphertext.erase(ciphertext.begin(), ciphertext.begin() + CRYPTOBOX_HEADER_LEN);
159 std::string_view passphrase)
166std::string
decrypt(
const uint8_t input[],
size_t input_len,
167 std::string_view passphrase)
176 std::string_view passphrase)
179 input.size(), passphrase);
static std::unique_ptr< Cipher_Mode > create_or_throw(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(std::string_view algo_spec, std::string_view provider="")
static std::unique_ptr< PasswordHashFamily > create_or_throw(std::string_view algo_spec, std::string_view provider="")
void randomize(std::span< uint8_t > output)
#define BOTAN_DIAGNOSTIC_POP
#define BOTAN_DIAGNOSTIC_PUSH
#define BOTAN_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS
secure_vector< uint8_t > decrypt_bin(const uint8_t input[], size_t input_len, std::string_view passphrase)
std::string encrypt(const uint8_t input[], size_t input_len, std::string_view passphrase, RandomNumberGenerator &rng)
std::string decrypt(const uint8_t input[], size_t input_len, std::string_view passphrase)
std::string encode(const uint8_t der[], size_t length, std::string_view label, size_t width)
secure_vector< uint8_t > decode_check_label(DataSource &source, std::string_view label_want)
constexpr 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)
constexpr uint32_t load_be< uint32_t >(const uint8_t in[], size_t off)
constexpr void store_be(uint16_t in, uint8_t out[2])
const char * cast_uint8_ptr_to_char(const uint8_t *b)
std::vector< T, secure_allocator< T > > secure_vector
const uint8_t * cast_char_ptr_to_uint8(const char *s)