Updated: October 28, 2024 |
The qcrypto library API includes cryptographic cipher functions.
See the library reference for detailed information on the following functions:
The counter is 128 bits long, which is the size of the initialization vector (IV). It is up to the client code to make sure that the IV never repeats itself for the same key.
Because CCM mode does not support incremental updates, the caller must complete encrypting the plaintext or decrypting the ciphertext in one call.
All qcrypto library cipher algorithms working in a block cipher mode of operation (for example, AES CBC (Cipher Block Chaining)) require that the total input size be a multiple of the cipher block size.
#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 enc_result = 1; int dec_result = 1; qcrypto_ctx_t *qctx = NULL; qcrypto_ctx_t *qkeyctx = NULL; qcrypto_key_t *qkey = NULL; const char key_hex[] = "000102030405060708090a0b0c0d0e0f"; const size_t keysize = (sizeof(key_hex)-1)/2; uint8_t key_bin[keysize]; const char ptext_hex[] = "00112233445566778899aabbccddeeff"; const size_t psize = (sizeof(ptext_hex)-1)/2; uint8_t ptext_bin[psize]; uint8_t ptext_cmp[psize]; uint8_t *ptext_ptr = ptext_cmp; size_t psize_cmp = 0; const char ctext_hex[] = "69c4e0d86a7b0430d8cdb78070b4c55a"; const size_t csize = (sizeof(ctext_hex)-1)/2; uint8_t ctext_bin[csize]; uint8_t ctext_cmp[csize]; uint8_t *ctext_ptr = ctext_cmp; size_t csize_cmp = 0; /* 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; } /* Initialize cipher arguments */ qcrypto_cipher_args_t cargs = { .action = QCRYPTO_CIPHER_ENCRYPT, .iv = NULL, .ivsize = 0, }; /* Request aes-128-ecb */ ret = qcrypto_cipher_request("aes-128-ecb", NULL, 0, &qctx); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_cipher_request() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Convert key */ ret = qcrypto_hex2bin(key_bin, key_hex, keysize); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_hex2bin() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Convert ptext */ ret = qcrypto_hex2bin(ptext_bin, ptext_hex, psize); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_hex2bin() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Convert ctext */ ret = qcrypto_hex2bin(ctext_bin, ctext_hex, csize); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_hex2bin() 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 cipher encryption */ ret = qcrypto_cipher_init(qctx, qkey, &cargs); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_cipher_init() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Cipher encryption */ ret = qcrypto_cipher_encrypt(qctx, ptext_bin, psize, ctext_ptr, &csize_cmp); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_cipher_encrypt() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Finalize cipher encryption */ ret = qcrypto_cipher_final(qctx, ctext_ptr, &csize_cmp); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_cipher_final() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Compare the encryption results */ enc_result = memcmp(ctext_bin, ctext_cmp, csize); if (enc_result == 0) { printf("Computed encryption matches with expected encryption\n"); } else { fprintf(stderr, "Computed encryption failed to match with expected encryption\n"); goto done; } /* Switch to decryption mode */ cargs.action = QCRYPTO_CIPHER_DECRYPT; /* Initialize cipher encryption */ ret = qcrypto_cipher_init(qctx, qkey, &cargs); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_cipher_init() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Cipher decryption */ ret = qcrypto_cipher_decrypt(qctx, ctext_bin, csize, ptext_ptr, &psize_cmp); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_cipher_decrypt() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } /* Finalize cipher decryption */ ret = qcrypto_cipher_final(qctx, ptext_ptr, &psize_cmp); if (ret != QCRYPTO_R_EOK) { fprintf(stderr, "qcrypto_cipher_final() failed (%d:%s)\n", ret, qcrypto_strerror(ret)); goto done; } dec_result = memcmp(ptext_bin, ptext_cmp, psize); if (dec_result == 0) { printf("Computed decryption matches with expected decryption\n"); } else { fprintf(stderr, "Computed decryption failed to match with expected decryption\n"); goto done; } 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