8 #include <botan/cryptobox.h>
9 #include <botan/filters.h>
10 #include <botan/pipe.h>
11 #include <botan/sha2_64.h>
12 #include <botan/hmac.h>
13 #include <botan/pbkdf2.h>
14 #include <botan/pem.h>
15 #include <botan/loadstor.h>
16 #include <botan/mem_ops.h>
28 const uint32_t CRYPTOBOX_VERSION_CODE = 0xEFC22400;
30 const size_t VERSION_CODE_LEN = 4;
31 const size_t CIPHER_KEY_LEN = 32;
32 const size_t CIPHER_IV_LEN = 16;
33 const size_t MAC_KEY_LEN = 32;
34 const size_t MAC_OUTPUT_LEN = 20;
35 const size_t PBKDF_SALT_LEN = 10;
36 const size_t PBKDF_ITERATIONS = 8 * 1024;
38 const size_t PBKDF_OUTPUT_LEN = CIPHER_KEY_LEN + CIPHER_IV_LEN + MAC_KEY_LEN;
42 std::string
encrypt(
const uint8_t input[],
size_t input_len,
43 const std::string& passphrase,
47 rng.
randomize(pbkdf_salt.data(), pbkdf_salt.size());
58 const uint8_t* mk = master_key.
begin();
68 mac_key, MAC_OUTPUT_LEN)));
79 const size_t ciphertext_len = pipe.
remaining(0);
81 std::vector<uint8_t> out_buf(VERSION_CODE_LEN +
86 for(
size_t i = 0; i != VERSION_CODE_LEN; ++i)
87 out_buf[i] =
get_byte(i, CRYPTOBOX_VERSION_CODE);
89 copy_mem(&out_buf[VERSION_CODE_LEN], pbkdf_salt.data(), PBKDF_SALT_LEN);
92 pipe.
read(&out_buf[VERSION_CODE_LEN + PBKDF_SALT_LEN], MAC_OUTPUT_LEN, 1),
93 MAC_OUTPUT_LEN,
"MAC output");
95 pipe.
read(&out_buf[VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN],
97 ciphertext_len,
"Ciphertext size");
102 std::string
decrypt(
const uint8_t input[],
size_t input_len,
103 const std::string& passphrase)
108 "BOTAN CRYPTOBOX MESSAGE");
110 if(ciphertext.size() < (VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN))
113 for(
size_t i = 0; i != VERSION_CODE_LEN; ++i)
114 if(ciphertext[i] !=
get_byte(i, CRYPTOBOX_VERSION_CODE))
117 const uint8_t* pbkdf_salt = &ciphertext[VERSION_CODE_LEN];
128 const uint8_t* mk = master_key.
begin();
137 mac_key, MAC_OUTPUT_LEN)));
139 const size_t ciphertext_offset =
140 VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN;
143 ciphertext.size() - ciphertext_offset);
145 uint8_t computed_mac[MAC_OUTPUT_LEN];
149 &ciphertext[VERSION_CODE_LEN + PBKDF_SALT_LEN],
157 const std::string& passphrase)
159 return decrypt(reinterpret_cast<const uint8_t*>(input.data()),
bool same_mem(const T *p1, const T *p2, size_t n)
virtual void randomize(uint8_t output[], size_t length)=0
size_t remaining(message_id msg=DEFAULT_MESSAGE) const BOTAN_WARN_UNUSED_RESULT
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
OctetString derive_key(size_t out_len, const std::string &passphrase, const uint8_t salt[], size_t salt_len, size_t iterations) const
size_t read(uint8_t output[], size_t length) override BOTAN_WARN_UNUSED_RESULT
std::string encrypt(const uint8_t input[], size_t input_len, const std::string &passphrase, RandomNumberGenerator &rng)
std::vector< T, secure_allocator< T >> secure_vector
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
std::string read_all_as_string(message_id=DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT
std::string decrypt(const uint8_t input[], size_t input_len, const std::string &passphrase)
void process_msg(const uint8_t in[], size_t length)
void copy_mem(T *out, const T *in, size_t n)
secure_vector< uint8_t > decode_check_label(DataSource &source, const std::string &label_want)
uint8_t get_byte(size_t byte_num, T input)
const uint8_t * begin() const
Keyed_Filter * get_cipher(const std::string &algo_spec, Cipher_Dir direction)