1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 2021 NVIDIA Corporation & Affiliates 3 */ 4 5 #include <rte_ip.h> 6 #include <rte_common.h> 7 #include <rte_errno.h> 8 #include <rte_log.h> 9 10 #include <mlx5_prm.h> 11 #include <mlx5_devx_cmds.h> 12 13 #include "mlx5_crypto_utils.h" 14 #include "mlx5_crypto.h" 15 16 struct mlx5_crypto_dek_ctx { 17 struct rte_crypto_cipher_xform *cipher; 18 struct mlx5_crypto_priv *priv; 19 }; 20 21 int 22 mlx5_crypto_dek_destroy(struct mlx5_crypto_priv *priv, 23 struct mlx5_crypto_dek *dek) 24 { 25 return mlx5_hlist_unregister(priv->dek_hlist, &dek->entry); 26 } 27 28 struct mlx5_crypto_dek * 29 mlx5_crypto_dek_prepare(struct mlx5_crypto_priv *priv, 30 struct rte_crypto_cipher_xform *cipher) 31 { 32 struct mlx5_hlist *dek_hlist = priv->dek_hlist; 33 struct mlx5_crypto_dek_ctx dek_ctx = { 34 .cipher = cipher, 35 .priv = priv, 36 }; 37 struct rte_crypto_cipher_xform *cipher_ctx = cipher; 38 uint64_t key64 = __rte_raw_cksum(cipher_ctx->key.data, 39 cipher_ctx->key.length, 0); 40 struct mlx5_list_entry *entry = mlx5_hlist_register(dek_hlist, 41 key64, &dek_ctx); 42 43 return entry == NULL ? NULL : 44 container_of(entry, struct mlx5_crypto_dek, entry); 45 } 46 47 static struct mlx5_list_entry * 48 mlx5_crypto_dek_clone_cb(void *tool_ctx __rte_unused, 49 struct mlx5_list_entry *oentry, 50 void *cb_ctx __rte_unused) 51 { 52 struct mlx5_crypto_dek *entry = rte_zmalloc(__func__, sizeof(*entry), 53 RTE_CACHE_LINE_SIZE); 54 55 if (!entry) { 56 DRV_LOG(ERR, "Cannot allocate dek resource memory."); 57 rte_errno = ENOMEM; 58 return NULL; 59 } 60 memcpy(entry, oentry, sizeof(*entry)); 61 return &entry->entry; 62 } 63 64 static void 65 mlx5_crypto_dek_clone_free_cb(void *tool_ctx __rte_unused, 66 struct mlx5_list_entry *entry) 67 { 68 struct mlx5_crypto_dek *dek = container_of(entry, 69 struct mlx5_crypto_dek, entry); 70 71 rte_free(dek); 72 } 73 74 static int 75 mlx5_crypto_dek_match_cb(void *tool_ctx __rte_unused, 76 struct mlx5_list_entry *entry, void *cb_ctx) 77 { 78 struct mlx5_crypto_dek_ctx *ctx = cb_ctx; 79 struct rte_crypto_cipher_xform *cipher_ctx = ctx->cipher; 80 struct mlx5_crypto_dek *dek = 81 container_of(entry, typeof(*dek), entry); 82 uint32_t key_len = dek->size_is_48 ? 48 : 80; 83 84 if (key_len != cipher_ctx->key.length) 85 return -1; 86 return memcmp(cipher_ctx->key.data, dek->data, key_len); 87 } 88 89 static struct mlx5_list_entry * 90 mlx5_crypto_dek_create_cb(void *tool_ctx __rte_unused, void *cb_ctx) 91 { 92 struct mlx5_crypto_dek_ctx *ctx = cb_ctx; 93 struct rte_crypto_cipher_xform *cipher_ctx = ctx->cipher; 94 struct mlx5_crypto_dek *dek = rte_zmalloc(__func__, sizeof(*dek), 95 RTE_CACHE_LINE_SIZE); 96 struct mlx5_devx_dek_attr dek_attr = { 97 .pd = ctx->priv->cdev->pdn, 98 .key_purpose = MLX5_CRYPTO_KEY_PURPOSE_AES_XTS, 99 .has_keytag = 1, 100 }; 101 102 if (dek == NULL) { 103 DRV_LOG(ERR, "Failed to allocate dek memory."); 104 return NULL; 105 } 106 switch (cipher_ctx->key.length) { 107 case 48: 108 dek->size_is_48 = true; 109 dek_attr.key_size = MLX5_CRYPTO_KEY_SIZE_128b; 110 break; 111 case 80: 112 dek->size_is_48 = false; 113 dek_attr.key_size = MLX5_CRYPTO_KEY_SIZE_256b; 114 break; 115 default: 116 DRV_LOG(ERR, "Key size not supported."); 117 return NULL; 118 } 119 memcpy(&dek_attr.key, cipher_ctx->key.data, cipher_ctx->key.length); 120 dek->obj = mlx5_devx_cmd_create_dek_obj(ctx->priv->cdev->ctx, 121 &dek_attr); 122 if (dek->obj == NULL) { 123 rte_free(dek); 124 return NULL; 125 } 126 memcpy(&dek->data, cipher_ctx->key.data, cipher_ctx->key.length); 127 return &dek->entry; 128 } 129 130 static void 131 mlx5_crypto_dek_remove_cb(void *tool_ctx __rte_unused, 132 struct mlx5_list_entry *entry) 133 { 134 struct mlx5_crypto_dek *dek = 135 container_of(entry, typeof(*dek), entry); 136 137 claim_zero(mlx5_devx_cmd_destroy(dek->obj)); 138 rte_free(dek); 139 } 140 141 int 142 mlx5_crypto_dek_setup(struct mlx5_crypto_priv *priv) 143 { 144 priv->dek_hlist = mlx5_hlist_create("dek_hlist", 145 MLX5_CRYPTO_DEK_HTABLE_SZ, 146 0, 1, NULL, mlx5_crypto_dek_create_cb, 147 mlx5_crypto_dek_match_cb, 148 mlx5_crypto_dek_remove_cb, 149 mlx5_crypto_dek_clone_cb, 150 mlx5_crypto_dek_clone_free_cb); 151 if (priv->dek_hlist == NULL) 152 return -1; 153 return 0; 154 } 155 156 void 157 mlx5_crypto_dek_unset(struct mlx5_crypto_priv *priv) 158 { 159 mlx5_hlist_destroy(priv->dek_hlist); 160 priv->dek_hlist = NULL; 161 } 162