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