new file mode 100644
@@ -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;
+}