Key Derivation Function (KDF)

QNX SDP8.0QNX OS System Security GuideAPIConfiguration

The qcrypto library API includes cryptographic KDF functions.

See the library reference for detailed descriptions of the following functions:

KDF 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_ctx_t *qkeyctx = NULL;
    qcrypto_key_t *qkey = NULL;

    const uint8_t inkeybuf[] = {
        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
    };
    const size_t inkeysize = sizeof(inkeybuf);
    const uint8_t *inkey = inkeybuf;

    const uint8_t saltbuf[] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
        0x0c
    };
    const size_t saltsize = sizeof(saltbuf);
    const uint8_t *salt = saltbuf;

    const uint8_t infobuf[] = {
        0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9
    };
    const size_t infosize = sizeof(infobuf);
    const uint8_t *info = infobuf;

    const uint8_t outkey_buf[] = {
        0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64,
        0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
        0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08,
        0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65
    };
    size_t outkeysize = sizeof(outkey_buf);

    uint8_t outkey_cmpbuf[outkeysize];
    uint8_t *outkey_cmp = outkey_cmpbuf;

    /* 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 hkdf-sha256 */
    ret = qcrypto_kdf_request("hkdf-sha256", NULL, 0, &qctx);
    if (ret != QCRYPTO_R_EOK) {
        fprintf(stderr, "qcrypto_kdf_request() failed (%d:%s)\n", ret, qcrypto_strerror(ret));
        goto done;
    }

    /* Initialize KDF arguments */
    qcrypto_kdf_args_t kargs = {
        .secret = inkey,
        .secretsize = inkeysize,
        .salt = salt,
        .saltsize = saltsize,
        .hkdf.info = info,
        .hkdf.infosize = infosize,
    };

    /* Generate a symmetric key via the KDF */
    ret = qcrypto_kdf_generate(qctx, &qkey, outkeysize, &kargs, &qkeyctx);
    if (ret != QCRYPTO_R_EOK) {
        fprintf(stderr, "qcrypto_kdf_generate() failed (%d:%s)\n", ret, qcrypto_strerror(ret));
        goto done;
    }

    /* Save the outkey to a buffer */
    ret = qcrypto_key_to_mem(qkeyctx, qkey, outkey_cmp, &outkeysize);
    if (ret != QCRYPTO_R_EOK) {
        fprintf(stderr, "qcrypto_key_to_mem() failed (%d:%s)\n", ret, qcrypto_strerror(ret));
        goto done;
    }

    /* Compare the results */
    result = memcmp(outkey_cmp, outkey_buf, outkeysize);
    if(result == 0) {
         printf("Computed key matches with expected key\n");
    } else {
         fprintf(stderr, "Computed key failed to match with expected key\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: