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 (chained_op) {
92 [ # # ]: 0 : if (unlikely(key_len != 16))
93 : : return -1;
94 : : fc_type = ROC_SE_PDCP_CHAIN;
95 : : } else {
96 : : fc_type = ROC_SE_PDCP;
97 : : }
98 : : break;
99 : 0 : case ROC_SE_SNOW3G_UEA2:
100 [ # # ]: 0 : if (unlikely(key_len != 16))
101 : : return -1;
102 [ # # ]: 0 : if (chained_op)
103 : : fc_type = ROC_SE_PDCP_CHAIN;
104 : : else
105 : : fc_type = ROC_SE_PDCP;
106 : : break;
107 : 0 : case ROC_SE_AES_CTR_EEA2:
108 [ # # ]: 0 : if (chained_op)
109 : : fc_type = ROC_SE_PDCP_CHAIN;
110 : : else
111 : : fc_type = ROC_SE_PDCP;
112 : : break;
113 : 0 : case ROC_SE_KASUMI_F8_CBC:
114 : : case ROC_SE_KASUMI_F8_ECB:
115 [ # # ]: 0 : if (unlikely(key_len != 16))
116 : : return -1;
117 : : /* No support for AEAD yet */
118 [ # # ]: 0 : if (unlikely(ctx->hash_type))
119 : : return -1;
120 : : fc_type = ROC_SE_KASUMI;
121 : : break;
122 : : default:
123 : : return -1;
124 : : }
125 : :
126 : 0 : ctx->fc_type = fc_type;
127 : 0 : return 0;
128 : : }
129 : :
130 : : static inline void
131 : 0 : cpt_ciph_aes_key_type_set(struct roc_se_context *fctx, uint16_t key_len)
132 : : {
133 : : roc_se_aes_type aes_key_type = 0;
134 : :
135 [ # # # # ]: 0 : switch (key_len) {
136 : : case 16:
137 : : aes_key_type = ROC_SE_AES_128_BIT;
138 : : break;
139 : 0 : case 24:
140 : : aes_key_type = ROC_SE_AES_192_BIT;
141 : 0 : break;
142 : 0 : case 32:
143 : : aes_key_type = ROC_SE_AES_256_BIT;
144 : 0 : break;
145 : 0 : default:
146 : : /* This should not happen */
147 : 0 : plt_err("Invalid AES key len");
148 : 0 : return;
149 : : }
150 : 0 : fctx->enc.aes_key = aes_key_type;
151 : : }
152 : :
153 : : static void
154 : 0 : cpt_hmac_opad_ipad_gen(roc_se_auth_type auth_type, const uint8_t *key, uint16_t length,
155 : : struct roc_se_hmac_context *hmac)
156 : : {
157 : 0 : uint8_t opad[128] = {[0 ... 127] = 0x5c};
158 : 0 : uint8_t ipad[128] = {[0 ... 127] = 0x36};
159 : : uint32_t i;
160 : :
161 : : /* HMAC OPAD and IPAD */
162 [ # # # # ]: 0 : for (i = 0; i < 128 && i < length; i++) {
163 : 0 : opad[i] = opad[i] ^ key[i];
164 : 0 : ipad[i] = ipad[i] ^ key[i];
165 : : }
166 : :
167 : : /* Precompute hash of HMAC OPAD and IPAD to avoid
168 : : * per packet computation
169 : : */
170 [ # # # # : 0 : switch (auth_type) {
# # # ]
171 : 0 : case ROC_SE_MD5_TYPE:
172 : 0 : roc_hash_md5_gen(opad, (uint32_t *)hmac->opad);
173 : 0 : roc_hash_md5_gen(ipad, (uint32_t *)hmac->ipad);
174 : 0 : break;
175 : 0 : case ROC_SE_SHA1_TYPE:
176 : 0 : roc_hash_sha1_gen(opad, (uint32_t *)hmac->opad);
177 : 0 : roc_hash_sha1_gen(ipad, (uint32_t *)hmac->ipad);
178 : 0 : break;
179 : 0 : case ROC_SE_SHA2_SHA224:
180 : 0 : roc_hash_sha256_gen(opad, (uint32_t *)hmac->opad, 224);
181 : 0 : roc_hash_sha256_gen(ipad, (uint32_t *)hmac->ipad, 224);
182 : 0 : break;
183 : 0 : case ROC_SE_SHA2_SHA256:
184 : 0 : roc_hash_sha256_gen(opad, (uint32_t *)hmac->opad, 256);
185 : 0 : roc_hash_sha256_gen(ipad, (uint32_t *)hmac->ipad, 256);
186 : 0 : break;
187 : 0 : case ROC_SE_SHA2_SHA384:
188 : 0 : roc_hash_sha512_gen(opad, (uint64_t *)hmac->opad, 384);
189 : 0 : roc_hash_sha512_gen(ipad, (uint64_t *)hmac->ipad, 384);
190 : 0 : break;
191 : 0 : case ROC_SE_SHA2_SHA512:
192 : 0 : roc_hash_sha512_gen(opad, (uint64_t *)hmac->opad, 512);
193 : 0 : roc_hash_sha512_gen(ipad, (uint64_t *)hmac->ipad, 512);
194 : 0 : break;
195 : : default:
196 : : break;
197 : : }
198 : 0 : }
199 : :
200 : : static int
201 [ # # ]: 0 : cpt_pdcp_key_type_set(struct roc_se_zuc_snow3g_ctx *zs_ctx, uint16_t key_len)
202 : : {
203 : : roc_se_aes_type key_type = 0;
204 : :
205 [ # # ]: 0 : if (roc_model_is_cn9k()) {
206 [ # # ]: 0 : if (key_len != 16) {
207 : 0 : plt_err("Only key len 16 is supported on cn9k");
208 : 0 : return -ENOTSUP;
209 : : }
210 : : }
211 : :
212 [ # # # ]: 0 : switch (key_len) {
213 : : case 16:
214 : : key_type = ROC_SE_AES_128_BIT;
215 : : break;
216 : 0 : case 32:
217 : : key_type = ROC_SE_AES_256_BIT;
218 : 0 : break;
219 : 0 : default:
220 : 0 : plt_err("Invalid AES key len");
221 : 0 : return -ENOTSUP;
222 : : }
223 : 0 : zs_ctx->zuc.otk_ctx.w0.s.key_len = key_type;
224 : 0 : return 0;
225 : : }
226 : :
227 : : static int
228 : 0 : cpt_pdcp_chain_key_type_get(uint16_t key_len)
229 : : {
230 : : roc_se_aes_type key_type;
231 : :
232 [ # # # # ]: 0 : switch (key_len) {
233 : : case 16:
234 : : key_type = ROC_SE_AES_128_BIT;
235 : : break;
236 : 0 : case 24:
237 : : key_type = ROC_SE_AES_192_BIT;
238 : 0 : break;
239 : 0 : case 32:
240 : : key_type = ROC_SE_AES_256_BIT;
241 : 0 : break;
242 : 0 : default:
243 : 0 : plt_err("Invalid key len");
244 : 0 : return -ENOTSUP;
245 : : }
246 : :
247 : 0 : return key_type;
248 : : }
249 : :
250 : : static int
251 [ # # ]: 0 : cpt_pdcp_mac_len_set(struct roc_se_zuc_snow3g_ctx *zs_ctx, uint16_t mac_len)
252 : : {
253 : : roc_se_pdcp_mac_len_type mac_type = 0;
254 : :
255 [ # # ]: 0 : if (roc_model_is_cn9k()) {
256 [ # # ]: 0 : if (mac_len != 4) {
257 : 0 : plt_err("Only mac len 4 is supported on cn9k");
258 : 0 : return -ENOTSUP;
259 : : }
260 : : }
261 : :
262 [ # # # # ]: 0 : switch (mac_len) {
263 : : case 4:
264 : : mac_type = ROC_SE_PDCP_MAC_LEN_32_BIT;
265 : : break;
266 : 0 : case 8:
267 : : mac_type = ROC_SE_PDCP_MAC_LEN_64_BIT;
268 : 0 : break;
269 : 0 : case 16:
270 : : mac_type = ROC_SE_PDCP_MAC_LEN_128_BIT;
271 : 0 : break;
272 : 0 : default:
273 : 0 : plt_err("Invalid ZUC MAC len");
274 : 0 : return -ENOTSUP;
275 : : }
276 : 0 : zs_ctx->zuc.otk_ctx.w0.s.mac_len = mac_type;
277 : 0 : return 0;
278 : : }
279 : :
280 : : static void
281 : 0 : cpt_zuc_const_update(uint8_t *zuc_const, int key_len, int mac_len)
282 : : {
283 [ # # ]: 0 : if (key_len == 16) {
284 : : memcpy(zuc_const, zuc_key128, 32);
285 [ # # ]: 0 : } else if (key_len == 32) {
286 [ # # # # ]: 0 : switch (mac_len) {
287 : : case 4:
288 : : memcpy(zuc_const, zuc_key256_mac4, 16);
289 : : break;
290 : : case 8:
291 : : memcpy(zuc_const, zuc_key256_mac8, 16);
292 : : break;
293 : : case 16:
294 : : memcpy(zuc_const, zuc_key256_mac16, 16);
295 : : break;
296 : 0 : default:
297 : 0 : plt_err("Unsupported mac len");
298 : : }
299 : : }
300 : 0 : }
301 : :
302 : : int
303 : 0 : roc_se_auth_key_set(struct roc_se_ctx *se_ctx, roc_se_auth_type type,
304 : : const uint8_t *key, uint16_t key_len, uint16_t mac_len)
305 : : {
306 : : struct roc_se_zuc_snow3g_chain_ctx *zs_ch_ctx;
307 : : struct roc_se_zuc_snow3g_ctx *zs_ctx;
308 : : struct roc_se_kasumi_ctx *k_ctx;
309 : : struct roc_se_context *fctx;
310 : : uint8_t opcode_minor;
311 : : uint8_t pdcp_alg;
312 : : bool chained_op;
313 : : int ret;
314 : :
315 [ # # ]: 0 : if (se_ctx == NULL)
316 : : return -1;
317 : :
318 : 0 : zs_ctx = &se_ctx->se_ctx.zs_ctx;
319 : : zs_ch_ctx = &se_ctx->se_ctx.zs_ch_ctx;
320 : : k_ctx = &se_ctx->se_ctx.k_ctx;
321 : : fctx = &se_ctx->se_ctx.fctx;
322 : :
323 : 0 : chained_op = se_ctx->ciph_then_auth || se_ctx->auth_then_ciph;
324 : :
325 [ # # ]: 0 : if ((type >= ROC_SE_ZUC_EIA3) && (type <= ROC_SE_KASUMI_F9_ECB)) {
326 : : uint8_t *zuc_const;
327 : : uint32_t keyx[4];
328 : : uint8_t *ci_key;
329 : :
330 [ # # ]: 0 : if (!key_len)
331 : : return -1;
332 : :
333 [ # # ]: 0 : if (se_ctx->fc_type == ROC_SE_FC_GEN) {
334 : 0 : plt_err("Cipher and Auth algorithm combination is not supported");
335 : 0 : return -1;
336 : : }
337 : :
338 [ # # ]: 0 : if (roc_model_is_cn9k()) {
339 : 0 : ci_key = zs_ctx->zuc.onk_ctx.ci_key;
340 : 0 : zuc_const = zs_ctx->zuc.onk_ctx.zuc_const;
341 : : } else {
342 : 0 : ci_key = zs_ctx->zuc.otk_ctx.ci_key;
343 : 0 : zuc_const = zs_ctx->zuc.otk_ctx.zuc_const;
344 : : }
345 : :
346 : : /* For ZUC/SNOW3G/Kasumi */
347 [ # # # # : 0 : switch (type) {
# ]
348 : 0 : case ROC_SE_SNOW3G_UIA2:
349 [ # # ]: 0 : if (chained_op) {
350 : : struct roc_se_onk_zuc_chain_ctx *ctx =
351 : : &zs_ch_ctx->zuc.onk_ctx;
352 : 0 : zs_ch_ctx->zuc.onk_ctx.w0.s.state_conf =
353 : : ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
354 : 0 : ctx->w0.s.auth_type =
355 : : ROC_SE_PDCP_CHAIN_ALG_TYPE_SNOW3G;
356 : 0 : ctx->w0.s.mac_len = mac_len;
357 : 0 : ctx->w0.s.auth_key_len = key_len;
358 : 0 : se_ctx->fc_type = ROC_SE_PDCP_CHAIN;
359 : 0 : cpt_snow3g_key_gen(key, keyx);
360 : 0 : memcpy(ctx->st.auth_key, keyx, key_len);
361 : : } else {
362 : 0 : zs_ctx->zuc.otk_ctx.w0.s.alg_type =
363 : : ROC_SE_PDCP_ALG_TYPE_SNOW3G;
364 : 0 : zs_ctx->zuc.otk_ctx.w0.s.mac_len =
365 : : ROC_SE_PDCP_MAC_LEN_32_BIT;
366 : 0 : cpt_snow3g_key_gen(key, keyx);
367 : 0 : memcpy(ci_key, keyx, key_len);
368 : 0 : se_ctx->fc_type = ROC_SE_PDCP;
369 : : }
370 : 0 : se_ctx->pdcp_auth_alg = ROC_SE_PDCP_ALG_TYPE_SNOW3G;
371 : 0 : se_ctx->zsk_flags = 0x1;
372 : 0 : break;
373 : 0 : case ROC_SE_ZUC_EIA3:
374 [ # # ]: 0 : if (chained_op) {
375 : : struct roc_se_onk_zuc_chain_ctx *ctx =
376 : : &zs_ch_ctx->zuc.onk_ctx;
377 : 0 : ctx->w0.s.state_conf =
378 : : ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
379 : 0 : ctx->w0.s.auth_type =
380 : : ROC_SE_PDCP_CHAIN_ALG_TYPE_ZUC;
381 : 0 : ctx->w0.s.mac_len = mac_len;
382 : 0 : ctx->w0.s.auth_key_len = key_len;
383 : 0 : memcpy(ctx->st.auth_key, key, key_len);
384 : 0 : cpt_zuc_const_update(ctx->st.auth_zuc_const,
385 : : key_len, mac_len);
386 : 0 : se_ctx->fc_type = ROC_SE_PDCP_CHAIN;
387 : : } else {
388 : 0 : zs_ctx->zuc.otk_ctx.w0.s.alg_type =
389 : : ROC_SE_PDCP_ALG_TYPE_ZUC;
390 : 0 : ret = cpt_pdcp_key_type_set(zs_ctx, key_len);
391 [ # # ]: 0 : if (ret)
392 : : return ret;
393 : 0 : ret = cpt_pdcp_mac_len_set(zs_ctx, mac_len);
394 [ # # ]: 0 : if (ret)
395 : : return ret;
396 [ # # ]: 0 : memcpy(ci_key, key, key_len);
397 [ # # ]: 0 : if (key_len == 32)
398 : : roc_se_zuc_bytes_swap(ci_key, key_len);
399 : 0 : cpt_zuc_const_update(zuc_const, key_len,
400 : : mac_len);
401 : 0 : se_ctx->fc_type = ROC_SE_PDCP;
402 : : }
403 : 0 : se_ctx->pdcp_auth_alg = ROC_SE_PDCP_ALG_TYPE_ZUC;
404 : 0 : se_ctx->zsk_flags = 0x1;
405 : 0 : break;
406 : 0 : case ROC_SE_AES_CMAC_EIA2:
407 [ # # ]: 0 : if (chained_op) {
408 : : struct roc_se_onk_zuc_chain_ctx *ctx =
409 : : &zs_ch_ctx->zuc.onk_ctx;
410 : : int key_type;
411 : 0 : key_type = cpt_pdcp_chain_key_type_get(key_len);
412 [ # # ]: 0 : if (key_type < 0)
413 : : return key_type;
414 : 0 : ctx->w0.s.auth_key_len = key_type;
415 : 0 : ctx->w0.s.state_conf =
416 : : ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
417 : 0 : ctx->w0.s.auth_type =
418 : : ROC_SE_PDCP_ALG_TYPE_AES_CTR;
419 : 0 : ctx->w0.s.mac_len = mac_len;
420 : 0 : memcpy(ctx->st.auth_key, key, key_len);
421 : 0 : se_ctx->fc_type = ROC_SE_PDCP_CHAIN;
422 : : } else {
423 : 0 : zs_ctx->zuc.otk_ctx.w0.s.alg_type =
424 : : ROC_SE_PDCP_ALG_TYPE_AES_CTR;
425 : 0 : zs_ctx->zuc.otk_ctx.w0.s.mac_len =
426 : : ROC_SE_PDCP_MAC_LEN_32_BIT;
427 : 0 : memcpy(ci_key, key, key_len);
428 : 0 : se_ctx->fc_type = ROC_SE_PDCP;
429 : : }
430 : 0 : se_ctx->pdcp_auth_alg = ROC_SE_PDCP_ALG_TYPE_AES_CMAC;
431 : 0 : se_ctx->eia2 = 1;
432 : 0 : se_ctx->zsk_flags = 0x1;
433 : 0 : break;
434 : 0 : case ROC_SE_KASUMI_F9_ECB:
435 : : /* Kasumi ECB mode */
436 : 0 : se_ctx->k_ecb = 1;
437 : 0 : memcpy(k_ctx->ci_key, key, key_len);
438 : 0 : se_ctx->fc_type = ROC_SE_KASUMI;
439 : 0 : se_ctx->zsk_flags = 0x1;
440 : 0 : break;
441 : 0 : case ROC_SE_KASUMI_F9_CBC:
442 : 0 : memcpy(k_ctx->ci_key, key, key_len);
443 : 0 : se_ctx->fc_type = ROC_SE_KASUMI;
444 : 0 : se_ctx->zsk_flags = 0x1;
445 : 0 : break;
446 : : default:
447 : : return -1;
448 : : }
449 : :
450 [ # # # # ]: 0 : if ((se_ctx->fc_type == ROC_SE_PDCP_CHAIN) && (mac_len != 4)) {
451 : 0 : plt_err("Only digest length of 4 is supported with PDCP chain");
452 : 0 : return -1;
453 : : }
454 : :
455 : 0 : se_ctx->mac_len = mac_len;
456 : 0 : se_ctx->hash_type = type;
457 : 0 : pdcp_alg = zs_ctx->zuc.otk_ctx.w0.s.alg_type;
458 [ # # ]: 0 : if (chained_op)
459 [ # # ]: 0 : opcode_minor = se_ctx->ciph_then_auth ? 2 : 3;
460 [ # # ]: 0 : else if (roc_model_is_cn9k())
461 : 0 : opcode_minor = ((1 << 7) | (pdcp_alg << 5) | 1);
462 : : else
463 : : opcode_minor = ((1 << 4) | 1);
464 : :
465 : 0 : se_ctx->template_w4.s.opcode_minor = opcode_minor;
466 : 0 : return 0;
467 : : }
468 : :
469 [ # # # # : 0 : if (!se_ctx->fc_type || (type && type != ROC_SE_GMAC_TYPE && !se_ctx->enc_cipher))
# # ]
470 : 0 : se_ctx->fc_type = ROC_SE_HASH_HMAC;
471 : :
472 [ # # # # ]: 0 : if (se_ctx->fc_type == ROC_SE_FC_GEN && key_len > 64) {
473 : 0 : plt_err("Maximum auth key length supported is 64");
474 : 0 : return -1;
475 : : }
476 : :
477 : : /* For GMAC auth, cipher must be NULL */
478 [ # # ]: 0 : if (type == ROC_SE_GMAC_TYPE) {
479 : 0 : fctx->enc.enc_cipher = 0;
480 : 0 : se_ctx->template_w4.s.opcode_minor = BIT(5);
481 : : }
482 : :
483 : 0 : fctx->enc.hash_type = type;
484 : 0 : se_ctx->hash_type = type;
485 : 0 : fctx->enc.mac_len = mac_len;
486 : 0 : se_ctx->mac_len = mac_len;
487 : :
488 [ # # ]: 0 : if (key_len) {
489 : : /*
490 : : * Chained operation (FC opcode) requires precomputed ipad and opad hashes, but for
491 : : * auth only (HMAC opcode) this is not required
492 : : */
493 [ # # ]: 0 : if (chained_op) {
494 : 0 : memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad));
495 : 0 : memset(fctx->hmac.opad, 0, sizeof(fctx->hmac.opad));
496 : 0 : cpt_hmac_opad_ipad_gen(type, key, key_len, &fctx->hmac);
497 : 0 : fctx->enc.auth_input_type = 0;
498 : : } else {
499 : 0 : se_ctx->hmac = 1;
500 : :
501 : 0 : se_ctx->auth_key = plt_zmalloc(key_len, 8);
502 [ # # ]: 0 : if (se_ctx->auth_key == NULL)
503 : : return -1;
504 : :
505 : : memcpy(se_ctx->auth_key, key, key_len);
506 : 0 : se_ctx->auth_key_len = key_len;
507 : : }
508 : : }
509 : : return 0;
510 : : }
511 : :
512 : : int
513 : 0 : roc_se_ciph_key_set(struct roc_se_ctx *se_ctx, roc_se_cipher_type type, const uint8_t *key,
514 : : uint16_t key_len)
515 : : {
516 : 0 : bool chained_op = se_ctx->ciph_then_auth || se_ctx->auth_then_ciph;
517 : 0 : struct roc_se_zuc_snow3g_ctx *zs_ctx = &se_ctx->se_ctx.zs_ctx;
518 : 0 : struct roc_se_context *fctx = &se_ctx->se_ctx.fctx;
519 : : struct roc_se_zuc_snow3g_chain_ctx *zs_ch_ctx;
520 : : uint8_t opcode_minor = 0;
521 : : uint8_t *zuc_const;
522 : : uint32_t keyx[4];
523 : : uint8_t *ci_key;
524 : : int i, ret;
525 : :
526 : : /* For NULL cipher, no processing required. */
527 [ # # ]: 0 : if (type == ROC_SE_PASSTHROUGH)
528 : : return 0;
529 : :
530 : : zs_ch_ctx = &se_ctx->se_ctx.zs_ch_ctx;
531 : :
532 [ # # ]: 0 : if (roc_model_is_cn9k()) {
533 : 0 : ci_key = zs_ctx->zuc.onk_ctx.ci_key;
534 : 0 : zuc_const = zs_ctx->zuc.onk_ctx.zuc_const;
535 : : } else {
536 : 0 : ci_key = zs_ctx->zuc.otk_ctx.ci_key;
537 : 0 : zuc_const = zs_ctx->zuc.otk_ctx.zuc_const;
538 : : }
539 : :
540 [ # # ]: 0 : if ((type == ROC_SE_AES_GCM) || (type == ROC_SE_AES_CCM))
541 : 0 : se_ctx->template_w4.s.opcode_minor = BIT(5);
542 : :
543 : 0 : ret = cpt_ciph_type_set(type, se_ctx, key_len);
544 [ # # ]: 0 : if (unlikely(ret))
545 : : return -1;
546 : :
547 [ # # ]: 0 : if (se_ctx->fc_type == ROC_SE_FC_GEN) {
548 : : /*
549 : : * We need to always say IV is from DPTR as user can
550 : : * sometimes override IV per operation.
551 : : */
552 : 0 : fctx->enc.iv_source = ROC_SE_FROM_DPTR;
553 : :
554 [ # # ]: 0 : if (se_ctx->auth_key_len > 64)
555 : : return -1;
556 : : }
557 : :
558 [ # # # # : 0 : switch (type) {
# # # # #
# # # # ]
559 : 0 : case ROC_SE_DES3_CBC:
560 : : /* CPT performs DES using 3DES with the 8B DES-key
561 : : * replicated 2 more times to match the 24B 3DES-key.
562 : : * Eg. If org. key is "0x0a 0x0b", then new key is
563 : : * "0x0a 0x0b 0x0a 0x0b 0x0a 0x0b"
564 : : */
565 [ # # ]: 0 : if (key_len == 8) {
566 : : /* Skipping the first 8B as it will be copied
567 : : * in the regular code flow
568 : : */
569 : 0 : memcpy(fctx->enc.encr_key + key_len, key, key_len);
570 : 0 : memcpy(fctx->enc.encr_key + 2 * key_len, key, key_len);
571 : : }
572 : : break;
573 : 0 : case ROC_SE_DES3_ECB:
574 : : /* For DES3_ECB IV need to be from CTX. */
575 : 0 : fctx->enc.iv_source = ROC_SE_FROM_CTX;
576 : 0 : break;
577 : 0 : case ROC_SE_AES_CBC:
578 : : case ROC_SE_AES_ECB:
579 : : case ROC_SE_AES_CFB:
580 : : case ROC_SE_AES_CTR:
581 : : case ROC_SE_CHACHA20:
582 : 0 : cpt_ciph_aes_key_type_set(fctx, key_len);
583 : 0 : break;
584 : 0 : case ROC_SE_AES_GCM:
585 : : case ROC_SE_AES_CCM:
586 : 0 : cpt_ciph_aes_key_type_set(fctx, key_len);
587 : 0 : break;
588 : 0 : case ROC_SE_AES_XTS:
589 : 0 : key_len = key_len / 2;
590 : 0 : cpt_ciph_aes_key_type_set(fctx, key_len);
591 : :
592 : : /* Copy key2 for XTS into ipad */
593 : 0 : memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad));
594 : 0 : memcpy(fctx->hmac.ipad, &key[key_len], key_len);
595 : : break;
596 : 0 : case ROC_SE_AES_DOCSISBPI:
597 : : /*
598 : : * DOCSIS uses the combination of AES-CBC and residual termination blocks that are
599 : : * less than 128. Pass it as regular AES-CBC cipher to CPT, but keep type in
600 : : * se_ctx as AES_DOCSISBPI to skip block size checks in instruction preparation.
601 : : */
602 : 0 : cpt_ciph_aes_key_type_set(fctx, key_len);
603 : 0 : fctx->enc.enc_cipher = ROC_SE_AES_CBC;
604 : 0 : memcpy(fctx->enc.encr_key, key, key_len);
605 : 0 : goto success;
606 : : case ROC_SE_DES_DOCSISBPI:
607 : : /* See case ROC_SE_DES3_CBC: for explanation */
608 [ # # ]: 0 : for (i = 0; i < 3; i++)
609 : 0 : memcpy(fctx->enc.encr_key + key_len * i, key, key_len);
610 : : /*
611 : : * DOCSIS uses DES-CBC mode with special handling of residual termination blocks
612 : : * that are less than 64 bits. Pass it as regular DES-CBC, but keep type in
613 : : * se_ctx as DES_DOCSISBPI to skip block size checks in instruction preparation.
614 : : */
615 : 0 : fctx->enc.enc_cipher = ROC_SE_DES3_CBC;
616 : 0 : goto success;
617 : 0 : case ROC_SE_SNOW3G_UEA2:
618 [ # # ]: 0 : if (chained_op == true) {
619 : : struct roc_se_onk_zuc_chain_ctx *ctx =
620 : : &zs_ch_ctx->zuc.onk_ctx;
621 : 0 : zs_ch_ctx->zuc.onk_ctx.w0.s.state_conf =
622 : : ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
623 : 0 : zs_ch_ctx->zuc.onk_ctx.w0.s.cipher_type =
624 : : ROC_SE_PDCP_CHAIN_ALG_TYPE_SNOW3G;
625 : 0 : zs_ch_ctx->zuc.onk_ctx.w0.s.ci_key_len = key_len;
626 : 0 : cpt_snow3g_key_gen(key, keyx);
627 : 0 : memcpy(ctx->st.ci_key, keyx, key_len);
628 : : } else {
629 : 0 : zs_ctx->zuc.otk_ctx.w0.s.key_len = ROC_SE_AES_128_BIT;
630 : 0 : zs_ctx->zuc.otk_ctx.w0.s.alg_type =
631 : : ROC_SE_PDCP_ALG_TYPE_SNOW3G;
632 : 0 : cpt_snow3g_key_gen(key, keyx);
633 : 0 : memcpy(ci_key, keyx, key_len);
634 : : }
635 : 0 : se_ctx->pdcp_ci_alg = ROC_SE_PDCP_ALG_TYPE_SNOW3G;
636 : 0 : se_ctx->zsk_flags = 0;
637 : 0 : goto success;
638 : 0 : case ROC_SE_ZUC_EEA3:
639 [ # # ]: 0 : if (chained_op == true) {
640 : : struct roc_se_onk_zuc_chain_ctx *ctx =
641 : : &zs_ch_ctx->zuc.onk_ctx;
642 : 0 : zs_ch_ctx->zuc.onk_ctx.w0.s.state_conf =
643 : : ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
644 : 0 : zs_ch_ctx->zuc.onk_ctx.w0.s.cipher_type =
645 : : ROC_SE_PDCP_CHAIN_ALG_TYPE_ZUC;
646 : 0 : memcpy(ctx->st.ci_key, key, key_len);
647 : 0 : memcpy(ctx->st.ci_zuc_const, zuc_key128, 32);
648 : 0 : zs_ch_ctx->zuc.onk_ctx.w0.s.ci_key_len = key_len;
649 : : } else {
650 : 0 : ret = cpt_pdcp_key_type_set(zs_ctx, key_len);
651 [ # # ]: 0 : if (ret)
652 : : return ret;
653 : 0 : zs_ctx->zuc.otk_ctx.w0.s.alg_type =
654 : : ROC_SE_PDCP_ALG_TYPE_ZUC;
655 [ # # ]: 0 : memcpy(ci_key, key, key_len);
656 [ # # ]: 0 : if (key_len == 32) {
657 : : roc_se_zuc_bytes_swap(ci_key, key_len);
658 : : memcpy(zuc_const, zuc_key256, 16);
659 : : } else
660 : : memcpy(zuc_const, zuc_key128, 32);
661 : : }
662 : :
663 : 0 : se_ctx->pdcp_ci_alg = ROC_SE_PDCP_ALG_TYPE_ZUC;
664 : 0 : se_ctx->zsk_flags = 0;
665 : 0 : goto success;
666 : 0 : case ROC_SE_AES_CTR_EEA2:
667 [ # # ]: 0 : if (chained_op == true) {
668 : : struct roc_se_onk_zuc_chain_ctx *ctx =
669 : : &zs_ch_ctx->zuc.onk_ctx;
670 : : int key_type;
671 : 0 : key_type = cpt_pdcp_chain_key_type_get(key_len);
672 [ # # ]: 0 : if (key_type < 0)
673 : : return key_type;
674 : 0 : ctx->w0.s.ci_key_len = key_type;
675 : 0 : ctx->w0.s.state_conf = ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
676 : 0 : ctx->w0.s.cipher_type = ROC_SE_PDCP_ALG_TYPE_AES_CTR;
677 : 0 : memcpy(ctx->st.ci_key, key, key_len);
678 : : } else {
679 : 0 : zs_ctx->zuc.otk_ctx.w0.s.key_len = ROC_SE_AES_128_BIT;
680 : 0 : zs_ctx->zuc.otk_ctx.w0.s.alg_type =
681 : : ROC_SE_PDCP_ALG_TYPE_AES_CTR;
682 : 0 : memcpy(ci_key, key, key_len);
683 : : }
684 : 0 : se_ctx->pdcp_ci_alg = ROC_SE_PDCP_ALG_TYPE_AES_CTR;
685 : 0 : se_ctx->zsk_flags = 0;
686 : 0 : goto success;
687 : 0 : case ROC_SE_KASUMI_F8_ECB:
688 : 0 : se_ctx->k_ecb = 1;
689 : 0 : memcpy(se_ctx->se_ctx.k_ctx.ci_key, key, key_len);
690 : 0 : se_ctx->zsk_flags = 0;
691 : 0 : goto success;
692 : 0 : case ROC_SE_KASUMI_F8_CBC:
693 : 0 : memcpy(se_ctx->se_ctx.k_ctx.ci_key, key, key_len);
694 : 0 : se_ctx->zsk_flags = 0;
695 : 0 : goto success;
696 : : default:
697 : : return -1;
698 : : }
699 : :
700 : : /* Only for ROC_SE_FC_GEN case */
701 : :
702 : : /* For GMAC auth, cipher must be NULL */
703 [ # # ]: 0 : if (se_ctx->hash_type != ROC_SE_GMAC_TYPE)
704 : 0 : fctx->enc.enc_cipher = type;
705 : :
706 : 0 : memcpy(fctx->enc.encr_key, key, key_len);
707 : :
708 : 0 : success:
709 : 0 : se_ctx->enc_cipher = type;
710 [ # # ]: 0 : if (se_ctx->fc_type == ROC_SE_PDCP_CHAIN) {
711 [ # # ]: 0 : se_ctx->template_w4.s.opcode_minor = se_ctx->ciph_then_auth ? 2 : 3;
712 [ # # ]: 0 : } else if (se_ctx->fc_type == ROC_SE_PDCP) {
713 [ # # ]: 0 : if (roc_model_is_cn9k())
714 : 0 : opcode_minor =
715 : 0 : ((1 << 7) | (se_ctx->pdcp_ci_alg << 5) | (se_ctx->zsk_flags & 0x7));
716 : : else
717 : : opcode_minor = ((1 << 4));
718 : 0 : se_ctx->template_w4.s.opcode_minor = opcode_minor;
719 : : }
720 : : return 0;
721 : : }
722 : :
723 : : void
724 [ # # ]: 0 : roc_se_ctx_swap(struct roc_se_ctx *se_ctx)
725 : : {
726 : : struct roc_se_zuc_snow3g_ctx *zs_ctx = &se_ctx->se_ctx.zs_ctx;
727 : :
728 [ # # ]: 0 : if (roc_model_is_cn9k())
729 : : return;
730 : :
731 [ # # ]: 0 : if (se_ctx->fc_type == ROC_SE_PDCP_CHAIN)
732 : : return;
733 : :
734 : 0 : zs_ctx->zuc.otk_ctx.w0.u64 = htobe64(zs_ctx->zuc.otk_ctx.w0.u64);
735 : : }
736 : :
737 : : void
738 : 0 : roc_se_ctx_init(struct roc_se_ctx *roc_se_ctx)
739 : : {
740 : 0 : struct se_ctx_s *ctx = &roc_se_ctx->se_ctx;
741 : : uint64_t ctx_len, *uc_ctx;
742 : : uint8_t i;
743 : :
744 [ # # ]: 0 : switch (roc_se_ctx->fc_type) {
745 : : case ROC_SE_FC_GEN:
746 : : ctx_len = sizeof(struct roc_se_context);
747 : : break;
748 : : case ROC_SE_PDCP:
749 : : ctx_len = sizeof(struct roc_se_zuc_snow3g_ctx);
750 : : break;
751 : : case ROC_SE_KASUMI:
752 : : ctx_len = sizeof(struct roc_se_kasumi_ctx);
753 : : break;
754 : : case ROC_SE_PDCP_CHAIN:
755 : : ctx_len = sizeof(struct roc_se_zuc_snow3g_chain_ctx);
756 : : break;
757 : : case ROC_SE_SM:
758 : : ctx_len = sizeof(struct roc_se_sm_context);
759 : : break;
760 : : default:
761 : : ctx_len = 0;
762 : : }
763 : :
764 : 0 : ctx_len = PLT_ALIGN_CEIL(ctx_len, 8);
765 : :
766 : : /* Skip w0 for swap */
767 : 0 : uc_ctx = PLT_PTR_ADD(ctx, sizeof(ctx->w0));
768 [ # # ]: 0 : for (i = 0; i < (ctx_len / 8); i++)
769 [ # # ]: 0 : uc_ctx[i] = plt_cpu_to_be_64(((uint64_t *)uc_ctx)[i]);
770 : :
771 : : /* Include w0 */
772 : : ctx_len += sizeof(ctx->w0);
773 : 0 : ctx_len = PLT_ALIGN_CEIL(ctx_len, 8);
774 : :
775 : 0 : ctx->w0.s.aop_valid = 1;
776 : 0 : ctx->w0.s.ctx_hdr_size = 0;
777 : :
778 : 0 : ctx->w0.s.ctx_size = PLT_ALIGN_FLOOR(ctx_len, 128);
779 : : if (ctx->w0.s.ctx_size == 0)
780 : 0 : ctx->w0.s.ctx_size = 1;
781 : :
782 : 0 : ctx->w0.s.ctx_push_size = ctx_len / 8;
783 : : if (ctx->w0.s.ctx_push_size > 32)
784 : : ctx->w0.s.ctx_push_size = 32;
785 : 0 : }
|