[dpdk-dev,05/16] crypto/cpt/base: add sym crypto session init API for CPT
diff mbox series

Message ID 1528476325-15585-6-git-send-email-anoob.joseph@caviumnetworks.com
State Superseded, archived
Delegated to: akhil goyal
Headers show
Series
  • Adding Cavium's crypto device(CPT) driver
Related show

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation success Compilation OK

Commit Message

Anoob Joseph June 8, 2018, 4:45 p.m. UTC
From: Ankur Dwivedi <ankur.dwivedi@cavium.com>

Adds symmetric crypto session init API dependent on hardware/microcode.

Signed-off-by: Ankur Dwivedi <ankur.dwivedi@cavium.com>
Signed-off-by: Murthy NSSR <Nidadavolu.Murthy@cavium.com>
Signed-off-by: Nithin Dabilpuram <nithin.dabilpuram@cavium.com>
Signed-off-by: Ragothaman Jayaraman <Ragothaman.Jayaraman@cavium.com>
Signed-off-by: Srisivasubramanian Srinivasan <Srisivasubramanian.Srinivasan@cavium.com>
---
 drivers/crypto/cpt/base/cpt_ops.c | 308 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 308 insertions(+)
 create mode 100644 drivers/crypto/cpt/base/cpt_ops.c

Patch
diff mbox series

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;
+}