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_openssl.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/core/crypto_openssl.c (limited to 'src/core/crypto_openssl.c') diff --git a/src/core/crypto_openssl.c b/src/core/crypto_openssl.c new file mode 100644 index 0000000..551ea83 --- /dev/null +++ b/src/core/crypto_openssl.c @@ -0,0 +1,142 @@ +#include "hybbx/types.h" + +#include +#include + +#include +#include + +void hybbx_openssl_sha256_hex(const char *data, size_t len, char hex[65]) +{ + unsigned char digest[32]; + unsigned int digest_len = sizeof(digest); + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + + if (ctx == NULL) { + hex[0] = '\0'; + return; + } + + if (EVP_DigestInit_ex(ctx, EVP_sha256(), NULL) != 1 || + EVP_DigestUpdate(ctx, data, len) != 1 || + EVP_DigestFinal_ex(ctx, digest, &digest_len) != 1) { + EVP_MD_CTX_free(ctx); + hex[0] = '\0'; + return; + } + + EVP_MD_CTX_free(ctx); + + for (size_t i = 0; i < digest_len; i++) { + snprintf(hex + i * 2, 3, "%02x", digest[i]); + } +} + +static int openssl_gcm_crypt(int encrypt, const uint8_t key[32], + const uint8_t nonce[12], const uint8_t *aad, + size_t aad_len, const uint8_t *in, size_t in_len, + uint8_t *out, const uint8_t tag_in[16], + uint8_t tag_out[16]) +{ + EVP_CIPHER_CTX *ctx = NULL; + int out_len = 0; + int total = 0; + int rc = -1; + + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + return -1; + } + + if (EVP_CipherInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL, encrypt) != + 1 || + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL) != 1 || + EVP_CipherInit_ex(ctx, NULL, NULL, key, nonce, encrypt) != 1) { + goto done; + } + + if (aad_len > 0 && aad != NULL) { + if (EVP_CipherUpdate(ctx, NULL, &out_len, aad, (int)aad_len) != 1) { + goto done; + } + } + + if (in_len > 0) { + if (EVP_CipherUpdate(ctx, out, &out_len, in, (int)in_len) != 1) { + goto done; + } + total = out_len; + } + + if (encrypt) { + if (EVP_EncryptFinal_ex(ctx, out + total, &out_len) != 1) { + goto done; + } + if (tag_out == NULL || + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag_out) != 1) { + goto done; + } + rc = 0; + goto done; + } + + if (tag_in == NULL || + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, + (void *)(uintptr_t)tag_in) != 1) { + goto done; + } + + if (EVP_DecryptFinal_ex(ctx, out + total, &out_len) != 1) { + goto done; + } + + rc = 0; +done: + EVP_CIPHER_CTX_free(ctx); + return rc; +} + +int hybbx_openssl_aes256gcm_encrypt( + const uint8_t key[32], const uint8_t nonce[12], const uint8_t *aad, + size_t aad_len, const uint8_t *plaintext, size_t plaintext_len, + uint8_t *ciphertext, uint8_t tag[16]) +{ + if (key == NULL || nonce == NULL || tag == NULL) { + return -1; + } + if (plaintext_len > 0 && (plaintext == NULL || ciphertext == NULL)) { + return -1; + } + + return openssl_gcm_crypt(1, key, nonce, aad, aad_len, plaintext, + plaintext_len, ciphertext, NULL, tag); +} + +int hybbx_openssl_aes256gcm_decrypt( + const uint8_t key[32], const uint8_t nonce[12], const uint8_t *aad, + size_t aad_len, const uint8_t *ciphertext, size_t ciphertext_len, + uint8_t *plaintext, const uint8_t tag[16]) +{ + if (key == NULL || nonce == NULL || tag == NULL) { + return -1; + } + if (ciphertext_len > 0 && (ciphertext == NULL || plaintext == NULL)) { + return -1; + } + + return openssl_gcm_crypt(0, key, nonce, aad, aad_len, ciphertext, + ciphertext_len, plaintext, tag, NULL); +} + +hybbx_result_t hybbx_openssl_random(uint8_t *buf, size_t len) +{ + if (buf == NULL || len == 0) { + return HYBBX_ERR_INVALID; + } + + if (RAND_bytes(buf, (int)len) == 1) { + return HYBBX_OK; + } + + return HYBBX_ERR_IO; +} -- cgit v1.3.1