/* * (C) 2019 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include #include namespace Botan { namespace { int sodium_aead_chacha20poly1305_encrypt(uint8_t ctext[], unsigned long long* ctext_len, const uint8_t ptext[], size_t ptext_len, const uint8_t ad[], size_t ad_len, const uint8_t nonce[], size_t nonce_len, const uint8_t key[]) { auto chacha20poly1305 = AEAD_Mode::create_or_throw("ChaCha20Poly1305", ENCRYPTION); chacha20poly1305->set_key(key, 32); chacha20poly1305->set_associated_data(ad, ad_len); chacha20poly1305->start(nonce, nonce_len); // FIXME do this in-place secure_vector buf; buf.reserve(ptext_len + 16); buf.assign(ptext, ptext + ptext_len); chacha20poly1305->finish(buf); copy_mem(ctext, buf.data(), buf.size()); if(ctext_len) *ctext_len = buf.size(); return 0; } int sodium_aead_chacha20poly1305_decrypt(uint8_t ptext[], unsigned long long* ptext_len, const uint8_t ctext[], size_t ctext_len, const uint8_t ad[], size_t ad_len, const uint8_t nonce[], size_t nonce_len, const uint8_t key[]) { if(ctext_len < 16) return -1; *ptext_len = 0; auto chacha20poly1305 = AEAD_Mode::create_or_throw("ChaCha20Poly1305", DECRYPTION); chacha20poly1305->set_key(key, 32); chacha20poly1305->set_associated_data(ad, ad_len); chacha20poly1305->start(nonce, nonce_len); // FIXME do this in-place secure_vector buf; buf.assign(ctext, ctext + ctext_len); try { chacha20poly1305->finish(buf); } catch(Invalid_Authentication_Tag&) { return -1; } *ptext_len = ctext_len - 16; copy_mem(ptext, buf.data(), buf.size()); return 0; } int sodium_aead_chacha20poly1305_encrypt_detached(uint8_t ctext[], uint8_t mac[], const uint8_t ptext[], size_t ptext_len, const uint8_t ad[], size_t ad_len, const uint8_t nonce[], size_t nonce_len, const uint8_t key[]) { auto chacha20poly1305 = AEAD_Mode::create_or_throw("ChaCha20Poly1305", ENCRYPTION); chacha20poly1305->set_key(key, 32); chacha20poly1305->set_associated_data(ad, ad_len); chacha20poly1305->start(nonce, nonce_len); // FIXME do this in-place secure_vector buf; buf.reserve(ptext_len + 16); buf.assign(ptext, ptext + ptext_len); chacha20poly1305->finish(buf); copy_mem(ctext, buf.data(), ptext_len); copy_mem(mac, buf.data() + ptext_len, 16); return 0; } int sodium_aead_chacha20poly1305_decrypt_detached(uint8_t ptext[], const uint8_t ctext[], size_t ctext_len, const uint8_t mac[], const uint8_t ad[], size_t ad_len, const uint8_t nonce[], size_t nonce_len, const uint8_t key[]) { auto chacha20poly1305 = AEAD_Mode::create_or_throw("ChaCha20Poly1305", DECRYPTION); chacha20poly1305->set_key(key, 32); chacha20poly1305->set_associated_data(ad, ad_len); chacha20poly1305->start(nonce, nonce_len); // FIXME do this in-place secure_vector buf; buf.reserve(ctext_len + 16); buf.assign(ctext, ctext + ctext_len); buf.insert(buf.end(), mac, mac + 16); try { chacha20poly1305->finish(buf); } catch(Invalid_Authentication_Tag&) { return -1; } copy_mem(ptext, buf.data(), buf.size()); return 0; } } int Sodium::crypto_aead_chacha20poly1305_ietf_encrypt(uint8_t ctext[], unsigned long long* ctext_len, const uint8_t ptext[], size_t ptext_len, const uint8_t ad[], size_t ad_len, const uint8_t* unused_secret_nonce, const uint8_t nonce[], const uint8_t key[]) { BOTAN_UNUSED(unused_secret_nonce); return sodium_aead_chacha20poly1305_encrypt( ctext, ctext_len, ptext, ptext_len, ad, ad_len, nonce, crypto_aead_chacha20poly1305_ietf_npubbytes(), key); } int Sodium::crypto_aead_chacha20poly1305_ietf_decrypt(uint8_t ptext[], unsigned long long* ptext_len, uint8_t* unused_secret_nonce, const uint8_t ctext[], size_t ctext_len, const uint8_t ad[], size_t ad_len, const uint8_t nonce[], const uint8_t key[]) { BOTAN_UNUSED(unused_secret_nonce); return sodium_aead_chacha20poly1305_decrypt( ptext, ptext_len, ctext, ctext_len, ad, ad_len, nonce, crypto_aead_chacha20poly1305_ietf_npubbytes(), key); } int Sodium::crypto_aead_chacha20poly1305_ietf_encrypt_detached(uint8_t ctext[], uint8_t mac[], unsigned long long* mac_len, const uint8_t ptext[], size_t ptext_len, const uint8_t ad[], size_t ad_len, const uint8_t unused_secret_nonce[], const uint8_t nonce[], const uint8_t key[]) { BOTAN_UNUSED(unused_secret_nonce); if(mac_len) *mac_len = 16; return sodium_aead_chacha20poly1305_encrypt_detached( ctext, mac, ptext, ptext_len, ad, ad_len, nonce, crypto_aead_chacha20poly1305_ietf_npubbytes(), key); } int Sodium::crypto_aead_chacha20poly1305_ietf_decrypt_detached(uint8_t ptext[], uint8_t unused_secret_nonce[], const uint8_t ctext[], size_t ctext_len, const uint8_t mac[], const uint8_t ad[], size_t ad_len, const uint8_t nonce[], const uint8_t key[]) { BOTAN_UNUSED(unused_secret_nonce); return sodium_aead_chacha20poly1305_decrypt_detached( ptext, ctext, ctext_len, mac, ad, ad_len, nonce, crypto_aead_chacha20poly1305_ietf_npubbytes(), key); } int Sodium::crypto_aead_chacha20poly1305_encrypt(uint8_t ctext[], unsigned long long* ctext_len, const uint8_t ptext[], size_t ptext_len, const uint8_t ad[], size_t ad_len, const uint8_t unused_secret_nonce[], const uint8_t nonce[], const uint8_t key[]) { BOTAN_UNUSED(unused_secret_nonce); return sodium_aead_chacha20poly1305_encrypt( ctext, ctext_len, ptext, ptext_len, ad, ad_len, nonce, crypto_aead_chacha20poly1305_npubbytes(), key); } int Sodium::crypto_aead_chacha20poly1305_decrypt(uint8_t ptext[], unsigned long long* ptext_len, uint8_t unused_secret_nonce[], const uint8_t ctext[], size_t ctext_len, const uint8_t ad[], size_t ad_len, const uint8_t nonce[], const uint8_t key[]) { BOTAN_UNUSED(unused_secret_nonce); return sodium_aead_chacha20poly1305_decrypt( ptext, ptext_len, ctext, ctext_len, ad, ad_len, nonce, crypto_aead_chacha20poly1305_npubbytes(), key); } int Sodium::crypto_aead_chacha20poly1305_encrypt_detached(uint8_t ctext[], uint8_t mac[], unsigned long long* mac_len, const uint8_t ptext[], size_t ptext_len, const uint8_t ad[], size_t ad_len, const uint8_t unused_secret_nonce[], const uint8_t nonce[], const uint8_t key[]) { BOTAN_UNUSED(unused_secret_nonce); if(mac_len) *mac_len = 16; return sodium_aead_chacha20poly1305_encrypt_detached( ctext, mac, ptext, ptext_len, ad, ad_len, nonce, crypto_aead_chacha20poly1305_npubbytes(), key); } int Sodium::crypto_aead_chacha20poly1305_decrypt_detached(uint8_t ptext[], uint8_t unused_secret_nonce[], const uint8_t ctext[], size_t ctext_len, const uint8_t mac[], const uint8_t ad[], size_t ad_len, const uint8_t nonce[], const uint8_t key[]) { BOTAN_UNUSED(unused_secret_nonce); return sodium_aead_chacha20poly1305_decrypt_detached( ptext, ctext, ctext_len, mac, ad, ad_len, nonce, crypto_aead_chacha20poly1305_npubbytes(), key); } int Sodium::crypto_aead_xchacha20poly1305_ietf_encrypt(uint8_t ctext[], unsigned long long* ctext_len, const uint8_t ptext[], size_t ptext_len, const uint8_t ad[], size_t ad_len, const uint8_t unused_secret_nonce[], const uint8_t nonce[], const uint8_t key[]) { BOTAN_UNUSED(unused_secret_nonce); return sodium_aead_chacha20poly1305_encrypt( ctext, ctext_len, ptext, ptext_len, ad, ad_len, nonce, crypto_aead_xchacha20poly1305_ietf_npubbytes(), key); } int Sodium::crypto_aead_xchacha20poly1305_ietf_decrypt(uint8_t ptext[], unsigned long long* ptext_len, uint8_t unused_secret_nonce[], const uint8_t ctext[], size_t ctext_len, const uint8_t ad[], size_t ad_len, const uint8_t nonce[], const uint8_t key[]) { BOTAN_UNUSED(unused_secret_nonce); return sodium_aead_chacha20poly1305_decrypt( ptext, ptext_len, ctext, ctext_len, ad, ad_len, nonce, crypto_aead_xchacha20poly1305_ietf_npubbytes(), key); } int Sodium::crypto_aead_xchacha20poly1305_ietf_encrypt_detached(uint8_t ctext[], uint8_t mac[], unsigned long long* mac_len, const uint8_t ptext[], size_t ptext_len, const uint8_t ad[], size_t ad_len, const uint8_t unused_secret_nonce[], const uint8_t nonce[], const uint8_t key[]) { BOTAN_UNUSED(unused_secret_nonce); if(mac_len) *mac_len = 16; return sodium_aead_chacha20poly1305_encrypt_detached( ctext, mac, ptext, ptext_len, ad, ad_len, nonce, crypto_aead_xchacha20poly1305_ietf_npubbytes(), key); } int Sodium::crypto_aead_xchacha20poly1305_ietf_decrypt_detached(uint8_t ptext[], uint8_t unused_secret_nonce[], const uint8_t ctext[], size_t ctext_len, const uint8_t mac[], const uint8_t ad[], size_t ad_len, const uint8_t nonce[], const uint8_t key[]) { BOTAN_UNUSED(unused_secret_nonce); return sodium_aead_chacha20poly1305_decrypt_detached( ptext, ctext, ctext_len, mac, ad, ad_len, nonce, crypto_aead_xchacha20poly1305_ietf_npubbytes(), key); } }