Skip to content

Commit

Permalink
Mac API, implementation and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pushkarnk committed Nov 28, 2023
1 parent 554ec9a commit d88007c
Show file tree
Hide file tree
Showing 4 changed files with 230 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Makefile
Expand Up @@ -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
Expand All @@ -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
32 changes: 32 additions & 0 deletions include/mac.h
@@ -0,0 +1,32 @@
#include <openssl/evp.h>
#include <openssl/params.h>

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);
84 changes: 84 additions & 0 deletions src/mac.c
@@ -0,0 +1,84 @@
#include "jssl.h"
#include "mac.h"
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/core_names.h>

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);
}
109 changes: 109 additions & 0 deletions 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("...<length = %ld, truncated>", 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);
}

0 comments on commit d88007c

Please sign in to comment.