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_config.c | 247 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 src/core/crypto_config.c (limited to 'src/core/crypto_config.c') diff --git a/src/core/crypto_config.c b/src/core/crypto_config.c new file mode 100644 index 0000000..65b64ef --- /dev/null +++ b/src/core/crypto_config.c @@ -0,0 +1,247 @@ +#include "hybbx/crypto_config.h" +#include "hybbx/config.h" +#include "hybbx/log.h" + +#include +#include +#include + +static hybbx_crypto_config_t g_crypto_config; +static int g_crypto_config_ready; + +static int str_ieq(const char *a, const char *b) +{ + if (a == NULL || b == NULL) { + return 0; + } + + while (*a != '\0' && *b != '\0') { + char ca = (char)(*a >= 'A' && *a <= 'Z' ? *a + 32 : *a); + char cb = (char)(*b >= 'A' && *b <= 'Z' ? *b + 32 : *b); + + if (ca != cb) { + return 0; + } + a++; + b++; + } + + return *a == '\0' && *b == '\0'; +} + +static hybbx_password_hash_backend_t parse_password_hash(const char *value) +{ + if (value == NULL || value[0] == '\0' || + str_ieq(value, "tinysha256") || str_ieq(value, "bundled") || + str_ieq(value, "default")) { + return HYBBX_PASSWORD_HASH_TINYSHA256; + } + + if (str_ieq(value, "openssl") || str_ieq(value, "libcrypto")) { + return HYBBX_PASSWORD_HASH_OPENSSL; + } + + return HYBBX_PASSWORD_HASH_TINYSHA256; +} + +static hybbx_aes_gcm_backend_t parse_aes_gcm(const char *value) +{ + if (value == NULL || value[0] == '\0' || + str_ieq(value, "tinyaes") || str_ieq(value, "bundled") || + str_ieq(value, "default")) { + return HYBBX_AES_GCM_TINYAES; + } + + if (str_ieq(value, "openssl") || str_ieq(value, "libcrypto")) { + return HYBBX_AES_GCM_OPENSSL; + } + + return HYBBX_AES_GCM_TINYAES; +} + +static hybbx_chacha_backend_t parse_chacha(const char *value) +{ + if (value == NULL || value[0] == '\0' || + str_ieq(value, "monocypher") || str_ieq(value, "bundled") || + str_ieq(value, "default")) { + return HYBBX_CHACHA_MONOCYPHER; + } + + if (str_ieq(value, "libsodium") || str_ieq(value, "sodium")) { + return HYBBX_CHACHA_LIBSODIUM; + } + + return HYBBX_CHACHA_MONOCYPHER; +} + +static hybbx_x25519_backend_t parse_x25519(const char *value) +{ + if (value == NULL || value[0] == '\0' || + str_ieq(value, "monocypher") || str_ieq(value, "bundled") || + str_ieq(value, "default")) { + return HYBBX_X25519_MONOCYPHER; + } + + if (str_ieq(value, "libsodium") || str_ieq(value, "sodium")) { + return HYBBX_X25519_LIBSODIUM; + } + + return HYBBX_X25519_MONOCYPHER; +} + +static hybbx_random_backend_t parse_random(const char *value) +{ + if (value == NULL || value[0] == '\0' || + str_ieq(value, "system") || str_ieq(value, "bundled") || + str_ieq(value, "default") || str_ieq(value, "getrandom") || + str_ieq(value, "urandom")) { + return HYBBX_RANDOM_SYSTEM; + } + + if (str_ieq(value, "openssl") || str_ieq(value, "libcrypto")) { + return HYBBX_RANDOM_OPENSSL; + } + + return HYBBX_RANDOM_SYSTEM; +} + +static void resolve_backends(hybbx_crypto_config_t *cfg) +{ +#if !defined(HYBBX_HAVE_OPENSSL) + if (cfg->password_hash == HYBBX_PASSWORD_HASH_OPENSSL) { + hybbx_log_warn("[crypto] password_hash=openssl requested but HyBBX was not " + "built with OpenSSL; using tinysha256"); + cfg->password_hash = HYBBX_PASSWORD_HASH_TINYSHA256; + } + if (cfg->aes_gcm == HYBBX_AES_GCM_OPENSSL) { + hybbx_log_warn("[crypto] aes_gcm=openssl requested but HyBBX was not built " + "with OpenSSL; using tinyaes"); + cfg->aes_gcm = HYBBX_AES_GCM_TINYAES; + } + if (cfg->random == HYBBX_RANDOM_OPENSSL) { + hybbx_log_warn("[crypto] random=openssl requested but HyBBX was not built " + "with OpenSSL; using system"); + cfg->random = HYBBX_RANDOM_SYSTEM; + } +#endif + +#if !defined(HYBBX_HAVE_LIBSODIUM) + if (cfg->chacha == HYBBX_CHACHA_LIBSODIUM) { + hybbx_log_warn("[crypto] chacha=libsodium requested but HyBBX was not built " + "with libsodium; using monocypher"); + cfg->chacha = HYBBX_CHACHA_MONOCYPHER; + } + if (cfg->x25519 == HYBBX_X25519_LIBSODIUM) { + hybbx_log_warn("[crypto] x25519=libsodium requested but HyBBX was not built " + "with libsodium; using monocypher"); + cfg->x25519 = HYBBX_X25519_MONOCYPHER; + } +#endif +} + +void hybbx_crypto_config_defaults(hybbx_crypto_config_t *cfg) +{ + if (cfg == NULL) { + return; + } + + cfg->password_hash = HYBBX_PASSWORD_HASH_TINYSHA256; + cfg->aes_gcm = HYBBX_AES_GCM_TINYAES; + cfg->chacha = HYBBX_CHACHA_MONOCYPHER; + cfg->x25519 = HYBBX_X25519_MONOCYPHER; + cfg->random = HYBBX_RANDOM_SYSTEM; +} + +void hybbx_crypto_config_apply(const hybbx_config_t *config) +{ + const char *value; + + hybbx_crypto_config_defaults(&g_crypto_config); + + if (config != NULL) { + value = hybbx_config_get(config, "crypto", "password_hash", NULL); + g_crypto_config.password_hash = parse_password_hash(value); + + value = hybbx_config_get(config, "crypto", "aes_gcm", NULL); + g_crypto_config.aes_gcm = parse_aes_gcm(value); + + value = hybbx_config_get(config, "crypto", "chacha", NULL); + g_crypto_config.chacha = parse_chacha(value); + + value = hybbx_config_get(config, "crypto", "x25519", NULL); + g_crypto_config.x25519 = parse_x25519(value); + + value = hybbx_config_get(config, "crypto", "random", NULL); + g_crypto_config.random = parse_random(value); + } + + resolve_backends(&g_crypto_config); + g_crypto_config_ready = 1; + + hybbx_log_info("[crypto] password_hash=%s aes_gcm=%s chacha=%s x25519=%s random=%s", + hybbx_password_hash_backend_name(g_crypto_config.password_hash), + hybbx_aes_gcm_backend_name(g_crypto_config.aes_gcm), + hybbx_chacha_backend_name(g_crypto_config.chacha), + hybbx_x25519_backend_name(g_crypto_config.x25519), + hybbx_random_backend_name(g_crypto_config.random)); +} + +const hybbx_crypto_config_t *hybbx_crypto_config_get(void) +{ + if (!g_crypto_config_ready) { + hybbx_crypto_config_defaults(&g_crypto_config); + g_crypto_config_ready = 1; + } + + return &g_crypto_config; +} + +const char *hybbx_password_hash_backend_name(hybbx_password_hash_backend_t b) +{ + switch (b) { + case HYBBX_PASSWORD_HASH_OPENSSL: + return "openssl"; + default: + return "tinysha256"; + } +} + +const char *hybbx_aes_gcm_backend_name(hybbx_aes_gcm_backend_t b) +{ + switch (b) { + case HYBBX_AES_GCM_OPENSSL: + return "openssl"; + default: + return "tinyaes"; + } +} + +const char *hybbx_chacha_backend_name(hybbx_chacha_backend_t b) +{ + switch (b) { + case HYBBX_CHACHA_LIBSODIUM: + return "libsodium"; + default: + return "monocypher"; + } +} + +const char *hybbx_x25519_backend_name(hybbx_x25519_backend_t b) +{ + switch (b) { + case HYBBX_X25519_LIBSODIUM: + return "libsodium"; + default: + return "monocypher"; + } +} + +const char *hybbx_random_backend_name(hybbx_random_backend_t b) +{ + switch (b) { + case HYBBX_RANDOM_OPENSSL: + return "openssl"; + default: + return "system"; + } +} -- cgit v1.3.1