From bf866f4dea6ca1baa323208b63c919024a3144b4 Mon Sep 17 00:00:00 2001 From: Andrew Jackson Date: Mon, 9 Nov 2026 21:28:37 -0600 Subject: [PATCH] feat: move encryption type to aes256gcm --- flake.lock | 8 +- src/crypto_aead_aes_256_gcm.c | 72 ++++++++++++++++++ src/crypto_aead_aes_256_gcm.h | 40 ++++++++++ src/crypto_aead_det_xchacha20.c | 131 -------------------------------- src/crypto_aead_det_xchacha20.h | 43 ----------- src/pgsodium.c | 24 +++--- 6 files changed, 128 insertions(+), 190 deletions(-) create mode 100644 src/crypto_aead_aes_256_gcm.c create mode 100644 src/crypto_aead_aes_256_gcm.h delete mode 100644 src/crypto_aead_det_xchacha20.c delete mode 100644 src/crypto_aead_det_xchacha20.h diff --git a/flake.lock b/flake.lock index 704715e..0f9a553 100644 --- a/flake.lock +++ b/flake.lock @@ -43,16 +43,16 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1791394750, - "narHash": "sha256-SMv4EKUaGmfUyXyeGHW3AiX1vbef7El56RKTIxio8jQ=", + "lastModified": 1793674321, + "narHash": "sha256-wLcCioA8+xi7ck/gdZmBeZo/NJfXxvYYCVOpAGvCgK8=", "owner": "supabase", "repo": "xpg", - "rev": "8f2a2005e8e020e0db5a7cbb94a87a9dd3227411", + "rev": "27aedcb0a23bce2879e7b114369e9c937665082d", "type": "github" }, "original": { "owner": "supabase", - "ref": "v2.6.0", + "ref": "v2.7.0", "repo": "xpg", "type": "github" } diff --git a/src/crypto_aead_aes_256_gcm.c b/src/crypto_aead_aes_256_gcm.c new file mode 100644 index 0000000..b44ff16 --- /dev/null +++ b/src/crypto_aead_aes_256_gcm.c @@ -0,0 +1,72 @@ +#include + +#include "crypto_aead_aes_256_gcm.h" + +// TOOD generate new aes256gcm key +int crypto_aead_aes_256_gcm_encrypt_detached( + unsigned char *ciphertext, + const unsigned char *message, size_t message_len, const unsigned char *additional_data, size_t additional_data_len, + unsigned char nonce[crypto_aead_aes256gcm_NPUBBYTES], + const unsigned char key[crypto_aead_aes256gcm_KEYBYTES]) { + + unsigned long long ciphertext_len; + + if (crypto_aead_aes256gcm_is_available() == 0) { + return 1; /* Not available on this CPU */ + } + + if (crypto_aead_aes256gcm_encrypt(ciphertext, &ciphertext_len, + message, message_len, + additional_data, additional_data_len, + NULL, nonce, key)){ + return 1; +} + return 0; +} + +int crypto_aead_aes_256_gcm_decrypt_detached( + unsigned char *message, const unsigned char *ciphertext, size_t ciphertext_len, + const unsigned char *additional_data, size_t additional_data_len, unsigned char nonce[crypto_aead_aes256gcm_NPUBBYTES], + const unsigned char key[crypto_aead_aes256gcm_KEYBYTES]) { + + unsigned long long message_len = ciphertext_len; + + if (crypto_aead_aes256gcm_decrypt(message, &message_len, + NULL, + ciphertext, ciphertext_len, + additional_data, + additional_data_len, + nonce, key) != 0) { + + return -1; + /* message forged! */ +} +return 0; + +} + +int crypto_aead_aes_256_gcm_encrypt( + unsigned char *ciphertext, const unsigned char *message, size_t message_len, + const unsigned char *additional_data, size_t additional_data_len, unsigned char nonce[crypto_aead_aes256gcm_NPUBBYTES], + const unsigned char key[crypto_aead_aes256gcm_KEYBYTES]) { + return crypto_aead_aes_256_gcm_encrypt_detached(ciphertext, message, message_len, additional_data, + additional_data_len, nonce, key); +} + +int crypto_aead_aes_256_gcm_decrypt( + unsigned char *message, const unsigned char *ciphertext, size_t ciphertext_len, + const unsigned char *additional_data, size_t additional_data_len, unsigned char nonce[crypto_aead_aes256gcm_NPUBBYTES], + const unsigned char key[crypto_aead_aes256gcm_KEYBYTES]) { + + if (ciphertext_len < crypto_aead_aes256gcm_ABYTES) { + return -1; + } + return crypto_aead_aes_256_gcm_decrypt_detached(message, ciphertext, ciphertext_len, additional_data, + additional_data_len, nonce, key); +} + +void crypto_aead_aes_256_gcm_keygen( + unsigned char k[crypto_aead_aes256gcm_KEYBYTES]) { + randombytes_buf(k, crypto_aead_aes256gcm_KEYBYTES); +} + diff --git a/src/crypto_aead_aes_256_gcm.h b/src/crypto_aead_aes_256_gcm.h new file mode 100644 index 0000000..d893b9d --- /dev/null +++ b/src/crypto_aead_aes_256_gcm.h @@ -0,0 +1,40 @@ +#ifndef crypto_aead_aes_256_gcm_H +#define crypto_aead_aes_256_gcm_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +int crypto_aead_aes_256_gcm_encrypt_detached( + unsigned char *ciphertext, + const unsigned char *message, size_t message_len, const unsigned char *additional_data, size_t additional_data_len, + unsigned char nonce[crypto_aead_aes256gcm_NPUBBYTES], + const unsigned char key[crypto_aead_aes256gcm_KEYBYTES]); + +int crypto_aead_aes_256_gcm_decrypt_detached( + unsigned char *message, const unsigned char *ciphertext, size_t ciphertext_len, + const unsigned char *additional_data, size_t additional_data_len, unsigned char nonce[crypto_aead_aes256gcm_NPUBBYTES], + const unsigned char key[crypto_aead_aes256gcm_KEYBYTES]); + +int crypto_aead_aes_256_gcm_encrypt( + unsigned char *ciphertext, const unsigned char *message, size_t message_len, + const unsigned char *additional_data, size_t additional_data_len, unsigned char nonce[crypto_aead_aes256gcm_NPUBBYTES], + const unsigned char key[crypto_aead_aes256gcm_KEYBYTES]); + +int crypto_aead_aes_256_gcm_decrypt( + unsigned char *message, const unsigned char *ciphertext, size_t ciphertext_len, + const unsigned char *additional_data, size_t additional_data_len, unsigned char nonce[crypto_aead_aes256gcm_NPUBBYTES], + const unsigned char key[crypto_aead_aes256gcm_KEYBYTES]); + +void crypto_aead_aes_256_gcm_keygen( + unsigned char key[crypto_aead_aes256gcm_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/crypto_aead_det_xchacha20.c b/src/crypto_aead_det_xchacha20.c deleted file mode 100644 index 6cfcb55..0000000 --- a/src/crypto_aead_det_xchacha20.c +++ /dev/null @@ -1,131 +0,0 @@ -#include -#include - -#include "crypto_aead_det_xchacha20.h" - -static void s2v_dbl256(unsigned char d[32]) { - unsigned char t[32]; - unsigned char mask; - size_t i; - - memcpy(t, d, 32); - for (i = 0; i < 32; i++) { - t[i] = (unsigned char)(t[i] << 1); - } - for (i = 31; i != 0; i--) { - t[i - 1] |= d[i] >> 7; - } - mask = ~((d[0] >> 7) - 1); - t[30] ^= (0x04 & mask); - t[31] ^= (0x25 & mask); - memcpy(d, t, 32); -} - -static inline void s2v_xor(unsigned char *d, const unsigned char *h, - size_t len) { - size_t i; - - for (i = 0; i < len; i++) { - d[i] ^= h[i]; - } -} - -static void s2v(unsigned char iv[crypto_aead_det_xchacha20_ABYTES], - const unsigned char *m, size_t mlen, const unsigned char *ad, - size_t adlen, const unsigned char *nonce, size_t noncelen, - const unsigned char ka[32]) { - static const unsigned char zero[crypto_aead_det_xchacha20_ABYTES] = {0}; - crypto_generichash_state st; - unsigned char d[32]; - - crypto_generichash(d, sizeof d, zero, sizeof zero, ka, sizeof d); - - if (ad != NULL && adlen > 0) { - s2v_dbl256(d); - crypto_generichash(iv, crypto_aead_det_xchacha20_ABYTES, ad, adlen, ka, 32); - s2v_xor(d, iv, sizeof d); - } - if (nonce != NULL && noncelen > 0) { - s2v_dbl256(d); - crypto_generichash(iv, crypto_aead_det_xchacha20_ABYTES, nonce, noncelen, - ka, 32); - s2v_xor(d, iv, sizeof d); - } - - crypto_generichash_init(&st, ka, 32, crypto_aead_det_xchacha20_ABYTES); - if (mlen >= crypto_aead_det_xchacha20_ABYTES) { - crypto_generichash_update(&st, m, mlen - crypto_aead_det_xchacha20_ABYTES); - s2v_xor(d, &m[mlen - crypto_aead_det_xchacha20_ABYTES], - crypto_aead_det_xchacha20_KEYBYTES); - } else { - s2v_dbl256(d); - s2v_xor(d, m, mlen); - d[mlen] ^= 0x80; - } - crypto_generichash_update(&st, d, sizeof d); - crypto_generichash_final(&st, iv, crypto_aead_det_xchacha20_ABYTES); -} - -int crypto_aead_det_xchacha20_encrypt_detached( - unsigned char *c, unsigned char mac[crypto_aead_det_xchacha20_ABYTES], - const unsigned char *m, size_t mlen, const unsigned char *ad, size_t adlen, - const unsigned char *nonce, - const unsigned char k[crypto_aead_det_xchacha20_KEYBYTES]) { - unsigned char subkeys[64], *ka = &subkeys[0], *ke = &subkeys[32]; - - crypto_generichash(subkeys, sizeof subkeys, NULL, 0, k, - crypto_aead_det_xchacha20_KEYBYTES); - s2v(mac, m, mlen, ad, adlen, nonce, crypto_aead_det_xchacha20_NONCEBYTES, ka); - crypto_stream_xchacha20_xor(c, m, mlen, mac, ke); - - return 0; -} - -int crypto_aead_det_xchacha20_decrypt_detached( - unsigned char *m, const unsigned char *c, size_t clen, - const unsigned char mac[crypto_aead_det_xchacha20_ABYTES], - const unsigned char *ad, size_t adlen, const unsigned char *nonce, - const unsigned char k[crypto_aead_det_xchacha20_KEYBYTES]) { - unsigned char subkeys[64], *ka = &subkeys[0], *ke = &subkeys[32]; - unsigned char computed_mac[crypto_aead_det_xchacha20_ABYTES]; - const size_t mlen = clen; - - crypto_generichash(subkeys, sizeof subkeys, NULL, 0, k, - crypto_aead_det_xchacha20_KEYBYTES); - crypto_stream_xchacha20_xor(m, c, clen, mac, ke); - s2v(computed_mac, m, mlen, ad, adlen, nonce, - crypto_aead_det_xchacha20_NONCEBYTES, ka); - if (sodium_memcmp(mac, computed_mac, crypto_aead_det_xchacha20_ABYTES) != 0) { - memset(m, 0, mlen); - return -1; - } - return 0; -} - -int crypto_aead_det_xchacha20_encrypt( - unsigned char *c, const unsigned char *m, size_t mlen, - const unsigned char *ad, size_t adlen, const unsigned char *nonce, - const unsigned char k[crypto_aead_det_xchacha20_KEYBYTES]) { - return crypto_aead_det_xchacha20_encrypt_detached(c, c + mlen, m, mlen, ad, - adlen, nonce, k); -} - -int crypto_aead_det_xchacha20_decrypt( - unsigned char *m, const unsigned char *c, size_t clen, - const unsigned char *ad, size_t adlen, const unsigned char *nonce, - const unsigned char k[crypto_aead_det_xchacha20_KEYBYTES]) { - size_t mlen; - - if (clen < crypto_aead_det_xchacha20_ABYTES) { - return -1; - } - mlen = clen - crypto_aead_det_xchacha20_ABYTES; - - return crypto_aead_det_xchacha20_decrypt_detached(m, c, mlen, c + mlen, ad, - adlen, nonce, k); -} - -void crypto_aead_det_xchacha20_keygen( - unsigned char k[crypto_aead_det_xchacha20_KEYBYTES]) { - randombytes_buf(k, crypto_aead_det_xchacha20_KEYBYTES); -} diff --git a/src/crypto_aead_det_xchacha20.h b/src/crypto_aead_det_xchacha20.h deleted file mode 100644 index def3a34..0000000 --- a/src/crypto_aead_det_xchacha20.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef crypto_aead_det_xchacha20_H -#define crypto_aead_det_xchacha20_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#define crypto_aead_det_xchacha20_KEYBYTES 32 -#define crypto_aead_det_xchacha20_ABYTES 32 -#define crypto_aead_det_xchacha20_NONCEBYTES 16 - -int crypto_aead_det_xchacha20_encrypt_detached( - unsigned char *c, unsigned char mac[crypto_aead_det_xchacha20_ABYTES], - const unsigned char *m, size_t mlen, const unsigned char *ad, size_t adlen, - const unsigned char *nonce, - const unsigned char k[crypto_aead_det_xchacha20_KEYBYTES]); - -int crypto_aead_det_xchacha20_decrypt_detached( - unsigned char *m, const unsigned char *c, size_t clen, - const unsigned char mac[crypto_aead_det_xchacha20_ABYTES], - const unsigned char *ad, size_t adlen, const unsigned char *nonce, - const unsigned char k[crypto_aead_det_xchacha20_KEYBYTES]); - -int crypto_aead_det_xchacha20_encrypt( - unsigned char *c, const unsigned char *m, size_t mlen, - const unsigned char *ad, size_t adlen, const unsigned char *nonce, - const unsigned char k[crypto_aead_det_xchacha20_KEYBYTES]); - -int crypto_aead_det_xchacha20_decrypt( - unsigned char *m, const unsigned char *c, size_t clen, - const unsigned char *ad, size_t adlen, const unsigned char *nonce, - const unsigned char k[crypto_aead_det_xchacha20_KEYBYTES]); - -void crypto_aead_det_xchacha20_keygen( - unsigned char k[crypto_aead_det_xchacha20_KEYBYTES]); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/pgsodium.c b/src/pgsodium.c index 5fbe512..a5b91c5 100644 --- a/src/pgsodium.c +++ b/src/pgsodium.c @@ -3,7 +3,7 @@ #include #include -#include "crypto_aead_det_xchacha20.h" +#include "crypto_aead_aes_256_gcm.h" #include "pgsodium.h" bytea *pgsodium_secret_key = NULL; @@ -37,19 +37,19 @@ Datum pgsodium_crypto_aead_det_encrypt_by_id(PG_FUNCTION_ARGS) { if (!PG_ARGISNULL(4)) { nonce = PG_GETARG_BYTEA_PP(4); - ERRORIF(VARSIZE_ANY_EXHDR(nonce) != crypto_aead_det_xchacha20_NONCEBYTES, + ERRORIF(VARSIZE_ANY_EXHDR(nonce) != crypto_aead_aes256gcm_NPUBBYTES, "%s: invalid nonce"); } else { nonce = NULL; } - result_size = VARSIZE_ANY_EXHDR(message) + crypto_aead_det_xchacha20_ABYTES; + result_size = VARSIZE_ANY_EXHDR(message) + crypto_aead_aes256gcm_ABYTES; result = _pgsodium_zalloc_bytea(result_size + VARHDRSZ); - key = pgsodium_derive_helper(key_id, crypto_aead_det_xchacha20_KEYBYTES, + key = pgsodium_derive_helper(key_id, crypto_aead_aes256gcm_KEYBYTES, context); - success = crypto_aead_det_xchacha20_encrypt( + success = crypto_aead_aes_256_gcm_encrypt( PGSODIUM_UCHARDATA(result), PGSODIUM_UCHARDATA_ANY(message), VARSIZE_ANY_EXHDR(message), associated != NULL ? PGSODIUM_UCHARDATA_ANY(associated) : NULL, @@ -87,19 +87,19 @@ Datum pgsodium_crypto_aead_det_decrypt_by_id(PG_FUNCTION_ARGS) { if (!PG_ARGISNULL(4)) { nonce = PG_GETARG_BYTEA_PP(4); - ERRORIF(VARSIZE_ANY_EXHDR(nonce) != crypto_aead_det_xchacha20_NONCEBYTES, + ERRORIF(VARSIZE_ANY_EXHDR(nonce) != crypto_aead_aes256gcm_NPUBBYTES, "%s: invalid nonce"); } else { nonce = NULL; } - ERRORIF(VARSIZE_ANY_EXHDR(ciphertext) < crypto_aead_det_xchacha20_ABYTES, + ERRORIF(VARSIZE_ANY_EXHDR(ciphertext) < crypto_aead_aes256gcm_ABYTES, "%s: invalid message"); - result_len = VARSIZE_ANY_EXHDR(ciphertext) - crypto_aead_det_xchacha20_ABYTES; + result_len = VARSIZE_ANY_EXHDR(ciphertext) - crypto_aead_aes256gcm_ABYTES; result = _pgsodium_zalloc_bytea(result_len + VARHDRSZ); - key = pgsodium_derive_helper(key_id, crypto_aead_det_xchacha20_KEYBYTES, + key = pgsodium_derive_helper(key_id, crypto_aead_aes256gcm_KEYBYTES, context); - success = crypto_aead_det_xchacha20_decrypt( + success = crypto_aead_aes_256_gcm_decrypt( PGSODIUM_UCHARDATA(result), PGSODIUM_UCHARDATA_ANY(ciphertext), VARSIZE_ANY_EXHDR(ciphertext), associated != NULL ? PGSODIUM_UCHARDATA_ANY(associated) : NULL, @@ -112,8 +112,8 @@ Datum pgsodium_crypto_aead_det_decrypt_by_id(PG_FUNCTION_ARGS) { PG_FUNCTION_INFO_V1(pgsodium_crypto_aead_det_noncegen); Datum pgsodium_crypto_aead_det_noncegen(PG_FUNCTION_ARGS) { - int result_size = VARHDRSZ + crypto_aead_det_xchacha20_NONCEBYTES; + int result_size = VARHDRSZ + crypto_aead_aes256gcm_NPUBBYTES; bytea *result = _pgsodium_zalloc_bytea(result_size); - randombytes_buf(VARDATA(result), crypto_aead_det_xchacha20_NONCEBYTES); + randombytes_buf(VARDATA(result), crypto_aead_aes256gcm_NPUBBYTES); PG_RETURN_BYTEA_P(result); }