From: Ankur Dwivedi <ankur.dwiv...@cavium.com>

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

Signed-off-by: Ankur Dwivedi <ankur.dwiv...@cavium.com>
Signed-off-by: Murthy NSSR <nidadavolu.mur...@cavium.com>
Signed-off-by: Nithin Dabilpuram <nithin.dabilpu...@cavium.com>
Signed-off-by: Ragothaman Jayaraman <ragothaman.jayara...@cavium.com>
Signed-off-by: Srisivasubramanian Srinivasan 
<srisivasubramanian.sriniva...@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

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

Reply via email to