summaryrefslogtreecommitdiff
path: root/src/core/crypto_libsodium.c
diff options
context:
space:
mode:
authorinfo@mode42.com <info@mode42.com>2026-08-08 03:54:55 +0000
committerinfo@mode42.com <info@mode42.com>2026-08-08 03:54:55 +0000
commit20cb29c2f8c5c87bc590896854a20b1473ceb358 (patch)
tree2857f41513a56ad41af97b57362639298aa7f033 /src/core/crypto_libsodium.c
#2
Diffstat (limited to 'src/core/crypto_libsodium.c')
-rw-r--r--src/core/crypto_libsodium.c111
1 files changed, 111 insertions, 0 deletions
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 <sodium.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+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);
+}
git clone -b <branch> https://cgit.mode42.com/<repo>.git
git clone -b <branch> git://cgit.mode42.com/<repo>.git

info@mode42.com