From 20cb29c2f8c5c87bc590896854a20b1473ceb358 Mon Sep 17 00:00:00 2001 From: "info@mode42.com" Date: Sat, 8 Aug 2026 03:54:55 +0000 Subject: #2 --- src/core/crypto_libsodium.c | 111 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/core/crypto_libsodium.c (limited to 'src/core/crypto_libsodium.c') diff --git a/src/core/crypto_libsodium.c b/src/core/crypto_libsodium.c new file mode 100644 index 0000000..85cf537 --- /dev/null +++ b/src/core/crypto_libsodium.c @@ -0,0 +1,111 @@ +#include "hybbx/types.h" + +#include + +#include +#include + +static int sodium_ready; + +static int ensure_sodium(void) +{ + if (!sodium_ready) { + if (sodium_init() < 0) { + return -1; + } + sodium_ready = 1; + } + + return 0; +} + +void hybbx_libsodium_chacha_lock(uint8_t *ciphertext, uint8_t tag[16], + const uint8_t key[32], const uint8_t nonce[24], + const uint8_t *aad, size_t aad_len, + const uint8_t *plaintext, size_t plaintext_len) +{ + unsigned long long out_len = 0; + uint8_t *packed; + size_t packed_cap; + + if (ensure_sodium() != 0) { + return; + } + + packed_cap = plaintext_len + + crypto_aead_xchacha20poly1305_ietf_ABYTES; + packed = malloc(packed_cap); + if (packed == NULL) { + return; + } + + if (crypto_aead_xchacha20poly1305_ietf_encrypt( + packed, &out_len, plaintext, plaintext_len, aad, aad_len, NULL, + nonce, key) != 0) { + free(packed); + return; + } + + if (plaintext_len > 0 && ciphertext != NULL) { + memcpy(ciphertext, packed, plaintext_len); + } + memcpy(tag, packed + plaintext_len, + crypto_aead_xchacha20poly1305_ietf_ABYTES); + free(packed); +} + +int hybbx_libsodium_chacha_unlock(uint8_t *plaintext, const uint8_t tag[16], + const uint8_t key[32], const uint8_t nonce[24], + const uint8_t *aad, size_t aad_len, + const uint8_t *ciphertext, size_t ciphertext_len) +{ + unsigned long long pt_len = 0; + uint8_t *packed; + size_t packed_len; + int rc; + + if (ensure_sodium() != 0) { + return -1; + } + + packed_len = ciphertext_len + + crypto_aead_xchacha20poly1305_ietf_ABYTES; + packed = malloc(packed_len); + if (packed == NULL) { + return -1; + } + + if (ciphertext_len > 0 && ciphertext != NULL) { + memcpy(packed, ciphertext, ciphertext_len); + } + memcpy(packed + ciphertext_len, tag, + crypto_aead_xchacha20poly1305_ietf_ABYTES); + + rc = crypto_aead_xchacha20poly1305_ietf_decrypt( + plaintext, &pt_len, NULL, packed, packed_len, aad, aad_len, nonce, + key); + + free(packed); + return rc; +} + +void hybbx_libsodium_x25519_public_key(uint8_t public_key[32], + const uint8_t secret_key[32]) +{ + if (ensure_sodium() != 0) { + return; + } + + crypto_scalarmult_base(public_key, secret_key); +} + +void hybbx_libsodium_x25519_shared(uint8_t shared[32], + const uint8_t secret_key[32], + const uint8_t peer_public_key[32]) +{ + if (ensure_sodium() != 0) { + return; + } + + crypto_scalarmult(shared, secret_key, peer_public_key); +} -- cgit v1.3.1