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; 83 84 if (key_len != cipher_ctx->key.length) 85 return -1; 86 return memcmp(cipher_ctx->key.data, dek->data, cipher_ctx->key.length); 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 bool is_wrapped = ctx->priv->is_wrapped_mode; 102 103 if (dek == NULL) { 104 DRV_LOG(ERR, "Failed to allocate dek memory."); 105 return NULL; 106 } 107 if (is_wrapped) { 108 switch (cipher_ctx->key.length) { 109 case 48: 110 dek->size = 48; 111 dek_attr.key_size = MLX5_CRYPTO_KEY_SIZE_128b; 112 break; 113 case 80: 114 dek->size = 80; 115 dek_attr.key_size = MLX5_CRYPTO_KEY_SIZE_256b; 116 break; 117 default: 118 DRV_LOG(ERR, "Wrapped key size not supported."); 119 return NULL; 120 } 121 } else { 122 switch (cipher_ctx->key.length) { 123 case 32: 124 dek->size = 40; 125 dek_attr.key_size = MLX5_CRYPTO_KEY_SIZE_128b; 126 break; 127 case 64: 128 dek->size = 72; 129 dek_attr.key_size = MLX5_CRYPTO_KEY_SIZE_256b; 130 break; 131 default: 132 DRV_LOG(ERR, "Key size not supported."); 133 return NULL; 134 } 135 memcpy(&dek_attr.key[cipher_ctx->key.length], 136 &ctx->priv->keytag, 8); 137 } 138 memcpy(&dek_attr.key, cipher_ctx->key.data, cipher_ctx->key.length); 139 dek->obj = mlx5_devx_cmd_create_dek_obj(ctx->priv->cdev->ctx, 140 &dek_attr); 141 if (dek->obj == NULL) { 142 rte_free(dek); 143 return NULL; 144 } 145 memcpy(&dek->data, cipher_ctx->key.data, cipher_ctx->key.length); 146 return &dek->entry; 147 } 148 149 static void 150 mlx5_crypto_dek_remove_cb(void *tool_ctx __rte_unused, 151 struct mlx5_list_entry *entry) 152 { 153 struct mlx5_crypto_dek *dek = 154 container_of(entry, typeof(*dek), entry); 155 156 claim_zero(mlx5_devx_cmd_destroy(dek->obj)); 157 rte_free(dek); 158 } 159 160 int 161 mlx5_crypto_dek_setup(struct mlx5_crypto_priv *priv) 162 { 163 priv->dek_hlist = mlx5_hlist_create("dek_hlist", 164 MLX5_CRYPTO_DEK_HTABLE_SZ, 165 0, 1, NULL, mlx5_crypto_dek_create_cb, 166 mlx5_crypto_dek_match_cb, 167 mlx5_crypto_dek_remove_cb, 168 mlx5_crypto_dek_clone_cb, 169 mlx5_crypto_dek_clone_free_cb); 170 if (priv->dek_hlist == NULL) 171 return -1; 172 return 0; 173 } 174 175 void 176 mlx5_crypto_dek_unset(struct mlx5_crypto_priv *priv) 177 { 178 if (priv->dek_hlist) { 179 mlx5_hlist_destroy(priv->dek_hlist); 180 priv->dek_hlist = NULL; 181 } 182 } 183