From a95d1a04a54df856510e1ea0b71bef71997e6c0a Mon Sep 17 00:00:00 2001 From: Premkumar Shanmugam Date: Fri, 8 Mar 2024 20:49:00 +0530 Subject: [PATCH] QAT_HW AES-CCM Provider support. AES-128-CCM, AES-192-CCM & AES256-CCM provider support Signed-off-by: Premkumar Shanmugam --- Makefile.am | 4 +- docs/qat_common.md | 1 + e_qat.c | 4 + e_qat.h | 1 + qat_evp.c | 4 + qat_hw_ccm.c | 396 +++++++++++++++++++++--- qat_hw_ccm.h | 13 + qat_prov_aes_ccm.c | 657 ++++++++++++++++++++++++++++++++++++++++ qat_prov_aes_ccm.h | 286 +++++++++++++++++ qat_prov_dh.h | 4 +- qat_prov_dsa.c | 4 +- qat_prov_dsa.h | 4 +- qat_prov_ecx.h | 4 +- qat_prov_hkdf.h | 1 - qat_prov_init.c | 10 + qat_prov_prf.h | 1 - qat_prov_sign_rsa.c | 4 +- qat_prov_sm4_cbc.h | 5 +- qat_prov_sm4_ccm.h | 2 - qat_prov_sm4_gcm.h | 4 +- qat_provider.h | 3 + test/tests_aes128_ccm.c | 42 +++ test/tests_aes192_ccm.c | 42 +++ test/tests_aes256_ccm.c | 42 +++ 24 files changed, 1470 insertions(+), 68 deletions(-) create mode 100644 qat_prov_aes_ccm.c create mode 100644 qat_prov_aes_ccm.h diff --git a/Makefile.am b/Makefile.am index c4dbdb7f..3907ccba 100644 --- a/Makefile.am +++ b/Makefile.am @@ -54,7 +54,9 @@ if QAT_PROVIDER qat_prov_sm4_gcm.c \ qat_prov_sm4_ccm.c \ qat_prov_sm4_cbc.c \ - qat_prov_sm3.c + qat_prov_sm3.c \ + qat_prov_aes_ccm.c + if QAT_FIPS QAT_FIPS_SRC = qat_fips.c \ diff --git a/docs/qat_common.md b/docs/qat_common.md index 29d4479d..abddf2a0 100644 --- a/docs/qat_common.md +++ b/docs/qat_common.md @@ -29,6 +29,7 @@ and the default if not specified will use engine interface. | SM4-CCM (BabaSSL only) | QAT_SW | | SM4-CBC | QAT_HW & QAT_SW | | SM3 | QAT_HW & QAT_SW | +| AES-CCM | QAT_HW | This support is added as an experimental feature and tested with OpenSSL Speed and testapp only and not tested with any application. diff --git a/e_qat.c b/e_qat.c index f333a33b..a588e5e3 100644 --- a/e_qat.c +++ b/e_qat.c @@ -1372,6 +1372,10 @@ int bind_qat(ENGINE *e, const char *id) qat_sw_sm3_offload = 1; INFO("QAT_SW SM3 for Provider Enabled\n"); # endif +# ifdef ENABLE_QAT_HW_CCM + qat_hw_aes_ccm_offload = 1; + INFO("QAT_HW AES-CCM for Provider Enabled\n"); +# endif #endif #ifndef QAT_BORINGSSL diff --git a/e_qat.h b/e_qat.h index b449ee05..0edf7e22 100644 --- a/e_qat.h +++ b/e_qat.h @@ -927,6 +927,7 @@ int qat_sw_cpu_support(void); # endif # ifdef QAT_OPENSSL_PROVIDER +typedef _Atomic int CRYPTO_REF_COUNT; static __inline__ int CRYPTO_UP_REF(int *val, int *ret, ossl_unused void *lock) { *ret = __atomic_fetch_add(val, 1, __ATOMIC_RELAXED) + 1; diff --git a/qat_evp.c b/qat_evp.c index 30fe20e2..0a714782 100644 --- a/qat_evp.c +++ b/qat_evp.c @@ -938,15 +938,19 @@ const EVP_CIPHER *qat_create_ccm_cipher_meth(int nid, int keylen) #endif res &= EVP_CIPHER_meth_set_iv_length(c, AES_CCM_IV_LEN); res &= EVP_CIPHER_meth_set_flags(c, QAT_CCM_FLAGS); +#ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_init(c, qat_aes_ccm_init); res &= EVP_CIPHER_meth_set_do_cipher(c, qat_aes_ccm_cipher); res &= EVP_CIPHER_meth_set_cleanup(c, qat_aes_ccm_cleanup); +#endif res &= EVP_CIPHER_meth_set_impl_ctx_size(c, sizeof(qat_ccm_ctx)); res &= EVP_CIPHER_meth_set_set_asn1_params(c, EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv); res &= EVP_CIPHER_meth_set_get_asn1_params(c, EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv); +#ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_ctrl(c, qat_aes_ccm_ctrl); +#endif if (0 == res) { WARN("Failed to set cipher methods for nid %d\n", nid); EVP_CIPHER_meth_free(c); diff --git a/qat_hw_ccm.c b/qat_hw_ccm.c index 2325d8bd..9ba54682 100644 --- a/qat_hw_ccm.c +++ b/qat_hw_ccm.c @@ -67,6 +67,9 @@ #include "qat_evp.h" #include "qat_hw_ccm.h" #include "qat_hw_ciphers.h" +#ifdef QAT_OPENSSL_PROVIDER +# include "qat_prov_aes_ccm.h" +#endif #include #include @@ -99,11 +102,22 @@ * * It will return 1 if successful and 0 on failure. ******************************************************************************/ +# ifdef QAT_OPENSSL_PROVIDER +static int qat_session_data_init(EVP_CIPHER_CTX *ctx, + void *vctx, + const unsigned char *key, + int keylen, + const unsigned char *iv, int ivlen, int enc) +# else static int qat_session_data_init(EVP_CIPHER_CTX *ctx, qat_ccm_ctx * qctx, const unsigned char *key, const unsigned char *iv, int enc) +# endif { +# ifdef QAT_OPENSSL_PROVIDER + QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) vctx; +# endif DEBUG("QAT HW CCM Started\n"); if (NULL == qctx || NULL == ctx) { WARN("qctx or ctx is NULL\n"); @@ -117,15 +131,23 @@ static int qat_session_data_init(EVP_CIPHER_CTX *ctx, OPENSSL_free(qctx->cipher_key); qctx->cipher_key = NULL; } +# ifdef QAT_OPENSSL_PROVIDER + qctx->cipher_key = OPENSSL_zalloc(keylen); +# else qctx->cipher_key = OPENSSL_zalloc(EVP_CIPHER_CTX_key_length(ctx)); +# endif } else { if (qctx->cipher_key) { qaeCryptoMemFreeNonZero(qctx->cipher_key); qctx->cipher_key = NULL; } +# ifdef QAT_OPENSSL_PROVIDER + qctx->cipher_key = qaeCryptoMemAlloc(keylen, __FILE__, __LINE__); +# else qctx->cipher_key = qaeCryptoMemAlloc(EVP_CIPHER_CTX_key_length(ctx), __FILE__, __LINE__); +# endif } if (qctx->cipher_key == NULL) { @@ -133,7 +155,11 @@ static int qat_session_data_init(EVP_CIPHER_CTX *ctx, QATerr(QAT_F_QAT_SESSION_DATA_INIT, QAT_R_KEY_MALLOC_FAILURE); return 0; } +# ifdef QAT_OPENSSL_PROVIDER + memcpy(qctx->cipher_key, key, keylen); +# else memcpy(qctx->cipher_key, key, EVP_CIPHER_CTX_key_length(ctx)); +# endif qctx->key_set = 1; } @@ -158,8 +184,14 @@ static int qat_session_data_init(EVP_CIPHER_CTX *ctx, qctx->session_data->cipherSetupData.cipherAlgorithm = CPA_CY_SYM_CIPHER_AES_CCM; /* Cipher key length */ - qctx->session_data->cipherSetupData.cipherKeyLenInBytes = - EVP_CIPHER_CTX_key_length(ctx); + if (key != NULL && qctx->key_set) { +# ifdef QAT_OPENSSL_PROVIDER + qctx->session_data->cipherSetupData.cipherKeyLenInBytes = keylen; +# else + qctx->session_data->cipherSetupData.cipherKeyLenInBytes = + EVP_CIPHER_CTX_key_length(ctx); +# endif + } if (qctx->key_set) { qctx->session_data->cipherSetupData.pCipherKey = @@ -227,13 +259,28 @@ static int qat_session_data_init(EVP_CIPHER_CTX *ctx, * EVP context. * ******************************************************************************/ +# ifdef QAT_OPENSSL_PROVIDER +int qat_aes_ccm_init(void *ctx, const unsigned char *inkey, + int keylen, const unsigned char *iv, int ivlen, int enc) +{ +# else int qat_aes_ccm_init(EVP_CIPHER_CTX *ctx, const unsigned char *inkey, const unsigned char *iv, int enc) { +# endif +# ifdef QAT_OPENSSL_PROVIDER + QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; +# else qat_ccm_ctx *qctx = NULL; +# endif + # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD int ret = 1; +# ifdef QAT_OPENSSL_PROVIDER + QAT_EVP_CIPHER sw_aes_ccm_cipher; + int nid = qctx->nid; +# endif # endif if (NULL == ctx) { @@ -245,7 +292,11 @@ int qat_aes_ccm_init(EVP_CIPHER_CTX *ctx, DEBUG("CTX = %p, key = %p, iv = %p, enc = %d\n", (void *)ctx, (void *)inkey, (void *)iv, enc); +# ifndef QAT_OPENSSL_PROVIDER qctx = QAT_CCM_GET_CTX(ctx); +# else + qctx->enc = enc; +# endif /* Initialise a QAT session and set the cipher keys */ if (NULL == qctx) { @@ -254,6 +305,7 @@ int qat_aes_ccm_init(EVP_CIPHER_CTX *ctx, return 0; } # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD +# ifndef QAT_OPENSSL_PROVIDER EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); /* Run the software init function */ ret = @@ -262,6 +314,29 @@ int qat_aes_ccm_init(EVP_CIPHER_CTX *ctx, EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); if (ret != 1) goto err; +# else + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + sw_aes_ccm_cipher = get_default_cipher_aes_ccm(nid); + + if (enc) { + if (!qctx->sw_ctx) + qctx->sw_ctx = sw_aes_ccm_cipher.newctx(ctx); + ret = + sw_aes_ccm_cipher.einit(qctx->sw_ctx, inkey, keylen, iv, ivlen, + params); + } else { + if (!qctx->sw_ctx) + qctx->sw_ctx = sw_aes_ccm_cipher.newctx(ctx); + + unsigned int pad = 0; + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pad); + ret = + sw_aes_ccm_cipher.dinit(qctx->sw_ctx, inkey, keylen, iv, ivlen, + params); + } + if (ret != 1) + goto err; +# endif # endif if (!inkey && !iv) { @@ -276,8 +351,8 @@ int qat_aes_ccm_init(EVP_CIPHER_CTX *ctx, } qctx->qat_svm = - !qat_instance_details[qctx->inst_num]. - qat_instance_info.requiresPhysicallyContiguousMemory; + !qat_instance_details[qctx->inst_num].qat_instance_info. + requiresPhysicallyContiguousMemory; if (iv) { /* Set the value of the IV */ @@ -292,7 +367,11 @@ int qat_aes_ccm_init(EVP_CIPHER_CTX *ctx, qctx->len_set = 0; /* Initialize QAT session */ +# ifdef QAT_OPENSSL_PROVIDER + if (0 == qat_session_data_init(ctx, qctx, inkey, keylen, iv, ivlen, enc)) { +# else if (0 == qat_session_data_init(ctx, qctx, inkey, iv, enc)) { +# endif WARN("qat_session_data_init failed.\n"); goto err; } @@ -329,20 +408,33 @@ int qat_aes_ccm_init(EVP_CIPHER_CTX *ctx, * in the authentication calculation and to identify record payload size. * ******************************************************************************/ +# ifdef QAT_OPENSSL_PROVIDER +int qat_aes_ccm_ctrl(void *ctx, int type, int arg, void *ptr) +# else int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +# endif { +# ifdef QAT_OPENSSL_PROVIDER + QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; +# else qat_ccm_ctx *qctx = NULL; - unsigned int plen = 0; - int enc = 0; -# ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD +# ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD int ret_sw = 0; + int nid = EVP_CIPHER_CTX_nid(ctx); +# endif # endif + unsigned int plen = 0; + int enc = 0; if (NULL == ctx) { WARN("ctx is NULL.\n"); QATerr(QAT_F_QAT_AES_CCM_CTRL, QAT_R_CTX_NULL); return 0; } +# ifdef QAT_OPENSSL_PROVIDER + enc = qctx->enc; +# else + enc = EVP_CIPHER_CTX_encrypting(ctx); qctx = QAT_CCM_GET_CTX(ctx); if (NULL == qctx) { @@ -350,8 +442,7 @@ int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) QATerr(QAT_F_QAT_AES_CCM_CTRL, QAT_R_QCTX_NULL); return 0; } - - enc = EVP_CIPHER_CTX_encrypting(ctx); +# endif switch (type) { case EVP_CTRL_INIT: @@ -367,6 +458,7 @@ int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) qctx->tag_len = -1; qctx->len_set = 0; # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD +# ifndef QAT_OPENSSL_PROVIDER if (qctx->sw_ctx_cipher_data == NULL) { unsigned int sw_size = 0; sw_size = EVP_CIPHER_impl_ctx_size(GET_SW_AES_CCM_CIPHER(ctx)); @@ -377,6 +469,7 @@ int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) } } goto sw_ctrl; +# endif # endif return 1; @@ -385,10 +478,11 @@ int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) " arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); *(int *)ptr = QAT_AES_CCM_OP_VALUE - qctx->L; # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD - if (qctx->packet_size <= - qat_pkt_threshold_table_get_threshold(EVP_CIPHER_CTX_nid(ctx))) { +# ifndef QAT_OPENSSL_PROVIDER + if (qctx->packet_size <= qat_pkt_threshold_table_get_threshold(nid)) { goto sw_ctrl; } +# endif # endif return 1; @@ -418,10 +512,11 @@ int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) qctx->tag_len = arg; qctx->M = arg; # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD - if (qctx->packet_size <= - qat_pkt_threshold_table_get_threshold(EVP_CIPHER_CTX_nid(ctx))) { +# ifndef QAT_OPENSSL_PROVIDER + if (qctx->packet_size <= qat_pkt_threshold_table_get_threshold(nid)) { goto sw_ctrl; } +# endif # endif return 1; @@ -443,10 +538,11 @@ int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) qctx->iv_set = 0; qctx->len_set = 0; # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD - if (qctx->packet_size <= - qat_pkt_threshold_table_get_threshold(EVP_CIPHER_CTX_nid(ctx))) { +# ifndef QAT_OPENSSL_PROVIDER + if (qctx->packet_size <= qat_pkt_threshold_table_get_threshold(nid)) { goto sw_ctrl; } +# endif # endif return 1; @@ -481,10 +577,11 @@ int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) memcpy(qctx->next_iv, ptr, arg); } # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD - if (qctx->packet_size <= - qat_pkt_threshold_table_get_threshold(EVP_CIPHER_CTX_nid(ctx))) { +# ifndef QAT_OPENSSL_PROVIDER + if (qctx->packet_size <= qat_pkt_threshold_table_get_threshold(nid)) { goto sw_ctrl; } +# endif # endif return 1; @@ -502,8 +599,10 @@ int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) qctx->L = arg; # endif # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD +# ifndef QAT_OPENSSL_PROVIDER qctx->L = QAT_AES_CCM_OP_VALUE - arg; goto sw_ctrl; +# endif # endif return 1; @@ -580,20 +679,22 @@ int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) DEBUG("OUT plen = %d\n", plen); DUMPL("OUT qctx->aad", qctx->aad, TLS_VIRT_HDR_SIZE); # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD - if (qctx->packet_size <= - qat_pkt_threshold_table_get_threshold(EVP_CIPHER_CTX_nid(ctx))) { +# ifndef QAT_OPENSSL_PROVIDER + if (qctx->packet_size <= qat_pkt_threshold_table_get_threshold(nid)) { goto sw_ctrl; } +# endif # endif /* Return the length of the TAG */ return qctx->M; case EVP_CTRL_COPY: # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD - if (qctx->packet_size <= - qat_pkt_threshold_table_get_threshold(EVP_CIPHER_CTX_nid(ctx))) { +# ifndef QAT_OPENSSL_PROVIDER + if (qctx->packet_size <= qat_pkt_threshold_table_get_threshold(nid)) { goto sw_ctrl; } +# endif # endif return 1; @@ -603,6 +704,7 @@ int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) return -1; } # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD +# ifndef QAT_OPENSSL_PROVIDER sw_ctrl: EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); ret_sw = @@ -614,6 +716,7 @@ int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) return -1; } return ret_sw; +# endif # endif } @@ -631,9 +734,17 @@ int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) * cryptographic transform. * ******************************************************************************/ +# ifdef QAT_OPENSSL_PROVIDER +int qat_aes_ccm_cleanup(void *ctx) +# else int qat_aes_ccm_cleanup(EVP_CIPHER_CTX *ctx) +# endif { +# ifdef QAT_OPENSSL_PROVIDER + QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; +# else qat_ccm_ctx *qctx = NULL; +# endif CpaStatus sts = 0; CpaCySymSessionSetupData *session_data = NULL; CpaBoolean sessionInUse = CPA_FALSE; @@ -646,7 +757,7 @@ int qat_aes_ccm_cleanup(EVP_CIPHER_CTX *ctx) QATerr(QAT_F_QAT_AES_CCM_CLEANUP, QAT_R_CTX_NULL); return 0; } - +# ifndef QAT_OPENSSL_PROVIDER qctx = QAT_CCM_GET_CTX(ctx); if (NULL == qctx) { @@ -654,6 +765,7 @@ int qat_aes_ccm_cleanup(EVP_CIPHER_CTX *ctx) QATerr(QAT_F_QAT_AES_CCM_CLEANUP, QAT_R_QCTX_NULL); return 0; } +# endif /* Wait for in-flight requests before removing session */ if (qctx->qat_ctx != NULL) { @@ -685,7 +797,8 @@ int qat_aes_ccm_cleanup(EVP_CIPHER_CTX *ctx) qctx->qat_svm); QAT_MEM_FREE_BUFF(qctx->cipher_key, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qctx->aad, qctx->qat_svm); - QAT_MEM_FREE_NONZERO_BUFF(qctx->OpData.pAdditionalAuthData, qctx->qat_svm); + QAT_MEM_FREE_NONZERO_BUFF(qctx->OpData.pAdditionalAuthData, + qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qctx->OpData.pIv, qctx->qat_svm); qctx->qat_ctx = NULL; qctx->srcBufferList.pPrivateMetaData = NULL; @@ -700,11 +813,19 @@ int qat_aes_ccm_cleanup(EVP_CIPHER_CTX *ctx) } qctx->is_session_init = 0; # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD +# ifndef QAT_OPENSSL_PROVIDER qctx->packet_size = 0; if (qctx->sw_ctx_cipher_data) { OPENSSL_free(qctx->sw_ctx_cipher_data); qctx->sw_ctx_cipher_data = NULL; } +# endif +# endif +# ifdef QAT_OPENSSL_PROVIDER + if (qctx->sw_ctx) { + OPENSSL_free(qctx->sw_ctx); + qctx->sw_ctx = NULL; + } # endif return ret_val; @@ -756,9 +877,17 @@ static void qat_ccm_cb(void *pCallbackTag, CpaStatus status, * This function synchronises the initialisation of the QAT session and * pre-allocates the necessary buffers for the session. ******************************************************************************/ +# ifdef QAT_OPENSSL_PROVIDER +static int qat_aes_ccm_session_init(void *ctx) +# else static int qat_aes_ccm_session_init(EVP_CIPHER_CTX *ctx) +# endif { +# ifdef QAT_OPENSSL_PROVIDER + QAT_PROV_CCM_CTX *qctx = NULL; +# else qat_ccm_ctx *qctx = NULL; +# endif CpaCySymSessionSetupData *sessionSetupData = NULL; Cpa32U sessionCtxSize = 0; CpaCySymSessionCtx pSessionCtx = NULL; @@ -771,9 +900,13 @@ static int qat_aes_ccm_session_init(EVP_CIPHER_CTX *ctx) QATerr(QAT_F_QAT_AES_CCM_SESSION_INIT, QAT_R_CTX_NULL); return 0; } - +# ifdef QAT_OPENSSL_PROVIDER + qctx = (QAT_PROV_CCM_CTX *) ctx; + enc = QAT_CCM_GET_ENC(qctx);; +# else qctx = QAT_CCM_GET_CTX(ctx); enc = EVP_CIPHER_CTX_encrypting(ctx); +# endif if (NULL == qctx) { WARN("qctx is NULL\n"); @@ -806,7 +939,8 @@ static int qat_aes_ccm_session_init(EVP_CIPHER_CTX *ctx) are mismatch for decryption */ if (!enc) { DEBUG("digestResultLenInBytes = %d, tag len = %d\n", - sessionSetupData->hashSetupData.digestResultLenInBytes, qctx->M); + sessionSetupData->hashSetupData.digestResultLenInBytes, + (int)qctx->M); if (!(qctx->tag_len < 0) && sessionSetupData->hashSetupData.digestResultLenInBytes != qctx->M) { @@ -888,7 +1022,7 @@ static int qat_aes_ccm_session_init(EVP_CIPHER_CTX *ctx) if (NULL == qctx->OpData.pIv) { qctx->OpData.pIv = qat_mem_alloc(QAT_CCM_IV_MAX_LEN, qctx->qat_svm, - __FILE__, __LINE__); + __FILE__, __LINE__); if (NULL == qctx->OpData.pIv) { WARN("qctx->OpData.pIv is NULL.\n"); QATerr(QAT_F_QAT_AES_CCM_SESSION_INIT, ERR_R_INTERNAL_ERROR); @@ -913,7 +1047,7 @@ static int qat_aes_ccm_session_init(EVP_CIPHER_CTX *ctx) qctx->OpData.pAdditionalAuthData = qat_mem_alloc(aad_buffer_len + QAT_CCM_IV_MAX_LEN, qctx->qat_svm, - __FILE__, __LINE__); + __FILE__, __LINE__); if (NULL == qctx->OpData.pAdditionalAuthData) { WARN("qctx->OpData.pAdditionalAuthData is NULL.\n"); QATerr(QAT_F_QAT_AES_CCM_SESSION_INIT, ERR_R_INTERNAL_ERROR); @@ -922,8 +1056,8 @@ static int qat_aes_ccm_session_init(EVP_CIPHER_CTX *ctx) if (qctx->aad) { memcpy(&qctx->OpData.pAdditionalAuthData[QAT_CCM_AAD_WRITE_BUFFER], qctx->aad, - qctx->session_data->hashSetupData.authModeSetupData. - aadLenInBytes); + qctx->session_data->hashSetupData. + authModeSetupData.aadLenInBytes); } memcpy(&qctx->OpData.pAdditionalAuthData[QAT_CCM_IV_WRITE_BUFFER], qctx->next_iv, qctx->iv_len); @@ -977,15 +1111,31 @@ static int qat_aes_ccm_session_init(EVP_CIPHER_CTX *ctx) * This is the function used in the TLS case. * ******************************************************************************/ +# ifdef QAT_OPENSSL_PROVIDER +int qat_aes_ccm_tls_cipher(void *ctx, unsigned char *out, + size_t *padlen, size_t outsize, + const unsigned char *in, size_t len) +# else int qat_aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) +# endif { +# ifdef QAT_OPENSSL_PROVIDER + QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; +# ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD + QAT_EVP_CIPHER sw_aes_ccm_cipher; +# endif +# else qat_ccm_ctx *qctx = NULL; +# endif CpaStatus sts = 0; op_done_t op_done; int ret_val = -1; int job_ret = 0; int enc = 0; +# ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD + int nid = 0; +# endif unsigned int message_len = 0; unsigned int buffer_len = 0; thread_local_variables_t *tlv = NULL; @@ -997,8 +1147,9 @@ int qat_aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, QATerr(QAT_F_QAT_AES_CCM_TLS_CIPHER, QAT_R_CTX_NULL); return -1; } - +# ifndef QAT_OPENSSL_PROVIDER qctx = QAT_CCM_GET_CTX(ctx); +# endif if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_TLS_CIPHER, QAT_R_QCTX_NULL); @@ -1007,34 +1158,65 @@ int qat_aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, /* Encrypt/decrypt must be performed in place */ if (NULL == in || - out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)qctx->M)) { + out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + qctx->M)) { WARN("Input parameters are not valid.\n"); QATerr(QAT_F_QAT_AES_CCM_TLS_CIPHER, QAT_R_INVALID_LEN); return -1; } - +# ifdef QAT_OPENSSL_PROVIDER + enc = QAT_CCM_GET_ENC(qctx); +# else enc = EVP_CIPHER_CTX_encrypting(ctx); +# endif + +# ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD +# ifdef QAT_OPENSSL_PROVIDER + nid = qctx->nid; +# else + nid = EVP_CIPHER_CTX_nid(ctx); +# endif +# endif + DEBUG("enc = %d - ctx = %p, out = %p, in = %p, len = %zu\n", enc, (void *)ctx, (void *)out, (void *)in, len); # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD qctx->packet_size = len; if ((len - (EVP_CCM_TLS_EXPLICIT_IV_LEN + qctx->M)) <= - qat_pkt_threshold_table_get_threshold(EVP_CIPHER_CTX_nid(ctx))) { + qat_pkt_threshold_table_get_threshold(nid)) { DEBUG("Using OpenSSL SW for Packetsize %zu\n", len - (EVP_CCM_TLS_EXPLICIT_IV_LEN + qctx->M)); +# ifdef QAT_OPENSSL_PROVIDER + sw_aes_ccm_cipher = get_default_cipher_aes_ccm(nid); + if (sw_aes_ccm_cipher.cupdate == NULL) + goto err; + + ret_val = + sw_aes_ccm_cipher.cupdate(qctx->sw_ctx, out, padlen, outsize, in, + len); + + if (!ret_val) + goto err; + + return ret_val; +# else EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); ret_val = EVP_CIPHER_meth_get_do_cipher(GET_SW_AES_CCM_CIPHER(ctx)) (ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); goto err; +# endif } # endif /* The key has been set in the init function: no need to check it here */ /* Initialize the session if not done before */ if (0 == qctx->is_session_init) { +# ifdef QAT_OPENSSL_PROVIDER + if (0 == qat_aes_ccm_session_init(qctx)) { +# else if (0 == qat_aes_ccm_session_init(ctx)) { +# endif WARN("Unable to initialise Cipher context.\n"); goto err; } @@ -1209,6 +1391,19 @@ int qat_aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); +# ifdef QAT_OPENSSL_PROVIDER + if (enc) { + *padlen = len; + ret_val = 1; + DEBUG("Encryption succeeded\n"); + } else if (CPA_TRUE == op_done.verifyResult) { + *padlen = message_len; + ret_val = 1; + DEBUG("Decryption succeeded\n"); + } else { + DEBUG("Decryption failed\n"); + } +# else if (enc) { ret_val = len; DEBUG("Encryption succeeded\n"); @@ -1218,6 +1413,7 @@ int qat_aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } else { DEBUG("Decryption failed\n"); } +# endif DUMP_SYM_PERFORM_OP_GCM_CCM_OUTPUT(qctx->dstBufferList); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); @@ -1290,11 +1486,25 @@ int qat_aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * a single operation like in the QAT engine. * ******************************************************************************/ +# ifdef QAT_OPENSSL_PROVIDER +int qat_aes_ccm_cipher(void *ctx, unsigned char *out, + size_t *padlen, size_t outsize, + const unsigned char *in, size_t len) +# else int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) +# endif { +# ifdef QAT_OPENSSL_PROVIDER + QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; + const int RET_SUCCESS = 1; +# ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD + QAT_EVP_CIPHER sw_aes_ccm_cipher; +# endif +# else qat_ccm_ctx *qctx = NULL; const int RET_SUCCESS = 0; +# endif CpaStatus sts = 0; op_done_t op_done; const int RET_FAIL = -1; @@ -1306,7 +1516,10 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, unsigned buffer_len = 0; thread_local_variables_t *tlv = NULL; # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD + int nid = 0; +# ifndef QAT_OPENSSL_PROVIDER int retVal = 0; +# endif # endif CRYPTO_QAT_LOG("CIPHER - %s\n", __func__); @@ -1316,21 +1529,36 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, QATerr(QAT_F_QAT_AES_CCM_CIPHER, QAT_R_CTX_NULL); return RET_FAIL; } - +# ifdef QAT_OPENSSL_PROVIDER + enc = qctx->enc; +# else qctx = QAT_CCM_GET_CTX(ctx); + enc = EVP_CIPHER_CTX_encrypting(ctx); +# endif + +# ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD +# ifdef QAT_OPENSSL_PROVIDER + nid = qctx->nid; +# else + nid = EVP_CIPHER_CTX_nid(ctx); +# endif +# endif if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_CIPHER, QAT_R_QCTX_NULL); return RET_FAIL; } - enc = EVP_CIPHER_CTX_encrypting(ctx); DEBUG("enc = %d - ctx = %p, out = %p, in = %p, len = %zu\n", enc, (void *)ctx, (void *)out, (void *)in, len); /* Distinguish the Update and TLS case */ if (qctx->tls_aad_len >= 0) { +# ifdef QAT_OPENSSL_PROVIDER + return qat_aes_ccm_tls_cipher(ctx, out, padlen, outsize, in, len); +# else return qat_aes_ccm_tls_cipher(ctx, out, in, len); +# endif } /* If either key or IV not set, throw error here. */ @@ -1344,7 +1572,7 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (qctx->OpData.pIv == NULL) { qctx->OpData.pIv = qat_mem_alloc(QAT_CCM_IV_MAX_LEN, qctx->qat_svm, - __FILE__, __LINE__); + __FILE__, __LINE__); if (NULL == qctx->OpData.pIv) { WARN("Unable to allocate memory for qctx->OpData.pIv\n"); return RET_FAIL; @@ -1354,10 +1582,23 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, qctx->iv_len); qctx->len_set = 1; # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD +# ifdef QAT_OPENSSL_PROVIDER + sw_aes_ccm_cipher = get_default_cipher_aes_ccm(nid); + if (sw_aes_ccm_cipher.cupdate == NULL) + return RET_FAIL; + + if (!sw_aes_ccm_cipher. + cupdate(qctx->sw_ctx, out, padlen, outsize, in, len)) + return RET_FAIL; +# else EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); EVP_CIPHER_meth_get_do_cipher(GET_SW_AES_CCM_CIPHER(ctx)) (ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); +# endif +# endif +# ifdef QAT_OPENSSL_PROVIDER + *padlen = len; # endif return len; } @@ -1370,11 +1611,12 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, aad_len = len; /* Check if the length of the AAD has changed */ - if (qctx->session_data->hashSetupData.authModeSetupData. - aadLenInBytes != aad_len) { + if (qctx->session_data->hashSetupData. + authModeSetupData.aadLenInBytes != aad_len) { /* Free the memory used for the previous AAD */ if (qctx->OpData.pAdditionalAuthData) { - QAT_MEM_FREE_BUFF(qctx->OpData.pAdditionalAuthData, qctx->qat_svm); + QAT_MEM_FREE_BUFF(qctx->OpData.pAdditionalAuthData, + qctx->qat_svm); qctx->OpData.pAdditionalAuthData = NULL; } /* For QAT the length of the buffer for AAD must be multiple of block size */ @@ -1385,8 +1627,8 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, DEBUG("Adjusting AAD buffer length = %d\n", aad_buffer_len); } qctx->OpData.pAdditionalAuthData = - qat_mem_alloc(aad_buffer_len + QAT_CCM_IV_MAX_LEN, qctx->qat_svm, - __FILE__, __LINE__); + qat_mem_alloc(aad_buffer_len + QAT_CCM_IV_MAX_LEN, + qctx->qat_svm, __FILE__, __LINE__); if (NULL == qctx->OpData.pAdditionalAuthData) { WARN("Unable to allocate memory for AAD\n"); QATerr(QAT_F_QAT_AES_CCM_CIPHER, ERR_R_INTERNAL_ERROR); @@ -1394,8 +1636,8 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } /* Set the length of the AAD */ - qctx->session_data->hashSetupData.authModeSetupData. - aadLenInBytes = aad_len; + qctx->session_data->hashSetupData. + authModeSetupData.aadLenInBytes = aad_len; } memcpy(&qctx->OpData.pAdditionalAuthData[QAT_CCM_AAD_WRITE_BUFFER], @@ -1411,20 +1653,45 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, &qctx->OpData.pIv[QAT_CCM_IV_WRITE_BUFFER], QAT_AES_CCM_OP_VALUE - qctx->L); # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD +# ifdef QAT_OPENSSL_PROVIDER + sw_aes_ccm_cipher = get_default_cipher_aes_ccm(nid); + if (sw_aes_ccm_cipher.cupdate == NULL) + return RET_FAIL; + + if (!sw_aes_ccm_cipher. + cupdate(qctx->sw_ctx, out, padlen, outsize, in, len)) + return RET_FAIL; +# else EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); EVP_CIPHER_meth_get_do_cipher(GET_SW_AES_CCM_CIPHER(ctx)) (ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); +# endif +# endif +# ifdef QAT_OPENSSL_PROVIDER + *padlen = aad_len; # endif return 1; } else { /* The key has been set in the init function: no need to check it */ # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD qctx->packet_size = len; - if (len <= - qat_pkt_threshold_table_get_threshold(EVP_CIPHER_CTX_nid(ctx))) - { + if (len <= qat_pkt_threshold_table_get_threshold(nid)) { DEBUG("Using OpenSSL SW for Packetsize %zu\n", len); +# ifdef QAT_OPENSSL_PROVIDER + sw_aes_ccm_cipher = get_default_cipher_aes_ccm(nid); + if (sw_aes_ccm_cipher.cupdate == NULL) + return 0; + + ret_val = + sw_aes_ccm_cipher.cupdate(qctx->sw_ctx, out, padlen, + outsize, in, len); + if (!ret_val) + return RET_FAIL; + + *padlen = len; + return ret_val; +# else EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); retVal = EVP_CIPHER_meth_get_do_cipher(GET_SW_AES_CCM_CIPHER(ctx)) @@ -1434,10 +1701,15 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return len; return retVal; +# endif } # endif if (0 == qctx->is_session_init) { +# ifdef QAT_OPENSSL_PROVIDER + if (0 == qat_aes_ccm_session_init(qctx)) { +# else if (0 == qat_aes_ccm_session_init(ctx)) { +# endif WARN("Unable to initialise Cipher context.\n"); return RET_FAIL; } @@ -1474,6 +1746,10 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, qctx->dstBufferList.pUserData = NULL; qctx->OpData.messageLenToCipherInBytes = len; +# ifdef QAT_OPENSSL_PROVIDER + qctx->OpData.ivLenInBytes = QAT_AES_CCM_OP_VALUE - qctx->L; + qctx->OpData.cryptoStartSrcOffsetInBytes = 0; +# endif /* Decryption: set the digest (tag) for verification * This is different from SW implementation. Here we have a single @@ -1483,6 +1759,9 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, /* Copy EVP_CCM_TLS_TAG_LEN bytes from tag buffer as the maximum tag length can only be EVP_CCM_TLS_TAG_LEN */ +# ifdef QAT_OPENSSL_PROVIDER + memcpy(qctx->dstFlatBuffer.pData + len, qctx->buf, qctx->M); +# else if (NULL == EVP_CIPHER_CTX_buf_noconst(ctx)) { WARN("Tag not set\n"); if (!qctx->qat_svm) { @@ -1495,6 +1774,7 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, memcpy(qctx->dstFlatBuffer.pData + len, EVP_CIPHER_CTX_buf_noconst(ctx), qctx->M); } +# endif } tlv = qat_check_create_local_variables(); @@ -1518,8 +1798,8 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, qctx->OpData, qctx->srcBufferList, qctx->dstBufferList); DUMPL("AAD: ", qctx->OpData.pAdditionalAuthData, - qctx->session_data->hashSetupData.authModeSetupData. - aadLenInBytes); + qctx->session_data->hashSetupData. + authModeSetupData.aadLenInBytes); sts = qat_sym_perform_op(qctx->inst_num, &op_done, @@ -1604,6 +1884,11 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (enc) { /* After encryption, copy the TAG from the buffer to the ctx */ +# ifdef QAT_OPENSSL_PROVIDER + memcpy(qctx->buf, qctx->dstFlatBuffer.pData + len, qctx->M); + DUMPL("TAG calculated by QAT", qctx->buf, qctx->M); + qctx->tag_set = 1; +# endif memcpy(EVP_CIPHER_CTX_buf_noconst(ctx), qctx->dstFlatBuffer.pData + len, qctx->M); DUMPL("TAG calculated by QAT", EVP_CIPHER_CTX_buf_noconst(ctx), @@ -1617,9 +1902,24 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, qctx->srcFlatBuffer.pData = NULL; qctx->dstFlatBuffer.pData = NULL; } +# ifdef QAT_OPENSSL_PROVIDER + *padlen = len; +# endif return ret_val; } } else { +# ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD +# ifdef QAT_OPENSSL_PROVIDER + if (len <= qat_pkt_threshold_table_get_threshold(nid)) { + sw_aes_ccm_cipher = get_default_cipher_aes_ccm(nid); + if (sw_aes_ccm_cipher.cfinal == NULL) + return 0; + ret_val = + sw_aes_ccm_cipher.cfinal(qctx->sw_ctx, out, padlen, outsize); + *padlen = len; + } +# endif +# endif if (!enc) { if (qctx->tag_len < 0) return RET_FAIL; diff --git a/qat_hw_ccm.h b/qat_hw_ccm.h index 6c889dce..e434c464 100644 --- a/qat_hw_ccm.h +++ b/qat_hw_ccm.h @@ -146,10 +146,22 @@ typedef struct qat_aes_ccm_ctx_t { int tag_set; int L, M; int packet_size; + int nid; void *sw_ctx_cipher_data; int qat_svm; + EVP_CIPHER_CTX *sw_ctx; + EVP_CIPHER *sw_cipher; } qat_ccm_ctx; +# ifdef QAT_OPENSSL_PROVIDER +int qat_aes_ccm_init(void *ctx, const unsigned char *inkey, + int keylen, const unsigned char *iv, int ivlen, int enc); +int qat_aes_ccm_cipher(void *ctx, unsigned char *out, + size_t *padlen, size_t outsize, + const unsigned char *in, size_t len); +int qat_aes_ccm_cleanup(void *ctx); +int qat_aes_ccm_ctrl(void *ctx, int type, int arg, void *ptr); +# else int qat_aes_ccm_init(EVP_CIPHER_CTX *ctx, const unsigned char *inkey, const unsigned char *iv, int enc); @@ -157,5 +169,6 @@ int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); int qat_aes_ccm_cleanup(EVP_CIPHER_CTX *ctx); int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +# endif #endif /* QAT_HW_CCM_H */ diff --git a/qat_prov_aes_ccm.c b/qat_prov_aes_ccm.c new file mode 100644 index 00000000..5796e934 --- /dev/null +++ b/qat_prov_aes_ccm.c @@ -0,0 +1,657 @@ +/* ==================================================================== + * + * + * BSD LICENSE + * + * Copyright(c) 2024 Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * ==================================================================== + */ + +/***************************************************************************** + * @qat_prov_aes_ccm.c + * + * This file contains the qatprovider implementation for AES-CCM operations + * + *****************************************************************************/ + +#include "qat_provider.h" +#include "qat_prov_aes_ccm.h" +#include "qat_utils.h" +#include "e_qat.h" +#include "qat_evp.h" +#ifdef ENABLE_QAT_HW_CCM +# include "qat_hw_ccm.h" +#endif + +#define AES_CCM_IV_MIN_SIZE (64 / 8) +#define AEAD_FLAGS (PROV_CIPHER_FLAG_AEAD | PROV_CIPHER_FLAG_CUSTOM_IV) +#define QAT_AES_CCM_OP_VALUE 15 + +#ifdef ENABLE_QAT_HW_CCM +static OSSL_FUNC_cipher_freectx_fn qat_aes_ccm_freectx; + +void qat_aes_ccm_init_ctx(void *provctx, QAT_PROV_CCM_CTX * ctx, size_t keybits, + size_t ivlen_min) +{ + ctx->keylen = keybits / 8; + ctx->key_set = 0; + ctx->iv_set = 0; + ctx->tag_set = 0; + ctx->len_set = 0; + ctx->L = 8; + ctx->M = 12; + ctx->tls_aad_len = -1; + ctx->pad = 1; + ctx->mode = EVP_CIPH_CCM_MODE; + ctx->tag_len = -1; + ctx->ivlen_min = ivlen_min; + ctx->libctx = prov_libctx_of(provctx); + ctx->iv_len = (EVP_CCM_TLS_FIXED_IV_LEN + EVP_CCM_TLS_EXPLICIT_IV_LEN); +} + +const char *qat_ccm_cipher_name(int nid) +{ + switch (nid) { + case NID_aes_128_ccm: + return LN_aes_128_ccm; + case NID_aes_192_ccm: + return LN_aes_192_ccm; + case NID_aes_256_ccm: + return LN_aes_256_ccm; + default: + WARN("Invalid nid %d\n", nid); + return NULL; + } +} + +#if (!defined(QAT20_OOT) && !defined(QAT_HW_INTREE)) || !defined(ENABLE_QAT_SMALL_PKT_OFFLOAD) +QAT_EVP_CIPHER get_default_cipher_aes_ccm(int nid) +{ + static QAT_EVP_CIPHER ccm_cipher; + static int initialized = 0; + if (!initialized) { + QAT_EVP_CIPHER *cipher = + (QAT_EVP_CIPHER *) EVP_CIPHER_fetch(NULL, qat_ccm_cipher_name(nid), + "provider=default"); + if (cipher) { + ccm_cipher = *cipher; + EVP_CIPHER_free((EVP_CIPHER *)cipher); + initialized = 1; + } else { + WARN("EVP_CIPHER_fetch from default provider failed"); + } + } + return ccm_cipher; +} +#endif + +static void *qat_aes_ccm_newctx(void *provctx, size_t keybits, int nid) +{ + QAT_PROV_AES_CCM_CTX *ctx = NULL; + QAT_EVP_CIPHER *cipher; + + if (!qat_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); + cipher = OPENSSL_zalloc(sizeof(QAT_EVP_CIPHER)); + + cipher->nid = nid; + ctx->cipher = cipher; + ctx->base.nid = nid; + + if (ctx != NULL) { + qat_aes_ccm_init_ctx(provctx, &ctx->base, keybits, AES_CCM_IV_MIN_SIZE); + } + + return ctx; +} + +size_t qat_aes_ccm_get_ivlen(QAT_PROV_CCM_CTX * ctx) +{ + return QAT_AES_CCM_OP_VALUE - ctx->L; +} + +int qat_aes_ccm_einit(void *ctx, const unsigned char *inkey, size_t keylen, + const unsigned char *iv, size_t ivlen, int enc) +{ + int sts = 0; +# if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) + QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + QAT_EVP_CIPHER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(qctx->nid); + + if (qctx->nid == NID_aes_192_ccm || qctx->nid == NID_aes_256_ccm) { + if (!qctx->sw_ctx) + qctx->sw_ctx = sw_aes_ccm_cipher.newctx(ctx); + + sts = + sw_aes_ccm_cipher.einit(qctx->sw_ctx, inkey, keylen, iv, ivlen, + params); + if (sts != 1) + return 0; + + return sts; + } +# endif + if (qat_hw_aes_ccm_offload) + sts = qat_aes_ccm_init(ctx, inkey, keylen, iv, ivlen, 1); + + return sts; +} + +int qat_aes_ccm_dinit(void *ctx, const unsigned char *inkey, size_t keylen, + const unsigned char *iv, size_t ivlen, int enc) +{ + int sts = 0; +# if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) + QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + QAT_EVP_CIPHER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(qctx->nid); + if (qctx->nid == NID_aes_192_ccm || qctx->nid == NID_aes_256_ccm) { + if (!qctx->sw_ctx) + qctx->sw_ctx = sw_aes_ccm_cipher.newctx(ctx); + + unsigned int pad = 0; + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pad); + sts = + sw_aes_ccm_cipher.dinit(qctx->sw_ctx, inkey, keylen, iv, ivlen, + params); + if (sts != 1) + return 0; + + return sts; + } +# endif + if (qat_hw_aes_ccm_offload) + sts = qat_aes_ccm_init(ctx, inkey, keylen, iv, ivlen, 0); + + return sts; +} + +int qat_aes_ccm_stream_update(void *vctx, unsigned char *out, + size_t *outl, size_t outsize, + const unsigned char *in, size_t inl) +{ + QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; +# if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) + QAT_EVP_CIPHER sw_aes_ccm_cipher; +# endif + + if (inl == 0) { + *outl = 0; + return 1; + } + + if (outsize < inl) { + QATerr(ERR_LIB_PROV, QAT_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } +# if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) + if (ctx->nid == NID_aes_192_ccm || ctx->nid == NID_aes_256_ccm) { + sw_aes_ccm_cipher = get_default_cipher_aes_ccm(ctx->nid); + if (sw_aes_ccm_cipher.cupdate == NULL) + return 0; + + if (sw_aes_ccm_cipher.cupdate(ctx->sw_ctx, out, outl, + outsize, in, inl) <= 0) { + return 0; + } + + return 1; + } +# endif + + if (qat_hw_aes_ccm_offload) { + if ((qat_aes_ccm_cipher(ctx, out, outl, outsize, in, inl)) <= 0) { + QATerr(ERR_LIB_PROV, QAT_R_CIPHER_OPERATION_FAILED); + return 0; + } + } + + return 1; + +} + +int qat_aes_ccm_stream_final(void *vctx, unsigned char *out, + size_t *outl, size_t outsize) +{ + int i = 0; + QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; +# if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) + QAT_EVP_CIPHER sw_aes_ccm_cipher; +# endif + + if (!qat_prov_is_running()) + return 0; + +# if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) + if (ctx->nid == NID_aes_192_ccm || ctx->nid == NID_aes_256_ccm) { + sw_aes_ccm_cipher = get_default_cipher_aes_ccm(ctx->nid); + if (sw_aes_ccm_cipher.cfinal == NULL) + return 0; + i = sw_aes_ccm_cipher.cfinal(ctx->sw_ctx, out, outl, outsize); + *outl = 0; + return 1; + } +# endif + + if (qat_hw_aes_ccm_offload) + i = qat_aes_ccm_cipher(ctx, out, outl, outsize, NULL, 0); + + if (i <= 0) + return 0; + + *outl = 0; + return 1; +} + +int qat_aes_ccm_do_cipher(void *vctx, unsigned char *out, + size_t *outl, size_t outsize, + const unsigned char *in, size_t inl) +{ + QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; +# if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) + QAT_EVP_CIPHER sw_aes_ccm_cipher; +# endif + + if (!qat_prov_is_running()) + return 0; + + if (outsize < inl) { + QATerr(ERR_LIB_PROV, QAT_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } +# if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) + if (ctx->nid == NID_aes_192_ccm || ctx->nid == NID_aes_256_ccm) { + sw_aes_ccm_cipher = get_default_cipher_aes_ccm(ctx->nid); + if (sw_aes_ccm_cipher.cupdate == NULL) + return 0; + + if (sw_aes_ccm_cipher.cupdate(ctx->sw_ctx, out, outl, + outsize, in, inl) <= 0) { + return 0; + } + + return 1; + } +# endif + if (qat_hw_aes_ccm_offload) { + if (qat_aes_ccm_cipher(ctx, out, outl, outsize, in, inl) <= 0) { + return 0; + } + } + + *outl = inl; + return 1; +} + +int qat_aes_ccm_get_ctx_params(void *vctx, OSSL_PARAM params[]) +{ + QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; + OSSL_PARAM *p; + +# if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) + if (ctx->nid == NID_aes_192_ccm || ctx->nid == NID_aes_256_ccm) { + if (ctx->sw_ctx) { + QAT_EVP_CIPHER sw_aes_ccm_cipher = + get_default_cipher_aes_ccm(ctx->nid); + return sw_aes_ccm_cipher.get_ctx_params(ctx->sw_ctx, params); + } + } +# endif + + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); + if (p != NULL && !OSSL_PARAM_set_size_t(p, qat_aes_ccm_get_ivlen(ctx))) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); + if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN); + if (p != NULL) { + size_t m = ctx->M; + if (!OSSL_PARAM_set_size_t(p, m)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); + if (p != NULL) { + if (qat_aes_ccm_get_ivlen(ctx) > p->data_size) { + QATerr(ERR_LIB_PROV, QAT_R_INVALID_IV_LENGTH); + return 0; + } + if (!OSSL_PARAM_set_octet_string(p, ctx->iv, p->data_size) + && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, p->data_size)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + } + + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); + if (p != NULL) { + if (ctx->iv_set == IV_STATE_UNINITIALISED) + return 0; + if (qat_aes_ccm_get_ivlen(ctx) > p->data_size) { + QATerr(ERR_LIB_PROV, QAT_R_INVALID_IV_LENGTH); + return 0; + } + if (!OSSL_PARAM_set_octet_string(p, ctx->iv, p->data_size) + && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, p->data_size)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD); + if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); + if (p != NULL) { +# ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD + if (ctx->packet_size > qat_pkt_threshold_table_get_threshold(ctx->nid)) { + if (!ctx->enc || !ctx->tag_set) { + QATerr(ERR_LIB_PROV, QAT_R_INVALID_TAG); + return 0; + } + } +# else + if (!ctx->enc || !ctx->tag_set) { + QATerr(ERR_LIB_PROV, QAT_R_INVALID_TAG); + return 0; + } +# endif + if (p->data_type != OSSL_PARAM_OCTET_STRING) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + if (qat_hw_aes_ccm_offload) + qat_aes_ccm_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, p->data_size, p->data); + + ctx->tag_set = 0; + ctx->iv_set = 0; + ctx->len_set = 0; +# ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD + if (ctx->packet_size > qat_pkt_threshold_table_get_threshold(ctx->nid)) + return 1; +# endif + + } +# ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD + if (ctx->sw_ctx) { + QAT_EVP_CIPHER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(ctx->nid); + sw_aes_ccm_cipher.get_ctx_params(ctx->sw_ctx, params); + } +# endif + return 1; +} + +int qat_aes_ccm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; + const OSSL_PARAM *p; + size_t sz = 0; + + if (params == NULL) + return 1; + +# if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) + if (ctx->nid == NID_aes_192_ccm || ctx->nid == NID_aes_256_ccm) { + if (ctx->sw_ctx) { + QAT_EVP_CIPHER sw_aes_ccm_cipher = + get_default_cipher_aes_ccm(ctx->nid); + return sw_aes_ccm_cipher.set_ctx_params(ctx->sw_ctx, params); + } + } +# endif + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_OCTET_STRING) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); + return 0; + } + if ((p->data_size & 1) || (p->data_size < 4) || p->data_size > 16) { + QATerr(ERR_LIB_PROV, QAT_R_INVALID_TAG); + return 0; + } + + if (p->data != NULL) { + if (ctx->enc) { + QATerr(ERR_LIB_PROV, QAT_R_TAG_NOT_NEEDED); + return 0; + } + memcpy(ctx->buf, p->data, p->data_size); + ctx->tag_set = 1; + } + if (qat_hw_aes_ccm_offload) + qat_aes_ccm_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, p->data_size, p->data); + + ctx->M = p->data_size; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_IVLEN); + if (p != NULL) { + size_t ivlen; + + if (!OSSL_PARAM_get_size_t(p, &sz)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); + return 0; + } + ivlen = QAT_AES_CCM_OP_VALUE - sz; + if (ivlen < 2 || ivlen > 8) { + QATerr(ERR_LIB_PROV, QAT_R_INVALID_IV_LENGTH); + return 0; + } + if (ctx->L != ivlen) { + ctx->L = ivlen; + ctx->iv_set = 0; + } + } + + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_OCTET_STRING) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); + return 0; + } + if (qat_hw_aes_ccm_offload) + sz = qat_aes_ccm_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, p->data_size, + p->data); + + if (sz == 0) { + QATerr(ERR_LIB_PROV, QAT_R_INVALID_DATA); + return 0; + } + ctx->tls_aad_pad_sz = sz; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_OCTET_STRING) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); + return 0; + } + if (qat_hw_aes_ccm_offload) { + if (qat_aes_ccm_ctrl + (ctx, EVP_CTRL_CCM_SET_IV_FIXED, p->data_size, p->data) == 0) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); + return 0; + } + } + } +# ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD + if (ctx->sw_ctx) { + QAT_EVP_CIPHER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(ctx->nid); + sw_aes_ccm_cipher.set_ctx_params(ctx->sw_ctx, params); + } +# endif + return 1; +} + +int qat_aes_ccm_generic_get_params(OSSL_PARAM params[], unsigned int md, + uint64_t flags, size_t kbits, + size_t blkbits, size_t ivbits) +{ + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); + if (p != NULL && !OSSL_PARAM_set_uint(p, md)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD); + if (p != NULL + && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV); + if (p != NULL + && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS); + if (p != NULL + && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CTS) != 0)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK); + if (p != NULL + && !OSSL_PARAM_set_int(p, + (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != + 0)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY); + if (p != NULL + && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); + if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); + if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); + if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) { + QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); + return 0; + } + return 1; +} + +static void qat_aes_ccm_freectx(void *vctx) +{ + QAT_PROV_AES_CCM_CTX *ctx = (QAT_PROV_AES_CCM_CTX *) vctx; + if (ctx != NULL) { + if (ctx->cipher) { + OPENSSL_free(ctx->cipher); + ctx->cipher = NULL; + } + + if (qat_hw_aes_ccm_offload) + qat_aes_ccm_cleanup(&ctx->base); + + OPENSSL_clear_free(ctx, sizeof(*ctx)); + } +} + +static const OSSL_PARAM qat_aes_ccm_known_gettable_params[] = { + OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL), + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL), + OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL), + OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL), + OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL), + OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL), + OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL), + OSSL_PARAM_END +}; + +const OSSL_PARAM *qat_aes_ccm_generic_gettable_params(ossl_unused void *provctx) +{ + return qat_aes_ccm_known_gettable_params; +} + +static const OSSL_PARAM qat_aes_ccm_aead_known_gettable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0), + OSSL_PARAM_END +}; + +const OSSL_PARAM *qat_aes_ccm_aead_gettable_ctx_params + (ossl_unused void *cctx, ossl_unused void *provctx) { + return qat_aes_ccm_aead_known_gettable_ctx_params; +} + +static const OSSL_PARAM qat_aes_ccm_aead_known_settable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0), + OSSL_PARAM_END +}; + +const OSSL_PARAM *qat_aes_ccm_aead_settable_ctx_params + (ossl_unused void *cctx, ossl_unused void *provctx) { + return qat_aes_ccm_aead_known_settable_ctx_params; +} + +/* qat_aes_128_ccm_functions */ +QAT_aes_cipher(qat_aes, ccm, CCM, AEAD_FLAGS, 128, 8, 96, NID_aes_128_ccm); +/* qat_aes_192_ccm_functions */ +QAT_aes_cipher(qat_aes, ccm, CCM, AEAD_FLAGS, 192, 8, 96, NID_aes_192_ccm); +/* qat_aes_256_ccm_functions */ +QAT_aes_cipher(qat_aes, ccm, CCM, AEAD_FLAGS, 256, 8, 96, NID_aes_256_ccm); +#endif /* ENABLE_QAT_HW_CCM */ diff --git a/qat_prov_aes_ccm.h b/qat_prov_aes_ccm.h new file mode 100644 index 00000000..ef97647b --- /dev/null +++ b/qat_prov_aes_ccm.h @@ -0,0 +1,286 @@ +/* ==================================================================== + * + * + * BSD LICENSE + * + * Copyright(c) 2024 Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * ==================================================================== + */ +/***************************************************************************** + * @file qat_prov_aes_ccm.h + * + * This file provides an interface to QAT provider AES-CCM operations + * + *****************************************************************************/ + +#ifndef QAT_PROV_AES_CCM_H +# define QAT_PROV_AES_CCM_H + +# ifdef ENABLE_QAT_HW_CCM +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include "qat_utils.h" +# include "e_qat.h" +# include "qat_hw_ccm.h" + +# define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */ +# define QAT_AES_BLOCK_SIZE 16 + +# define PROV_CIPHER_FLAG_AEAD 0x0001 +# define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 +# define PROV_CIPHER_FLAG_CTS 0x0004 +# define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 +# define PROV_CIPHER_FLAG_RAND_KEY 0x0010 + +typedef struct qat_evp_cipher_st { + int nid; + + int block_size; + /* Default value for variable length ciphers */ + int key_len; + int iv_len; + + /* Legacy structure members */ + /* Various flags */ + unsigned long flags; + /* How the EVP_CIPHER was created. */ + int origin; + /* init key */ + int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + /* encrypt/decrypt data */ + int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); + /* cleanup ctx */ + int (*cleanup)(EVP_CIPHER_CTX *); + /* how big ctx->cipher_data needs to be */ + int ctx_size; + /* Populate a ASN1_TYPE with parameters */ + int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); + /* Get parameters from a ASN1_TYPE */ + int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); + /* Miscellaneous operations */ + int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); + /* Application data */ + void *app_data; + /* New structure members */ + /* Above comment to be removed when legacy has gone */ + int name_id; + char *type_name; + const char *description; + OSSL_PROVIDER *prov; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + OSSL_FUNC_cipher_newctx_fn *newctx; + OSSL_FUNC_cipher_encrypt_init_fn *einit; + OSSL_FUNC_cipher_decrypt_init_fn *dinit; + OSSL_FUNC_cipher_update_fn *cupdate; + OSSL_FUNC_cipher_final_fn *cfinal; + OSSL_FUNC_cipher_cipher_fn *ccipher; + OSSL_FUNC_cipher_freectx_fn *freectx; + OSSL_FUNC_cipher_dupctx_fn *dupctx; + OSSL_FUNC_cipher_get_params_fn *get_params; + OSSL_FUNC_cipher_get_ctx_params_fn *get_ctx_params; + OSSL_FUNC_cipher_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_cipher_gettable_params_fn *gettable_params; + OSSL_FUNC_cipher_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_FUNC_cipher_settable_ctx_params_fn *settable_ctx_params; +} QAT_EVP_CIPHER; + +# pragma pack(push, 16) +typedef struct qat_ccm_ctx_st { + int inst_num; + CpaCySymSessionSetupData *session_data; + CpaCySymSessionCtx qat_ctx; + int init_params_set; + + /* This flag is set to 1 when the session has been initialized */ + int is_session_init; + + /* QAT Op Params */ + CpaCySymOpData OpData; + + CpaBufferList srcBufferList; + CpaBufferList dstBufferList; + CpaFlatBuffer srcFlatBuffer; + CpaFlatBuffer dstFlatBuffer; + /* -- Crypto -- */ + + /* Pointer to AAD. + * In the TLS case this will contain the TLS header */ + Cpa8U *aad; + + /* Size of the meta data for the driver + * It cannot allocate memory so this must be done by the user application */ + unsigned int meta_size; + + /* Pointer to pCipherKey */ + Cpa8U *cipher_key; + + /* Flag to keep track of key passed */ + int key_set; + + int qat_svm; + int tls_aad_len; + int tag_len; + int iv_len; + unsigned int iv_set; + int iv_gen; + Cpa8U next_iv[EVP_MAX_IV_LENGTH]; + unsigned char *iv; + unsigned int mode; /* The mode that we are using */ + size_t keylen; + size_t ivlen_min; + size_t tls_aad_pad_sz; + uint64_t tls_enc_records; /* Number of TLS records encrypted */ + + /* + * num contains the number of bytes of |iv| which are valid for modes that + * manage partial blocks themselves. + */ + size_t num; + size_t bufsz; /* Number of bytes in buf */ + + unsigned int enc:1; /* Set to 1 if we are encrypting or 0 otherwise */ + unsigned int pad:1; /* Whether padding should be used or not */ + unsigned int iv_gen_rand:1; /* No IV was specified, so generate a rand IV */ + unsigned char buf[QAT_AES_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */ + OSSL_LIB_CTX *libctx; /* needed for rand calls */ + ctr128_f ctr; + size_t L, M; + int tag_set, len_set; + int packet_size; + int nid; + void *sw_ctx_cipher_data; + EVP_CIPHER_CTX *sw_ctx; + QAT_EVP_CIPHER *sw_cipher; +} QAT_PROV_CCM_CTX; +# pragma pack(pop) + +struct evp_cipher_ctx_st { + const EVP_CIPHER *cipher; + ENGINE *engine; /* functional reference if 'cipher' is + * ENGINE-provided */ + int encrypt; /* encrypt or decrypt */ + int buf_len; /* number we have left */ + unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */ + unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */ + unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */ + int num; /* used by cfb/ofb/ctr mode */ + void *app_data; /* application stuff */ + int key_len; /* May change for variable length cipher */ + unsigned long flags; /* Various flags */ + void *cipher_data; /* per EVP data */ + int final_used; + int block_mask; + unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */ + + /* + * Opaque ctx returned from a providers cipher algorithm implementation + * OSSL_FUNC_cipher_newctx() + */ + void *algctx; + EVP_CIPHER *fetched_cipher; +} /* EVP_CIPHER_CTX */ ; + +typedef struct prov_aes_ccm_ctx_st { + QAT_PROV_CCM_CTX base; /* must be first entry in struct */ + QAT_EVP_CIPHER *cipher; +} QAT_PROV_AES_CCM_CTX; + +size_t qat_aes_ccm_get_ivlen(QAT_PROV_CCM_CTX * ctx); +void qat_aes_ccm_init_ctx(void *provctx, QAT_PROV_CCM_CTX * ctx, size_t keybits, + size_t ivlen_min); +int qat_aes_ccm_get_ctx_params(void *vctx, OSSL_PARAM params[]); +int qat_aes_ccm_set_ctx_params(void *vctx, const OSSL_PARAM params[]); +int qat_aes_ccm_einit(void *ctx, const unsigned char *inkey, size_t keylen, + const unsigned char *iv, size_t ivlen, int enc); +int qat_aes_ccm_dinit(void *ctx, const unsigned char *inkey, size_t keylen, + const unsigned char *iv, size_t ivlen, int enc); +int qat_aes_ccm_stream_update(void *ctx, unsigned char *out, + size_t *outl, size_t outsize, + const unsigned char *in, size_t inl); +int qat_aes_ccm_stream_final(void *ctx, unsigned char *out, + size_t *outl, size_t outsize); +int qat_aes_ccm_do_cipher(void *ctx, unsigned char *out, + size_t *outl, size_t outsize, + const unsigned char *in, size_t inl); +const char *qat_ccm_cipher_name(int nid); +#if (!defined(QAT20_OOT) && !defined(QAT_HW_INTREE)) || !defined(ENABLE_QAT_SMALL_PKT_OFFLOAD) +QAT_EVP_CIPHER get_default_cipher_aes_ccm(int nid); +#endif + +# define QAT_aes_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits,nid) \ +static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lc##_get_params; \ +static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \ +{ \ + return qat_aes_ccm_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + flags, kbits, blkbits, ivbits); \ +} \ +static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lc##_newctx; \ +static void *alg##_##kbits##_##lc##_newctx(void *provctx) \ +{ \ + return alg##_##lc##_newctx(provctx, kbits, nid); \ +} \ +const OSSL_DISPATCH alg##kbits##lc##_functions[] = { \ + { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##_##kbits##_##lc##_newctx }, \ + { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx }, \ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))alg##_##lc##_einit }, \ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))alg##_##lc##_dinit }, \ + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))alg##_##lc##_stream_update }, \ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))alg##_##lc##_stream_final }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))alg##_##lc##_cipher }, \ + { OSSL_FUNC_CIPHER_GET_PARAMS, \ + (void (*)(void)) alg##_##kbits##_##lc##_get_params }, \ + { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ + (void (*)(void)) alg##_##lc##_get_ctx_params }, \ + { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ + (void (*)(void)) alg##_##lc##_set_ctx_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ + (void (*)(void))alg##_##lc##_generic_gettable_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ + (void (*)(void))alg##_##lc##_aead_gettable_ctx_params }, \ + { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ + (void (*)(void))alg##_##lc##_aead_settable_ctx_params }, \ + { 0, NULL } \ +} +# endif /* ENABLE_QAT_HW_CCM */ +#endif /* QAT_PROV_AES_CCM_H */ diff --git a/qat_prov_dh.h b/qat_prov_dh.h index 0288e8f2..dbe7c9dd 100644 --- a/qat_prov_dh.h +++ b/qat_prov_dh.h @@ -64,7 +64,7 @@ #include #include -typedef int CRYPTO_REF_COUNT; +typedef int CRYPTO_REFERENCE_COUNT; #define FFC_UNVERIFIABLE_GINDEX -1 #define FFC_PARAM_FLAG_VALIDATE_PQ 0x01 #define FFC_PARAM_FLAG_VALIDATE_G 0x02 @@ -123,7 +123,7 @@ struct dh_st BIGNUM *priv_key; /* x */ int flags; BN_MONT_CTX *method_mont_p; - CRYPTO_REF_COUNT references; + CRYPTO_REFERENCE_COUNT references; #ifndef FIPS_MODULE CRYPTO_EX_DATA ex_data; ENGINE *engine; diff --git a/qat_prov_dsa.c b/qat_prov_dsa.c index c07aab93..23a57323 100644 --- a/qat_prov_dsa.c +++ b/qat_prov_dsa.c @@ -68,14 +68,12 @@ static OSSL_FUNC_signature_freectx_fn qat_dsa_freectx; static OSSL_FUNC_signature_set_ctx_params_fn qat_dsa_set_ctx_params; static OSSL_FUNC_signature_settable_ctx_params_fn qat_dsa_settable_ctx_params; -typedef int CRYPTO_REF_COUNT; - struct evp_signature_st { int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; - CRYPTO_REF_COUNT refcnt; + CRYPTO_REFERENCE_COUNT refcnt; CRYPTO_RWLOCK *lock; OSSL_FUNC_signature_newctx_fn *newctx; diff --git a/qat_prov_dsa.h b/qat_prov_dsa.h index 4401fe23..fc1fe04e 100644 --- a/qat_prov_dsa.h +++ b/qat_prov_dsa.h @@ -66,7 +66,7 @@ #define OSSL_MAX_PROPQUERY_SIZE 256 /* Property query strings */ #define OSSL_MAX_ALGORITHM_ID_SIZE 256 /* AlgorithmIdentifier DER */ -typedef int CRYPTO_REF_COUNT; +typedef int CRYPTO_REFERENCE_COUNT; #define FFC_UNVERIFIABLE_GINDEX -1 #define FFC_PARAM_FLAG_VALIDATE_PQ 0x01 #define FFC_PARAM_FLAG_VALIDATE_G 0x02 @@ -131,7 +131,7 @@ struct dsa_st int flags; /* Normally used to cache montgomery values */ BN_MONT_CTX *method_mont_p; - CRYPTO_REF_COUNT references; + CRYPTO_REFERENCE_COUNT references; #ifndef FIPS_MODULE CRYPTO_EX_DATA ex_data; #endif diff --git a/qat_prov_ecx.h b/qat_prov_ecx.h index 2bf123c7..be36db2c 100644 --- a/qat_prov_ecx.h +++ b/qat_prov_ecx.h @@ -115,7 +115,7 @@ typedef enum { ECX_KEY_TYPE_X448, }ECX_KEY_TYPE; -typedef int CRYPTO_REF_COUNT; +typedef int CRYPTO_REFERENCE_COUNT; typedef void CRYPTO_RWLOCK; typedef struct qat_ecx_key_st { @@ -126,7 +126,7 @@ typedef struct qat_ecx_key_st { unsigned char *privkey; size_t keylen; ECX_KEY_TYPE type; - CRYPTO_REF_COUNT references; + CRYPTO_REFERENCE_COUNT references; CRYPTO_RWLOCK *lock; }ECX_KEY; diff --git a/qat_prov_hkdf.h b/qat_prov_hkdf.h index 02f34d32..c385ce39 100644 --- a/qat_prov_hkdf.h +++ b/qat_prov_hkdf.h @@ -66,7 +66,6 @@ # include "qat_prov_hkdf_packet.h" # define HKDF_MAXBUF 1024 -typedef _Atomic int CRYPTO_REF_COUNT; typedef void CRYPTO_RWLOCK; struct kdf_data_st { diff --git a/qat_prov_init.c b/qat_prov_init.c index 248cdf20..ad8c94d5 100644 --- a/qat_prov_init.c +++ b/qat_prov_init.c @@ -100,6 +100,11 @@ extern const OSSL_DISPATCH qat_aes192gcm_functions[]; # endif extern const OSSL_DISPATCH qat_aes256gcm_functions[]; #endif +#ifdef ENABLE_QAT_HW_CCM +extern const OSSL_DISPATCH qat_aes128ccm_functions[]; +extern const OSSL_DISPATCH qat_aes192ccm_functions[]; +extern const OSSL_DISPATCH qat_aes256ccm_functions[]; +#endif #if defined(ENABLE_QAT_HW_DSA) && defined(QAT_INSECURE_ALGO) extern const OSSL_DISPATCH qat_dsa_keymgmt_functions[]; #endif @@ -224,6 +229,11 @@ static const OSSL_ALGORITHM_CAPABLE qat_deflt_ciphers[] = { #ifdef ENABLE_QAT_SW_GCM ALG(QAT_NAMES_AES_192_GCM, qat_aes192gcm_functions), #endif +#ifdef ENABLE_QAT_HW_CCM + ALG(QAT_NAMES_AES_128_CCM, qat_aes128ccm_functions), + ALG(QAT_NAMES_AES_192_CCM, qat_aes192ccm_functions), + ALG(QAT_NAMES_AES_256_CCM, qat_aes256ccm_functions), +#endif #if defined(ENABLE_QAT_HW_CIPHERS) && !defined(ENABLE_QAT_FIPS) # ifdef QAT_INSECURE_ALGO ALG(QAT_NAMES_AES_128_CBC_HMAC_SHA1, qat_aes128cbc_hmac_sha1_functions), diff --git a/qat_prov_prf.h b/qat_prov_prf.h index 337b2704..0c57ef9a 100644 --- a/qat_prov_prf.h +++ b/qat_prov_prf.h @@ -63,7 +63,6 @@ # define TLS1_PRF_MAXBUF 1024 -typedef _Atomic int CRYPTO_REF_COUNT; typedef void CRYPTO_RWLOCK; struct evp_kdf_st { diff --git a/qat_prov_sign_rsa.c b/qat_prov_sign_rsa.c index 3cb958da..08249438 100644 --- a/qat_prov_sign_rsa.c +++ b/qat_prov_sign_rsa.c @@ -61,14 +61,14 @@ static const unsigned char digestinfo_##name##_der[] = { \ #define RSA_KEY_SIZE 8 #if defined(ENABLE_QAT_HW_RSA) || defined(ENABLE_QAT_SW_RSA) -typedef int CRYPTO_REF_COUNT; +typedef int CRYPTO_REFERENCE_COUNT; struct evp_signature_st { int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; - CRYPTO_REF_COUNT refcnt; + CRYPTO_REFERENCE_COUNT refcnt; CRYPTO_RWLOCK *lock; OSSL_FUNC_signature_newctx_fn *newctx; diff --git a/qat_prov_sm4_cbc.h b/qat_prov_sm4_cbc.h index ae8dc326..15d3afa5 100644 --- a/qat_prov_sm4_cbc.h +++ b/qat_prov_sm4_cbc.h @@ -60,6 +60,7 @@ # include # include # include + # ifdef ENABLE_QAT_SW_SM4_CBC # include "crypto_mb/sm4.h" # endif @@ -78,7 +79,7 @@ #define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x0100 #define PROV_CIPHER_FLAG_INVERSE_CIPHER 0x0200 -typedef _Atomic int CRYPTO_REF_COUNT; +typedef _Atomic int CRYPTO_REFERENCE_COUNT; typedef struct qat_evp_cipher_st { int nid; @@ -117,7 +118,7 @@ typedef struct qat_evp_cipher_st { char *type_name; const char *description; OSSL_PROVIDER *prov; - CRYPTO_REF_COUNT refcnt; + CRYPTO_REFERENCE_COUNT refcnt; CRYPTO_RWLOCK *lock; OSSL_FUNC_cipher_newctx_fn *newctx; OSSL_FUNC_cipher_encrypt_init_fn *einit; diff --git a/qat_prov_sm4_ccm.h b/qat_prov_sm4_ccm.h index fe68b41a..1a9a0c8e 100644 --- a/qat_prov_sm4_ccm.h +++ b/qat_prov_sm4_ccm.h @@ -83,8 +83,6 @@ ossl_uintmax_t align_int; \ void *align_ptr -typedef _Atomic int CRYPTO_REF_COUNT; - typedef struct qat_evp_cipher_st { int nid; diff --git a/qat_prov_sm4_gcm.h b/qat_prov_sm4_gcm.h index d15e4eee..1d114017 100644 --- a/qat_prov_sm4_gcm.h +++ b/qat_prov_sm4_gcm.h @@ -62,6 +62,8 @@ # include # include "crypto_mb/sm4_gcm.h" +# include "e_qat.h" + # define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */ # define SM4_GCM_TAG_MAX_SIZE 16 @@ -74,8 +76,6 @@ # define SM4_GCM_IV_MAX_SIZE (1024 / 8) # define QAT_SM4_GCM_BLOCK_SIZE 16 -typedef _Atomic int CRYPTO_REF_COUNT; - typedef struct qat_evp_cipher_st { int nid; diff --git a/qat_provider.h b/qat_provider.h index 4634f3fe..3c84eaa9 100644 --- a/qat_provider.h +++ b/qat_provider.h @@ -66,6 +66,9 @@ # define QAT_NAMES_AES_128_GCM "AES-128-GCM" # define QAT_NAMES_AES_192_GCM "AES-192-GCM" # define QAT_NAMES_AES_256_GCM "AES-256-GCM" +# define QAT_NAMES_AES_128_CCM "AES-128-CCM" +# define QAT_NAMES_AES_192_CCM "AES-192-CCM" +# define QAT_NAMES_AES_256_CCM "AES-256-CCM" # define QAT_NAMES_AES_128_CBC_HMAC_SHA1 "AES-128-CBC-HMAC-SHA1" # define QAT_NAMES_AES_256_CBC_HMAC_SHA1 "AES-256-CBC-HMAC-SHA1" # define QAT_NAMES_AES_128_CBC_HMAC_SHA256 "AES-128-CBC-HMAC-SHA256" diff --git a/test/tests_aes128_ccm.c b/test/tests_aes128_ccm.c index 552eae3d..53accebe 100644 --- a/test/tests_aes128_ccm.c +++ b/test/tests_aes128_ccm.c @@ -86,7 +86,9 @@ static const unsigned char iv[] = { static int run_aesccm128_tls(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; +#ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; +#endif int size = INPUT_TEXT_SIZE; int print_output = temp_args->print_output; int verify = temp_args->verify; @@ -127,6 +129,7 @@ static int run_aesccm128_tls(void *args) EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; +#ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_128_ccm); @@ -135,6 +138,7 @@ static int run_aesccm128_tls(void *args) e = NULL; } } +#endif if (input == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", @@ -165,7 +169,11 @@ static int run_aesccm128_tls(void *args) * IV used in the initialization of the cipher: in TLS case it is set * using ctrl() instead of EncryptInit_ex(). */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_ccm(), NULL, NULL, NULL); +#else ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_ccm(), e, NULL, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); @@ -190,7 +198,11 @@ static int run_aesccm128_tls(void *args) } /* set 16-byte of key to the aes-ccm context. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); +#else ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_ccm(), e, key, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed for setting key: ret %d\n", __func__, ret); goto err; @@ -255,7 +267,11 @@ static int run_aesccm128_tls(void *args) } /* Initialise the context for decryption with 16-byte key and 12-byte IV. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_ccm(), NULL, NULL, NULL); +#else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_ccm(), e, NULL, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); @@ -280,7 +296,11 @@ static int run_aesccm128_tls(void *args) } /* set 16-byte of key to the aes-ccm context. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, NULL); +#else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_ccm(), e, key, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed for setting key: ret %d\n", __func__, ret); goto err; @@ -368,7 +388,9 @@ static int run_aesccm128_tls(void *args) static int run_aesccm128_update(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; +#ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; +#endif int size = INPUT_TEXT_SIZE; int print_output = temp_args->print_output; int verify = temp_args->verify; @@ -386,6 +408,7 @@ static int run_aesccm128_update(void *args) EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; +#ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_128_ccm); @@ -394,6 +417,7 @@ static int run_aesccm128_update(void *args) e = NULL; } } +#endif /* * Set the plaintext input data. @@ -420,7 +444,11 @@ static int run_aesccm128_update(void *args) } /* Initialize encryption context for aes-ccm */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_EncryptInit(ctx, EVP_aes_128_ccm(), NULL, NULL); +#else ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_ccm(), e, NULL, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() encryption failed while setting context: ret %d\n", __func__, ret); goto err; @@ -441,15 +469,21 @@ static int run_aesccm128_update(void *args) goto err; } +#ifndef QAT_OPENSSL_PROVIDER /* set 16-byte of key to the aes-ccm context. */ ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting key: ret %d\n", __func__, ret); goto err; } +#endif /* set 12-byte of iv to the aes-ccm context. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_EncryptInit(ctx, NULL, key, iv); +#else ret = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting iv: ret %d\n", __func__, ret); goto err; @@ -510,7 +544,11 @@ static int run_aesccm128_update(void *args) } /* Initialize decryption context for aes-ccm */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_DecryptInit(dec_ctx, EVP_aes_128_ccm(), NULL, NULL); +#else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_ccm(), e, NULL, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); @@ -541,7 +579,11 @@ static int run_aesccm128_update(void *args) * Initialise the aes-ccm decryption context with 16-byte key and * 12-byte IV. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_DecryptInit(dec_ctx, NULL, key, iv); +#else ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, iv); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); diff --git a/test/tests_aes192_ccm.c b/test/tests_aes192_ccm.c index 4aecc1db..668f6572 100644 --- a/test/tests_aes192_ccm.c +++ b/test/tests_aes192_ccm.c @@ -87,7 +87,9 @@ static const unsigned char iv[] = { static int run_aesccm192_tls(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; +#ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; +#endif int size = INPUT_TEXT_SIZE; int print_output = temp_args->print_output; int verify = temp_args->verify; @@ -128,6 +130,7 @@ static int run_aesccm192_tls(void *args) EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; +#ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_192_ccm); @@ -136,6 +139,7 @@ static int run_aesccm192_tls(void *args) e = NULL; } } +#endif if (input == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", @@ -166,7 +170,11 @@ static int run_aesccm192_tls(void *args) * IV used in the initialization of the cipher: in TLS case it is set * using ctrl() instead of EncryptInit_ex(). */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_EncryptInit_ex(ctx, EVP_aes_192_ccm(), NULL, NULL, NULL); +#else ret = EVP_EncryptInit_ex(ctx, EVP_aes_192_ccm(), e, NULL, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); @@ -191,7 +199,11 @@ static int run_aesccm192_tls(void *args) } /* set 24-byte of key to the aes-ccm context. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); +#else ret = EVP_EncryptInit_ex(ctx, EVP_aes_192_ccm(), e, key, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed for setting key: ret %d\n", __func__, ret); goto err; @@ -256,7 +268,11 @@ static int run_aesccm192_tls(void *args) } /* Initialise the context for decryption with 24-byte key and 12-byte IV. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_192_ccm(), NULL, NULL, NULL); +#else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_192_ccm(), e, NULL, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); @@ -281,7 +297,11 @@ static int run_aesccm192_tls(void *args) } /* set 24-byte of key to the aes-ccm context. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, NULL); +#else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_192_ccm(), e, key, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed for setting key: ret %d\n", __func__, ret); goto err; @@ -369,7 +389,9 @@ static int run_aesccm192_tls(void *args) static int run_aesccm192_update(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; +#ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; +#endif int size = INPUT_TEXT_SIZE; int print_output = temp_args->print_output; int verify = temp_args->verify; @@ -387,6 +409,7 @@ static int run_aesccm192_update(void *args) EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; +#ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_192_ccm); @@ -395,6 +418,7 @@ static int run_aesccm192_update(void *args) e = NULL; } } +#endif /* * Set the plaintext input data. @@ -421,7 +445,11 @@ static int run_aesccm192_update(void *args) } /* Initialize encryption context for aes-ccm */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_EncryptInit(ctx, EVP_aes_192_ccm(), NULL, NULL); +#else ret = EVP_EncryptInit_ex(ctx, EVP_aes_192_ccm(), e, NULL, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() encryption failed while setting context: ret %d\n", __func__, ret); goto err; @@ -442,15 +470,21 @@ static int run_aesccm192_update(void *args) goto err; } +#ifndef QAT_OPENSSL_PROVIDER /* set 24-byte of key to the aes-ccm context. */ ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting key: ret %d\n", __func__, ret); goto err; } +#endif /* set 12-byte of iv to the aes-ccm context. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_EncryptInit(ctx, NULL, key, iv); +#else ret = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting iv: ret %d\n", __func__, ret); goto err; @@ -511,7 +545,11 @@ static int run_aesccm192_update(void *args) } /* Initialize decryption context for aes-ccm */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_DecryptInit(dec_ctx, EVP_aes_192_ccm(), NULL, NULL); +#else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_192_ccm(), e, NULL, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); @@ -542,7 +580,11 @@ static int run_aesccm192_update(void *args) * Initialise the aes-ccm decryption context with 24-byte key and * 12-byte IV. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_DecryptInit(dec_ctx, NULL, key, iv); +#else ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, iv); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); diff --git a/test/tests_aes256_ccm.c b/test/tests_aes256_ccm.c index 94767476..b2bed8a7 100644 --- a/test/tests_aes256_ccm.c +++ b/test/tests_aes256_ccm.c @@ -88,7 +88,9 @@ static const unsigned char iv[] = { static int run_aesccm256_tls(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; +#ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; +#endif int size = INPUT_TEXT_SIZE; int print_output = temp_args->print_output; int verify = temp_args->verify; @@ -129,6 +131,7 @@ static int run_aesccm256_tls(void *args) EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; +#ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_256_ccm); @@ -137,6 +140,7 @@ static int run_aesccm256_tls(void *args) e = NULL; } } +#endif if (input == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", @@ -167,7 +171,11 @@ static int run_aesccm256_tls(void *args) * IV used in the initialization of the cipher: in TLS case it is set * using ctrl() instead of EncryptInit_ex(). */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ccm(), NULL, NULL, NULL); +#else ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ccm(), e, NULL, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); @@ -192,7 +200,11 @@ static int run_aesccm256_tls(void *args) } /* set 32-byte of key to the aes-ccm context. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); +#else ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ccm(), e, key, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed for setting key: ret %d\n", __func__, ret); goto err; @@ -257,7 +269,11 @@ static int run_aesccm256_tls(void *args) } /* Initialise the context for decryption with 32-byte key and 12-byte IV. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_256_ccm(), NULL, NULL, NULL); +#else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_256_ccm(), e, NULL, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); @@ -282,7 +298,11 @@ static int run_aesccm256_tls(void *args) } /* set 32-byte of key to the aes-ccm context. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, NULL); +#else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_256_ccm(), e, key, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed for setting key: ret %d\n", __func__, ret); goto err; @@ -370,7 +390,9 @@ static int run_aesccm256_tls(void *args) static int run_aesccm256_update(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; +#ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; +#endif int size = INPUT_TEXT_SIZE; int print_output = temp_args->print_output; int verify = temp_args->verify; @@ -388,6 +410,7 @@ static int run_aesccm256_update(void *args) EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; +#ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_256_ccm); @@ -396,6 +419,7 @@ static int run_aesccm256_update(void *args) e = NULL; } } +#endif /* * Set the plaintext input data. @@ -422,7 +446,11 @@ static int run_aesccm256_update(void *args) } /* Initialize encryption context for aes-ccm */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_EncryptInit(ctx, EVP_aes_256_ccm(), NULL, NULL); +#else ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ccm(), e, NULL, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() encryption failed while setting context: ret %d\n", __func__, ret); goto err; @@ -443,15 +471,21 @@ static int run_aesccm256_update(void *args) goto err; } +#ifndef QAT_OPENSSL_PROVIDER /* set 32-byte of key to the aes-ccm context. */ ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting key: ret %d\n", __func__, ret); goto err; } +#endif /* set 12-byte of iv to the aes-ccm context. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_EncryptInit(ctx, NULL, key, iv); +#else ret = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting iv: ret %d\n", __func__, ret); goto err; @@ -512,7 +546,11 @@ static int run_aesccm256_update(void *args) } /* Initialize decryption context for aes-ccm */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_DecryptInit(dec_ctx, EVP_aes_256_ccm(), NULL, NULL); +#else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_256_ccm(), e, NULL, NULL); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); @@ -543,7 +581,11 @@ static int run_aesccm256_update(void *args) * Initialise the aes-ccm decryption context with 32-byte key and * 12-byte IV. */ +#ifdef QAT_OPENSSL_PROVIDER + ret = EVP_DecryptInit(dec_ctx, NULL, key, iv); +#else ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, iv); +#endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret);