Updated: October 28, 2024 |
The qcrypto library API includes cryptographic KDF functions.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <qcrypto/qcrypto.h> #include <qcrypto/qcrypto_error.h> #include <qcrypto/qcrypto_keys.h> #include <private/qcrypto/qcrypto_internal.h> int main(void) { int ret; int result; qcrypto_ctx_t *qctx = NULL; qcrypto_ctx_t *qkeyctx = NULL; qcrypto_key_t *qkey = NULL; const char inkey_hex[] = "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"; const size_t inkeysize = (sizeof(inkey_hex)-1)/2; uint8_t inkeybuf[inkeysize]; uint8_t *inkey_bin = inkeybuf; const char salt_hex[] = "000102030405060708090a0b0c"; const size_t saltsize = (sizeof(salt_hex)-1)/2; uint8_t saltbuf[saltsize]; uint8_t *salt_bin = saltbuf; const char info_hex[] = "f0f1f2f3f4f5f6f7f8f9"; const size_t infosize = (sizeof(info_hex)-1)/2; uint8_t infobuf[infosize]; uint8_t *info_bin = infobuf; const char outkey_hex[] = "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"; size_t outkeysize = (sizeof(outkey_hex)-1)/2; uint8_t outkey_cmpbuf[outkeysize]; uint8_t *outkey_cmp = outkey_cmpbuf; char outkey_cmp_hexbuf[outkeysize*2]; char *outkey_cmp_hex = outkey_cmp_hexbuf; /* 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; } /* Convert inkey */ ret = qcrypto_hex2bin(inkey_bin, inkey_hex, inkeysize); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_hex2bin() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Convert salt */ ret = qcrypto_hex2bin(salt_bin, salt_hex, saltsize); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_hex2bin() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Convert info */ ret = qcrypto_hex2bin(info_bin, info_hex, infosize); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_hex2bin() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Initialize KDF arguments */ qcrypto_kdf_args_t kargs = { .secret = inkey_bin, .secretsize = inkeysize, .salt = salt_bin, .saltsize = saltsize, .hkdf.info = info_bin, .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; } /* Convert the outkey */ qcrypto_bin2hex(outkey_cmp_hex, outkey_cmp, outkeysize); /* Compare the results */ result = memcmp(outkey_cmp_hex, outkey_hex, 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; } #if defined(__QNXNTO__) && defined(__USESRCVERSION) #include <sys/srcversion.h> __SRCVERSION("$URL$ $Rev$") #endif