crypto/ccp: support session related ops
[dpdk.git] / drivers / crypto / ccp / ccp_crypto.c
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved.
3  */
4
5 #include <dirent.h>
6 #include <fcntl.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <sys/mman.h>
10 #include <sys/queue.h>
11 #include <sys/types.h>
12 #include <unistd.h>
13
14 #include <rte_hexdump.h>
15 #include <rte_memzone.h>
16 #include <rte_malloc.h>
17 #include <rte_memory.h>
18 #include <rte_spinlock.h>
19 #include <rte_string_fns.h>
20 #include <rte_cryptodev_pmd.h>
21
22 #include "ccp_dev.h"
23 #include "ccp_crypto.h"
24 #include "ccp_pci.h"
25 #include "ccp_pmd_private.h"
26
27 static enum ccp_cmd_order
28 ccp_get_cmd_id(const struct rte_crypto_sym_xform *xform)
29 {
30         enum ccp_cmd_order res = CCP_CMD_NOT_SUPPORTED;
31
32         if (xform == NULL)
33                 return res;
34         if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
35                 if (xform->next == NULL)
36                         return CCP_CMD_AUTH;
37                 else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
38                         return CCP_CMD_HASH_CIPHER;
39         }
40         if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
41                 if (xform->next == NULL)
42                         return CCP_CMD_CIPHER;
43                 else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH)
44                         return CCP_CMD_CIPHER_HASH;
45         }
46         if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
47                 return CCP_CMD_COMBINED;
48         return res;
49 }
50
51 /* configure session */
52 static int
53 ccp_configure_session_cipher(struct ccp_session *sess,
54                              const struct rte_crypto_sym_xform *xform)
55 {
56         const struct rte_crypto_cipher_xform *cipher_xform = NULL;
57
58         cipher_xform = &xform->cipher;
59
60         /* set cipher direction */
61         if (cipher_xform->op ==  RTE_CRYPTO_CIPHER_OP_ENCRYPT)
62                 sess->cipher.dir = CCP_CIPHER_DIR_ENCRYPT;
63         else
64                 sess->cipher.dir = CCP_CIPHER_DIR_DECRYPT;
65
66         /* set cipher key */
67         sess->cipher.key_length = cipher_xform->key.length;
68         rte_memcpy(sess->cipher.key, cipher_xform->key.data,
69                    cipher_xform->key.length);
70
71         /* set iv parameters */
72         sess->iv.offset = cipher_xform->iv.offset;
73         sess->iv.length = cipher_xform->iv.length;
74
75         switch (cipher_xform->algo) {
76         default:
77                 CCP_LOG_ERR("Unsupported cipher algo");
78                 return -1;
79         }
80
81
82         switch (sess->cipher.engine) {
83         default:
84                 CCP_LOG_ERR("Invalid CCP Engine");
85                 return -ENOTSUP;
86         }
87         return 0;
88 }
89
90 static int
91 ccp_configure_session_auth(struct ccp_session *sess,
92                            const struct rte_crypto_sym_xform *xform)
93 {
94         const struct rte_crypto_auth_xform *auth_xform = NULL;
95
96         auth_xform = &xform->auth;
97
98         sess->auth.digest_length = auth_xform->digest_length;
99         if (auth_xform->op ==  RTE_CRYPTO_AUTH_OP_GENERATE)
100                 sess->auth.op = CCP_AUTH_OP_GENERATE;
101         else
102                 sess->auth.op = CCP_AUTH_OP_VERIFY;
103         switch (auth_xform->algo) {
104         default:
105                 CCP_LOG_ERR("Unsupported hash algo");
106                 return -ENOTSUP;
107         }
108         return 0;
109 }
110
111 static int
112 ccp_configure_session_aead(struct ccp_session *sess,
113                            const struct rte_crypto_sym_xform *xform)
114 {
115         const struct rte_crypto_aead_xform *aead_xform = NULL;
116
117         aead_xform = &xform->aead;
118
119         sess->cipher.key_length = aead_xform->key.length;
120         rte_memcpy(sess->cipher.key, aead_xform->key.data,
121                    aead_xform->key.length);
122
123         if (aead_xform->op == RTE_CRYPTO_AEAD_OP_ENCRYPT) {
124                 sess->cipher.dir = CCP_CIPHER_DIR_ENCRYPT;
125                 sess->auth.op = CCP_AUTH_OP_GENERATE;
126         } else {
127                 sess->cipher.dir = CCP_CIPHER_DIR_DECRYPT;
128                 sess->auth.op = CCP_AUTH_OP_VERIFY;
129         }
130         sess->auth.aad_length = aead_xform->aad_length;
131         sess->auth.digest_length = aead_xform->digest_length;
132
133         /* set iv parameters */
134         sess->iv.offset = aead_xform->iv.offset;
135         sess->iv.length = aead_xform->iv.length;
136
137         switch (aead_xform->algo) {
138         default:
139                 CCP_LOG_ERR("Unsupported aead algo");
140                 return -ENOTSUP;
141         }
142         return 0;
143 }
144
145 int
146 ccp_set_session_parameters(struct ccp_session *sess,
147                            const struct rte_crypto_sym_xform *xform)
148 {
149         const struct rte_crypto_sym_xform *cipher_xform = NULL;
150         const struct rte_crypto_sym_xform *auth_xform = NULL;
151         const struct rte_crypto_sym_xform *aead_xform = NULL;
152         int ret = 0;
153
154         sess->cmd_id = ccp_get_cmd_id(xform);
155
156         switch (sess->cmd_id) {
157         case CCP_CMD_CIPHER:
158                 cipher_xform = xform;
159                 break;
160         case CCP_CMD_AUTH:
161                 auth_xform = xform;
162                 break;
163         case CCP_CMD_CIPHER_HASH:
164                 cipher_xform = xform;
165                 auth_xform = xform->next;
166                 break;
167         case CCP_CMD_HASH_CIPHER:
168                 auth_xform = xform;
169                 cipher_xform = xform->next;
170                 break;
171         case CCP_CMD_COMBINED:
172                 aead_xform = xform;
173                 break;
174         default:
175                 CCP_LOG_ERR("Unsupported cmd_id");
176                 return -1;
177         }
178
179         /* Default IV length = 0 */
180         sess->iv.length = 0;
181         if (cipher_xform) {
182                 ret = ccp_configure_session_cipher(sess, cipher_xform);
183                 if (ret != 0) {
184                         CCP_LOG_ERR("Invalid/unsupported cipher parameters");
185                         return ret;
186                 }
187         }
188         if (auth_xform) {
189                 ret = ccp_configure_session_auth(sess, auth_xform);
190                 if (ret != 0) {
191                         CCP_LOG_ERR("Invalid/unsupported auth parameters");
192                         return ret;
193                 }
194         }
195         if (aead_xform) {
196                 ret = ccp_configure_session_aead(sess, aead_xform);
197                 if (ret != 0) {
198                         CCP_LOG_ERR("Invalid/unsupported aead parameters");
199                         return ret;
200                 }
201         }
202         return ret;
203 }