1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Cavium, Inc
8 #include "cpt_mcode_defines.h"
11 * This file defines functions that are interfaces to microcode spec.
15 static uint8_t zuc_d[32] = {
16 0x44, 0xD7, 0x26, 0xBC, 0x62, 0x6B, 0x13, 0x5E,
17 0x57, 0x89, 0x35, 0xE2, 0x71, 0x35, 0x09, 0xAF,
18 0x4D, 0x78, 0x2F, 0x13, 0x6B, 0xC4, 0x1A, 0xF1,
19 0x5E, 0x26, 0x3C, 0x4D, 0x78, 0x9A, 0x47, 0xAC
22 static __rte_always_inline int
23 cpt_is_algo_supported(struct rte_crypto_sym_xform *xform)
26 * Microcode only supports the following combination.
27 * Encryption followed by authentication
28 * Authentication followed by decryption
31 if ((xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) &&
32 (xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) &&
33 (xform->next->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT)) {
34 /* Unsupported as of now by microcode */
35 CPT_LOG_DP_ERR("Unsupported combination");
38 if ((xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) &&
39 (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) &&
40 (xform->cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT)) {
41 /* For GMAC auth there is no cipher operation */
42 if (xform->aead.algo != RTE_CRYPTO_AEAD_AES_GCM ||
43 xform->next->auth.algo !=
44 RTE_CRYPTO_AUTH_AES_GMAC) {
45 /* Unsupported as of now by microcode */
46 CPT_LOG_DP_ERR("Unsupported combination");
54 static __rte_always_inline void
55 gen_key_snow3g(uint8_t *ck, uint32_t *keyx)
59 for (i = 0; i < 4; i++) {
61 keyx[3 - i] = (ck[base] << 24) | (ck[base + 1] << 16) |
62 (ck[base + 2] << 8) | (ck[base + 3]);
63 keyx[3 - i] = rte_cpu_to_be_32(keyx[3 - i]);
67 static __rte_always_inline int
68 cpt_fc_ciph_validate_key_aes(uint16_t key_len)
80 static __rte_always_inline int
81 cpt_fc_ciph_validate_key(cipher_type_t type, struct cpt_ctx *cpt_ctx,
98 if (unlikely(cpt_fc_ciph_validate_key_aes(key_len) != 0))
103 key_len = key_len / 2;
104 if (unlikely(key_len == CPT_BYTE_24)) {
105 CPT_LOG_DP_ERR("Invalid AES key len for XTS");
108 if (unlikely(cpt_fc_ciph_validate_key_aes(key_len) != 0))
114 if (unlikely(key_len != 16))
116 /* No support for AEAD yet */
117 if (unlikely(cpt_ctx->hash_type))
119 fc_type = ZUC_SNOW3G;
123 if (unlikely(key_len != 16))
125 /* No support for AEAD yet */
126 if (unlikely(cpt_ctx->hash_type))
136 static __rte_always_inline void
137 cpt_fc_ciph_set_key_passthrough(struct cpt_ctx *cpt_ctx, mc_fc_context_t *fctx)
139 cpt_ctx->enc_cipher = 0;
140 CPT_P_ENC_CTRL(fctx).enc_cipher = 0;
143 static __rte_always_inline void
144 cpt_fc_ciph_set_key_set_aes_key_type(mc_fc_context_t *fctx, uint16_t key_len)
146 mc_aes_type_t aes_key_type = 0;
149 aes_key_type = AES_128_BIT;
152 aes_key_type = AES_192_BIT;
155 aes_key_type = AES_256_BIT;
158 /* This should not happen */
159 CPT_LOG_DP_ERR("Invalid AES key len");
162 CPT_P_ENC_CTRL(fctx).aes_key = aes_key_type;
165 static __rte_always_inline void
166 cpt_fc_ciph_set_key_snow3g_uea2(struct cpt_ctx *cpt_ctx, uint8_t *key,
171 gen_key_snow3g(key, keyx);
172 memcpy(cpt_ctx->zs_ctx.ci_key, keyx, key_len);
173 cpt_ctx->fc_type = ZUC_SNOW3G;
174 cpt_ctx->zsk_flags = 0;
177 static __rte_always_inline void
178 cpt_fc_ciph_set_key_zuc_eea3(struct cpt_ctx *cpt_ctx, uint8_t *key,
182 memcpy(cpt_ctx->zs_ctx.ci_key, key, key_len);
183 memcpy(cpt_ctx->zs_ctx.zuc_const, zuc_d, 32);
184 cpt_ctx->fc_type = ZUC_SNOW3G;
185 cpt_ctx->zsk_flags = 0;
188 static __rte_always_inline void
189 cpt_fc_ciph_set_key_kasumi_f8_ecb(struct cpt_ctx *cpt_ctx, uint8_t *key,
193 memcpy(cpt_ctx->k_ctx.ci_key, key, key_len);
194 cpt_ctx->zsk_flags = 0;
195 cpt_ctx->fc_type = KASUMI;
198 static __rte_always_inline void
199 cpt_fc_ciph_set_key_kasumi_f8_cbc(struct cpt_ctx *cpt_ctx, uint8_t *key,
202 memcpy(cpt_ctx->k_ctx.ci_key, key, key_len);
203 cpt_ctx->zsk_flags = 0;
204 cpt_ctx->fc_type = KASUMI;
207 static __rte_always_inline int
208 cpt_fc_ciph_set_key(void *ctx, cipher_type_t type, uint8_t *key,
209 uint16_t key_len, uint8_t *salt)
211 struct cpt_ctx *cpt_ctx = ctx;
212 mc_fc_context_t *fctx = &cpt_ctx->fctx;
213 uint64_t *ctrl_flags = NULL;
216 /* Validate key before proceeding */
217 fc_type = cpt_fc_ciph_validate_key(type, cpt_ctx, key_len);
218 if (unlikely(fc_type == -1))
221 if (fc_type == FC_GEN) {
222 cpt_ctx->fc_type = FC_GEN;
223 ctrl_flags = (uint64_t *)&(fctx->enc.enc_ctrl.flags);
224 *ctrl_flags = rte_be_to_cpu_64(*ctrl_flags);
226 * We need to always say IV is from DPTR as user can
227 * sometimes iverride IV per operation.
229 CPT_P_ENC_CTRL(fctx).iv_source = CPT_FROM_DPTR;
234 cpt_fc_ciph_set_key_passthrough(cpt_ctx, fctx);
237 /* CPT performs DES using 3DES with the 8B DES-key
238 * replicated 2 more times to match the 24B 3DES-key.
239 * Eg. If org. key is "0x0a 0x0b", then new key is
240 * "0x0a 0x0b 0x0a 0x0b 0x0a 0x0b"
243 /* Skipping the first 8B as it will be copied
244 * in the regular code flow
246 memcpy(fctx->enc.encr_key+key_len, key, key_len);
247 memcpy(fctx->enc.encr_key+2*key_len, key, key_len);
251 /* For DES3_ECB IV need to be from CTX. */
252 CPT_P_ENC_CTRL(fctx).iv_source = CPT_FROM_CTX;
258 cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len);
261 /* Even though iv source is from dptr,
262 * aes_gcm salt is taken from ctx
265 memcpy(fctx->enc.encr_iv, salt, 4);
266 /* Assuming it was just salt update
272 cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len);
275 key_len = key_len / 2;
276 cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len);
278 /* Copy key2 for XTS into ipad */
279 memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad));
280 memcpy(fctx->hmac.ipad, &key[key_len], key_len);
283 cpt_fc_ciph_set_key_snow3g_uea2(cpt_ctx, key, key_len);
286 cpt_fc_ciph_set_key_zuc_eea3(cpt_ctx, key, key_len);
289 cpt_fc_ciph_set_key_kasumi_f8_ecb(cpt_ctx, key, key_len);
292 cpt_fc_ciph_set_key_kasumi_f8_cbc(cpt_ctx, key, key_len);
298 /* Only for FC_GEN case */
300 /* For GMAC auth, cipher must be NULL */
301 if (cpt_ctx->hash_type != GMAC_TYPE)
302 CPT_P_ENC_CTRL(fctx).enc_cipher = type;
304 memcpy(fctx->enc.encr_key, key, key_len);
307 *ctrl_flags = rte_cpu_to_be_64(*ctrl_flags);
310 cpt_ctx->enc_cipher = type;
315 static __rte_always_inline int
316 cpt_fc_auth_set_key(void *ctx, auth_type_t type, uint8_t *key,
317 uint16_t key_len, uint16_t mac_len)
319 struct cpt_ctx *cpt_ctx = ctx;
320 mc_fc_context_t *fctx = &cpt_ctx->fctx;
321 uint64_t *ctrl_flags = NULL;
323 if ((type >= ZUC_EIA3) && (type <= KASUMI_F9_ECB)) {
328 /* No support for AEAD yet */
329 if (cpt_ctx->enc_cipher)
331 /* For ZUC/SNOW3G/Kasumi */
335 gen_key_snow3g(key, keyx);
336 memcpy(cpt_ctx->zs_ctx.ci_key, keyx, key_len);
337 cpt_ctx->fc_type = ZUC_SNOW3G;
338 cpt_ctx->zsk_flags = 0x1;
342 memcpy(cpt_ctx->zs_ctx.ci_key, key, key_len);
343 memcpy(cpt_ctx->zs_ctx.zuc_const, zuc_d, 32);
344 cpt_ctx->fc_type = ZUC_SNOW3G;
345 cpt_ctx->zsk_flags = 0x1;
348 /* Kasumi ECB mode */
350 memcpy(cpt_ctx->k_ctx.ci_key, key, key_len);
351 cpt_ctx->fc_type = KASUMI;
352 cpt_ctx->zsk_flags = 0x1;
355 memcpy(cpt_ctx->k_ctx.ci_key, key, key_len);
356 cpt_ctx->fc_type = KASUMI;
357 cpt_ctx->zsk_flags = 0x1;
362 cpt_ctx->mac_len = 4;
363 cpt_ctx->hash_type = type;
367 if (!(cpt_ctx->fc_type == FC_GEN && !type)) {
368 if (!cpt_ctx->fc_type || !cpt_ctx->enc_cipher)
369 cpt_ctx->fc_type = HASH_HMAC;
372 ctrl_flags = (uint64_t *)&fctx->enc.enc_ctrl.flags;
373 *ctrl_flags = rte_be_to_cpu_64(*ctrl_flags);
375 /* For GMAC auth, cipher must be NULL */
376 if (type == GMAC_TYPE)
377 CPT_P_ENC_CTRL(fctx).enc_cipher = 0;
379 CPT_P_ENC_CTRL(fctx).hash_type = cpt_ctx->hash_type = type;
380 CPT_P_ENC_CTRL(fctx).mac_len = cpt_ctx->mac_len = mac_len;
384 memset(cpt_ctx->auth_key, 0, sizeof(cpt_ctx->auth_key));
385 memcpy(cpt_ctx->auth_key, key, key_len);
386 cpt_ctx->auth_key_len = key_len;
387 memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad));
388 memset(fctx->hmac.opad, 0, sizeof(fctx->hmac.opad));
389 memcpy(fctx->hmac.opad, key, key_len);
390 CPT_P_ENC_CTRL(fctx).auth_input_type = 1;
392 *ctrl_flags = rte_cpu_to_be_64(*ctrl_flags);
396 static __rte_always_inline int
397 fill_sess_aead(struct rte_crypto_sym_xform *xform,
398 struct cpt_sess_misc *sess)
400 struct rte_crypto_aead_xform *aead_form;
401 cipher_type_t enc_type = 0; /* NULL Cipher type */
402 auth_type_t auth_type = 0; /* NULL Auth type */
403 uint32_t cipher_key_len = 0;
404 uint8_t zsk_flag = 0, aes_gcm = 0;
405 aead_form = &xform->aead;
408 if (aead_form->op == RTE_CRYPTO_AEAD_OP_ENCRYPT &&
409 aead_form->algo == RTE_CRYPTO_AEAD_AES_GCM) {
410 sess->cpt_op |= CPT_OP_CIPHER_ENCRYPT;
411 sess->cpt_op |= CPT_OP_AUTH_GENERATE;
412 } else if (aead_form->op == RTE_CRYPTO_AEAD_OP_DECRYPT &&
413 aead_form->algo == RTE_CRYPTO_AEAD_AES_GCM) {
414 sess->cpt_op |= CPT_OP_CIPHER_DECRYPT;
415 sess->cpt_op |= CPT_OP_AUTH_VERIFY;
417 CPT_LOG_DP_ERR("Unknown cipher operation\n");
420 switch (aead_form->algo) {
421 case RTE_CRYPTO_AEAD_AES_GCM:
426 case RTE_CRYPTO_AEAD_AES_CCM:
427 CPT_LOG_DP_ERR("Crypto: Unsupported cipher algo %u",
431 CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified",
435 if (aead_form->key.length < cipher_key_len) {
436 CPT_LOG_DP_ERR("Invalid cipher params keylen %lu",
437 (unsigned int long)aead_form->key.length);
440 sess->zsk_flag = zsk_flag;
441 sess->aes_gcm = aes_gcm;
442 sess->mac_len = aead_form->digest_length;
443 sess->iv_offset = aead_form->iv.offset;
444 sess->iv_length = aead_form->iv.length;
445 sess->aad_length = aead_form->aad_length;
446 ctx = (void *)((uint8_t *)sess + sizeof(struct cpt_sess_misc)),
448 cpt_fc_ciph_set_key(ctx, enc_type, aead_form->key.data,
449 aead_form->key.length, NULL);
451 cpt_fc_auth_set_key(ctx, auth_type, NULL, 0, aead_form->digest_length);
456 static __rte_always_inline int
457 fill_sess_cipher(struct rte_crypto_sym_xform *xform,
458 struct cpt_sess_misc *sess)
460 struct rte_crypto_cipher_xform *c_form;
461 cipher_type_t enc_type = 0; /* NULL Cipher type */
462 uint32_t cipher_key_len = 0;
463 uint8_t zsk_flag = 0, aes_gcm = 0, aes_ctr = 0, is_null = 0;
465 if (xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER)
468 c_form = &xform->cipher;
470 if (c_form->op == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
471 sess->cpt_op |= CPT_OP_CIPHER_ENCRYPT;
472 else if (c_form->op == RTE_CRYPTO_CIPHER_OP_DECRYPT)
473 sess->cpt_op |= CPT_OP_CIPHER_DECRYPT;
475 CPT_LOG_DP_ERR("Unknown cipher operation\n");
479 switch (c_form->algo) {
480 case RTE_CRYPTO_CIPHER_AES_CBC:
484 case RTE_CRYPTO_CIPHER_3DES_CBC:
488 case RTE_CRYPTO_CIPHER_DES_CBC:
489 /* DES is implemented using 3DES in hardware */
493 case RTE_CRYPTO_CIPHER_AES_CTR:
498 case RTE_CRYPTO_CIPHER_NULL:
502 case RTE_CRYPTO_CIPHER_KASUMI_F8:
503 enc_type = KASUMI_F8_ECB;
507 case RTE_CRYPTO_CIPHER_SNOW3G_UEA2:
508 enc_type = SNOW3G_UEA2;
512 case RTE_CRYPTO_CIPHER_ZUC_EEA3:
517 case RTE_CRYPTO_CIPHER_AES_XTS:
521 case RTE_CRYPTO_CIPHER_3DES_ECB:
525 case RTE_CRYPTO_CIPHER_AES_ECB:
529 case RTE_CRYPTO_CIPHER_3DES_CTR:
530 case RTE_CRYPTO_CIPHER_AES_F8:
531 case RTE_CRYPTO_CIPHER_ARC4:
532 CPT_LOG_DP_ERR("Crypto: Unsupported cipher algo %u",
536 CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified",
541 if (c_form->key.length < cipher_key_len) {
542 CPT_LOG_DP_ERR("Invalid cipher params keylen %lu",
543 (unsigned long) c_form->key.length);
547 sess->zsk_flag = zsk_flag;
548 sess->aes_gcm = aes_gcm;
549 sess->aes_ctr = aes_ctr;
550 sess->iv_offset = c_form->iv.offset;
551 sess->iv_length = c_form->iv.length;
552 sess->is_null = is_null;
554 cpt_fc_ciph_set_key(SESS_PRIV(sess), enc_type, c_form->key.data,
555 c_form->key.length, NULL);
560 static __rte_always_inline int
561 fill_sess_auth(struct rte_crypto_sym_xform *xform,
562 struct cpt_sess_misc *sess)
564 struct rte_crypto_auth_xform *a_form;
565 auth_type_t auth_type = 0; /* NULL Auth type */
566 uint8_t zsk_flag = 0, aes_gcm = 0, is_null = 0;
568 if (xform->type != RTE_CRYPTO_SYM_XFORM_AUTH)
571 a_form = &xform->auth;
573 if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY)
574 sess->cpt_op |= CPT_OP_AUTH_VERIFY;
575 else if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE)
576 sess->cpt_op |= CPT_OP_AUTH_GENERATE;
578 CPT_LOG_DP_ERR("Unknown auth operation");
582 if (a_form->key.length > 64) {
583 CPT_LOG_DP_ERR("Auth key length is big");
587 switch (a_form->algo) {
588 case RTE_CRYPTO_AUTH_SHA1_HMAC:
590 case RTE_CRYPTO_AUTH_SHA1:
591 auth_type = SHA1_TYPE;
593 case RTE_CRYPTO_AUTH_SHA256_HMAC:
594 case RTE_CRYPTO_AUTH_SHA256:
595 auth_type = SHA2_SHA256;
597 case RTE_CRYPTO_AUTH_SHA512_HMAC:
598 case RTE_CRYPTO_AUTH_SHA512:
599 auth_type = SHA2_SHA512;
601 case RTE_CRYPTO_AUTH_AES_GMAC:
602 auth_type = GMAC_TYPE;
605 case RTE_CRYPTO_AUTH_SHA224_HMAC:
606 case RTE_CRYPTO_AUTH_SHA224:
607 auth_type = SHA2_SHA224;
609 case RTE_CRYPTO_AUTH_SHA384_HMAC:
610 case RTE_CRYPTO_AUTH_SHA384:
611 auth_type = SHA2_SHA384;
613 case RTE_CRYPTO_AUTH_MD5_HMAC:
614 case RTE_CRYPTO_AUTH_MD5:
615 auth_type = MD5_TYPE;
617 case RTE_CRYPTO_AUTH_KASUMI_F9:
618 auth_type = KASUMI_F9_ECB;
620 * Indicate that direction needs to be taken out
625 case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
626 auth_type = SNOW3G_UIA2;
629 case RTE_CRYPTO_AUTH_ZUC_EIA3:
630 auth_type = ZUC_EIA3;
633 case RTE_CRYPTO_AUTH_NULL:
637 case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
638 case RTE_CRYPTO_AUTH_AES_CMAC:
639 case RTE_CRYPTO_AUTH_AES_CBC_MAC:
640 CPT_LOG_DP_ERR("Crypto: Unsupported hash algo %u",
644 CPT_LOG_DP_ERR("Crypto: Undefined Hash algo %u specified",
649 sess->zsk_flag = zsk_flag;
650 sess->aes_gcm = aes_gcm;
651 sess->mac_len = a_form->digest_length;
652 sess->is_null = is_null;
654 sess->auth_iv_offset = a_form->iv.offset;
655 sess->auth_iv_length = a_form->iv.length;
657 cpt_fc_auth_set_key(SESS_PRIV(sess), auth_type, a_form->key.data,
658 a_form->key.length, a_form->digest_length);
666 static __rte_always_inline int
667 fill_sess_gmac(struct rte_crypto_sym_xform *xform,
668 struct cpt_sess_misc *sess)
670 struct rte_crypto_auth_xform *a_form;
671 cipher_type_t enc_type = 0; /* NULL Cipher type */
672 auth_type_t auth_type = 0; /* NULL Auth type */
673 uint8_t zsk_flag = 0, aes_gcm = 0;
676 if (xform->type != RTE_CRYPTO_SYM_XFORM_AUTH)
679 a_form = &xform->auth;
681 if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE)
682 sess->cpt_op |= CPT_OP_ENCODE;
683 else if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY)
684 sess->cpt_op |= CPT_OP_DECODE;
686 CPT_LOG_DP_ERR("Unknown auth operation");
690 switch (a_form->algo) {
691 case RTE_CRYPTO_AUTH_AES_GMAC:
693 auth_type = GMAC_TYPE;
696 CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified",
701 sess->zsk_flag = zsk_flag;
702 sess->aes_gcm = aes_gcm;
704 sess->iv_offset = a_form->iv.offset;
705 sess->iv_length = a_form->iv.length;
706 sess->mac_len = a_form->digest_length;
707 ctx = (void *)((uint8_t *)sess + sizeof(struct cpt_sess_misc)),
709 cpt_fc_ciph_set_key(ctx, enc_type, a_form->key.data,
710 a_form->key.length, NULL);
711 cpt_fc_auth_set_key(ctx, auth_type, NULL, 0, a_form->digest_length);
716 #endif /*_CPT_UCODE_H_ */