xref: /dpdk/drivers/crypto/bcmfs/bcmfs_sym_engine.c (revision cd5db556ace9f01521a039a75f0b1a35cfcd6bcb)
1492a19a0SVikas Gupta /* SPDX-License-Identifier: BSD-3-Clause
2492a19a0SVikas Gupta  * Copyright(C) 2020 Broadcom.
3492a19a0SVikas Gupta  * All rights reserved.
4492a19a0SVikas Gupta  */
5492a19a0SVikas Gupta 
6492a19a0SVikas Gupta #include <stdbool.h>
7492a19a0SVikas Gupta #include <string.h>
8492a19a0SVikas Gupta 
9492a19a0SVikas Gupta #include <rte_common.h>
10492a19a0SVikas Gupta #include <rte_cryptodev.h>
11492a19a0SVikas Gupta #include <rte_crypto_sym.h>
12492a19a0SVikas Gupta 
13492a19a0SVikas Gupta #include "bcmfs_logs.h"
14492a19a0SVikas Gupta #include "bcmfs_sym_defs.h"
15492a19a0SVikas Gupta #include "bcmfs_dev_msg.h"
16492a19a0SVikas Gupta #include "bcmfs_sym_req.h"
17492a19a0SVikas Gupta #include "bcmfs_sym_engine.h"
18492a19a0SVikas Gupta 
19492a19a0SVikas Gupta enum spu2_cipher_type {
20492a19a0SVikas Gupta 	SPU2_CIPHER_TYPE_NONE = 0x0,
21492a19a0SVikas Gupta 	SPU2_CIPHER_TYPE_AES128 = 0x1,
22492a19a0SVikas Gupta 	SPU2_CIPHER_TYPE_AES192 = 0x2,
23492a19a0SVikas Gupta 	SPU2_CIPHER_TYPE_AES256 = 0x3,
24492a19a0SVikas Gupta 	SPU2_CIPHER_TYPE_DES = 0x4,
25492a19a0SVikas Gupta 	SPU2_CIPHER_TYPE_3DES = 0x5,
26492a19a0SVikas Gupta 	SPU2_CIPHER_TYPE_LAST
27492a19a0SVikas Gupta };
28492a19a0SVikas Gupta 
29492a19a0SVikas Gupta enum spu2_cipher_mode {
30492a19a0SVikas Gupta 	SPU2_CIPHER_MODE_ECB = 0x0,
31492a19a0SVikas Gupta 	SPU2_CIPHER_MODE_CBC = 0x1,
32492a19a0SVikas Gupta 	SPU2_CIPHER_MODE_CTR = 0x2,
33492a19a0SVikas Gupta 	SPU2_CIPHER_MODE_CFB = 0x3,
34492a19a0SVikas Gupta 	SPU2_CIPHER_MODE_OFB = 0x4,
35492a19a0SVikas Gupta 	SPU2_CIPHER_MODE_XTS = 0x5,
36492a19a0SVikas Gupta 	SPU2_CIPHER_MODE_CCM = 0x6,
37492a19a0SVikas Gupta 	SPU2_CIPHER_MODE_GCM = 0x7,
38492a19a0SVikas Gupta 	SPU2_CIPHER_MODE_LAST
39492a19a0SVikas Gupta };
40492a19a0SVikas Gupta 
41492a19a0SVikas Gupta enum spu2_hash_type {
42492a19a0SVikas Gupta 	SPU2_HASH_TYPE_NONE = 0x0,
43492a19a0SVikas Gupta 	SPU2_HASH_TYPE_AES128 = 0x1,
44492a19a0SVikas Gupta 	SPU2_HASH_TYPE_AES192 = 0x2,
45492a19a0SVikas Gupta 	SPU2_HASH_TYPE_AES256 = 0x3,
46492a19a0SVikas Gupta 	SPU2_HASH_TYPE_MD5 = 0x6,
47492a19a0SVikas Gupta 	SPU2_HASH_TYPE_SHA1 = 0x7,
48492a19a0SVikas Gupta 	SPU2_HASH_TYPE_SHA224 = 0x8,
49492a19a0SVikas Gupta 	SPU2_HASH_TYPE_SHA256 = 0x9,
50492a19a0SVikas Gupta 	SPU2_HASH_TYPE_SHA384 = 0xa,
51492a19a0SVikas Gupta 	SPU2_HASH_TYPE_SHA512 = 0xb,
52492a19a0SVikas Gupta 	SPU2_HASH_TYPE_SHA512_224 = 0xc,
53492a19a0SVikas Gupta 	SPU2_HASH_TYPE_SHA512_256 = 0xd,
54492a19a0SVikas Gupta 	SPU2_HASH_TYPE_SHA3_224 = 0xe,
55492a19a0SVikas Gupta 	SPU2_HASH_TYPE_SHA3_256 = 0xf,
56492a19a0SVikas Gupta 	SPU2_HASH_TYPE_SHA3_384 = 0x10,
57492a19a0SVikas Gupta 	SPU2_HASH_TYPE_SHA3_512 = 0x11,
58492a19a0SVikas Gupta 	SPU2_HASH_TYPE_LAST
59492a19a0SVikas Gupta };
60492a19a0SVikas Gupta 
61492a19a0SVikas Gupta enum spu2_hash_mode {
62492a19a0SVikas Gupta 	SPU2_HASH_MODE_CMAC = 0x0,
63492a19a0SVikas Gupta 	SPU2_HASH_MODE_CBC_MAC = 0x1,
64492a19a0SVikas Gupta 	SPU2_HASH_MODE_XCBC_MAC = 0x2,
65492a19a0SVikas Gupta 	SPU2_HASH_MODE_HMAC = 0x3,
66492a19a0SVikas Gupta 	SPU2_HASH_MODE_RABIN = 0x4,
67492a19a0SVikas Gupta 	SPU2_HASH_MODE_CCM = 0x5,
68492a19a0SVikas Gupta 	SPU2_HASH_MODE_GCM = 0x6,
69492a19a0SVikas Gupta 	SPU2_HASH_MODE_RESERVED = 0x7,
70492a19a0SVikas Gupta 	SPU2_HASH_MODE_LAST
71492a19a0SVikas Gupta };
72492a19a0SVikas Gupta 
73492a19a0SVikas Gupta enum spu2_proto_sel {
74492a19a0SVikas Gupta 	SPU2_PROTO_RESV = 0,
75492a19a0SVikas Gupta 	SPU2_MACSEC_SECTAG8_ECB = 1,
76492a19a0SVikas Gupta 	SPU2_MACSEC_SECTAG8_SCB = 2,
77492a19a0SVikas Gupta 	SPU2_MACSEC_SECTAG16 = 3,
78492a19a0SVikas Gupta 	SPU2_MACSEC_SECTAG16_8_XPN = 4,
79492a19a0SVikas Gupta 	SPU2_IPSEC = 5,
80492a19a0SVikas Gupta 	SPU2_IPSEC_ESN = 6,
81492a19a0SVikas Gupta 	SPU2_TLS_CIPHER = 7,
82492a19a0SVikas Gupta 	SPU2_TLS_AEAD = 8,
83492a19a0SVikas Gupta 	SPU2_DTLS_CIPHER = 9,
84492a19a0SVikas Gupta 	SPU2_DTLS_AEAD = 10
85492a19a0SVikas Gupta };
86492a19a0SVikas Gupta 
87492a19a0SVikas Gupta /* SPU2 response size */
88492a19a0SVikas Gupta #define SPU2_STATUS_LEN			2
89492a19a0SVikas Gupta 
90492a19a0SVikas Gupta /* Metadata settings in response */
91492a19a0SVikas Gupta enum spu2_ret_md_opts {
92492a19a0SVikas Gupta 	SPU2_RET_NO_MD = 0,		/* return no metadata */
93492a19a0SVikas Gupta 	SPU2_RET_FMD_OMD = 1,		/* return both FMD and OMD */
94492a19a0SVikas Gupta 	SPU2_RET_FMD_ONLY = 2,		/* return only FMD */
95492a19a0SVikas Gupta 	SPU2_RET_FMD_OMD_IV = 3,	/* return FMD and OMD with just IVs */
96492a19a0SVikas Gupta };
97492a19a0SVikas Gupta 
98492a19a0SVikas Gupta /* FMD ctrl0 field masks */
99492a19a0SVikas Gupta #define SPU2_CIPH_ENCRYPT_EN            0x1 /* 0: decrypt, 1: encrypt */
100492a19a0SVikas Gupta #define SPU2_CIPH_TYPE_SHIFT              4
101492a19a0SVikas Gupta #define SPU2_CIPH_MODE                0xF00 /* one of spu2_cipher_mode */
102492a19a0SVikas Gupta #define SPU2_CIPH_MODE_SHIFT              8
103492a19a0SVikas Gupta #define SPU2_CFB_MASK                0x7000 /* cipher feedback mask */
104492a19a0SVikas Gupta #define SPU2_CFB_MASK_SHIFT              12
105492a19a0SVikas Gupta #define SPU2_PROTO_SEL             0xF00000 /* MACsec, IPsec, TLS... */
106492a19a0SVikas Gupta #define SPU2_PROTO_SEL_SHIFT             20
107492a19a0SVikas Gupta #define SPU2_HASH_FIRST           0x1000000 /* 1: hash input is input pkt
108492a19a0SVikas Gupta 					     * data
109492a19a0SVikas Gupta 					     */
110492a19a0SVikas Gupta #define SPU2_CHK_TAG              0x2000000 /* 1: check digest provided */
111492a19a0SVikas Gupta #define SPU2_HASH_TYPE          0x1F0000000 /* one of spu2_hash_type */
112492a19a0SVikas Gupta #define SPU2_HASH_TYPE_SHIFT             28
113492a19a0SVikas Gupta #define SPU2_HASH_MODE         0xF000000000 /* one of spu2_hash_mode */
114492a19a0SVikas Gupta #define SPU2_HASH_MODE_SHIFT             36
115492a19a0SVikas Gupta #define SPU2_CIPH_PAD_EN     0x100000000000 /* 1: Add pad to end of payload for
116492a19a0SVikas Gupta 					     *    enc
117492a19a0SVikas Gupta 					     */
118492a19a0SVikas Gupta #define SPU2_CIPH_PAD      0xFF000000000000 /* cipher pad value */
119492a19a0SVikas Gupta #define SPU2_CIPH_PAD_SHIFT              48
120492a19a0SVikas Gupta 
121492a19a0SVikas Gupta /* FMD ctrl1 field masks */
122492a19a0SVikas Gupta #define SPU2_TAG_LOC                    0x1 /* 1: end of payload, 0: undef */
123492a19a0SVikas Gupta #define SPU2_HAS_FR_DATA                0x2 /* 1: msg has frame data */
124492a19a0SVikas Gupta #define SPU2_HAS_AAD1                   0x4 /* 1: msg has AAD1 field */
125492a19a0SVikas Gupta #define SPU2_HAS_NAAD                   0x8 /* 1: msg has NAAD field */
126492a19a0SVikas Gupta #define SPU2_HAS_AAD2                  0x10 /* 1: msg has AAD2 field */
127492a19a0SVikas Gupta #define SPU2_HAS_ESN                   0x20 /* 1: msg has ESN field */
128492a19a0SVikas Gupta #define SPU2_HASH_KEY_LEN            0xFF00 /* len of hash key in bytes.
129492a19a0SVikas Gupta 					     * HMAC only.
130492a19a0SVikas Gupta 					     */
131492a19a0SVikas Gupta #define SPU2_HASH_KEY_LEN_SHIFT           8
132492a19a0SVikas Gupta #define SPU2_CIPH_KEY_LEN         0xFF00000 /* len of cipher key in bytes */
133492a19a0SVikas Gupta #define SPU2_CIPH_KEY_LEN_SHIFT          20
134492a19a0SVikas Gupta #define SPU2_GENIV               0x10000000 /* 1: hw generates IV */
135492a19a0SVikas Gupta #define SPU2_HASH_IV             0x20000000 /* 1: IV incl in hash */
136492a19a0SVikas Gupta #define SPU2_RET_IV              0x40000000 /* 1: return IV in output msg
137492a19a0SVikas Gupta 					     *    b4 payload
138492a19a0SVikas Gupta 					     */
139492a19a0SVikas Gupta #define SPU2_RET_IV_LEN         0xF00000000 /* length in bytes of IV returned.
140492a19a0SVikas Gupta 					     * 0 = 16 bytes
141492a19a0SVikas Gupta 					     */
142492a19a0SVikas Gupta #define SPU2_RET_IV_LEN_SHIFT            32
143492a19a0SVikas Gupta #define SPU2_IV_OFFSET         0xF000000000 /* gen IV offset */
144492a19a0SVikas Gupta #define SPU2_IV_OFFSET_SHIFT             36
145492a19a0SVikas Gupta #define SPU2_IV_LEN          0x1F0000000000 /* length of input IV in bytes */
146492a19a0SVikas Gupta #define SPU2_IV_LEN_SHIFT                40
147492a19a0SVikas Gupta #define SPU2_HASH_TAG_LEN  0x7F000000000000 /* hash tag length in bytes */
148492a19a0SVikas Gupta #define SPU2_HASH_TAG_LEN_SHIFT          48
149492a19a0SVikas Gupta #define SPU2_RETURN_MD    0x300000000000000 /* return metadata */
150492a19a0SVikas Gupta #define SPU2_RETURN_MD_SHIFT             56
151492a19a0SVikas Gupta #define SPU2_RETURN_FD    0x400000000000000
152492a19a0SVikas Gupta #define SPU2_RETURN_AAD1  0x800000000000000
153492a19a0SVikas Gupta #define SPU2_RETURN_NAAD 0x1000000000000000
154492a19a0SVikas Gupta #define SPU2_RETURN_AAD2 0x2000000000000000
155492a19a0SVikas Gupta #define SPU2_RETURN_PAY  0x4000000000000000 /* return payload */
156492a19a0SVikas Gupta 
157492a19a0SVikas Gupta /* FMD ctrl2 field masks */
158492a19a0SVikas Gupta #define SPU2_AAD1_OFFSET              0xFFF /* byte offset of AAD1 field */
159492a19a0SVikas Gupta #define SPU2_AAD1_LEN               0xFF000 /* length of AAD1 in bytes */
160492a19a0SVikas Gupta #define SPU2_AAD1_LEN_SHIFT              12
161492a19a0SVikas Gupta #define SPU2_AAD2_OFFSET         0xFFF00000 /* byte offset of AAD2 field */
162492a19a0SVikas Gupta #define SPU2_AAD2_OFFSET_SHIFT           20
163492a19a0SVikas Gupta #define SPU2_PL_OFFSET   0xFFFFFFFF00000000 /* payload offset from AAD2 */
164492a19a0SVikas Gupta #define SPU2_PL_OFFSET_SHIFT             32
165492a19a0SVikas Gupta 
166492a19a0SVikas Gupta /* FMD ctrl3 field masks */
167492a19a0SVikas Gupta #define SPU2_PL_LEN              0xFFFFFFFF /* payload length in bytes */
168492a19a0SVikas Gupta #define SPU2_TLS_LEN         0xFFFF00000000 /* TLS encrypt: cipher len
169492a19a0SVikas Gupta 					     * TLS decrypt: compressed len
170492a19a0SVikas Gupta 					     */
171492a19a0SVikas Gupta #define SPU2_TLS_LEN_SHIFT               32
172492a19a0SVikas Gupta 
173492a19a0SVikas Gupta /*
174492a19a0SVikas Gupta  * Max value that can be represented in the Payload Length field of the
175492a19a0SVikas Gupta  * ctrl3 word of FMD.
176492a19a0SVikas Gupta  */
177492a19a0SVikas Gupta #define SPU2_MAX_PAYLOAD  SPU2_PL_LEN
178492a19a0SVikas Gupta 
179492a19a0SVikas Gupta #define SPU2_VAL_NONE	0
180492a19a0SVikas Gupta 
181492a19a0SVikas Gupta /* CCM B_0 field definitions, common for SPU-M and SPU2 */
182492a19a0SVikas Gupta #define CCM_B0_ADATA		0x40
183492a19a0SVikas Gupta #define CCM_B0_ADATA_SHIFT	   6
184492a19a0SVikas Gupta #define CCM_B0_M_PRIME		0x38
185492a19a0SVikas Gupta #define CCM_B0_M_PRIME_SHIFT	   3
186492a19a0SVikas Gupta #define CCM_B0_L_PRIME		0x07
187492a19a0SVikas Gupta #define CCM_B0_L_PRIME_SHIFT	   0
188492a19a0SVikas Gupta #define CCM_ESP_L_VALUE		   4
189492a19a0SVikas Gupta 
190492a19a0SVikas Gupta static uint16_t
spu2_cipher_type_xlate(enum rte_crypto_cipher_algorithm cipher_alg,enum spu2_cipher_type * spu2_type,struct fsattr * key)191492a19a0SVikas Gupta spu2_cipher_type_xlate(enum rte_crypto_cipher_algorithm cipher_alg,
192492a19a0SVikas Gupta 		       enum spu2_cipher_type *spu2_type,
193492a19a0SVikas Gupta 		       struct fsattr *key)
194492a19a0SVikas Gupta {
195492a19a0SVikas Gupta 	int ret = 0;
196492a19a0SVikas Gupta 	int key_size = fsattr_sz(key);
197492a19a0SVikas Gupta 
198492a19a0SVikas Gupta 	if (cipher_alg == RTE_CRYPTO_CIPHER_AES_XTS)
199492a19a0SVikas Gupta 		key_size = key_size / 2;
200492a19a0SVikas Gupta 
201492a19a0SVikas Gupta 	switch (key_size) {
202492a19a0SVikas Gupta 	case BCMFS_CRYPTO_AES128:
203492a19a0SVikas Gupta 		*spu2_type = SPU2_CIPHER_TYPE_AES128;
204492a19a0SVikas Gupta 		break;
205492a19a0SVikas Gupta 	case BCMFS_CRYPTO_AES192:
206492a19a0SVikas Gupta 		*spu2_type = SPU2_CIPHER_TYPE_AES192;
207492a19a0SVikas Gupta 		break;
208492a19a0SVikas Gupta 	case BCMFS_CRYPTO_AES256:
209492a19a0SVikas Gupta 		*spu2_type = SPU2_CIPHER_TYPE_AES256;
210492a19a0SVikas Gupta 		break;
211492a19a0SVikas Gupta 	default:
212492a19a0SVikas Gupta 		ret = -EINVAL;
213492a19a0SVikas Gupta 	}
214492a19a0SVikas Gupta 
215492a19a0SVikas Gupta 	return ret;
216492a19a0SVikas Gupta }
217492a19a0SVikas Gupta 
218492a19a0SVikas Gupta static int
spu2_hash_xlate(enum rte_crypto_auth_algorithm auth_alg,struct fsattr * key,enum spu2_hash_type * spu2_type,enum spu2_hash_mode * spu2_mode)219492a19a0SVikas Gupta spu2_hash_xlate(enum rte_crypto_auth_algorithm auth_alg,
220492a19a0SVikas Gupta 		struct fsattr *key,
221492a19a0SVikas Gupta 		enum spu2_hash_type *spu2_type,
222492a19a0SVikas Gupta 		enum spu2_hash_mode *spu2_mode)
223492a19a0SVikas Gupta {
224492a19a0SVikas Gupta 	*spu2_mode = 0;
225492a19a0SVikas Gupta 
226492a19a0SVikas Gupta 	switch (auth_alg) {
227492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_NULL:
228492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_NONE;
229492a19a0SVikas Gupta 		break;
230492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_MD5:
231492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_MD5;
232492a19a0SVikas Gupta 		break;
233492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_MD5_HMAC:
234492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_MD5;
235492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_HMAC;
236492a19a0SVikas Gupta 		break;
237492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA1:
238492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA1;
239492a19a0SVikas Gupta 		break;
240492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA1_HMAC:
241492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA1;
242492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_HMAC;
243492a19a0SVikas Gupta 		break;
244492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA224:
245492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA224;
246492a19a0SVikas Gupta 		break;
247492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA224_HMAC:
248492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA224;
249492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_HMAC;
250492a19a0SVikas Gupta 		break;
251492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA256:
252492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA256;
253492a19a0SVikas Gupta 		break;
254492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA256_HMAC:
255492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA256;
256492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_HMAC;
257492a19a0SVikas Gupta 		break;
258492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA384:
259492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA384;
260492a19a0SVikas Gupta 		break;
261492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA384_HMAC:
262492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA384;
263492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_HMAC;
264492a19a0SVikas Gupta 		break;
265492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA512:
266492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA512;
267492a19a0SVikas Gupta 		break;
268492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA512_HMAC:
269492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA512;
270492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_HMAC;
271492a19a0SVikas Gupta 		break;
272492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA3_224:
273492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA3_224;
274492a19a0SVikas Gupta 		break;
275492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA3_224_HMAC:
276492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA3_224;
277492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_HMAC;
278492a19a0SVikas Gupta 		break;
279492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA3_256:
280492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA3_256;
281492a19a0SVikas Gupta 		break;
282492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA3_256_HMAC:
283492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA3_256;
284492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_HMAC;
285492a19a0SVikas Gupta 		break;
286492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA3_384:
287492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA3_384;
288492a19a0SVikas Gupta 		break;
289492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA3_384_HMAC:
290492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA3_384;
291492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_HMAC;
292492a19a0SVikas Gupta 		break;
293492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA3_512:
294492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA3_512;
295492a19a0SVikas Gupta 		break;
296492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_SHA3_512_HMAC:
297492a19a0SVikas Gupta 		*spu2_type = SPU2_HASH_TYPE_SHA3_512;
298492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_HMAC;
299492a19a0SVikas Gupta 		break;
300492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
301492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_XCBC_MAC;
302492a19a0SVikas Gupta 		switch (fsattr_sz(key)) {
303492a19a0SVikas Gupta 		case BCMFS_CRYPTO_AES128:
304492a19a0SVikas Gupta 			*spu2_type = SPU2_HASH_TYPE_AES128;
305492a19a0SVikas Gupta 			break;
306492a19a0SVikas Gupta 		case BCMFS_CRYPTO_AES192:
307492a19a0SVikas Gupta 			*spu2_type = SPU2_HASH_TYPE_AES192;
308492a19a0SVikas Gupta 			break;
309492a19a0SVikas Gupta 		case BCMFS_CRYPTO_AES256:
310492a19a0SVikas Gupta 			*spu2_type = SPU2_HASH_TYPE_AES256;
311492a19a0SVikas Gupta 			break;
312492a19a0SVikas Gupta 		default:
313492a19a0SVikas Gupta 			return -EINVAL;
314492a19a0SVikas Gupta 		}
315492a19a0SVikas Gupta 		break;
316492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_AES_CMAC:
317492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_CMAC;
318492a19a0SVikas Gupta 		switch (fsattr_sz(key)) {
319492a19a0SVikas Gupta 		case BCMFS_CRYPTO_AES128:
320492a19a0SVikas Gupta 			*spu2_type = SPU2_HASH_TYPE_AES128;
321492a19a0SVikas Gupta 			break;
322492a19a0SVikas Gupta 		case BCMFS_CRYPTO_AES192:
323492a19a0SVikas Gupta 			*spu2_type = SPU2_HASH_TYPE_AES192;
324492a19a0SVikas Gupta 			break;
325492a19a0SVikas Gupta 		case BCMFS_CRYPTO_AES256:
326492a19a0SVikas Gupta 			*spu2_type = SPU2_HASH_TYPE_AES256;
327492a19a0SVikas Gupta 			break;
328492a19a0SVikas Gupta 		default:
329492a19a0SVikas Gupta 			return -EINVAL;
330492a19a0SVikas Gupta 		}
331492a19a0SVikas Gupta 		break;
332492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_AES_GMAC:
333492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_GCM;
334492a19a0SVikas Gupta 		switch (fsattr_sz(key)) {
335492a19a0SVikas Gupta 		case BCMFS_CRYPTO_AES128:
336492a19a0SVikas Gupta 			*spu2_type = SPU2_HASH_TYPE_AES128;
337492a19a0SVikas Gupta 			break;
338492a19a0SVikas Gupta 		case BCMFS_CRYPTO_AES192:
339492a19a0SVikas Gupta 			*spu2_type = SPU2_HASH_TYPE_AES192;
340492a19a0SVikas Gupta 			break;
341492a19a0SVikas Gupta 		case BCMFS_CRYPTO_AES256:
342492a19a0SVikas Gupta 			*spu2_type = SPU2_HASH_TYPE_AES256;
343492a19a0SVikas Gupta 			break;
344492a19a0SVikas Gupta 		default:
345492a19a0SVikas Gupta 			return -EINVAL;
346492a19a0SVikas Gupta 		}
347492a19a0SVikas Gupta 		break;
348492a19a0SVikas Gupta 	case RTE_CRYPTO_AUTH_AES_CBC_MAC:
349492a19a0SVikas Gupta 		*spu2_mode = SPU2_HASH_MODE_CBC_MAC;
350492a19a0SVikas Gupta 		switch (fsattr_sz(key)) {
351492a19a0SVikas Gupta 		case BCMFS_CRYPTO_AES128:
352492a19a0SVikas Gupta 			*spu2_type = SPU2_HASH_TYPE_AES128;
353492a19a0SVikas Gupta 			break;
354492a19a0SVikas Gupta 		case BCMFS_CRYPTO_AES192:
355492a19a0SVikas Gupta 			*spu2_type = SPU2_HASH_TYPE_AES192;
356492a19a0SVikas Gupta 			break;
357492a19a0SVikas Gupta 		case BCMFS_CRYPTO_AES256:
358492a19a0SVikas Gupta 			*spu2_type = SPU2_HASH_TYPE_AES256;
359492a19a0SVikas Gupta 			break;
360492a19a0SVikas Gupta 		default:
361492a19a0SVikas Gupta 			return -EINVAL;
362492a19a0SVikas Gupta 		}
363492a19a0SVikas Gupta 		break;
364492a19a0SVikas Gupta 	default:
365492a19a0SVikas Gupta 		return -EINVAL;
366492a19a0SVikas Gupta 	}
367492a19a0SVikas Gupta 
368492a19a0SVikas Gupta 	return 0;
369492a19a0SVikas Gupta }
370492a19a0SVikas Gupta 
371492a19a0SVikas Gupta static int
spu2_cipher_xlate(enum rte_crypto_cipher_algorithm cipher_alg,struct fsattr * key,enum spu2_cipher_type * spu2_type,enum spu2_cipher_mode * spu2_mode)372492a19a0SVikas Gupta spu2_cipher_xlate(enum rte_crypto_cipher_algorithm cipher_alg,
373492a19a0SVikas Gupta 		  struct fsattr *key,
374492a19a0SVikas Gupta 		  enum spu2_cipher_type *spu2_type,
375492a19a0SVikas Gupta 		  enum spu2_cipher_mode *spu2_mode)
376492a19a0SVikas Gupta {
377492a19a0SVikas Gupta 	int ret = 0;
378492a19a0SVikas Gupta 
379492a19a0SVikas Gupta 	switch (cipher_alg) {
380492a19a0SVikas Gupta 	case RTE_CRYPTO_CIPHER_NULL:
381492a19a0SVikas Gupta 		*spu2_type = SPU2_CIPHER_TYPE_NONE;
382492a19a0SVikas Gupta 		break;
383492a19a0SVikas Gupta 	case RTE_CRYPTO_CIPHER_DES_CBC:
384492a19a0SVikas Gupta 		*spu2_mode =  SPU2_CIPHER_MODE_CBC;
385492a19a0SVikas Gupta 		*spu2_type = SPU2_CIPHER_TYPE_DES;
386492a19a0SVikas Gupta 		break;
387492a19a0SVikas Gupta 	case RTE_CRYPTO_CIPHER_3DES_ECB:
388492a19a0SVikas Gupta 		*spu2_mode =  SPU2_CIPHER_MODE_ECB;
389492a19a0SVikas Gupta 		*spu2_type = SPU2_CIPHER_TYPE_3DES;
390492a19a0SVikas Gupta 		break;
391492a19a0SVikas Gupta 	case RTE_CRYPTO_CIPHER_3DES_CBC:
392492a19a0SVikas Gupta 		*spu2_mode =  SPU2_CIPHER_MODE_CBC;
393492a19a0SVikas Gupta 		*spu2_type = SPU2_CIPHER_TYPE_3DES;
394492a19a0SVikas Gupta 		break;
395492a19a0SVikas Gupta 	case RTE_CRYPTO_CIPHER_AES_CBC:
396492a19a0SVikas Gupta 		*spu2_mode =  SPU2_CIPHER_MODE_CBC;
397492a19a0SVikas Gupta 		ret = spu2_cipher_type_xlate(cipher_alg, spu2_type, key);
398492a19a0SVikas Gupta 		break;
399492a19a0SVikas Gupta 	case RTE_CRYPTO_CIPHER_AES_ECB:
400492a19a0SVikas Gupta 		*spu2_mode =  SPU2_CIPHER_MODE_ECB;
401492a19a0SVikas Gupta 		ret = spu2_cipher_type_xlate(cipher_alg, spu2_type, key);
402492a19a0SVikas Gupta 		break;
403492a19a0SVikas Gupta 	case RTE_CRYPTO_CIPHER_AES_CTR:
404492a19a0SVikas Gupta 		*spu2_mode =  SPU2_CIPHER_MODE_CTR;
405492a19a0SVikas Gupta 		ret = spu2_cipher_type_xlate(cipher_alg, spu2_type, key);
406492a19a0SVikas Gupta 		break;
407492a19a0SVikas Gupta 	case RTE_CRYPTO_CIPHER_AES_XTS:
408492a19a0SVikas Gupta 		*spu2_mode =  SPU2_CIPHER_MODE_XTS;
409492a19a0SVikas Gupta 		ret = spu2_cipher_type_xlate(cipher_alg, spu2_type, key);
410492a19a0SVikas Gupta 		break;
411492a19a0SVikas Gupta 	default:
412492a19a0SVikas Gupta 		return -EINVAL;
413492a19a0SVikas Gupta 	}
414492a19a0SVikas Gupta 
415492a19a0SVikas Gupta 	return ret;
416492a19a0SVikas Gupta }
417492a19a0SVikas Gupta 
418492a19a0SVikas Gupta static void
spu2_fmd_ctrl0_write(struct spu2_fmd * fmd,bool is_inbound,bool auth_first,enum spu2_proto_sel protocol,enum spu2_cipher_type cipher_type,enum spu2_cipher_mode cipher_mode,enum spu2_hash_type auth_type,enum spu2_hash_mode auth_mode)419492a19a0SVikas Gupta spu2_fmd_ctrl0_write(struct spu2_fmd *fmd,
420492a19a0SVikas Gupta 		     bool is_inbound, bool auth_first,
421492a19a0SVikas Gupta 		     enum spu2_proto_sel protocol,
422492a19a0SVikas Gupta 		     enum spu2_cipher_type cipher_type,
423492a19a0SVikas Gupta 		     enum spu2_cipher_mode cipher_mode,
424492a19a0SVikas Gupta 		     enum spu2_hash_type auth_type,
425492a19a0SVikas Gupta 		     enum spu2_hash_mode auth_mode)
426492a19a0SVikas Gupta {
427492a19a0SVikas Gupta 	uint64_t ctrl0 = 0;
428492a19a0SVikas Gupta 
429492a19a0SVikas Gupta 	if (cipher_type != SPU2_CIPHER_TYPE_NONE && !is_inbound)
430492a19a0SVikas Gupta 		ctrl0 |= SPU2_CIPH_ENCRYPT_EN;
431492a19a0SVikas Gupta 
432492a19a0SVikas Gupta 	ctrl0 |= ((uint64_t)cipher_type << SPU2_CIPH_TYPE_SHIFT) |
433492a19a0SVikas Gupta 		  ((uint64_t)cipher_mode << SPU2_CIPH_MODE_SHIFT);
434492a19a0SVikas Gupta 
435492a19a0SVikas Gupta 	if (protocol != SPU2_PROTO_RESV)
436492a19a0SVikas Gupta 		ctrl0 |= (uint64_t)protocol << SPU2_PROTO_SEL_SHIFT;
437492a19a0SVikas Gupta 
438492a19a0SVikas Gupta 	if (auth_first)
439492a19a0SVikas Gupta 		ctrl0 |= SPU2_HASH_FIRST;
440492a19a0SVikas Gupta 
441492a19a0SVikas Gupta 	if (is_inbound && auth_type != SPU2_HASH_TYPE_NONE)
442492a19a0SVikas Gupta 		ctrl0 |= SPU2_CHK_TAG;
443492a19a0SVikas Gupta 
444492a19a0SVikas Gupta 	ctrl0 |= (((uint64_t)auth_type << SPU2_HASH_TYPE_SHIFT) |
445492a19a0SVikas Gupta 		  ((uint64_t)auth_mode << SPU2_HASH_MODE_SHIFT));
446492a19a0SVikas Gupta 
447492a19a0SVikas Gupta 	fmd->ctrl0 = ctrl0;
448492a19a0SVikas Gupta 
449492a19a0SVikas Gupta #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
450492a19a0SVikas Gupta 	BCMFS_DP_HEXDUMP_LOG(DEBUG, "ctrl0:", &fmd->ctrl0, sizeof(uint64_t));
451492a19a0SVikas Gupta #endif
452492a19a0SVikas Gupta }
453492a19a0SVikas Gupta 
454492a19a0SVikas Gupta static void
spu2_fmd_ctrl1_write(struct spu2_fmd * fmd,bool is_inbound,uint64_t assoc_size,uint64_t auth_key_len,uint64_t cipher_key_len,bool gen_iv,bool hash_iv,bool return_iv,uint64_t ret_iv_len,uint64_t ret_iv_offset,uint64_t cipher_iv_len,uint64_t digest_size,bool return_payload,bool return_md)455492a19a0SVikas Gupta spu2_fmd_ctrl1_write(struct spu2_fmd *fmd, bool is_inbound,
456492a19a0SVikas Gupta 		     uint64_t assoc_size, uint64_t auth_key_len,
457492a19a0SVikas Gupta 		     uint64_t cipher_key_len, bool gen_iv, bool hash_iv,
458492a19a0SVikas Gupta 		     bool return_iv, uint64_t ret_iv_len,
459492a19a0SVikas Gupta 		     uint64_t ret_iv_offset, uint64_t cipher_iv_len,
460492a19a0SVikas Gupta 		     uint64_t digest_size, bool return_payload, bool return_md)
461492a19a0SVikas Gupta {
462492a19a0SVikas Gupta 	uint64_t ctrl1 = 0;
463492a19a0SVikas Gupta 
464492a19a0SVikas Gupta 	if (is_inbound && digest_size != 0)
465492a19a0SVikas Gupta 		ctrl1 |= SPU2_TAG_LOC;
466492a19a0SVikas Gupta 
467492a19a0SVikas Gupta 	if (assoc_size != 0)
468492a19a0SVikas Gupta 		ctrl1 |= SPU2_HAS_AAD2;
469492a19a0SVikas Gupta 
470492a19a0SVikas Gupta 	if (auth_key_len != 0)
471492a19a0SVikas Gupta 		ctrl1 |= ((auth_key_len << SPU2_HASH_KEY_LEN_SHIFT) &
472492a19a0SVikas Gupta 			  SPU2_HASH_KEY_LEN);
473492a19a0SVikas Gupta 
474492a19a0SVikas Gupta 	if (cipher_key_len != 0)
475492a19a0SVikas Gupta 		ctrl1 |= ((cipher_key_len << SPU2_CIPH_KEY_LEN_SHIFT) &
476492a19a0SVikas Gupta 			  SPU2_CIPH_KEY_LEN);
477492a19a0SVikas Gupta 
478492a19a0SVikas Gupta 	if (gen_iv)
479492a19a0SVikas Gupta 		ctrl1 |= SPU2_GENIV;
480492a19a0SVikas Gupta 
481492a19a0SVikas Gupta 	if (hash_iv)
482492a19a0SVikas Gupta 		ctrl1 |= SPU2_HASH_IV;
483492a19a0SVikas Gupta 
484492a19a0SVikas Gupta 	if (return_iv) {
485492a19a0SVikas Gupta 		ctrl1 |= SPU2_RET_IV;
486492a19a0SVikas Gupta 		ctrl1 |= ret_iv_len << SPU2_RET_IV_LEN_SHIFT;
487492a19a0SVikas Gupta 		ctrl1 |= ret_iv_offset << SPU2_IV_OFFSET_SHIFT;
488492a19a0SVikas Gupta 	}
489492a19a0SVikas Gupta 
490492a19a0SVikas Gupta 	ctrl1 |= ((cipher_iv_len << SPU2_IV_LEN_SHIFT) & SPU2_IV_LEN);
491492a19a0SVikas Gupta 
492492a19a0SVikas Gupta 	if (digest_size != 0) {
493492a19a0SVikas Gupta 		ctrl1 |= ((digest_size << SPU2_HASH_TAG_LEN_SHIFT) &
494492a19a0SVikas Gupta 			  SPU2_HASH_TAG_LEN);
495492a19a0SVikas Gupta 	}
496492a19a0SVikas Gupta 
497492a19a0SVikas Gupta 	/*
498492a19a0SVikas Gupta 	 * Let's ask for the output pkt to include FMD, but don't need to
499492a19a0SVikas Gupta 	 * get keys and IVs back in OMD.
500492a19a0SVikas Gupta 	 */
501492a19a0SVikas Gupta 	if (return_md)
502492a19a0SVikas Gupta 		ctrl1 |= ((uint64_t)SPU2_RET_FMD_ONLY << SPU2_RETURN_MD_SHIFT);
503492a19a0SVikas Gupta 	else
504492a19a0SVikas Gupta 		ctrl1 |= ((uint64_t)SPU2_RET_NO_MD << SPU2_RETURN_MD_SHIFT);
505492a19a0SVikas Gupta 
506492a19a0SVikas Gupta 	/* Crypto API does not get assoc data back. So no need for AAD2. */
507492a19a0SVikas Gupta 
508492a19a0SVikas Gupta 	if (return_payload)
509492a19a0SVikas Gupta 		ctrl1 |= SPU2_RETURN_PAY;
510492a19a0SVikas Gupta 
511492a19a0SVikas Gupta 	fmd->ctrl1 = ctrl1;
512492a19a0SVikas Gupta 
513492a19a0SVikas Gupta #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
514492a19a0SVikas Gupta 	BCMFS_DP_HEXDUMP_LOG(DEBUG, "ctrl1:", &fmd->ctrl1, sizeof(uint64_t));
515492a19a0SVikas Gupta #endif
516492a19a0SVikas Gupta }
517492a19a0SVikas Gupta 
518492a19a0SVikas Gupta static void
spu2_fmd_ctrl2_write(struct spu2_fmd * fmd,uint64_t cipher_offset,uint64_t auth_key_len __rte_unused,uint64_t auth_iv_len __rte_unused,uint64_t cipher_key_len __rte_unused,uint64_t cipher_iv_len __rte_unused)519492a19a0SVikas Gupta spu2_fmd_ctrl2_write(struct spu2_fmd *fmd, uint64_t cipher_offset,
520492a19a0SVikas Gupta 		     uint64_t auth_key_len __rte_unused,
521492a19a0SVikas Gupta 		     uint64_t auth_iv_len  __rte_unused,
522492a19a0SVikas Gupta 		     uint64_t cipher_key_len  __rte_unused,
523492a19a0SVikas Gupta 		     uint64_t cipher_iv_len  __rte_unused)
524492a19a0SVikas Gupta {
525492a19a0SVikas Gupta 	uint64_t aad1_offset;
526492a19a0SVikas Gupta 	uint64_t aad2_offset;
527492a19a0SVikas Gupta 	uint16_t aad1_len = 0;
528492a19a0SVikas Gupta 	uint64_t payload_offset;
529492a19a0SVikas Gupta 
530492a19a0SVikas Gupta 	/* AAD1 offset is from start of FD. FD length always 0. */
531492a19a0SVikas Gupta 	aad1_offset = 0;
532492a19a0SVikas Gupta 
533492a19a0SVikas Gupta 	aad2_offset = aad1_offset;
534492a19a0SVikas Gupta 	payload_offset = cipher_offset;
535492a19a0SVikas Gupta 	fmd->ctrl2 = aad1_offset |
536492a19a0SVikas Gupta 		     (aad1_len << SPU2_AAD1_LEN_SHIFT) |
537492a19a0SVikas Gupta 		     (aad2_offset << SPU2_AAD2_OFFSET_SHIFT) |
538492a19a0SVikas Gupta 		     (payload_offset << SPU2_PL_OFFSET_SHIFT);
539492a19a0SVikas Gupta 
540492a19a0SVikas Gupta #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
541492a19a0SVikas Gupta 	BCMFS_DP_HEXDUMP_LOG(DEBUG, "ctrl2:", &fmd->ctrl2, sizeof(uint64_t));
542492a19a0SVikas Gupta #endif
543492a19a0SVikas Gupta }
544492a19a0SVikas Gupta 
545492a19a0SVikas Gupta static void
spu2_fmd_ctrl3_write(struct spu2_fmd * fmd,uint64_t payload_len)546492a19a0SVikas Gupta spu2_fmd_ctrl3_write(struct spu2_fmd *fmd, uint64_t payload_len)
547492a19a0SVikas Gupta {
548492a19a0SVikas Gupta 	fmd->ctrl3 = payload_len & SPU2_PL_LEN;
549492a19a0SVikas Gupta 
550492a19a0SVikas Gupta #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
551492a19a0SVikas Gupta 	BCMFS_DP_HEXDUMP_LOG(DEBUG, "ctrl3:", &fmd->ctrl3, sizeof(uint64_t));
552492a19a0SVikas Gupta #endif
553492a19a0SVikas Gupta }
554492a19a0SVikas Gupta 
555492a19a0SVikas Gupta int
bcmfs_crypto_build_auth_req(struct bcmfs_sym_request * sreq,enum rte_crypto_auth_algorithm a_alg,enum rte_crypto_auth_operation auth_op,struct fsattr * src,struct fsattr * dst,struct fsattr * mac,struct fsattr * auth_key,struct fsattr * iv)556492a19a0SVikas Gupta bcmfs_crypto_build_auth_req(struct bcmfs_sym_request *sreq,
557492a19a0SVikas Gupta 			    enum rte_crypto_auth_algorithm a_alg,
558492a19a0SVikas Gupta 			    enum rte_crypto_auth_operation auth_op,
559492a19a0SVikas Gupta 			    struct fsattr *src, struct fsattr *dst,
560492a19a0SVikas Gupta 			    struct fsattr *mac, struct fsattr *auth_key,
561492a19a0SVikas Gupta 			    struct fsattr *iv)
562492a19a0SVikas Gupta {
563492a19a0SVikas Gupta 	int ret;
564492a19a0SVikas Gupta 	uint64_t dst_size;
565492a19a0SVikas Gupta 	int src_index = 0;
566492a19a0SVikas Gupta 	struct spu2_fmd *fmd;
567492a19a0SVikas Gupta 	uint64_t payload_len;
568*cd5db556SVikas Gupta 	uint32_t src_msg_len = 0;
569492a19a0SVikas Gupta 	enum spu2_hash_mode spu2_auth_mode;
570492a19a0SVikas Gupta 	enum spu2_hash_type spu2_auth_type = SPU2_HASH_TYPE_NONE;
571492a19a0SVikas Gupta 	uint64_t iv_size = (iv != NULL) ? fsattr_sz(iv) : 0;
572492a19a0SVikas Gupta 	uint64_t auth_ksize = (auth_key != NULL) ? fsattr_sz(auth_key) : 0;
573492a19a0SVikas Gupta 	bool is_inbound = (auth_op == RTE_CRYPTO_AUTH_OP_VERIFY);
574492a19a0SVikas Gupta 
575492a19a0SVikas Gupta 	if (src == NULL)
576492a19a0SVikas Gupta 		return -EINVAL;
577492a19a0SVikas Gupta 
578492a19a0SVikas Gupta 	payload_len = fsattr_sz(src);
579492a19a0SVikas Gupta 	if (!payload_len) {
580492a19a0SVikas Gupta 		BCMFS_DP_LOG(ERR, "null payload not supported");
581492a19a0SVikas Gupta 		return -EINVAL;
582492a19a0SVikas Gupta 	}
583492a19a0SVikas Gupta 
584492a19a0SVikas Gupta 	/* one of dst or mac should not be NULL */
585492a19a0SVikas Gupta 	if (dst == NULL && mac == NULL)
586492a19a0SVikas Gupta 		return -EINVAL;
587492a19a0SVikas Gupta 
588492a19a0SVikas Gupta 	if (auth_op == RTE_CRYPTO_AUTH_OP_GENERATE && dst != NULL)
589492a19a0SVikas Gupta 		dst_size = fsattr_sz(dst);
590492a19a0SVikas Gupta 	else if (auth_op == RTE_CRYPTO_AUTH_OP_VERIFY && mac != NULL)
591492a19a0SVikas Gupta 		dst_size = fsattr_sz(mac);
592492a19a0SVikas Gupta 	else
593492a19a0SVikas Gupta 		return -EINVAL;
594492a19a0SVikas Gupta 
595492a19a0SVikas Gupta 	/* spu2 hash algorithm and hash algorithm mode */
596492a19a0SVikas Gupta 	ret = spu2_hash_xlate(a_alg, auth_key, &spu2_auth_type,
597492a19a0SVikas Gupta 			      &spu2_auth_mode);
598492a19a0SVikas Gupta 	if (ret)
599492a19a0SVikas Gupta 		return -EINVAL;
600492a19a0SVikas Gupta 
601492a19a0SVikas Gupta 	fmd  = &sreq->fmd;
602492a19a0SVikas Gupta 
603492a19a0SVikas Gupta 	spu2_fmd_ctrl0_write(fmd, is_inbound, SPU2_VAL_NONE,
604492a19a0SVikas Gupta 			     SPU2_PROTO_RESV, SPU2_VAL_NONE,
605492a19a0SVikas Gupta 			     SPU2_VAL_NONE, spu2_auth_type, spu2_auth_mode);
606492a19a0SVikas Gupta 
607492a19a0SVikas Gupta 	spu2_fmd_ctrl1_write(fmd, is_inbound, SPU2_VAL_NONE,
608492a19a0SVikas Gupta 			     auth_ksize, SPU2_VAL_NONE, false,
609492a19a0SVikas Gupta 			     false, SPU2_VAL_NONE, SPU2_VAL_NONE,
610492a19a0SVikas Gupta 			     SPU2_VAL_NONE, iv_size,
611492a19a0SVikas Gupta 			     dst_size, SPU2_VAL_NONE, SPU2_VAL_NONE);
612492a19a0SVikas Gupta 
613492a19a0SVikas Gupta 	memset(&fmd->ctrl2, 0, sizeof(uint64_t));
614492a19a0SVikas Gupta 
615492a19a0SVikas Gupta 	spu2_fmd_ctrl3_write(fmd, fsattr_sz(src));
616492a19a0SVikas Gupta 
617*cd5db556SVikas Gupta 	/* FMD */
618492a19a0SVikas Gupta 	sreq->msgs.srcs_addr[src_index] = sreq->fptr;
619*cd5db556SVikas Gupta 	src_msg_len += sizeof(*fmd);
620492a19a0SVikas Gupta 
621*cd5db556SVikas Gupta 	/* Start of OMD */
622*cd5db556SVikas Gupta 	if (auth_ksize != 0) {
623*cd5db556SVikas Gupta 		memcpy((uint8_t *)fmd + src_msg_len, fsattr_va(auth_key),
624*cd5db556SVikas Gupta 		       auth_ksize);
625*cd5db556SVikas Gupta 		src_msg_len += auth_ksize;
626492a19a0SVikas Gupta 	}
627492a19a0SVikas Gupta 
628*cd5db556SVikas Gupta 	if (iv_size != 0) {
629*cd5db556SVikas Gupta 		memcpy((uint8_t *)fmd + src_msg_len, fsattr_va(iv),
630*cd5db556SVikas Gupta 		       iv_size);
631*cd5db556SVikas Gupta 		src_msg_len += iv_size;
632*cd5db556SVikas Gupta 	} /* End of OMD */
633*cd5db556SVikas Gupta 
634*cd5db556SVikas Gupta 	sreq->msgs.srcs_len[src_index] = src_msg_len;
635492a19a0SVikas Gupta 	src_index++;
636492a19a0SVikas Gupta 
637492a19a0SVikas Gupta 	sreq->msgs.srcs_addr[src_index] = fsattr_pa(src);
638492a19a0SVikas Gupta 	sreq->msgs.srcs_len[src_index] = fsattr_sz(src);
639492a19a0SVikas Gupta 	src_index++;
640492a19a0SVikas Gupta 
641492a19a0SVikas Gupta 	/*
642492a19a0SVikas Gupta 	 * In case of authentication verify operation, use input mac data to
643492a19a0SVikas Gupta 	 * SPU2 engine.
644492a19a0SVikas Gupta 	 */
645492a19a0SVikas Gupta 	if (auth_op == RTE_CRYPTO_AUTH_OP_VERIFY && mac != NULL) {
646492a19a0SVikas Gupta 		sreq->msgs.srcs_addr[src_index] = fsattr_pa(mac);
647492a19a0SVikas Gupta 		sreq->msgs.srcs_len[src_index] = fsattr_sz(mac);
648492a19a0SVikas Gupta 		src_index++;
649492a19a0SVikas Gupta 	}
650492a19a0SVikas Gupta 	sreq->msgs.srcs_count = src_index;
651492a19a0SVikas Gupta 
652492a19a0SVikas Gupta 	/*
653492a19a0SVikas Gupta 	 * Output packet contains actual output from SPU2 and
654492a19a0SVikas Gupta 	 * the status packet, so the dsts_count is always 2  below.
655492a19a0SVikas Gupta 	 */
656492a19a0SVikas Gupta 	if (auth_op == RTE_CRYPTO_AUTH_OP_GENERATE) {
657492a19a0SVikas Gupta 		sreq->msgs.dsts_addr[0] = fsattr_pa(dst);
658492a19a0SVikas Gupta 		sreq->msgs.dsts_len[0] = fsattr_sz(dst);
659492a19a0SVikas Gupta 	} else {
660492a19a0SVikas Gupta 		/*
661492a19a0SVikas Gupta 		 * In case of authentication verify operation, provide dummy
662492a19a0SVikas Gupta 		 * location to SPU2 engine to generate hash. This is needed
663492a19a0SVikas Gupta 		 * because SPU2 generates hash even in case of verify operation.
664492a19a0SVikas Gupta 		 */
665492a19a0SVikas Gupta 		sreq->msgs.dsts_addr[0] = sreq->dptr;
666492a19a0SVikas Gupta 		sreq->msgs.dsts_len[0] = fsattr_sz(mac);
667492a19a0SVikas Gupta 	}
668492a19a0SVikas Gupta 
669492a19a0SVikas Gupta 	sreq->msgs.dsts_addr[1] = sreq->rptr;
670492a19a0SVikas Gupta 	sreq->msgs.dsts_len[1] = SPU2_STATUS_LEN;
671492a19a0SVikas Gupta 	sreq->msgs.dsts_count = 2;
672492a19a0SVikas Gupta 
673492a19a0SVikas Gupta 	return 0;
674492a19a0SVikas Gupta }
675492a19a0SVikas Gupta 
676492a19a0SVikas Gupta int
bcmfs_crypto_build_cipher_req(struct bcmfs_sym_request * sreq,enum rte_crypto_cipher_algorithm calgo,enum rte_crypto_cipher_operation cipher_op,struct fsattr * src,struct fsattr * dst,struct fsattr * cipher_key,struct fsattr * iv)677492a19a0SVikas Gupta bcmfs_crypto_build_cipher_req(struct bcmfs_sym_request *sreq,
678492a19a0SVikas Gupta 			      enum rte_crypto_cipher_algorithm calgo,
679492a19a0SVikas Gupta 			      enum rte_crypto_cipher_operation cipher_op,
680492a19a0SVikas Gupta 			      struct fsattr *src, struct fsattr *dst,
681492a19a0SVikas Gupta 			      struct fsattr *cipher_key, struct fsattr *iv)
682492a19a0SVikas Gupta {
683492a19a0SVikas Gupta 	int ret = 0;
684492a19a0SVikas Gupta 	int src_index = 0;
685492a19a0SVikas Gupta 	struct spu2_fmd *fmd;
686*cd5db556SVikas Gupta 	uint32_t src_msg_len = 0;
687492a19a0SVikas Gupta 	enum spu2_cipher_mode spu2_ciph_mode = 0;
688492a19a0SVikas Gupta 	enum spu2_cipher_type spu2_ciph_type = SPU2_CIPHER_TYPE_NONE;
689492a19a0SVikas Gupta 	bool is_inbound = (cipher_op == RTE_CRYPTO_CIPHER_OP_DECRYPT);
690492a19a0SVikas Gupta 
691492a19a0SVikas Gupta 	if (src == NULL || dst == NULL || iv == NULL)
692492a19a0SVikas Gupta 		return -EINVAL;
693492a19a0SVikas Gupta 
694492a19a0SVikas Gupta 	fmd  = &sreq->fmd;
695492a19a0SVikas Gupta 
696492a19a0SVikas Gupta 	/* spu2 cipher algorithm and cipher algorithm mode */
697492a19a0SVikas Gupta 	ret = spu2_cipher_xlate(calgo, cipher_key,
698492a19a0SVikas Gupta 				&spu2_ciph_type, &spu2_ciph_mode);
699492a19a0SVikas Gupta 	if (ret)
700492a19a0SVikas Gupta 		return -EINVAL;
701492a19a0SVikas Gupta 
702492a19a0SVikas Gupta 	spu2_fmd_ctrl0_write(fmd, is_inbound, SPU2_VAL_NONE,
703492a19a0SVikas Gupta 			     SPU2_PROTO_RESV, spu2_ciph_type, spu2_ciph_mode,
704492a19a0SVikas Gupta 			     SPU2_VAL_NONE, SPU2_VAL_NONE);
705492a19a0SVikas Gupta 
706492a19a0SVikas Gupta 	spu2_fmd_ctrl1_write(fmd, SPU2_VAL_NONE, SPU2_VAL_NONE, SPU2_VAL_NONE,
707492a19a0SVikas Gupta 			     fsattr_sz(cipher_key), false, false,
708492a19a0SVikas Gupta 			     SPU2_VAL_NONE, SPU2_VAL_NONE, SPU2_VAL_NONE,
709492a19a0SVikas Gupta 			     fsattr_sz(iv), SPU2_VAL_NONE, SPU2_VAL_NONE,
710492a19a0SVikas Gupta 			     SPU2_VAL_NONE);
711492a19a0SVikas Gupta 
712492a19a0SVikas Gupta 	/* Nothing for FMD2 */
713492a19a0SVikas Gupta 	memset(&fmd->ctrl2, 0, sizeof(uint64_t));
714492a19a0SVikas Gupta 
715492a19a0SVikas Gupta 	spu2_fmd_ctrl3_write(fmd, fsattr_sz(src));
716492a19a0SVikas Gupta 
717*cd5db556SVikas Gupta 	/* FMD */
718492a19a0SVikas Gupta 	sreq->msgs.srcs_addr[src_index] = sreq->fptr;
719*cd5db556SVikas Gupta 	src_msg_len += sizeof(*fmd);
720492a19a0SVikas Gupta 
721*cd5db556SVikas Gupta 	/* Start of OMD */
722492a19a0SVikas Gupta 	if (cipher_key != NULL && fsattr_sz(cipher_key) != 0) {
723*cd5db556SVikas Gupta 		uint8_t *cipher_buf = (uint8_t *)fmd + src_msg_len;
724492a19a0SVikas Gupta 		if (calgo == RTE_CRYPTO_CIPHER_AES_XTS) {
725*cd5db556SVikas Gupta 			uint32_t xts_keylen = fsattr_sz(cipher_key) / 2;
726*cd5db556SVikas Gupta 			memcpy(cipher_buf,
727492a19a0SVikas Gupta 			       (uint8_t *)fsattr_va(cipher_key) + xts_keylen,
728492a19a0SVikas Gupta 			       xts_keylen);
729*cd5db556SVikas Gupta 			memcpy(cipher_buf + xts_keylen,
730492a19a0SVikas Gupta 			       fsattr_va(cipher_key), xts_keylen);
731492a19a0SVikas Gupta 		} else {
732*cd5db556SVikas Gupta 			memcpy(cipher_buf, fsattr_va(cipher_key),
733*cd5db556SVikas Gupta 			       fsattr_sz(cipher_key));
734492a19a0SVikas Gupta 		}
735492a19a0SVikas Gupta 
736*cd5db556SVikas Gupta 		src_msg_len += fsattr_sz(cipher_key);
737492a19a0SVikas Gupta 	}
738492a19a0SVikas Gupta 
739492a19a0SVikas Gupta 	if (iv != NULL && fsattr_sz(iv) != 0) {
740*cd5db556SVikas Gupta 		memcpy((uint8_t *)fmd + src_msg_len,
741492a19a0SVikas Gupta 		       fsattr_va(iv), fsattr_sz(iv));
742*cd5db556SVikas Gupta 		src_msg_len +=  fsattr_sz(iv);
743*cd5db556SVikas Gupta 	} /* End of OMD */
744*cd5db556SVikas Gupta 
745*cd5db556SVikas Gupta 	sreq->msgs.srcs_len[src_index] = src_msg_len;
746492a19a0SVikas Gupta 	src_index++;
747492a19a0SVikas Gupta 
748492a19a0SVikas Gupta 	sreq->msgs.srcs_addr[src_index] = fsattr_pa(src);
749492a19a0SVikas Gupta 	sreq->msgs.srcs_len[src_index] = fsattr_sz(src);
750492a19a0SVikas Gupta 	src_index++;
751492a19a0SVikas Gupta 	sreq->msgs.srcs_count = src_index;
752492a19a0SVikas Gupta 
753492a19a0SVikas Gupta 	/**
754492a19a0SVikas Gupta 	 * Output packet contains actual output from SPU2 and
755492a19a0SVikas Gupta 	 * the status packet, so the dsts_count is always 2  below.
756492a19a0SVikas Gupta 	 */
757492a19a0SVikas Gupta 	sreq->msgs.dsts_addr[0] = fsattr_pa(dst);
758492a19a0SVikas Gupta 	sreq->msgs.dsts_len[0] = fsattr_sz(dst);
759492a19a0SVikas Gupta 
760492a19a0SVikas Gupta 	sreq->msgs.dsts_addr[1] = sreq->rptr;
761492a19a0SVikas Gupta 	sreq->msgs.dsts_len[1] = SPU2_STATUS_LEN;
762492a19a0SVikas Gupta 	sreq->msgs.dsts_count = 2;
763492a19a0SVikas Gupta 
764492a19a0SVikas Gupta 	return 0;
765492a19a0SVikas Gupta }
766492a19a0SVikas Gupta 
767492a19a0SVikas Gupta int
bcmfs_crypto_build_chain_request(struct bcmfs_sym_request * sreq,enum rte_crypto_cipher_algorithm cipher_alg,enum rte_crypto_cipher_operation cipher_op __rte_unused,enum rte_crypto_auth_algorithm auth_alg,enum rte_crypto_auth_operation auth_op,struct fsattr * src,struct fsattr * dst,struct fsattr * cipher_key,struct fsattr * auth_key,struct fsattr * iv,struct fsattr * aad,struct fsattr * digest,bool cipher_first)768492a19a0SVikas Gupta bcmfs_crypto_build_chain_request(struct bcmfs_sym_request *sreq,
769492a19a0SVikas Gupta 				 enum rte_crypto_cipher_algorithm cipher_alg,
770492a19a0SVikas Gupta 				 enum rte_crypto_cipher_operation cipher_op __rte_unused,
771492a19a0SVikas Gupta 				 enum rte_crypto_auth_algorithm auth_alg,
772492a19a0SVikas Gupta 				 enum rte_crypto_auth_operation auth_op,
773492a19a0SVikas Gupta 				 struct fsattr *src, struct fsattr *dst,
774492a19a0SVikas Gupta 				 struct fsattr *cipher_key,
775492a19a0SVikas Gupta 				 struct fsattr *auth_key,
776492a19a0SVikas Gupta 				 struct fsattr *iv, struct fsattr *aad,
777492a19a0SVikas Gupta 				 struct fsattr *digest, bool cipher_first)
778492a19a0SVikas Gupta {
779492a19a0SVikas Gupta 	int ret = 0;
780492a19a0SVikas Gupta 	int src_index = 0;
781492a19a0SVikas Gupta 	int dst_index = 0;
782492a19a0SVikas Gupta 	bool auth_first = 0;
783492a19a0SVikas Gupta 	struct spu2_fmd *fmd;
784492a19a0SVikas Gupta 	uint64_t payload_len;
785*cd5db556SVikas Gupta 	uint32_t src_msg_len = 0;
786492a19a0SVikas Gupta 	enum spu2_cipher_mode spu2_ciph_mode = 0;
787492a19a0SVikas Gupta 	enum spu2_hash_mode spu2_auth_mode = 0;
788492a19a0SVikas Gupta 	enum spu2_cipher_type spu2_ciph_type = SPU2_CIPHER_TYPE_NONE;
789492a19a0SVikas Gupta 	uint64_t auth_ksize = (auth_key != NULL) ?
790492a19a0SVikas Gupta 				fsattr_sz(auth_key) : 0;
791492a19a0SVikas Gupta 	uint64_t cipher_ksize = (cipher_key != NULL) ?
792492a19a0SVikas Gupta 					fsattr_sz(cipher_key) : 0;
793*cd5db556SVikas Gupta 	uint64_t iv_size = (iv != NULL) ? fsattr_sz(iv) : 0;
794492a19a0SVikas Gupta 	uint64_t digest_size = (digest != NULL) ?
795492a19a0SVikas Gupta 					fsattr_sz(digest) : 0;
796*cd5db556SVikas Gupta 	uint64_t aad_size = (aad != NULL) ?
797*cd5db556SVikas Gupta 				fsattr_sz(aad) : 0;
798492a19a0SVikas Gupta 	enum spu2_hash_type spu2_auth_type = SPU2_HASH_TYPE_NONE;
799492a19a0SVikas Gupta 	bool is_inbound = (auth_op == RTE_CRYPTO_AUTH_OP_VERIFY);
800492a19a0SVikas Gupta 
801492a19a0SVikas Gupta 	if (src == NULL)
802492a19a0SVikas Gupta 		return -EINVAL;
803492a19a0SVikas Gupta 
804492a19a0SVikas Gupta 	payload_len = fsattr_sz(src);
805492a19a0SVikas Gupta 	if (!payload_len) {
806492a19a0SVikas Gupta 		BCMFS_DP_LOG(ERR, "null payload not supported");
807492a19a0SVikas Gupta 		return -EINVAL;
808492a19a0SVikas Gupta 	}
809492a19a0SVikas Gupta 
810492a19a0SVikas Gupta 	/* spu2 hash algorithm and hash algorithm mode */
811492a19a0SVikas Gupta 	ret = spu2_hash_xlate(auth_alg, auth_key, &spu2_auth_type,
812492a19a0SVikas Gupta 			      &spu2_auth_mode);
813492a19a0SVikas Gupta 	if (ret)
814492a19a0SVikas Gupta 		return -EINVAL;
815492a19a0SVikas Gupta 
816492a19a0SVikas Gupta 	/* spu2 cipher algorithm and cipher algorithm mode */
817492a19a0SVikas Gupta 	ret = spu2_cipher_xlate(cipher_alg, cipher_key, &spu2_ciph_type,
818492a19a0SVikas Gupta 				&spu2_ciph_mode);
819492a19a0SVikas Gupta 	if (ret) {
820492a19a0SVikas Gupta 		BCMFS_DP_LOG(ERR, "cipher xlate error");
821492a19a0SVikas Gupta 		return -EINVAL;
822492a19a0SVikas Gupta 	}
823492a19a0SVikas Gupta 
824492a19a0SVikas Gupta 	auth_first = cipher_first ? 0 : 1;
825492a19a0SVikas Gupta 
826492a19a0SVikas Gupta 	fmd  = &sreq->fmd;
827492a19a0SVikas Gupta 
828492a19a0SVikas Gupta 	spu2_fmd_ctrl0_write(fmd, is_inbound, auth_first, SPU2_PROTO_RESV,
829492a19a0SVikas Gupta 			     spu2_ciph_type, spu2_ciph_mode,
830492a19a0SVikas Gupta 			     spu2_auth_type, spu2_auth_mode);
831492a19a0SVikas Gupta 
832492a19a0SVikas Gupta 	spu2_fmd_ctrl1_write(fmd, is_inbound, aad_size, auth_ksize,
833492a19a0SVikas Gupta 			     cipher_ksize, false, false, SPU2_VAL_NONE,
834492a19a0SVikas Gupta 			     SPU2_VAL_NONE, SPU2_VAL_NONE, iv_size,
835492a19a0SVikas Gupta 			     digest_size, false, SPU2_VAL_NONE);
836492a19a0SVikas Gupta 
837492a19a0SVikas Gupta 	spu2_fmd_ctrl2_write(fmd, aad_size, auth_ksize, 0,
838492a19a0SVikas Gupta 			     cipher_ksize, iv_size);
839492a19a0SVikas Gupta 
840492a19a0SVikas Gupta 	spu2_fmd_ctrl3_write(fmd, payload_len);
841492a19a0SVikas Gupta 
842*cd5db556SVikas Gupta 	/* FMD */
843492a19a0SVikas Gupta 	sreq->msgs.srcs_addr[src_index] = sreq->fptr;
844*cd5db556SVikas Gupta 	src_msg_len += sizeof(*fmd);
845492a19a0SVikas Gupta 
846*cd5db556SVikas Gupta 	/* Start of OMD */
847*cd5db556SVikas Gupta 	if (auth_ksize != 0) {
848*cd5db556SVikas Gupta 		memcpy((uint8_t *)fmd + src_msg_len,
849*cd5db556SVikas Gupta 		       fsattr_va(auth_key), auth_ksize);
850*cd5db556SVikas Gupta 		src_msg_len += auth_ksize;
851492a19a0SVikas Gupta #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
852492a19a0SVikas Gupta 	BCMFS_DP_HEXDUMP_LOG(DEBUG, "auth key:", fsattr_va(auth_key),
853*cd5db556SVikas Gupta 			     auth_ksize);
854492a19a0SVikas Gupta #endif
855492a19a0SVikas Gupta 	}
856492a19a0SVikas Gupta 
857*cd5db556SVikas Gupta 	if (cipher_ksize != 0) {
858*cd5db556SVikas Gupta 		memcpy((uint8_t *)fmd + src_msg_len,
859*cd5db556SVikas Gupta 		       fsattr_va(cipher_key), cipher_ksize);
860*cd5db556SVikas Gupta 		src_msg_len += cipher_ksize;
861492a19a0SVikas Gupta 
862492a19a0SVikas Gupta #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
863492a19a0SVikas Gupta 	BCMFS_DP_HEXDUMP_LOG(DEBUG, "cipher key:", fsattr_va(cipher_key),
864*cd5db556SVikas Gupta 			     cipher_ksize);
865492a19a0SVikas Gupta #endif
866492a19a0SVikas Gupta 	}
867492a19a0SVikas Gupta 
868*cd5db556SVikas Gupta 	if (iv_size != 0) {
869*cd5db556SVikas Gupta 		memcpy((uint8_t *)fmd + src_msg_len,
870*cd5db556SVikas Gupta 		       fsattr_va(iv), iv_size);
871*cd5db556SVikas Gupta 		src_msg_len += iv_size;
872492a19a0SVikas Gupta #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
873492a19a0SVikas Gupta 		BCMFS_DP_HEXDUMP_LOG(DEBUG, "iv key:", fsattr_va(iv),
874*cd5db556SVikas Gupta 				     iv_size);
875492a19a0SVikas Gupta #endif
876*cd5db556SVikas Gupta 	} /* End of OMD */
877492a19a0SVikas Gupta 
878*cd5db556SVikas Gupta 	sreq->msgs.srcs_len[src_index] = src_msg_len;
879*cd5db556SVikas Gupta 
880*cd5db556SVikas Gupta 	if (aad_size != 0) {
881*cd5db556SVikas Gupta 		if (fsattr_sz(aad) < BCMFS_AAD_THRESH_LEN) {
882*cd5db556SVikas Gupta 			memcpy((uint8_t *)fmd + src_msg_len, fsattr_va(aad), aad_size);
883*cd5db556SVikas Gupta 			sreq->msgs.srcs_len[src_index] += aad_size;
884*cd5db556SVikas Gupta 		} else {
885*cd5db556SVikas Gupta 			src_index++;
886*cd5db556SVikas Gupta 			sreq->msgs.srcs_addr[src_index] = fsattr_pa(aad);
887*cd5db556SVikas Gupta 			sreq->msgs.srcs_len[src_index] = aad_size;
888*cd5db556SVikas Gupta 		}
889492a19a0SVikas Gupta #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
890492a19a0SVikas Gupta 		BCMFS_DP_HEXDUMP_LOG(DEBUG, "aad :", fsattr_va(aad),
891*cd5db556SVikas Gupta 				     aad_size);
892492a19a0SVikas Gupta #endif
893492a19a0SVikas Gupta 	}
894492a19a0SVikas Gupta 
895*cd5db556SVikas Gupta 	src_index++;
896*cd5db556SVikas Gupta 
897492a19a0SVikas Gupta 	sreq->msgs.srcs_addr[src_index] = fsattr_pa(src);
898492a19a0SVikas Gupta 	sreq->msgs.srcs_len[src_index] = fsattr_sz(src);
899492a19a0SVikas Gupta 	src_index++;
900492a19a0SVikas Gupta 
901492a19a0SVikas Gupta 	if (auth_op == RTE_CRYPTO_AUTH_OP_VERIFY && digest != NULL &&
902492a19a0SVikas Gupta 	    fsattr_sz(digest) != 0) {
903492a19a0SVikas Gupta 		sreq->msgs.srcs_addr[src_index] = fsattr_pa(digest);
904492a19a0SVikas Gupta 		sreq->msgs.srcs_len[src_index] = fsattr_sz(digest);
905492a19a0SVikas Gupta 		src_index++;
906492a19a0SVikas Gupta 	}
907492a19a0SVikas Gupta 	sreq->msgs.srcs_count = src_index;
908492a19a0SVikas Gupta 
909492a19a0SVikas Gupta 	if (dst != NULL) {
910492a19a0SVikas Gupta 		sreq->msgs.dsts_addr[dst_index] = fsattr_pa(dst);
911492a19a0SVikas Gupta 		sreq->msgs.dsts_len[dst_index] = fsattr_sz(dst);
912492a19a0SVikas Gupta 		dst_index++;
913492a19a0SVikas Gupta 	}
914492a19a0SVikas Gupta 
915492a19a0SVikas Gupta 	if (auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {
916492a19a0SVikas Gupta 		/*
917492a19a0SVikas Gupta 		 * In case of decryption digest data is generated by
918492a19a0SVikas Gupta 		 * SPU2 engine  but application doesn't need digest
919492a19a0SVikas Gupta 		 * as such. So program dummy location to capture
920492a19a0SVikas Gupta 		 * digest data
921492a19a0SVikas Gupta 		 */
922*cd5db556SVikas Gupta 		if (digest_size != 0) {
923492a19a0SVikas Gupta 			sreq->msgs.dsts_addr[dst_index] =
924492a19a0SVikas Gupta 				sreq->dptr;
925492a19a0SVikas Gupta 			sreq->msgs.dsts_len[dst_index] =
926492a19a0SVikas Gupta 				fsattr_sz(digest);
927492a19a0SVikas Gupta 			dst_index++;
928492a19a0SVikas Gupta 		}
929492a19a0SVikas Gupta 	} else {
930*cd5db556SVikas Gupta 		if (digest_size != 0) {
931492a19a0SVikas Gupta 			sreq->msgs.dsts_addr[dst_index] =
932492a19a0SVikas Gupta 				fsattr_pa(digest);
933492a19a0SVikas Gupta 			sreq->msgs.dsts_len[dst_index] =
934492a19a0SVikas Gupta 				fsattr_sz(digest);
935492a19a0SVikas Gupta 			dst_index++;
936492a19a0SVikas Gupta 		}
937492a19a0SVikas Gupta 	}
938492a19a0SVikas Gupta 
939492a19a0SVikas Gupta 	sreq->msgs.dsts_addr[dst_index] = sreq->rptr;
940492a19a0SVikas Gupta 	sreq->msgs.dsts_len[dst_index] = SPU2_STATUS_LEN;
941492a19a0SVikas Gupta 	dst_index++;
942492a19a0SVikas Gupta 	sreq->msgs.dsts_count = dst_index;
943492a19a0SVikas Gupta 
944492a19a0SVikas Gupta 	return 0;
945492a19a0SVikas Gupta }
946492a19a0SVikas Gupta 
947492a19a0SVikas Gupta static void
bcmfs_crypto_ccm_update_iv(uint8_t * ivbuf,uint64_t * ivlen,bool is_esp)948492a19a0SVikas Gupta bcmfs_crypto_ccm_update_iv(uint8_t *ivbuf,
949*cd5db556SVikas Gupta 			   uint64_t *ivlen, bool is_esp)
950492a19a0SVikas Gupta {
951492a19a0SVikas Gupta 	int L;  /* size of length field, in bytes */
952492a19a0SVikas Gupta 
953492a19a0SVikas Gupta 	/*
954492a19a0SVikas Gupta 	 * In RFC4309 mode, L is fixed at 4 bytes; otherwise, IV from
955492a19a0SVikas Gupta 	 * testmgr contains (L-1) in bottom 3 bits of first byte,
956492a19a0SVikas Gupta 	 * per RFC 3610.
957492a19a0SVikas Gupta 	 */
958492a19a0SVikas Gupta 	if (is_esp)
959492a19a0SVikas Gupta 		L = CCM_ESP_L_VALUE;
960492a19a0SVikas Gupta 	else
961492a19a0SVikas Gupta 		L = ((ivbuf[0] & CCM_B0_L_PRIME) >>
962492a19a0SVikas Gupta 		      CCM_B0_L_PRIME_SHIFT) + 1;
963492a19a0SVikas Gupta 
964492a19a0SVikas Gupta 	/* SPU2 doesn't want these length bytes nor the first byte... */
965492a19a0SVikas Gupta 	*ivlen -= (1 + L);
966492a19a0SVikas Gupta 	memmove(ivbuf, &ivbuf[1], *ivlen);
967492a19a0SVikas Gupta }
968492a19a0SVikas Gupta 
969492a19a0SVikas Gupta int
bcmfs_crypto_build_aead_request(struct bcmfs_sym_request * sreq,enum rte_crypto_aead_algorithm ae_algo,enum rte_crypto_aead_operation aeop,struct fsattr * src,struct fsattr * dst,struct fsattr * key,struct fsattr * iv,struct fsattr * aad,struct fsattr * digest)970492a19a0SVikas Gupta bcmfs_crypto_build_aead_request(struct bcmfs_sym_request *sreq,
971492a19a0SVikas Gupta 				enum rte_crypto_aead_algorithm ae_algo,
972492a19a0SVikas Gupta 				enum rte_crypto_aead_operation aeop,
973492a19a0SVikas Gupta 				struct fsattr *src, struct fsattr *dst,
974492a19a0SVikas Gupta 				struct fsattr *key, struct fsattr *iv,
975492a19a0SVikas Gupta 				struct fsattr *aad, struct fsattr *digest)
976492a19a0SVikas Gupta {
977492a19a0SVikas Gupta 	int src_index = 0;
978492a19a0SVikas Gupta 	int dst_index = 0;
979492a19a0SVikas Gupta 	bool auth_first = 0;
980492a19a0SVikas Gupta 	struct spu2_fmd *fmd;
981492a19a0SVikas Gupta 	uint64_t payload_len;
982*cd5db556SVikas Gupta 	uint32_t src_msg_len = 0;
983*cd5db556SVikas Gupta 	uint8_t iv_buf[BCMFS_MAX_IV_SIZE];
984492a19a0SVikas Gupta 	enum spu2_cipher_mode spu2_ciph_mode = 0;
985492a19a0SVikas Gupta 	enum spu2_hash_mode spu2_auth_mode = 0;
986492a19a0SVikas Gupta 	enum spu2_cipher_type spu2_ciph_type = SPU2_CIPHER_TYPE_NONE;
987492a19a0SVikas Gupta 	enum spu2_hash_type spu2_auth_type = SPU2_HASH_TYPE_NONE;
988492a19a0SVikas Gupta 	uint64_t ksize = (key != NULL) ? fsattr_sz(key) : 0;
989*cd5db556SVikas Gupta 	uint64_t iv_size = (iv != NULL) ? fsattr_sz(iv) : 0;
990*cd5db556SVikas Gupta 	uint64_t aad_size = (aad != NULL) ? fsattr_sz(aad) : 0;
991492a19a0SVikas Gupta 	uint64_t digest_size = (digest != NULL) ?
992492a19a0SVikas Gupta 				fsattr_sz(digest) : 0;
993492a19a0SVikas Gupta 	bool is_inbound = (aeop == RTE_CRYPTO_AEAD_OP_DECRYPT);
994492a19a0SVikas Gupta 
995492a19a0SVikas Gupta 	if (src == NULL)
996492a19a0SVikas Gupta 		return -EINVAL;
997492a19a0SVikas Gupta 
998492a19a0SVikas Gupta 	payload_len = fsattr_sz(src);
999492a19a0SVikas Gupta 	if (!payload_len) {
1000492a19a0SVikas Gupta 		BCMFS_DP_LOG(ERR, "null payload not supported");
1001492a19a0SVikas Gupta 		return -EINVAL;
1002492a19a0SVikas Gupta 	}
1003492a19a0SVikas Gupta 
1004492a19a0SVikas Gupta 	switch (ksize) {
1005492a19a0SVikas Gupta 	case BCMFS_CRYPTO_AES128:
1006492a19a0SVikas Gupta 		spu2_auth_type = SPU2_HASH_TYPE_AES128;
1007492a19a0SVikas Gupta 		spu2_ciph_type = SPU2_CIPHER_TYPE_AES128;
1008492a19a0SVikas Gupta 		break;
1009492a19a0SVikas Gupta 	case BCMFS_CRYPTO_AES192:
1010492a19a0SVikas Gupta 		spu2_auth_type = SPU2_HASH_TYPE_AES192;
1011492a19a0SVikas Gupta 		spu2_ciph_type = SPU2_CIPHER_TYPE_AES192;
1012492a19a0SVikas Gupta 		break;
1013492a19a0SVikas Gupta 	case BCMFS_CRYPTO_AES256:
1014492a19a0SVikas Gupta 		spu2_auth_type = SPU2_HASH_TYPE_AES256;
1015492a19a0SVikas Gupta 		spu2_ciph_type = SPU2_CIPHER_TYPE_AES256;
1016492a19a0SVikas Gupta 		break;
1017492a19a0SVikas Gupta 	default:
1018492a19a0SVikas Gupta 		return -EINVAL;
1019492a19a0SVikas Gupta 	}
1020492a19a0SVikas Gupta 
1021492a19a0SVikas Gupta 	if (ae_algo == RTE_CRYPTO_AEAD_AES_GCM) {
1022492a19a0SVikas Gupta 		spu2_auth_mode = SPU2_HASH_MODE_GCM;
1023492a19a0SVikas Gupta 		spu2_ciph_mode = SPU2_CIPHER_MODE_GCM;
1024492a19a0SVikas Gupta 		/*
1025492a19a0SVikas Gupta 		 * SPU2 needs in total 12 bytes of IV
1026492a19a0SVikas Gupta 		 * ie IV of 8 bytes(random number) and 4 bytes of salt.
1027492a19a0SVikas Gupta 		 */
1028492a19a0SVikas Gupta 		if (fsattr_sz(iv) > 12)
1029492a19a0SVikas Gupta 			iv_size = 12;
1030492a19a0SVikas Gupta 
1031492a19a0SVikas Gupta 		/*
1032492a19a0SVikas Gupta 		 * On SPU 2, aes gcm cipher first on encrypt, auth first on
1033492a19a0SVikas Gupta 		 * decrypt
1034492a19a0SVikas Gupta 		 */
1035492a19a0SVikas Gupta 
1036492a19a0SVikas Gupta 		auth_first = (aeop == RTE_CRYPTO_AEAD_OP_ENCRYPT) ?
1037492a19a0SVikas Gupta 				0 : 1;
1038492a19a0SVikas Gupta 	}
1039492a19a0SVikas Gupta 
1040*cd5db556SVikas Gupta 	if (iv_size != 0)
1041*cd5db556SVikas Gupta 		memcpy(iv_buf, fsattr_va(iv), iv_size);
1042492a19a0SVikas Gupta 
1043492a19a0SVikas Gupta 	if (ae_algo == RTE_CRYPTO_AEAD_AES_CCM) {
1044492a19a0SVikas Gupta 		spu2_auth_mode = SPU2_HASH_MODE_CCM;
1045492a19a0SVikas Gupta 		spu2_ciph_mode = SPU2_CIPHER_MODE_CCM;
1046*cd5db556SVikas Gupta 		if (iv_size != 0)  {
1047*cd5db556SVikas Gupta 			memcpy(iv_buf, fsattr_va(iv),
1048*cd5db556SVikas Gupta 			       iv_size);
1049*cd5db556SVikas Gupta 			bcmfs_crypto_ccm_update_iv(iv_buf, &iv_size, false);
1050492a19a0SVikas Gupta 		}
1051492a19a0SVikas Gupta 
1052492a19a0SVikas Gupta 		/* opposite for ccm (auth 1st on encrypt) */
1053492a19a0SVikas Gupta 		auth_first = (aeop == RTE_CRYPTO_AEAD_OP_ENCRYPT) ?
1054492a19a0SVikas Gupta 			      0 : 1;
1055492a19a0SVikas Gupta 	}
1056492a19a0SVikas Gupta 
1057492a19a0SVikas Gupta 	fmd  = &sreq->fmd;
1058492a19a0SVikas Gupta 
1059492a19a0SVikas Gupta 	spu2_fmd_ctrl0_write(fmd, is_inbound, auth_first, SPU2_PROTO_RESV,
1060492a19a0SVikas Gupta 			     spu2_ciph_type, spu2_ciph_mode,
1061492a19a0SVikas Gupta 			     spu2_auth_type, spu2_auth_mode);
1062492a19a0SVikas Gupta 
1063492a19a0SVikas Gupta 	spu2_fmd_ctrl1_write(fmd, is_inbound, aad_size, 0,
1064492a19a0SVikas Gupta 			     ksize, false, false, SPU2_VAL_NONE,
1065492a19a0SVikas Gupta 			     SPU2_VAL_NONE, SPU2_VAL_NONE, iv_size,
1066492a19a0SVikas Gupta 			     digest_size, false, SPU2_VAL_NONE);
1067492a19a0SVikas Gupta 
1068492a19a0SVikas Gupta 	spu2_fmd_ctrl2_write(fmd, aad_size, 0, 0,
1069492a19a0SVikas Gupta 			     ksize, iv_size);
1070492a19a0SVikas Gupta 
1071492a19a0SVikas Gupta 	spu2_fmd_ctrl3_write(fmd, payload_len);
1072492a19a0SVikas Gupta 
1073*cd5db556SVikas Gupta 	/* FMD */
1074492a19a0SVikas Gupta 	sreq->msgs.srcs_addr[src_index] = sreq->fptr;
1075*cd5db556SVikas Gupta 	src_msg_len += sizeof(*fmd);
1076492a19a0SVikas Gupta 
1077*cd5db556SVikas Gupta 	if (ksize) {
1078*cd5db556SVikas Gupta 		memcpy((uint8_t *)fmd + src_msg_len,
1079*cd5db556SVikas Gupta 		       fsattr_va(key), ksize);
1080*cd5db556SVikas Gupta 		src_msg_len += ksize;
1081492a19a0SVikas Gupta 
1082492a19a0SVikas Gupta #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
1083492a19a0SVikas Gupta 	BCMFS_DP_HEXDUMP_LOG(DEBUG, "cipher key:", fsattr_va(key),
1084*cd5db556SVikas Gupta 			     ksize);
1085492a19a0SVikas Gupta #endif
1086492a19a0SVikas Gupta 	}
1087492a19a0SVikas Gupta 
1088*cd5db556SVikas Gupta 	if (iv_size) {
1089*cd5db556SVikas Gupta 		memcpy((uint8_t *)fmd + src_msg_len, iv_buf, iv_size);
1090*cd5db556SVikas Gupta 		src_msg_len += iv_size;
1091*cd5db556SVikas Gupta 
1092492a19a0SVikas Gupta #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
1093492a19a0SVikas Gupta 		BCMFS_DP_HEXDUMP_LOG(DEBUG, "iv key:", fsattr_va(iv),
1094492a19a0SVikas Gupta 				     fsattr_sz(iv));
1095492a19a0SVikas Gupta #endif
1096*cd5db556SVikas Gupta 	} /* End of OMD */
1097492a19a0SVikas Gupta 
1098*cd5db556SVikas Gupta 	sreq->msgs.srcs_len[src_index] = src_msg_len;
1099*cd5db556SVikas Gupta 
1100*cd5db556SVikas Gupta 	if (aad_size != 0) {
1101*cd5db556SVikas Gupta 		if (aad_size < BCMFS_AAD_THRESH_LEN) {
1102*cd5db556SVikas Gupta 			memcpy((uint8_t *)fmd + src_msg_len, fsattr_va(aad), aad_size);
1103*cd5db556SVikas Gupta 			sreq->msgs.srcs_len[src_index] += aad_size;
1104*cd5db556SVikas Gupta 		} else {
1105*cd5db556SVikas Gupta 			src_index++;
1106*cd5db556SVikas Gupta 			sreq->msgs.srcs_addr[src_index] = fsattr_pa(aad);
1107*cd5db556SVikas Gupta 			sreq->msgs.srcs_len[src_index] = aad_size;
1108*cd5db556SVikas Gupta 		}
1109492a19a0SVikas Gupta #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
1110492a19a0SVikas Gupta 		BCMFS_DP_HEXDUMP_LOG(DEBUG, "aad :", fsattr_va(aad),
1111*cd5db556SVikas Gupta 				     aad_size);
1112492a19a0SVikas Gupta #endif
1113492a19a0SVikas Gupta 	}
1114492a19a0SVikas Gupta 
1115*cd5db556SVikas Gupta 	src_index++;
1116*cd5db556SVikas Gupta 
1117492a19a0SVikas Gupta 	sreq->msgs.srcs_addr[src_index] = fsattr_pa(src);
1118492a19a0SVikas Gupta 	sreq->msgs.srcs_len[src_index] = fsattr_sz(src);
1119492a19a0SVikas Gupta 	src_index++;
1120492a19a0SVikas Gupta 
1121492a19a0SVikas Gupta 	if (aeop == RTE_CRYPTO_AEAD_OP_DECRYPT && digest != NULL &&
1122492a19a0SVikas Gupta 	    fsattr_sz(digest) != 0) {
1123492a19a0SVikas Gupta 		sreq->msgs.srcs_addr[src_index] = fsattr_pa(digest);
1124492a19a0SVikas Gupta 		sreq->msgs.srcs_len[src_index] = fsattr_sz(digest);
1125492a19a0SVikas Gupta 		src_index++;
1126492a19a0SVikas Gupta 	}
1127492a19a0SVikas Gupta 	sreq->msgs.srcs_count = src_index;
1128492a19a0SVikas Gupta 
1129492a19a0SVikas Gupta 	if (dst != NULL) {
1130492a19a0SVikas Gupta 		sreq->msgs.dsts_addr[dst_index] = fsattr_pa(dst);
1131492a19a0SVikas Gupta 		sreq->msgs.dsts_len[dst_index] = fsattr_sz(dst);
1132492a19a0SVikas Gupta 		dst_index++;
1133492a19a0SVikas Gupta 	}
1134492a19a0SVikas Gupta 
1135492a19a0SVikas Gupta 	if (aeop == RTE_CRYPTO_AEAD_OP_DECRYPT) {
1136492a19a0SVikas Gupta 		/*
1137492a19a0SVikas Gupta 		 * In case of decryption digest data is generated by
1138492a19a0SVikas Gupta 		 * SPU2 engine but application doesn't need digest
1139492a19a0SVikas Gupta 		 * as such. So program dummy location to capture
1140492a19a0SVikas Gupta 		 * digest data
1141492a19a0SVikas Gupta 		 */
1142*cd5db556SVikas Gupta 		if (digest_size != 0) {
1143492a19a0SVikas Gupta 			sreq->msgs.dsts_addr[dst_index] =
1144492a19a0SVikas Gupta 				sreq->dptr;
1145492a19a0SVikas Gupta 			sreq->msgs.dsts_len[dst_index] =
1146*cd5db556SVikas Gupta 				digest_size;
1147492a19a0SVikas Gupta 			dst_index++;
1148492a19a0SVikas Gupta 		}
1149492a19a0SVikas Gupta 	} else {
1150*cd5db556SVikas Gupta 		if (digest_size != 0) {
1151492a19a0SVikas Gupta 			sreq->msgs.dsts_addr[dst_index] =
1152492a19a0SVikas Gupta 				fsattr_pa(digest);
1153492a19a0SVikas Gupta 			sreq->msgs.dsts_len[dst_index] =
1154*cd5db556SVikas Gupta 				digest_size;
1155492a19a0SVikas Gupta 			dst_index++;
1156492a19a0SVikas Gupta 		}
1157492a19a0SVikas Gupta 	}
1158492a19a0SVikas Gupta 
1159492a19a0SVikas Gupta 	sreq->msgs.dsts_addr[dst_index] = sreq->rptr;
1160492a19a0SVikas Gupta 	sreq->msgs.dsts_len[dst_index] = SPU2_STATUS_LEN;
1161492a19a0SVikas Gupta 	dst_index++;
1162492a19a0SVikas Gupta 	sreq->msgs.dsts_count = dst_index;
1163492a19a0SVikas Gupta 
1164492a19a0SVikas Gupta 	return 0;
1165492a19a0SVikas Gupta }
1166