Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include "roc_api.h"
6 : :
7 : : static uint8_t zuc_key128[32] = {
8 : : 0x44, 0xD7, 0x26, 0xBC, 0x62, 0x6B, 0x13, 0x5E, 0x57, 0x89, 0x35,
9 : : 0xE2, 0x71, 0x35, 0x09, 0xAF, 0x4D, 0x78, 0x2F, 0x13, 0x6B, 0xC4,
10 : : 0x1A, 0xF1, 0x5E, 0x26, 0x3C, 0x4D, 0x78, 0x9A, 0x47, 0xAC};
11 : :
12 : : static uint8_t zuc_key256[16] = {0x22, 0x2f, 0x24, 0x2a, 0x6d, 0x40,
13 : : 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
14 : : 0x40, 0x52, 0x10, 0x30};
15 : :
16 : : static uint8_t zuc_key256_mac4[16] = {0x22, 0x2f, 0x25, 0x2a, 0x6d, 0x40,
17 : : 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
18 : : 0x40, 0x52, 0x10, 0x30};
19 : :
20 : : static uint8_t zuc_key256_mac8[16] = {0x23, 0x2f, 0x24, 0x2a, 0x6d, 0x40,
21 : : 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
22 : : 0x40, 0x52, 0x10, 0x30};
23 : :
24 : : static uint8_t zuc_key256_mac16[16] = {0x23, 0x2f, 0x25, 0x2a, 0x6d, 0x40,
25 : : 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
26 : : 0x40, 0x52, 0x10, 0x30};
27 : :
28 : : static uint8_t zuc_key256_v2[16] = {0x64, 0x43, 0x7b, 0x2a, 0x11, 0x05, 0x51, 0x42,
29 : : 0x1a, 0x31, 0x18, 0x66, 0x14, 0x2e, 0x01, 0x5c};
30 : :
31 : : static inline void
32 : 0 : cpt_snow3g_key_gen(const uint8_t *ck, uint32_t *keyx)
33 : : {
34 : : int i, base;
35 : :
36 [ # # ]: 0 : for (i = 0; i < 4; i++) {
37 : 0 : base = 4 * i;
38 : 0 : keyx[3 - i] = (ck[base] << 24) | (ck[base + 1] << 16) |
39 : 0 : (ck[base + 2] << 8) | (ck[base + 3]);
40 [ # # ]: 0 : keyx[3 - i] = plt_cpu_to_be_32(keyx[3 - i]);
41 : : }
42 : 0 : }
43 : :
44 : : static inline int
45 : : cpt_ciph_aes_key_validate(uint16_t key_len)
46 : : {
47 [ # # ]: 0 : switch (key_len) {
48 : : case 16:
49 : : case 24:
50 : : case 32:
51 : : return 0;
52 : 0 : default:
53 : 0 : return -1;
54 : : }
55 : : }
56 : :
57 : : static inline int
58 : 0 : cpt_ciph_type_set(roc_se_cipher_type type, struct roc_se_ctx *ctx, uint16_t key_len)
59 : : {
60 : 0 : bool chained_op = ctx->ciph_then_auth || ctx->auth_then_ciph;
61 : : int fc_type = 0;
62 : :
63 [ # # # # : 0 : switch (type) {
# # # #
# ]
64 : : case ROC_SE_DES3_CBC:
65 : : case ROC_SE_DES3_ECB:
66 : : case ROC_SE_DES_DOCSISBPI:
67 : : fc_type = ROC_SE_FC_GEN;
68 : : break;
69 [ # # ]: 0 : case ROC_SE_AES_CBC:
70 : : case ROC_SE_AES_ECB:
71 : : case ROC_SE_AES_CFB:
72 : : case ROC_SE_AES_CTR:
73 : : case ROC_SE_AES_GCM:
74 : : case ROC_SE_AES_CCM:
75 : : case ROC_SE_AES_DOCSISBPI:
76 [ # # ]: 0 : if (unlikely(cpt_ciph_aes_key_validate(key_len) != 0))
77 : : return -1;
78 : : fc_type = ROC_SE_FC_GEN;
79 : : break;
80 : : case ROC_SE_CHACHA20:
81 : : fc_type = ROC_SE_FC_GEN;
82 : : break;
83 : 0 : case ROC_SE_AES_XTS:
84 : 0 : key_len = key_len / 2;
85 [ # # ]: 0 : if (unlikely(key_len == 24)) {
86 : 0 : plt_err("Invalid AES key len for XTS");
87 : 0 : return -1;
88 : : }
89 [ # # ]: 0 : if (unlikely(cpt_ciph_aes_key_validate(key_len) != 0))
90 : : return -1;
91 : : fc_type = ROC_SE_FC_GEN;
92 : : break;
93 : 0 : case ROC_SE_ZUC_EEA3:
94 : : case ROC_SE_ZUC_NEA6:
95 [ # # ]: 0 : if (unlikely(key_len != 16)) {
96 : : /*
97 : : * ZUC 256 is not supported with older microcode
98 : : * where pdcp_iv_offset is 16
99 : : */
100 [ # # # # ]: 0 : if ((chained_op ||
101 [ # # ]: 0 : (!roc_model_is_cn20k() && (ctx->pdcp_iv_offset == 16)))) {
102 : 0 : plt_err("ZUC 256 is not supported with chained operations");
103 : 0 : return -1;
104 : : }
105 : : }
106 [ # # ]: 0 : if (chained_op)
107 : : fc_type = ROC_SE_PDCP_CHAIN;
108 : : else
109 : : fc_type = ROC_SE_PDCP;
110 : : break;
111 : 0 : case ROC_SE_SNOW3G_UEA2:
112 [ # # ]: 0 : if (unlikely(key_len != 16))
113 : : return -1;
114 [ # # ]: 0 : if (chained_op)
115 : : fc_type = ROC_SE_PDCP_CHAIN;
116 : : else
117 : : fc_type = ROC_SE_PDCP;
118 : : break;
119 : 0 : case ROC_SE_SNOW5G_NEA4:
120 [ # # ]: 0 : if (unlikely(key_len != 32))
121 : : return -1;
122 : : fc_type = ROC_SE_PDCP;
123 : : break;
124 : 0 : case ROC_SE_AES_CTR_EEA2:
125 [ # # ]: 0 : if (chained_op)
126 : : fc_type = ROC_SE_PDCP_CHAIN;
127 : : else
128 : : fc_type = ROC_SE_PDCP;
129 : : break;
130 : 0 : case ROC_SE_KASUMI_F8_CBC:
131 : : case ROC_SE_KASUMI_F8_ECB:
132 [ # # ]: 0 : if (unlikely(key_len != 16))
133 : : return -1;
134 : : /* No support for AEAD yet */
135 [ # # ]: 0 : if (unlikely(ctx->hash_type))
136 : : return -1;
137 : : fc_type = ROC_SE_KASUMI;
138 : : break;
139 : : default:
140 : : return -1;
141 : : }
142 : :
143 : 0 : ctx->fc_type = fc_type;
144 : 0 : return 0;
145 : : }
146 : :
147 : : static inline void
148 : 0 : cpt_ciph_aes_key_type_set(struct roc_se_context *fctx, uint16_t key_len)
149 : : {
150 : : roc_se_aes_type aes_key_type = 0;
151 : :
152 [ # # # # ]: 0 : switch (key_len) {
153 : : case 16:
154 : : aes_key_type = ROC_SE_AES_128_BIT;
155 : : break;
156 : 0 : case 24:
157 : : aes_key_type = ROC_SE_AES_192_BIT;
158 : 0 : break;
159 : 0 : case 32:
160 : : aes_key_type = ROC_SE_AES_256_BIT;
161 : 0 : break;
162 : 0 : default:
163 : : /* This should not happen */
164 : 0 : plt_err("Invalid AES key len");
165 : 0 : return;
166 : : }
167 : 0 : fctx->enc.aes_key = aes_key_type;
168 : : }
169 : :
170 : : void
171 : 0 : roc_se_hmac_opad_ipad_gen(roc_se_auth_type auth_type, const uint8_t *key, uint16_t length,
172 : : uint8_t *opad_ipad, roc_se_op_type op_type)
173 : : {
174 : 0 : uint8_t opad[128] = {[0 ... 127] = 0x5c};
175 : 0 : uint8_t ipad[128] = {[0 ... 127] = 0x36};
176 : : uint8_t ipad_offset, opad_offset;
177 : : uint32_t i;
178 : :
179 [ # # ]: 0 : if (op_type == ROC_SE_IPSEC) {
180 [ # # ]: 0 : if ((auth_type == ROC_SE_MD5_TYPE) || (auth_type == ROC_SE_SHA1_TYPE))
181 : : ipad_offset = 24;
182 : : else
183 : : ipad_offset = 64;
184 : : opad_offset = 0;
185 [ # # ]: 0 : } else if (op_type == ROC_SE_TLS) {
186 : : ipad_offset = 64;
187 : : opad_offset = 0;
188 : : } else {
189 : : ipad_offset = 0;
190 : : opad_offset = 64;
191 : : }
192 : :
193 : : /* HMAC OPAD and IPAD */
194 [ # # # # ]: 0 : for (i = 0; i < 128 && i < length; i++) {
195 : 0 : opad[i] = opad[i] ^ key[i];
196 : 0 : ipad[i] = ipad[i] ^ key[i];
197 : : }
198 : :
199 : : /* Precompute hash of HMAC OPAD and IPAD to avoid
200 : : * per packet computation
201 : : */
202 [ # # # # : 0 : switch (auth_type) {
# # # ]
203 : 0 : case ROC_SE_MD5_TYPE:
204 : 0 : roc_hash_md5_gen(opad, (uint32_t *)&opad_ipad[opad_offset]);
205 : 0 : roc_hash_md5_gen(ipad, (uint32_t *)&opad_ipad[ipad_offset]);
206 : 0 : break;
207 : 0 : case ROC_SE_SHA1_TYPE:
208 : 0 : roc_hash_sha1_gen(opad, (uint32_t *)&opad_ipad[opad_offset]);
209 : 0 : roc_hash_sha1_gen(ipad, (uint32_t *)&opad_ipad[ipad_offset]);
210 : 0 : break;
211 : 0 : case ROC_SE_SHA2_SHA224:
212 : 0 : roc_hash_sha256_gen(opad, (uint32_t *)&opad_ipad[opad_offset], 224);
213 : 0 : roc_hash_sha256_gen(ipad, (uint32_t *)&opad_ipad[ipad_offset], 224);
214 : 0 : break;
215 : 0 : case ROC_SE_SHA2_SHA256:
216 : 0 : roc_hash_sha256_gen(opad, (uint32_t *)&opad_ipad[opad_offset], 256);
217 : 0 : roc_hash_sha256_gen(ipad, (uint32_t *)&opad_ipad[ipad_offset], 256);
218 : 0 : break;
219 : 0 : case ROC_SE_SHA2_SHA384:
220 : 0 : roc_hash_sha512_gen(opad, (uint64_t *)&opad_ipad[opad_offset], 384);
221 : 0 : roc_hash_sha512_gen(ipad, (uint64_t *)&opad_ipad[ipad_offset], 384);
222 : 0 : break;
223 : 0 : case ROC_SE_SHA2_SHA512:
224 : 0 : roc_hash_sha512_gen(opad, (uint64_t *)&opad_ipad[opad_offset], 512);
225 : 0 : roc_hash_sha512_gen(ipad, (uint64_t *)&opad_ipad[ipad_offset], 512);
226 : 0 : break;
227 : : default:
228 : : break;
229 : : }
230 : 0 : }
231 : :
232 : : static int
233 : 0 : cpt_pdcp_chain_key_type_get(uint16_t key_len)
234 : : {
235 : : roc_se_aes_type key_type;
236 : :
237 [ # # # # ]: 0 : switch (key_len) {
238 : : case 16:
239 : : key_type = ROC_SE_AES_128_BIT;
240 : : break;
241 : 0 : case 24:
242 : : key_type = ROC_SE_AES_192_BIT;
243 : 0 : break;
244 : 0 : case 32:
245 : : key_type = ROC_SE_AES_256_BIT;
246 : 0 : break;
247 : 0 : default:
248 : 0 : plt_err("Invalid key len");
249 : 0 : return -ENOTSUP;
250 : : }
251 : :
252 : 0 : return key_type;
253 : : }
254 : :
255 : : static void
256 : 0 : cpt_zuc_const_update(uint8_t *zuc_const, int key_len, int mac_len)
257 : : {
258 [ # # ]: 0 : if (key_len == 16) {
259 : : memcpy(zuc_const, zuc_key128, 32);
260 [ # # ]: 0 : } else if (key_len == 32) {
261 [ # # # # ]: 0 : switch (mac_len) {
262 : : case 4:
263 : : memcpy(zuc_const, zuc_key256_mac4, 16);
264 : : break;
265 : : case 8:
266 : : memcpy(zuc_const, zuc_key256_mac8, 16);
267 : : break;
268 : : case 16:
269 : : memcpy(zuc_const, zuc_key256_mac16, 16);
270 : : break;
271 : 0 : default:
272 : 0 : plt_err("Unsupported mac len");
273 : : }
274 : : }
275 : 0 : }
276 : :
277 : : int
278 : 0 : roc_se_auth_key_set(struct roc_se_ctx *se_ctx, roc_se_auth_type type, const uint8_t *key,
279 : : uint16_t key_len, uint16_t mac_len)
280 : : {
281 : : uint8_t opcode_minor, opcode_major = 0;
282 : : struct roc_se_kasumi_ctx *k_ctx;
283 : : struct roc_se_pdcp_ctx *pctx;
284 : : struct roc_se_context *fctx;
285 : : bool chained_op;
286 : :
287 [ # # ]: 0 : if (se_ctx == NULL)
288 : : return -1;
289 : :
290 : : pctx = &se_ctx->se_ctx.pctx;
291 : : k_ctx = &se_ctx->se_ctx.k_ctx;
292 : : fctx = &se_ctx->se_ctx.fctx;
293 : :
294 : 0 : chained_op = se_ctx->ciph_then_auth || se_ctx->auth_then_ciph;
295 : :
296 [ # # ]: 0 : if ((type >= ROC_SE_ZUC_EIA3) && (type <= ROC_SE_ZUC_NIA6)) {
297 : : uint32_t keyx[4];
298 : : int key_type;
299 : :
300 [ # # ]: 0 : if (!key_len)
301 : : return -1;
302 : :
303 [ # # ]: 0 : if (se_ctx->fc_type == ROC_SE_FC_GEN) {
304 : 0 : plt_err("Cipher and Auth algorithm combination is not supported");
305 : 0 : return -1;
306 : : }
307 : :
308 : : /* For ZUC/SNOW3G/Kasumi */
309 [ # # # # : 0 : switch (type) {
# # ]
310 : 0 : case ROC_SE_SNOW3G_UIA2:
311 : 0 : pctx->w0.s.state_conf = ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
312 : 0 : pctx->w0.s.auth_type = ROC_SE_PDCP_CHAIN_ALG_TYPE_SNOW3G;
313 : 0 : pctx->w0.s.mac_len = mac_len;
314 : 0 : pctx->w0.s.auth_key_len = key_len;
315 : 0 : se_ctx->fc_type = ROC_SE_PDCP_CHAIN;
316 : 0 : cpt_snow3g_key_gen(key, keyx);
317 [ # # ]: 0 : memcpy(pctx->st.auth_key, keyx, key_len);
318 : :
319 [ # # ]: 0 : if (!chained_op)
320 : 0 : se_ctx->fc_type = ROC_SE_PDCP;
321 : 0 : se_ctx->pdcp_auth_alg = ROC_SE_PDCP_ALG_TYPE_SNOW3G;
322 : 0 : se_ctx->zsk_flags = 0x1;
323 : : opcode_major = ROC_SE_MAJOR_OP_PDCP_CHAIN;
324 : 0 : break;
325 : 0 : case ROC_SE_SNOW5G_NIA4:
326 : 0 : pctx->w0.s.state_conf = ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
327 : 0 : pctx->w0.s.auth_type = ROC_SE_PDCP_CHAIN_ALG_TYPE_SNOW5G;
328 : 0 : pctx->w0.s.mac_len = mac_len;
329 : 0 : pctx->w0.s.auth_key_len = 3;
330 : 0 : memcpy(pctx->st.auth_key, key, key_len);
331 : :
332 : 0 : se_ctx->fc_type = ROC_SE_PDCP;
333 : 0 : se_ctx->pdcp_auth_alg = ROC_SE_PDCP_ALG_TYPE_SNOW5G;
334 : 0 : se_ctx->zsk_flags = 0x1;
335 : : opcode_major = ROC_SE_MAJOR_OP_PDCP_CHAIN;
336 : 0 : break;
337 : 0 : case ROC_SE_ZUC_EIA3:
338 : : case ROC_SE_ZUC_NIA6:
339 [ # # ]: 0 : if (unlikely(key_len != 16)) {
340 : : /*
341 : : * ZUC 256 is not supported with older microcode
342 : : * where pdcp_iv_offset is 16
343 : : */
344 [ # # # # ]: 0 : if ((chained_op ||
345 [ # # ]: 0 : (!roc_model_is_cn20k() && (se_ctx->pdcp_iv_offset == 16)))) {
346 : 0 : plt_err("ZUC 256 is not supported with chained operations");
347 : 0 : return -1;
348 : : }
349 : : }
350 : 0 : key_type = cpt_pdcp_chain_key_type_get(key_len);
351 [ # # ]: 0 : if (key_type < 0)
352 : : return key_type;
353 : 0 : pctx->w0.s.auth_key_len = key_type;
354 : 0 : pctx->w0.s.state_conf = ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
355 : 0 : pctx->w0.s.auth_type = ROC_SE_PDCP_CHAIN_ALG_TYPE_ZUC;
356 : 0 : pctx->w0.s.mac_len = mac_len;
357 [ # # ]: 0 : memcpy(pctx->st.auth_key, key, key_len);
358 : :
359 [ # # # # ]: 0 : if (!roc_model_is_cn20k() && key_len == 32)
360 : : roc_se_zuc_bytes_swap(pctx->st.auth_key, key_len);
361 : :
362 : 0 : cpt_zuc_const_update(pctx->st.auth_zuc_const, key_len, mac_len);
363 : 0 : se_ctx->fc_type = ROC_SE_PDCP_CHAIN;
364 : :
365 [ # # ]: 0 : if (!chained_op)
366 : 0 : se_ctx->fc_type = ROC_SE_PDCP;
367 : :
368 : 0 : se_ctx->pdcp_auth_alg = ROC_SE_PDCP_ALG_TYPE_ZUC;
369 : 0 : se_ctx->zsk_flags = 0x1;
370 : : opcode_major = ROC_SE_MAJOR_OP_PDCP_CHAIN;
371 : 0 : break;
372 : 0 : case ROC_SE_AES_CMAC_EIA2:
373 : 0 : key_type = cpt_pdcp_chain_key_type_get(key_len);
374 [ # # ]: 0 : if (key_type < 0)
375 : : return key_type;
376 : 0 : pctx->w0.s.auth_key_len = key_type;
377 : 0 : pctx->w0.s.state_conf = ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
378 : 0 : pctx->w0.s.auth_type = ROC_SE_PDCP_ALG_TYPE_AES_CTR;
379 : 0 : pctx->w0.s.mac_len = mac_len;
380 [ # # ]: 0 : memcpy(pctx->st.auth_key, key, key_len);
381 : 0 : se_ctx->fc_type = ROC_SE_PDCP_CHAIN;
382 : :
383 [ # # ]: 0 : if (!chained_op)
384 : 0 : se_ctx->fc_type = ROC_SE_PDCP;
385 : 0 : se_ctx->pdcp_auth_alg = ROC_SE_PDCP_ALG_TYPE_AES_CMAC;
386 : 0 : se_ctx->eia2 = 1;
387 : 0 : se_ctx->zsk_flags = 0x1;
388 : : opcode_major = ROC_SE_MAJOR_OP_PDCP_CHAIN;
389 : 0 : break;
390 : 0 : case ROC_SE_KASUMI_F9_ECB:
391 : : /* Kasumi ECB mode */
392 : 0 : se_ctx->k_ecb = 1;
393 : 0 : memcpy(k_ctx->ci_key, key, key_len);
394 : 0 : se_ctx->fc_type = ROC_SE_KASUMI;
395 : 0 : se_ctx->zsk_flags = 0x1;
396 : : opcode_major = ROC_SE_MAJOR_OP_KASUMI | ROC_DMA_MODE_SG;
397 : 0 : break;
398 : 0 : case ROC_SE_KASUMI_F9_CBC:
399 : 0 : memcpy(k_ctx->ci_key, key, key_len);
400 : 0 : se_ctx->fc_type = ROC_SE_KASUMI;
401 : 0 : se_ctx->zsk_flags = 0x1;
402 : : opcode_major = ROC_SE_MAJOR_OP_KASUMI | ROC_DMA_MODE_SG;
403 : 0 : break;
404 : : default:
405 : : return -1;
406 : : }
407 : :
408 [ # # # # ]: 0 : if ((se_ctx->fc_type == ROC_SE_PDCP_CHAIN) && (mac_len != 4)) {
409 : 0 : plt_err("Only digest length of 4 is supported with PDCP chain");
410 : 0 : return -1;
411 : : }
412 : :
413 : 0 : se_ctx->mac_len = mac_len;
414 : 0 : se_ctx->hash_type = type;
415 [ # # ]: 0 : if (chained_op)
416 [ # # ]: 0 : opcode_minor = se_ctx->ciph_then_auth ? 2 : 3;
417 : : else
418 : : opcode_minor = ((1 << 4) | 1);
419 : :
420 : 0 : se_ctx->template_w4.s.opcode_major = opcode_major;
421 : 0 : se_ctx->template_w4.s.opcode_minor = opcode_minor;
422 : 0 : return 0;
423 : : }
424 : :
425 [ # # # # : 0 : if (!se_ctx->fc_type || (type && type != ROC_SE_GMAC_TYPE && !se_ctx->enc_cipher))
# # ]
426 : 0 : se_ctx->fc_type = ROC_SE_HASH_HMAC;
427 : :
428 [ # # # # ]: 0 : if (se_ctx->fc_type == ROC_SE_FC_GEN && key_len > 64) {
429 : 0 : plt_err("Maximum auth key length supported is 64");
430 : 0 : return -1;
431 : : }
432 : :
433 : : /* For GMAC auth, cipher must be NULL */
434 [ # # ]: 0 : if (type == ROC_SE_GMAC_TYPE) {
435 : 0 : fctx->enc.enc_cipher = 0;
436 : 0 : se_ctx->template_w4.s.opcode_minor = BIT(5);
437 : : }
438 : :
439 : 0 : fctx->enc.hash_type = type;
440 : 0 : se_ctx->hash_type = type;
441 : 0 : fctx->enc.mac_len = mac_len;
442 : 0 : se_ctx->mac_len = mac_len;
443 : :
444 [ # # ]: 0 : if (key_len) {
445 : : /*
446 : : * Chained operation (FC opcode) requires precomputed ipad and opad hashes, but for
447 : : * auth only (HMAC opcode) this is not required
448 : : */
449 [ # # ]: 0 : if (chained_op) {
450 : 0 : memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad));
451 : 0 : memset(fctx->hmac.opad, 0, sizeof(fctx->hmac.opad));
452 : 0 : roc_se_hmac_opad_ipad_gen(type, key, key_len, &fctx->hmac.ipad[0],
453 : : ROC_SE_FC);
454 : 0 : fctx->enc.auth_input_type = 0;
455 : : } else {
456 : 0 : se_ctx->hmac = 1;
457 : :
458 : 0 : se_ctx->auth_key = plt_zmalloc(key_len, 8);
459 [ # # ]: 0 : if (se_ctx->auth_key == NULL)
460 : : return -1;
461 : :
462 : : memcpy(se_ctx->auth_key, key, key_len);
463 : 0 : se_ctx->auth_key_len = key_len;
464 : : }
465 : : }
466 : : return 0;
467 : : }
468 : :
469 : : int
470 : 0 : roc_se_ciph_key_set(struct roc_se_ctx *se_ctx, roc_se_cipher_type type, const uint8_t *key,
471 : : uint16_t key_len)
472 : : {
473 : 0 : struct roc_se_context *fctx = &se_ctx->se_ctx.fctx;
474 : : struct roc_se_pdcp_ctx *pctx;
475 : : uint8_t opcode_minor = 0;
476 : : uint32_t keyx[4];
477 : : int key_type;
478 : : int i, ret;
479 : :
480 : : /* For NULL cipher, no processing required. */
481 [ # # ]: 0 : if (type == ROC_SE_PASSTHROUGH)
482 : : return 0;
483 : :
484 : : pctx = &se_ctx->se_ctx.pctx;
485 : :
486 [ # # ]: 0 : if ((type == ROC_SE_AES_GCM) || (type == ROC_SE_AES_CCM))
487 : 0 : se_ctx->template_w4.s.opcode_minor = BIT(5);
488 : :
489 : 0 : ret = cpt_ciph_type_set(type, se_ctx, key_len);
490 [ # # ]: 0 : if (unlikely(ret))
491 : : return -1;
492 : :
493 [ # # ]: 0 : if (se_ctx->fc_type == ROC_SE_FC_GEN) {
494 : : /*
495 : : * We need to always say IV is from DPTR as user can
496 : : * sometimes override IV per operation.
497 : : */
498 : 0 : fctx->enc.iv_source = ROC_SE_FROM_DPTR;
499 : :
500 [ # # ]: 0 : if (se_ctx->auth_key_len > 64)
501 : : return -1;
502 : : }
503 : :
504 [ # # # # : 0 : switch (type) {
# # # # #
# # # #
# ]
505 : 0 : case ROC_SE_DES3_CBC:
506 : : /* CPT performs DES using 3DES with the 8B DES-key
507 : : * replicated 2 more times to match the 24B 3DES-key.
508 : : * Eg. If org. key is "0x0a 0x0b", then new key is
509 : : * "0x0a 0x0b 0x0a 0x0b 0x0a 0x0b"
510 : : */
511 [ # # ]: 0 : if (key_len == 8) {
512 : : /* Skipping the first 8B as it will be copied
513 : : * in the regular code flow
514 : : */
515 : 0 : memcpy(fctx->enc.encr_key + key_len, key, key_len);
516 : 0 : memcpy(fctx->enc.encr_key + 2 * key_len, key, key_len);
517 : : }
518 : : break;
519 : 0 : case ROC_SE_DES3_ECB:
520 : : /* For DES3_ECB IV need to be from CTX. */
521 : 0 : fctx->enc.iv_source = ROC_SE_FROM_CTX;
522 : 0 : break;
523 : 0 : case ROC_SE_AES_CBC:
524 : : case ROC_SE_AES_ECB:
525 : : case ROC_SE_AES_CFB:
526 : : case ROC_SE_AES_CTR:
527 : : case ROC_SE_CHACHA20:
528 : 0 : cpt_ciph_aes_key_type_set(fctx, key_len);
529 : 0 : break;
530 : 0 : case ROC_SE_AES_GCM:
531 : : case ROC_SE_AES_CCM:
532 : 0 : cpt_ciph_aes_key_type_set(fctx, key_len);
533 : 0 : break;
534 : 0 : case ROC_SE_AES_XTS:
535 : 0 : key_len = key_len / 2;
536 : 0 : cpt_ciph_aes_key_type_set(fctx, key_len);
537 : :
538 : : /* Copy key2 for XTS into ipad */
539 : 0 : memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad));
540 : 0 : memcpy(fctx->hmac.ipad, &key[key_len], key_len);
541 : : break;
542 : 0 : case ROC_SE_AES_DOCSISBPI:
543 : : /*
544 : : * DOCSIS uses the combination of AES-CBC and residual termination blocks that are
545 : : * less than 128. Pass it as regular AES-CBC cipher to CPT, but keep type in
546 : : * se_ctx as AES_DOCSISBPI to skip block size checks in instruction preparation.
547 : : */
548 : 0 : cpt_ciph_aes_key_type_set(fctx, key_len);
549 : 0 : fctx->enc.enc_cipher = ROC_SE_AES_CBC;
550 : 0 : memcpy(fctx->enc.encr_key, key, key_len);
551 : 0 : goto success;
552 : : case ROC_SE_DES_DOCSISBPI:
553 : : /* See case ROC_SE_DES3_CBC: for explanation */
554 [ # # ]: 0 : for (i = 0; i < 3; i++)
555 : 0 : memcpy(fctx->enc.encr_key + key_len * i, key, key_len);
556 : : /*
557 : : * DOCSIS uses DES-CBC mode with special handling of residual termination blocks
558 : : * that are less than 64 bits. Pass it as regular DES-CBC, but keep type in
559 : : * se_ctx as DES_DOCSISBPI to skip block size checks in instruction preparation.
560 : : */
561 : 0 : fctx->enc.enc_cipher = ROC_SE_DES3_CBC;
562 : 0 : goto success;
563 : 0 : case ROC_SE_SNOW3G_UEA2:
564 : 0 : pctx->w0.s.state_conf = ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
565 : 0 : pctx->w0.s.cipher_type = ROC_SE_PDCP_CHAIN_ALG_TYPE_SNOW3G;
566 : 0 : pctx->w0.s.ci_key_len = key_len;
567 : 0 : cpt_snow3g_key_gen(key, keyx);
568 : 0 : memcpy(pctx->st.ci_key, keyx, key_len);
569 : 0 : se_ctx->pdcp_ci_alg = ROC_SE_PDCP_ALG_TYPE_SNOW3G;
570 : 0 : se_ctx->zsk_flags = 0;
571 : 0 : goto success;
572 : 0 : case ROC_SE_SNOW5G_NEA4:
573 : 0 : pctx->w0.s.state_conf = ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
574 : 0 : pctx->w0.s.cipher_type = ROC_SE_PDCP_CHAIN_ALG_TYPE_SNOW5G;
575 : 0 : pctx->w0.s.ci_key_len = 3;
576 : 0 : memcpy(pctx->st.ci_key, key, key_len);
577 : 0 : se_ctx->pdcp_ci_alg = ROC_SE_PDCP_ALG_TYPE_SNOW5G;
578 : 0 : se_ctx->zsk_flags = 0;
579 : 0 : goto success;
580 : 0 : case ROC_SE_ZUC_EEA3:
581 : : case ROC_SE_ZUC_NEA6:
582 : 0 : key_type = cpt_pdcp_chain_key_type_get(key_len);
583 [ # # ]: 0 : if (key_type < 0)
584 : : return key_type;
585 : 0 : pctx->w0.s.ci_key_len = key_type;
586 : 0 : pctx->w0.s.state_conf = ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
587 : 0 : pctx->w0.s.cipher_type = ROC_SE_PDCP_CHAIN_ALG_TYPE_ZUC;
588 [ # # ]: 0 : memcpy(pctx->st.ci_key, key, key_len);
589 [ # # ]: 0 : if (key_len == 32) {
590 [ # # ]: 0 : if (roc_model_is_cn20k())
591 : 0 : memcpy(pctx->st.ci_zuc_const, zuc_key256_v2, 16);
592 : : else {
593 : 0 : memcpy(pctx->st.ci_zuc_const, zuc_key256, 16);
594 : : roc_se_zuc_bytes_swap(pctx->st.ci_key, key_len);
595 : : }
596 : : } else
597 : 0 : memcpy(pctx->st.ci_zuc_const, zuc_key128, 32);
598 : 0 : se_ctx->pdcp_ci_alg = ROC_SE_PDCP_ALG_TYPE_ZUC;
599 : 0 : se_ctx->zsk_flags = 0;
600 : 0 : goto success;
601 : 0 : case ROC_SE_AES_CTR_EEA2:
602 : 0 : key_type = cpt_pdcp_chain_key_type_get(key_len);
603 [ # # ]: 0 : if (key_type < 0)
604 : : return key_type;
605 : 0 : pctx->w0.s.ci_key_len = key_type;
606 : 0 : pctx->w0.s.state_conf = ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
607 : 0 : pctx->w0.s.cipher_type = ROC_SE_PDCP_ALG_TYPE_AES_CTR;
608 : 0 : memcpy(pctx->st.ci_key, key, key_len);
609 : 0 : se_ctx->pdcp_ci_alg = ROC_SE_PDCP_ALG_TYPE_AES_CTR;
610 : 0 : se_ctx->zsk_flags = 0;
611 : 0 : goto success;
612 : 0 : case ROC_SE_KASUMI_F8_ECB:
613 : 0 : se_ctx->k_ecb = 1;
614 : 0 : memcpy(se_ctx->se_ctx.k_ctx.ci_key, key, key_len);
615 : 0 : se_ctx->zsk_flags = 0;
616 : 0 : goto success;
617 : 0 : case ROC_SE_KASUMI_F8_CBC:
618 : 0 : memcpy(se_ctx->se_ctx.k_ctx.ci_key, key, key_len);
619 : 0 : se_ctx->zsk_flags = 0;
620 : 0 : goto success;
621 : : default:
622 : : return -1;
623 : : }
624 : :
625 : : /* Only for ROC_SE_FC_GEN case */
626 : :
627 : : /* For GMAC auth, cipher must be NULL */
628 [ # # ]: 0 : if (se_ctx->hash_type != ROC_SE_GMAC_TYPE)
629 : 0 : fctx->enc.enc_cipher = type;
630 : :
631 : 0 : memcpy(fctx->enc.encr_key, key, key_len);
632 : :
633 : 0 : success:
634 : 0 : se_ctx->enc_cipher = type;
635 [ # # ]: 0 : if (se_ctx->fc_type == ROC_SE_PDCP_CHAIN) {
636 : 0 : se_ctx->template_w4.s.opcode_major = ROC_SE_MAJOR_OP_PDCP_CHAIN;
637 [ # # ]: 0 : se_ctx->template_w4.s.opcode_minor = se_ctx->ciph_then_auth ? 2 : 3;
638 [ # # ]: 0 : } else if (se_ctx->fc_type == ROC_SE_PDCP) {
639 [ # # ]: 0 : if (roc_model_is_cn9k())
640 : 0 : opcode_minor =
641 : 0 : ((1 << 7) | (se_ctx->pdcp_ci_alg << 5) | (se_ctx->zsk_flags & 0x7));
642 : : else
643 : : opcode_minor = ((1 << 4));
644 : 0 : se_ctx->template_w4.s.opcode_major = ROC_SE_MAJOR_OP_PDCP_CHAIN;
645 : 0 : se_ctx->template_w4.s.opcode_minor = opcode_minor;
646 : : }
647 : : return 0;
648 : : }
649 : :
650 : : void
651 : 0 : roc_se_ctx_init(struct roc_se_ctx *roc_se_ctx)
652 : : {
653 : 0 : struct se_ctx_s *ctx = &roc_se_ctx->se_ctx;
654 : : uint64_t ctx_len, *uc_ctx;
655 : : uint8_t i;
656 : :
657 [ # # ]: 0 : switch (roc_se_ctx->fc_type) {
658 : : case ROC_SE_FC_GEN:
659 : : ctx_len = sizeof(struct roc_se_context);
660 : : break;
661 : : case ROC_SE_PDCP_CHAIN:
662 : : case ROC_SE_PDCP:
663 : : ctx_len = sizeof(struct roc_se_pdcp_ctx);
664 : : break;
665 : : case ROC_SE_KASUMI:
666 : : ctx_len = sizeof(struct roc_se_kasumi_ctx);
667 : : break;
668 : : case ROC_SE_SM:
669 : : ctx_len = sizeof(struct roc_se_sm_context);
670 : : break;
671 : : default:
672 : : ctx_len = 0;
673 : : }
674 : :
675 : 0 : ctx_len = PLT_ALIGN_CEIL(ctx_len, 8);
676 : :
677 : : /* Skip w0 for swap */
678 : 0 : uc_ctx = PLT_PTR_ADD(ctx, sizeof(ctx->w0));
679 [ # # ]: 0 : for (i = 0; i < (ctx_len / 8); i++)
680 [ # # ]: 0 : uc_ctx[i] = plt_cpu_to_be_64(((uint64_t *)uc_ctx)[i]);
681 : :
682 : : /* Include w0 */
683 : : ctx_len += sizeof(ctx->w0);
684 : 0 : ctx_len = PLT_ALIGN_CEIL(ctx_len, 8);
685 : :
686 : 0 : ctx->w0.s.aop_valid = 1;
687 : 0 : ctx->w0.s.ctx_hdr_size = 0;
688 : :
689 : 0 : ctx->w0.s.ctx_size = PLT_ALIGN_FLOOR(ctx_len, 128);
690 : : if (ctx->w0.s.ctx_size == 0)
691 : 0 : ctx->w0.s.ctx_size = 1;
692 : :
693 : 0 : ctx->w0.s.ctx_push_size = ctx_len / 8;
694 : : if (ctx->w0.s.ctx_push_size > 32)
695 : : ctx->w0.s.ctx_push_size = 32;
696 : 0 : }
|