52 const size_t out_len =
add_or_throw(CRYPTOBOX_HEADER_LEN, input_len,
"CryptoBox input too large");
54 store_be(CRYPTOBOX_VERSION_CODE, out_buf.data());
55 rng.
randomize(&out_buf[VERSION_CODE_LEN], PBKDF_SALT_LEN);
58 copy_mem(&out_buf[CRYPTOBOX_HEADER_LEN], input, input_len);
64 auto pbkdf = pbkdf_fam->from_params(PBKDF_ITERATIONS);
68 pbkdf->derive_key(master_key.data(),
72 &out_buf[VERSION_CODE_LEN],
75 const uint8_t* mk = master_key.data();
76 const uint8_t* cipher_key = mk;
77 const uint8_t* mac_key = mk + CIPHER_KEY_LEN;
78 const uint8_t* iv = mk + CIPHER_KEY_LEN + MAC_KEY_LEN;
82 ctr->set_key(cipher_key, CIPHER_KEY_LEN);
83 ctr->start(iv, CIPHER_IV_LEN);
84 ctr->finish(out_buf, CRYPTOBOX_HEADER_LEN);
87 hmac->set_key(mac_key, MAC_KEY_LEN);
89 hmac->update(&out_buf[CRYPTOBOX_HEADER_LEN], input_len);
94 copy_mem(&out_buf[VERSION_CODE_LEN + PBKDF_SALT_LEN], mac.data(), MAC_OUTPUT_LEN);
103 if(ciphertext.size() < CRYPTOBOX_HEADER_LEN) {
107 for(
size_t i = 0; i != VERSION_CODE_LEN; ++i) {
109 if(version != CRYPTOBOX_VERSION_CODE) {
114 const uint8_t* pbkdf_salt = &ciphertext[VERSION_CODE_LEN];
115 const uint8_t* box_mac = &ciphertext[VERSION_CODE_LEN + PBKDF_SALT_LEN];
118 auto pbkdf = pbkdf_fam->from_params(PBKDF_ITERATIONS);
123 master_key.data(), master_key.size(), passphrase.data(), passphrase.size(), pbkdf_salt, PBKDF_SALT_LEN);
125 const uint8_t* mk = master_key.data();
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;
132 hmac->set_key(mac_key, MAC_KEY_LEN);
134 if(ciphertext.size() > CRYPTOBOX_HEADER_LEN) {
135 hmac->update(&ciphertext[CRYPTOBOX_HEADER_LEN], ciphertext.size() - CRYPTOBOX_HEADER_LEN);
139 if(!
CT::is_equal(computed_mac.data(), box_mac, MAC_OUTPUT_LEN).as_bool()) {
144 ctr->set_key(cipher_key, CIPHER_KEY_LEN);
145 ctr->start(iv, CIPHER_IV_LEN);
146 ctr->finish(ciphertext, CRYPTOBOX_HEADER_LEN);
148 ciphertext.erase(ciphertext.begin(), ciphertext.begin() + CRYPTOBOX_HEADER_LEN);