Message authentication code (MAC)

QNX SDP8.0QNX OS System Security GuideAPIConfiguration

The qcrypto library API includes cryptographic MAC functions.

HMAC

While HMAC key size has no length restrictions, the algorithm key size value is the minimum recommended length for security.

MAC examples

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <qcrypto/qcrypto.h>
#include <qcrypto/qcrypto_error.h>
#include <qcrypto/qcrypto_keys.h>

int main(void)
{
    int ret;
    int result;
    qcrypto_ctx_t *qctx = NULL;
    qcrypto_key_t *qkey = NULL;
    qcrypto_ctx_t *qkeyctx = NULL;

    const uint8_t inputbuf[] = {
        0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61,
        0x67, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6b, 0x65, 0x79, 0x6c, 0x65,
        0x6e, 0x3c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x6c, 0x65, 0x6e
    };
    const size_t inputsize = sizeof(inputbuf);
    const uint8_t *input_bin = inputbuf;

    const uint8_t keybuf[] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
        0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
    };
    const size_t keysize = sizeof(keybuf);
    const uint8_t *key_bin = keybuf;

    const uint8_t mac_buf[] = {
        0xa2, 0x8c, 0xf4, 0x31, 0x30, 0xee, 0x69, 0x6a, 0x98, 0xf1, 0x4a, 0x37,
        0x67, 0x8b, 0x56, 0xbc, 0xfc, 0xbd, 0xd9, 0xe5, 0xcf, 0x69, 0x71, 0x7f,
        0xec, 0xf5, 0x48, 0x0f, 0x0e, 0xbd, 0xf7, 0x90
    };
    const size_t macsize = sizeof(mac_buf);

    uint8_t mac_cmpbuf[512];
    uint8_t *mac_cmp = mac_cmpbuf;
    size_t mac_cmp_size = macsize;

    /* Initialize the Qcrypto Library */
    ret = qcrypto_init(QCRYPTO_INIT_LAZY, NULL);
    if (ret != QCRYPTO_R_EOK) {
        fprintf(stderr, "qcryto_init() failed (%d:%s)\n", ret, qcrypto_strerror(ret));
        goto done;
    }

     /* Request symmetric keygen */
    ret = qcrypto_keygen_request("symmetric", NULL, 0, &qkeyctx);
    if (ret != QCRYPTO_R_EOK) {
        fprintf(stderr, "qcrypto_keygen_request() failed (%d:%s)\n", ret, qcrypto_strerror(ret));
        goto done;
    }

    /* Request hmac-sha256 */
    ret = qcrypto_mac_request("hmac-sha256", NULL, 0, &qctx);
    if (ret != QCRYPTO_R_EOK) {
        fprintf(stderr, "qcrypto_mac_request() failed (%d:%s)\n", ret, qcrypto_strerror(ret));
        goto done;
    }

    /* Load key */
    ret = qcrypto_key_from_mem(qkeyctx, &qkey, key_bin, keysize);
    if (ret != QCRYPTO_R_EOK) {
        fprintf(stderr, "qcrypto_key_from_mem() failed (%d:%s)\n", ret, qcrypto_strerror(ret));
        goto done;
    }

    /* Initialize MAC */
    ret = qcrypto_mac_init(qctx, qkey);
    if (ret != QCRYPTO_R_EOK) {
        fprintf(stderr, "qcrypto_mac_init() failed (%d:%s)\n", ret, qcrypto_strerror(ret));
        goto done;
    }

    /* Update MAC */
    ret = qcrypto_mac_update(qctx, input_bin, inputsize);
    if (ret != QCRYPTO_R_EOK) {
        fprintf(stderr, "qcrypto_mac_update() failed (%d:%s)\n", ret, qcrypto_strerror(ret));
        goto done;
    }

    /* Finalize MAC */
    ret = qcrypto_mac_final(qctx, mac_cmp, &mac_cmp_size);
    if (ret != QCRYPTO_R_EOK) {
        fprintf(stderr, "qcrypto_mac_final() failed (%d:%s)\n", ret, qcrypto_strerror(ret));
        goto done;
    }

    /* Compare the results */
    result = memcmp(mac_cmp, mac_buf, mac_cmp_size);
    if(result == 0) {
         printf("Computed mac matches with expected mac\n");
    } else {
         fprintf(stderr, "Computed mac failed to match with expected mac\n");
    }
    goto done;

done:
    /* Release all context handles */
    qcrypto_release_ctx(qctx);
    qcrypto_release_ctx(qkeyctx);

    /* Release the key handle */
    qcrypto_release_key(qkey);

    /* Uninitialize the Qcrypto Library */
    qcrypto_uninit();

    return ret;
}
Page updated: