From d88007ce6d0ff9f0999f7d1b4d7a24d238ef529f Mon Sep 17 00:00:00 2001 From: Pushkar Kulkarni Date: Tue, 28 Nov 2023 08:57:35 +0530 Subject: [PATCH] Mac API, implementation and tests --- Makefile | 5 +++ include/mac.h | 32 +++++++++++++++ src/mac.c | 84 ++++++++++++++++++++++++++++++++++++++ test/mac.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 230 insertions(+) create mode 100644 include/mac.h create mode 100644 src/mac.c create mode 100644 test/mac.c diff --git a/Makefile b/Makefile index 4893079..620b26a 100644 --- a/Makefile +++ b/Makefile @@ -4,12 +4,14 @@ build: cc -I/usr/local/include/openssl/ -I./include -c -fPIC src/cipher.c -o build/bin/cipher.o && \ cc -I/usr/local/include/openssl/ -I./include -c -fPIC src/keyagreement.c -o build/bin/keyagreement.o && \ cc -I/usr/local/include/openssl/ -I./include -c -fPIC src/keyencapsulation.c -o build/bin/keyencapsulation.o && \ + cc -I/usr/local/include/openssl/ -I./include -c -fPIC src/mac.c -o build/bin/mac.o && \ cc -shared -fPIC -Wl,-soname,libjssl.so -o build/bin/libjssl.so \ build/bin/init.o \ build/bin/drbg.o \ build/bin/cipher.o \ build/bin/keyagreement.o \ build/bin/keyencapsulation.o \ + build/bin/mac.o \ -L/usr/local/lib64 -lcrypto -lssl test-drbg: build @@ -27,5 +29,8 @@ test-ka: build test-ke: build @mkdir -p build/test && cc -I./include/ -L./build/bin/ -L/usr/local/lib64 -o build/test/keyencapsulation test/keyencapsulation.c -ljssl && \ LD_LIBRARY_PATH=./build/bin ./build/test/keyencapsulation 2>/dev/null +test-mac: build + @mkdir -p build/test && cc -I./include/ -L./build/bin/ -L/usr/local/lib64 -o build/test/mac test/mac.c -ljssl && \ + LD_LIBRARY_PATH=./build/bin ./build/test/mac 2>/dev/null clean: @rm -rf build diff --git a/include/mac.h b/include/mac.h new file mode 100644 index 0000000..98f3bc7 --- /dev/null +++ b/include/mac.h @@ -0,0 +1,32 @@ +#include +#include + +typedef struct mac_params { + char *cipher_name; + char *digest_name; + byte *iv; + size_t iv_length; + size_t output_length; +} mac_params; + +mac_params *init_mac_params(char *cipher, char *digest, byte *iv, size_t iv_length, size_t output_length) { + mac_params *new = (mac_params*)malloc(sizeof(mac_params)); + new->cipher_name = cipher; + new->digest_name = digest; + new->iv = iv; + new->iv_length = iv_length; + new->output_length = output_length; + return new; +} + +typedef struct mac_context { + char *algorithm; + EVP_MAC_CTX *ctx; +} mac_context; + +mac_context *mac_init(char *algorithm, byte *key, size_t key_length, mac_params *params); +int mac_update(mac_context *ctx, byte *input, size_t input_size); +int mac_final_with_input(mac_context *ctx, byte *input, size_t input_size, byte *output, size_t *bytes_written, size_t output_size); +int mac_final(mac_context *ctx, byte *output, size_t *bytes_written, size_t output_size); +size_t get_mac_length(mac_context *mac); +void free_mac_context(mac_context *mac); diff --git a/src/mac.c b/src/mac.c new file mode 100644 index 0000000..600197b --- /dev/null +++ b/src/mac.c @@ -0,0 +1,84 @@ +#include "jssl.h" +#include "mac.h" +#include +#include +#include + +static void set_params(EVP_MAC_CTX *ctx, mac_params *params) { + OSSL_PARAM _params[8]; + int n_params = 0; + if (params->cipher_name != NULL) { + _params[n_params++] = OSSL_PARAM_construct_utf8_string("cipher", params->cipher_name, 0); + } + if (params->digest_name != NULL) { + _params[n_params++] = OSSL_PARAM_construct_utf8_string("digest", params->digest_name, 0); + } + if (params->iv != NULL) { + _params[n_params++] = OSSL_PARAM_construct_octet_string("iv", params->iv, params->iv_length); + } + _params[n_params] = OSSL_PARAM_construct_end(); + if (0 == EVP_MAC_CTX_set_params(ctx, _params)) { + ERR_print_errors_fp(stdout); + } +} + +mac_context *mac_init(char *algorithm, byte *key, size_t key_length, mac_params *params) { + mac_context *new_ctx = (mac_context *)malloc(sizeof(mac_context)); + new_ctx->algorithm = algorithm; + EVP_MAC *mac = EVP_MAC_fetch(NULL, algorithm, NULL); + EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(mac); + EVP_MAC_free(mac); + if (NULL == ctx) { + ERR_print_errors_fp(stdout); + free_mac_context(new_ctx); + return NULL; + } + new_ctx->ctx = ctx; + if (NULL != params) { + set_params(new_ctx->ctx, params); + } + if (0 == EVP_MAC_init(new_ctx->ctx, (const unsigned char*)key, key_length, NULL)) { + ERR_print_errors_fp(stdout); + free_mac_context(new_ctx); + return NULL; + } + return new_ctx; +} + +int mac_update(mac_context *ctx, byte *input, size_t input_size) { + if (0 == EVP_MAC_update(ctx->ctx, input, input_size)) { + free_mac_context(ctx); + return 0; + } + return 1; +} + +int mac_final(mac_context *ctx, byte *output, size_t *bytes_written, size_t output_size) { + if (0 == EVP_MAC_final(ctx->ctx, output, bytes_written, output_size)) { + free_mac_context(ctx); + return 0; + } + return 1; +} + +int mac_final_with_input(mac_context *ctx, byte *input, size_t input_size, + byte *output, size_t *bytes_written, size_t output_size) { + if (0 == mac_update(ctx, input, input_size)) { + free_mac_context(ctx); + return 0; + } + if (0 == mac_final(ctx, output, bytes_written, output_size)) { + free_mac_context(ctx); + return 0; + } + return 1; +} + +size_t get_mac_length(mac_context *mac) { + return EVP_MAC_CTX_get_mac_size(mac->ctx); +} + +void free_mac_context(mac_context *mac) { + EVP_MAC_CTX_free(mac->ctx); + free(mac); +} diff --git a/test/mac.c b/test/mac.c new file mode 100644 index 0000000..a0b90fc --- /dev/null +++ b/test/mac.c @@ -0,0 +1,109 @@ +#include "jssl.h" +#include "mac.h" + +static unsigned char key[] = { + 0x6c, 0xde, 0x14, 0xf5, 0xd5, 0x2a, 0x4a, 0xdf, + 0x12, 0x39, 0x1e, 0xbf, 0x36, 0xf9, 0x6a, 0x46, + 0x48, 0xd0, 0xb6, 0x51, 0x89, 0xfc, 0x24, 0x85, + 0xa8, 0x8d, 0xdf, 0x7e, 0x80, 0x14, 0xc8, 0xce, + 0x38, 0xb5, 0xb1, 0xe0, 0x82, 0x2c, 0x70, 0xa4, + 0xc0, 0x8e, 0x5e, 0xf9, 0x93, 0x9f, 0xcf, 0xf7, + 0x32, 0x4d, 0x0c, 0xbd, 0x31, 0x12, 0x0f, 0x9a, + 0x15, 0xee, 0x82, 0xdb, 0x8d, 0x29, 0x54, 0x14 +}; + +static unsigned char iv[] = { + 0xe0, 0xe0, 0x0f, 0x19, 0xfe, 0xd7, 0xba, + 0x01, 0x36, 0xa7, 0x97, 0xf3 +}; + +static unsigned char data[] = + "To be, or not to be, that is the question,\n" + "Whether tis nobler in the minde to suffer\n" + "The ſlings and arrowes of outragious fortune,\n" + "Or to take Armes again in a sea of troubles,\n" + "And by opposing, end them, to die to sleep;\n" + "No more, and by a sleep, to say we end\n" + "The heart-ache, and the thousand natural shocks\n" + "That flesh is heir to? tis a consumation\n" + "Devoutly to be wished. To die to sleep,\n" + "To sleepe, perchance to dreame, Aye, there's the rub,\n" + "For in that sleep of death what dreams may come\n" + "When we haue shuffled off this mortal coil\n" + "Must give us pause. There's the respect\n" + "That makes calamity of so long life:\n" + "For who would bear the Ships and Scorns of time,\n" + "The oppressor's wrong, the proud man's Contumely,\n" + "The pangs of dispised love, the Law's delay,\n" +; + +void run_test(mac_context *ctx) { + if (NULL == ctx) { + printf("FAILED (Couldn't init CMAC)\n"); + } + + if(0 == (mac_update(ctx, data, sizeof(data)))) { + printf("FAILED (Update failed)\n"); + } + + byte output[256]; + size_t written; + if(0 == (mac_final(ctx, output, &written, 256))) { + printf("FAILED(final)\n"); + } + + printf("PASSED (MAC: "); + for(int i = 0; i < (32 >= written ? written : 32); i++) { + printf("%x", output[i]); + } + if (written > 32) printf("...", written); + printf(")\n"); +} + +void test_cmac(OSSL_LIB_CTX *libctx) { + printf("Testing CMAC: "); + mac_params *params = init_mac_params("AES-256-CBC", NULL, NULL, 0, 0); + mac_context *ctx = mac_init("CMAC", key, 32, params); + run_test(ctx); +} + +void test_hmac(OSSL_LIB_CTX *libctx) { + printf("Testing HMAC: "); + mac_params *params = init_mac_params(NULL, "SHA3-512", NULL, 0, 0); + mac_context *ctx = mac_init("HMAC", key, 64, params); + run_test(ctx); +} + +void test_gmac(OSSL_LIB_CTX *libctx) { + printf("Testing GMAC: "); + mac_params *params = init_mac_params("AES-128-GCM", NULL, iv, sizeof(iv), 0); + mac_context *ctx = mac_init("GMAC", key, 16, params); + run_test(ctx); +} + +void test_kmac128(OSSL_LIB_CTX *libctx) { + printf("Testing KMAC-128: "); + mac_context *ctx = mac_init("KMAC-128", key, 4, NULL); + run_test(ctx); +} + +void test_kmac256(OSSL_LIB_CTX *libctx) { + printf("Testing KMAC-256: "); + mac_context *ctx = mac_init("KMAC-256", key, 32, NULL); + run_test(ctx); +} + + +void test_mac_context_creation(OSSL_LIB_CTX *libctx) { + test_cmac(libctx); + test_gmac(libctx); + test_hmac(libctx); + test_kmac128(libctx); + test_kmac256(libctx); +} + +int main(int argc, char ** argv) { + OSSL_LIB_CTX *libctx = load_openssl_fips_provider("/usr/local/ssl/openssl.cnf"); + test_mac_context_creation(libctx); +} +