/blog/2024/04/27/abba-encryption.gmi
ABBA isn't very good when both AB and BA can decrypt the message, and the intent is that one of those pairs cannot decrypt what they just encrypted, which is probably mentioned in the libsodium documentation but is easy enough to miss, though is mentioned in
https://flak.tedunangst.com/post/reop
which can be confirmed with some test code.
#include <err.h> #include <sodium.h> #define MESSAGE (const unsigned char *) "blub" #define MESSAGE_LEN 4 #define CIPHERTEXT_LEN (crypto_box_MACBYTES + MESSAGE_LEN) int main(int argc, char *argv[]) { unsigned char alice_pub[crypto_box_PUBLICKEYBYTES]; unsigned char bobby_pub[crypto_box_PUBLICKEYBYTES]; unsigned char alice_key[crypto_box_SECRETKEYBYTES]; unsigned char bobby_key[crypto_box_SECRETKEYBYTES]; if (sodium_init()) err(1, "sodium_init"); if (crypto_box_keypair(alice_pub, alice_key)) errx(1, "crypto_box_keypair"); if (crypto_box_keypair(bobby_pub, bobby_key)) errx(1, "crypto_box_keypair"); unsigned char nonce[crypto_box_NONCEBYTES]; randombytes_buf(nonce, sizeof nonce); unsigned char ciphertext[CIPHERTEXT_LEN]; unsigned char decrypted[MESSAGE_LEN]; if (crypto_box_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce, bobby_pub, alice_key)) errx(1, "crypto_box_easy"); if (crypto_box_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce, alice_pub, bobby_key)) { errx(1, "crypto_box_open_easy"); } printf("%.*s\n", MESSAGE_LEN, decrypted); // but can Alice also read it? yes! if (crypto_box_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce, bobby_pub, alice_key)) { errx(1, "crypto_box_open_easy"); } printf("%.*s\n", MESSAGE_LEN, decrypted); }
$ CFLAGS=`pkg-config --cflags --libs libsodium` make asymmetric cc -I/usr/local/include -L/usr/local/lib -lsodium -o asymmetric asymmetric.c $ ./asymmetric blub blub
Whoops!
There is a "crypto_box_seal" in libsodium that will prevent (or better prevent—someone could be stealing the ephemeral keys from memory, but if they can do that then they can probably also read what is being encrypted at the moment) the sender from being able to decrypt files pending pickup by the recipient.
Now to rewrite some code… maybe I should ditch libsodium and only use LibreSSL functions?