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