From mboxrd@z Thu Jan 1 00:00:00 1970 From: Anoob Joseph Subject: [PATCH 05/16] crypto/cpt/base: add sym crypto session init API for CPT Date: Fri, 8 Jun 2018 22:15:14 +0530 Message-ID: <1528476325-15585-6-git-send-email-anoob.joseph@caviumnetworks.com> References: <1528476325-15585-1-git-send-email-anoob.joseph@caviumnetworks.com> Mime-Version: 1.0 Content-Type: text/plain Cc: Ankur Dwivedi , Jerin Jacob , Murthy NSSR , Narayana Prasad , Nithin Dabilpuram , Ragothaman Jayaraman , Srisivasubramanian Srinivasan , dev@dpdk.org To: Akhil Goyal , Pablo de Lara , Thomas Monjalon Return-path: Received: from NAM04-SN1-obe.outbound.protection.outlook.com (mail-eopbgr700060.outbound.protection.outlook.com [40.107.70.60]) by dpdk.org (Postfix) with ESMTP id CC87A5F51 for ; Fri, 8 Jun 2018 18:49:02 +0200 (CEST) In-Reply-To: <1528476325-15585-1-git-send-email-anoob.joseph@caviumnetworks.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Ankur Dwivedi Adds symmetric crypto session init API dependent on hardware/microcode. Signed-off-by: Ankur Dwivedi Signed-off-by: Murthy NSSR Signed-off-by: Nithin Dabilpuram Signed-off-by: Ragothaman Jayaraman Signed-off-by: Srisivasubramanian Srinivasan --- drivers/crypto/cpt/base/cpt_ops.c | 308 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 drivers/crypto/cpt/base/cpt_ops.c diff --git a/drivers/crypto/cpt/base/cpt_ops.c b/drivers/crypto/cpt/base/cpt_ops.c new file mode 100644 index 0000000..e340006 --- /dev/null +++ b/drivers/crypto/cpt/base/cpt_ops.c @@ -0,0 +1,308 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017 Cavium, Inc + */ + +#include "cpt_request_mgr.h" + +#define __hot __attribute__((hot)) + +#define FC_GEN 0x1 +#define ZUC_SNOW3G 0x2 +#define KASUMI 0x3 +#define HASH_HMAC 0x4 + +struct cpt_ctx { + /* Below fields are accessed by sw */ + uint64_t enc_cipher :8; + uint64_t hash_type :8; + uint64_t mac_len :8; + uint64_t auth_key_len :8; + uint64_t fc_type :4; + uint64_t hmac :1; + uint64_t zsk_flags :3; + uint64_t k_ecb :1; + uint64_t snow3g :1; /* Set if it is snow3g and not ZUC */ + uint64_t rsvd :22; + /* Below fields are accessed by hardware */ + union { + mc_fc_context_t fctx; + mc_zuc_snow3g_ctx_t zs_ctx; + mc_kasumi_ctx_t k_ctx; + }; + uint8_t auth_key[64]; +}; + +static uint8_t zuc_d[32] = { + 0x44, 0xD7, 0x26, 0xBC, 0x62, 0x6B, 0x13, 0x5E, + 0x57, 0x89, 0x35, 0xE2, 0x71, 0x35, 0x09, 0xAF, + 0x4D, 0x78, 0x2F, 0x13, 0x6B, 0xC4, 0x1A, 0xF1, + 0x5E, 0x26, 0x3C, 0x4D, 0x78, 0x9A, 0x47, 0xAC +}; + +static void gen_key_snow3g(uint8_t *ck, uint32_t *keyx) +{ + int i, base; + + for (i = 0; i < 4; i++) { + base = 4 * i; + keyx[3 - i] = (ck[base] << 24) | (ck[base + 1] << 16) | + (ck[base + 2] << 8) | (ck[base + 3]); + keyx[3 - i] = htobe32(keyx[3 - i]); + } +} + +#define MAX_IV_LEN 16 + +int cpt_fc_get_op_meta_len(void) +{ + uint32_t len = 0; + + len += sizeof(cpt_request_info_t); + len += OFFSET_CONTROL_BYTES + MAX_IV_LEN; + len += ROUNDUP8(SG_LIST_HDR_SIZE + + (ROUNDUP4(MAX_SG_IN_OUT_CNT) >> 2) * SG_ENTRY_SIZE); + len += 2 * COMPLETION_CODE_SIZE; + len += 2 * sizeof(cpt_res_s_t); + return len; +} + +/* Provides meta length required when it is + * direct mode i.e single buf inplace + */ +int32_t cpt_fc_get_op_sb_meta_len(void) +{ + uint32_t len = 0; + + /* Request structure */ + len = sizeof(cpt_request_info_t); + /* CPT HW result structure plus extra as it is aligned */ + len += 2*sizeof(cpt_res_s_t); + + return len; +} + +int32_t cpt_fc_get_ctx_len(void) +{ + return sizeof(struct cpt_ctx); +} + +int +cpt_fc_ciph_set_key(cpt_instance_t *instance, + void *ctx, cipher_type_t type, uint8_t *key, + uint16_t key_len, uint8_t *salt) +{ + struct cpt_ctx *cpt_ctx = ctx; + mc_fc_context_t *fctx = &cpt_ctx->fctx; + mc_aes_type_t aes_key_type = 0; + uint64_t *ctrl_flags; + + (void) instance; + + if (!type) { + /* to support passthrough case */ + + cpt_ctx->fc_type = FC_GEN; + ctrl_flags = (uint64_t *)&(fctx->enc.enc_ctrl.flags); + cpt_ctx->enc_cipher = 0; + + *ctrl_flags = be64toh(*ctrl_flags); + P_ENC_CTRL(fctx).enc_cipher = 0; + *ctrl_flags = htobe64(*ctrl_flags); + + return 0; + } + + if ((type >= ZUC_EEA3) && (type <= KASUMI_F8_ECB)) { + uint32_t keyx[4]; + + if (key_len != 16) + return -1; + + /* No support for AEAD yet */ + if (cpt_ctx->hash_type) + return -1; + + /* For ZUC/SNOW3G/Kasumi */ + switch (type) { + case SNOW3G_UEA2: + cpt_ctx->snow3g = 1; + gen_key_snow3g(key, keyx); + memcpy(cpt_ctx->zs_ctx.ci_key, keyx, key_len); + cpt_ctx->fc_type = ZUC_SNOW3G; + cpt_ctx->zsk_flags = 0; + break; + case ZUC_EEA3: + cpt_ctx->snow3g = 0; + memcpy(cpt_ctx->zs_ctx.ci_key, key, key_len); + memcpy(cpt_ctx->zs_ctx.zuc_const, zuc_d, 32); + cpt_ctx->fc_type = ZUC_SNOW3G; + cpt_ctx->zsk_flags = 0; + break; + case KASUMI_F8_ECB: + /* Kasumi ECB mode */ + cpt_ctx->k_ecb = 1; + memcpy(cpt_ctx->k_ctx.ci_key, key, key_len); + cpt_ctx->zsk_flags = 0; + cpt_ctx->fc_type = KASUMI; + break; + case KASUMI_F8_CBC: + memcpy(cpt_ctx->k_ctx.ci_key, key, key_len); + cpt_ctx->zsk_flags = 0; + cpt_ctx->fc_type = KASUMI; + break; + default: + return -1; + } + cpt_ctx->enc_cipher = type; + return 0; + } + + fctx = &cpt_ctx->fctx; + /* Even though iv source is from dptr, + * aes_gcm salt is taken from ctx + */ + if (salt && (type == AES_GCM)) { + memcpy(fctx->enc.encr_iv, salt, 4); + /* Assuming it was just salt update + * and nothing else + */ + if (!key) + return 0; + } + + cpt_ctx->fc_type = FC_GEN; + ctrl_flags = (uint64_t *)&(fctx->enc.enc_ctrl.flags); + *ctrl_flags = be64toh(*ctrl_flags); + + cpt_ctx->enc_cipher = type; + /* For GMAC auth, cipher must be NULL */ + if (cpt_ctx->hash_type != GMAC_TYPE) + P_ENC_CTRL(fctx).enc_cipher = type; + + if (type == AES_XTS) + key_len = key_len / 2; + + /* key len only for AES */ + if ((type != DES3_CBC) && + (type != DES3_ECB)) { + switch (key_len) { + case BYTE_16: + aes_key_type = AES_128_BIT; + break; + case BYTE_24: + aes_key_type = AES_192_BIT; + if (type == AES_XTS) { + PMD_DRV_LOG(ERR, "Invalid AES key len for" + " XTS\n"); + return -1; + } + break; + case BYTE_32: + aes_key_type = AES_256_BIT; + break; + default: + PMD_DRV_LOG(ERR, "Invalid AES key len\n"); + return -1; + } + + P_ENC_CTRL(fctx).aes_key = aes_key_type; + } + /* + * We need to always say iv is from DPTR as user can + * sometimes override IV per operation + */ + P_ENC_CTRL(fctx).iv_source = FROM_DPTR; + + memcpy(fctx->enc.encr_key, key, key_len); + if (type == AES_XTS) { + /* Copy key2 for XTS into ipad */ + memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad)); + memcpy(fctx->hmac.ipad, &key[key_len], key_len); + } + + *ctrl_flags = htobe64(*ctrl_flags); + + return 0; +} + +int +cpt_fc_auth_set_key(cpt_instance_t *instance, + void *ctx, auth_type_t type, uint8_t *key, + uint16_t key_len, uint16_t mac_len) +{ + struct cpt_ctx *cpt_ctx = ctx; + mc_fc_context_t *fctx = &cpt_ctx->fctx; + uint64_t *ctrl_flags = NULL; + + (void) instance; + + if ((type >= ZUC_EIA3) && (type <= KASUMI_F9_ECB)) { + uint32_t keyx[4]; + + if (key_len != 16) + return -1; + /* No support for AEAD yet */ + if (cpt_ctx->enc_cipher) + return -1; + /* For ZUC/SNOW3G/Kasumi */ + switch (type) { + case SNOW3G_UIA2: + cpt_ctx->snow3g = 1; + gen_key_snow3g(key, keyx); + memcpy(cpt_ctx->zs_ctx.ci_key, keyx, key_len); + cpt_ctx->fc_type = ZUC_SNOW3G; + cpt_ctx->zsk_flags = 0x1; + break; + case ZUC_EIA3: + cpt_ctx->snow3g = 0; + memcpy(cpt_ctx->zs_ctx.ci_key, key, key_len); + memcpy(cpt_ctx->zs_ctx.zuc_const, zuc_d, 32); + cpt_ctx->fc_type = ZUC_SNOW3G; + cpt_ctx->zsk_flags = 0x1; + break; + case KASUMI_F9_ECB: + /* Kasumi ECB mode */ + cpt_ctx->k_ecb = 1; + memcpy(cpt_ctx->k_ctx.ci_key, key, key_len); + cpt_ctx->fc_type = KASUMI; + cpt_ctx->zsk_flags = 0x1; + break; + case KASUMI_F9_CBC: + memcpy(cpt_ctx->k_ctx.ci_key, key, key_len); + cpt_ctx->fc_type = KASUMI; + cpt_ctx->zsk_flags = 0x1; + break; + default: + return -1; + } + cpt_ctx->mac_len = 4; + cpt_ctx->hash_type = type; + return 0; + } + + if (!cpt_ctx->fc_type || !cpt_ctx->enc_cipher) + cpt_ctx->fc_type = HASH_HMAC; + + ctrl_flags = (uint64_t *)&fctx->enc.enc_ctrl.flags; + *ctrl_flags = be64toh(*ctrl_flags); + + /* For GMAC auth, cipher must be NULL */ + if (type == GMAC_TYPE) + P_ENC_CTRL(fctx).enc_cipher = 0; + + P_ENC_CTRL(fctx).hash_type = cpt_ctx->hash_type = type; + P_ENC_CTRL(fctx).mac_len = cpt_ctx->mac_len = mac_len; + + if (key_len) { + cpt_ctx->hmac = 1; + memset(cpt_ctx->auth_key, 0, sizeof(cpt_ctx->auth_key)); + memcpy(cpt_ctx->auth_key, key, key_len); + cpt_ctx->auth_key_len = key_len; + memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad)); + memset(fctx->hmac.opad, 0, sizeof(fctx->hmac.opad)); + memcpy(fctx->hmac.opad, key, key_len); + P_ENC_CTRL(fctx).auth_input_type = 1; + } + *ctrl_flags = htobe64(*ctrl_flags); + return 0; +} -- 1.9.3