1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Cavium, Inc 3 */ 4 5 #ifndef _CPT_UCODE_H_ 6 #define _CPT_UCODE_H_ 7 #include <stdbool.h> 8 9 #include "cpt_common.h" 10 #include "cpt_hw_types.h" 11 #include "cpt_mcode_defines.h" 12 13 /* 14 * This file defines functions that are interfaces to microcode spec. 15 * 16 */ 17 18 static uint8_t zuc_d[32] = { 19 0x44, 0xD7, 0x26, 0xBC, 0x62, 0x6B, 0x13, 0x5E, 20 0x57, 0x89, 0x35, 0xE2, 0x71, 0x35, 0x09, 0xAF, 21 0x4D, 0x78, 0x2F, 0x13, 0x6B, 0xC4, 0x1A, 0xF1, 22 0x5E, 0x26, 0x3C, 0x4D, 0x78, 0x9A, 0x47, 0xAC 23 }; 24 25 static __rte_always_inline void 26 gen_key_snow3g(const uint8_t *ck, uint32_t *keyx) 27 { 28 int i, base; 29 30 for (i = 0; i < 4; i++) { 31 base = 4 * i; 32 keyx[3 - i] = (ck[base] << 24) | (ck[base + 1] << 16) | 33 (ck[base + 2] << 8) | (ck[base + 3]); 34 keyx[3 - i] = rte_cpu_to_be_32(keyx[3 - i]); 35 } 36 } 37 38 static __rte_always_inline void 39 cpt_fc_salt_update(void *ctx, 40 uint8_t *salt) 41 { 42 struct cpt_ctx *cpt_ctx = ctx; 43 memcpy(&cpt_ctx->fctx.enc.encr_iv, salt, 4); 44 } 45 46 static __rte_always_inline int 47 cpt_fc_ciph_validate_key_aes(uint16_t key_len) 48 { 49 switch (key_len) { 50 case CPT_BYTE_16: 51 case CPT_BYTE_24: 52 case CPT_BYTE_32: 53 return 0; 54 default: 55 return -1; 56 } 57 } 58 59 static __rte_always_inline int 60 cpt_fc_ciph_set_type(cipher_type_t type, struct cpt_ctx *ctx, uint16_t key_len) 61 { 62 int fc_type = 0; 63 switch (type) { 64 case PASSTHROUGH: 65 fc_type = FC_GEN; 66 break; 67 case DES3_CBC: 68 case DES3_ECB: 69 fc_type = FC_GEN; 70 break; 71 case AES_CBC: 72 case AES_ECB: 73 case AES_CFB: 74 case AES_CTR: 75 case AES_GCM: 76 if (unlikely(cpt_fc_ciph_validate_key_aes(key_len) != 0)) 77 return -1; 78 fc_type = FC_GEN; 79 break; 80 case CHACHA20: 81 fc_type = FC_GEN; 82 break; 83 case AES_XTS: 84 key_len = key_len / 2; 85 if (unlikely(key_len == CPT_BYTE_24)) { 86 CPT_LOG_DP_ERR("Invalid AES key len for XTS"); 87 return -1; 88 } 89 if (unlikely(cpt_fc_ciph_validate_key_aes(key_len) != 0)) 90 return -1; 91 fc_type = FC_GEN; 92 break; 93 case ZUC_EEA3: 94 case SNOW3G_UEA2: 95 if (unlikely(key_len != 16)) 96 return -1; 97 /* No support for AEAD yet */ 98 if (unlikely(ctx->hash_type)) 99 return -1; 100 fc_type = ZUC_SNOW3G; 101 break; 102 case KASUMI_F8_CBC: 103 case KASUMI_F8_ECB: 104 if (unlikely(key_len != 16)) 105 return -1; 106 /* No support for AEAD yet */ 107 if (unlikely(ctx->hash_type)) 108 return -1; 109 fc_type = KASUMI; 110 break; 111 default: 112 return -1; 113 } 114 115 ctx->fc_type = fc_type; 116 return 0; 117 } 118 119 static __rte_always_inline void 120 cpt_fc_ciph_set_key_passthrough(struct cpt_ctx *cpt_ctx, mc_fc_context_t *fctx) 121 { 122 cpt_ctx->enc_cipher = 0; 123 fctx->enc.enc_cipher = 0; 124 } 125 126 static __rte_always_inline void 127 cpt_fc_ciph_set_key_set_aes_key_type(mc_fc_context_t *fctx, uint16_t key_len) 128 { 129 mc_aes_type_t aes_key_type = 0; 130 switch (key_len) { 131 case CPT_BYTE_16: 132 aes_key_type = AES_128_BIT; 133 break; 134 case CPT_BYTE_24: 135 aes_key_type = AES_192_BIT; 136 break; 137 case CPT_BYTE_32: 138 aes_key_type = AES_256_BIT; 139 break; 140 default: 141 /* This should not happen */ 142 CPT_LOG_DP_ERR("Invalid AES key len"); 143 return; 144 } 145 fctx->enc.aes_key = aes_key_type; 146 } 147 148 static __rte_always_inline void 149 cpt_fc_ciph_set_key_snow3g_uea2(struct cpt_ctx *cpt_ctx, const uint8_t *key, 150 uint16_t key_len) 151 { 152 uint32_t keyx[4]; 153 cpt_ctx->snow3g = 1; 154 gen_key_snow3g(key, keyx); 155 memcpy(cpt_ctx->zs_ctx.ci_key, keyx, key_len); 156 cpt_ctx->zsk_flags = 0; 157 } 158 159 static __rte_always_inline void 160 cpt_fc_ciph_set_key_zuc_eea3(struct cpt_ctx *cpt_ctx, const uint8_t *key, 161 uint16_t key_len) 162 { 163 cpt_ctx->snow3g = 0; 164 memcpy(cpt_ctx->zs_ctx.ci_key, key, key_len); 165 memcpy(cpt_ctx->zs_ctx.zuc_const, zuc_d, 32); 166 cpt_ctx->zsk_flags = 0; 167 } 168 169 static __rte_always_inline void 170 cpt_fc_ciph_set_key_kasumi_f8_ecb(struct cpt_ctx *cpt_ctx, const uint8_t *key, 171 uint16_t key_len) 172 { 173 cpt_ctx->k_ecb = 1; 174 memcpy(cpt_ctx->k_ctx.ci_key, key, key_len); 175 cpt_ctx->zsk_flags = 0; 176 } 177 178 static __rte_always_inline void 179 cpt_fc_ciph_set_key_kasumi_f8_cbc(struct cpt_ctx *cpt_ctx, const uint8_t *key, 180 uint16_t key_len) 181 { 182 memcpy(cpt_ctx->k_ctx.ci_key, key, key_len); 183 cpt_ctx->zsk_flags = 0; 184 } 185 186 static __rte_always_inline int 187 cpt_fc_ciph_set_key(void *ctx, cipher_type_t type, const uint8_t *key, 188 uint16_t key_len, uint8_t *salt) 189 { 190 struct cpt_ctx *cpt_ctx = ctx; 191 mc_fc_context_t *fctx = &cpt_ctx->fctx; 192 int ret; 193 194 ret = cpt_fc_ciph_set_type(type, cpt_ctx, key_len); 195 if (unlikely(ret)) 196 return -1; 197 198 if (cpt_ctx->fc_type == FC_GEN) { 199 /* 200 * We need to always say IV is from DPTR as user can 201 * sometimes iverride IV per operation. 202 */ 203 fctx->enc.iv_source = CPT_FROM_DPTR; 204 205 if (cpt_ctx->auth_key_len > 64) 206 return -1; 207 } 208 209 switch (type) { 210 case PASSTHROUGH: 211 cpt_fc_ciph_set_key_passthrough(cpt_ctx, fctx); 212 goto success; 213 case DES3_CBC: 214 /* CPT performs DES using 3DES with the 8B DES-key 215 * replicated 2 more times to match the 24B 3DES-key. 216 * Eg. If org. key is "0x0a 0x0b", then new key is 217 * "0x0a 0x0b 0x0a 0x0b 0x0a 0x0b" 218 */ 219 if (key_len == 8) { 220 /* Skipping the first 8B as it will be copied 221 * in the regular code flow 222 */ 223 memcpy(fctx->enc.encr_key+key_len, key, key_len); 224 memcpy(fctx->enc.encr_key+2*key_len, key, key_len); 225 } 226 break; 227 case DES3_ECB: 228 /* For DES3_ECB IV need to be from CTX. */ 229 fctx->enc.iv_source = CPT_FROM_CTX; 230 break; 231 case AES_CBC: 232 case AES_ECB: 233 case AES_CFB: 234 case AES_CTR: 235 case CHACHA20: 236 cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len); 237 break; 238 case AES_GCM: 239 /* Even though iv source is from dptr, 240 * aes_gcm salt is taken from ctx 241 */ 242 if (salt) { 243 memcpy(fctx->enc.encr_iv, salt, 4); 244 /* Assuming it was just salt update 245 * and nothing else 246 */ 247 if (!key) 248 goto success; 249 } 250 cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len); 251 break; 252 case AES_XTS: 253 key_len = key_len / 2; 254 cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len); 255 256 /* Copy key2 for XTS into ipad */ 257 memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad)); 258 memcpy(fctx->hmac.ipad, &key[key_len], key_len); 259 break; 260 case SNOW3G_UEA2: 261 cpt_fc_ciph_set_key_snow3g_uea2(cpt_ctx, key, key_len); 262 goto success; 263 case ZUC_EEA3: 264 cpt_fc_ciph_set_key_zuc_eea3(cpt_ctx, key, key_len); 265 goto success; 266 case KASUMI_F8_ECB: 267 cpt_fc_ciph_set_key_kasumi_f8_ecb(cpt_ctx, key, key_len); 268 goto success; 269 case KASUMI_F8_CBC: 270 cpt_fc_ciph_set_key_kasumi_f8_cbc(cpt_ctx, key, key_len); 271 goto success; 272 default: 273 return -1; 274 } 275 276 /* Only for FC_GEN case */ 277 278 /* For GMAC auth, cipher must be NULL */ 279 if (cpt_ctx->hash_type != GMAC_TYPE) 280 fctx->enc.enc_cipher = type; 281 282 memcpy(fctx->enc.encr_key, key, key_len); 283 284 success: 285 cpt_ctx->enc_cipher = type; 286 287 return 0; 288 } 289 290 static __rte_always_inline uint32_t 291 fill_sg_comp(sg_comp_t *list, 292 uint32_t i, 293 phys_addr_t dma_addr, 294 uint32_t size) 295 { 296 sg_comp_t *to = &list[i>>2]; 297 298 to->u.s.len[i%4] = rte_cpu_to_be_16(size); 299 to->ptr[i%4] = rte_cpu_to_be_64(dma_addr); 300 i++; 301 return i; 302 } 303 304 static __rte_always_inline uint32_t 305 fill_sg_comp_from_buf(sg_comp_t *list, 306 uint32_t i, 307 buf_ptr_t *from) 308 { 309 sg_comp_t *to = &list[i>>2]; 310 311 to->u.s.len[i%4] = rte_cpu_to_be_16(from->size); 312 to->ptr[i%4] = rte_cpu_to_be_64(from->dma_addr); 313 i++; 314 return i; 315 } 316 317 static __rte_always_inline uint32_t 318 fill_sg_comp_from_buf_min(sg_comp_t *list, 319 uint32_t i, 320 buf_ptr_t *from, 321 uint32_t *psize) 322 { 323 sg_comp_t *to = &list[i >> 2]; 324 uint32_t size = *psize; 325 uint32_t e_len; 326 327 e_len = (size > from->size) ? from->size : size; 328 to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); 329 to->ptr[i % 4] = rte_cpu_to_be_64(from->dma_addr); 330 *psize -= e_len; 331 i++; 332 return i; 333 } 334 335 /* 336 * This fills the MC expected SGIO list 337 * from IOV given by user. 338 */ 339 static __rte_always_inline uint32_t 340 fill_sg_comp_from_iov(sg_comp_t *list, 341 uint32_t i, 342 iov_ptr_t *from, uint32_t from_offset, 343 uint32_t *psize, buf_ptr_t *extra_buf, 344 uint32_t extra_offset) 345 { 346 int32_t j; 347 uint32_t extra_len = extra_buf ? extra_buf->size : 0; 348 uint32_t size = *psize; 349 buf_ptr_t *bufs; 350 351 bufs = from->bufs; 352 for (j = 0; (j < from->buf_cnt) && size; j++) { 353 phys_addr_t e_dma_addr; 354 uint32_t e_len; 355 sg_comp_t *to = &list[i >> 2]; 356 357 if (unlikely(from_offset)) { 358 if (from_offset >= bufs[j].size) { 359 from_offset -= bufs[j].size; 360 continue; 361 } 362 e_dma_addr = bufs[j].dma_addr + from_offset; 363 e_len = (size > (bufs[j].size - from_offset)) ? 364 (bufs[j].size - from_offset) : size; 365 from_offset = 0; 366 } else { 367 e_dma_addr = bufs[j].dma_addr; 368 e_len = (size > bufs[j].size) ? 369 bufs[j].size : size; 370 } 371 372 to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); 373 to->ptr[i % 4] = rte_cpu_to_be_64(e_dma_addr); 374 375 if (extra_len && (e_len >= extra_offset)) { 376 /* Break the data at given offset */ 377 uint32_t next_len = e_len - extra_offset; 378 phys_addr_t next_dma = e_dma_addr + extra_offset; 379 380 if (!extra_offset) { 381 i--; 382 } else { 383 e_len = extra_offset; 384 size -= e_len; 385 to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); 386 } 387 388 extra_len = RTE_MIN(extra_len, size); 389 /* Insert extra data ptr */ 390 if (extra_len) { 391 i++; 392 to = &list[i >> 2]; 393 to->u.s.len[i % 4] = 394 rte_cpu_to_be_16(extra_len); 395 to->ptr[i % 4] = 396 rte_cpu_to_be_64(extra_buf->dma_addr); 397 size -= extra_len; 398 } 399 400 next_len = RTE_MIN(next_len, size); 401 /* insert the rest of the data */ 402 if (next_len) { 403 i++; 404 to = &list[i >> 2]; 405 to->u.s.len[i % 4] = rte_cpu_to_be_16(next_len); 406 to->ptr[i % 4] = rte_cpu_to_be_64(next_dma); 407 size -= next_len; 408 } 409 extra_len = 0; 410 411 } else { 412 size -= e_len; 413 } 414 if (extra_offset) 415 extra_offset -= size; 416 i++; 417 } 418 419 *psize = size; 420 return (uint32_t)i; 421 } 422 423 static __rte_always_inline void 424 cpt_digest_gen_prep(uint32_t flags, 425 uint64_t d_lens, 426 digest_params_t *params, 427 void *op, 428 void **prep_req) 429 { 430 struct cpt_request_info *req; 431 uint32_t size, i; 432 uint16_t data_len, mac_len, key_len; 433 auth_type_t hash_type; 434 buf_ptr_t *meta_p; 435 struct cpt_ctx *ctx; 436 sg_comp_t *gather_comp; 437 sg_comp_t *scatter_comp; 438 uint8_t *in_buffer; 439 uint32_t g_size_bytes, s_size_bytes; 440 uint64_t dptr_dma, rptr_dma; 441 vq_cmd_word0_t vq_cmd_w0; 442 vq_cmd_word3_t vq_cmd_w3; 443 void *c_vaddr, *m_vaddr; 444 uint64_t c_dma, m_dma; 445 opcode_info_t opcode; 446 447 ctx = params->ctx_buf.vaddr; 448 meta_p = ¶ms->meta_buf; 449 450 m_vaddr = meta_p->vaddr; 451 m_dma = meta_p->dma_addr; 452 453 /* 454 * Save initial space that followed app data for completion code & 455 * alternate completion code to fall in same cache line as app data 456 */ 457 m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 458 m_dma += COMPLETION_CODE_SIZE; 459 size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 460 (uint8_t *)m_vaddr; 461 c_vaddr = (uint8_t *)m_vaddr + size; 462 c_dma = m_dma + size; 463 size += sizeof(cpt_res_s_t); 464 465 m_vaddr = (uint8_t *)m_vaddr + size; 466 m_dma += size; 467 468 req = m_vaddr; 469 470 size = sizeof(struct cpt_request_info); 471 m_vaddr = (uint8_t *)m_vaddr + size; 472 m_dma += size; 473 474 hash_type = ctx->hash_type; 475 mac_len = ctx->mac_len; 476 key_len = ctx->auth_key_len; 477 data_len = AUTH_DLEN(d_lens); 478 479 /*GP op header */ 480 vq_cmd_w0.u64 = 0; 481 vq_cmd_w0.s.param2 = ((uint16_t)hash_type << 8); 482 if (ctx->hmac) { 483 opcode.s.major = CPT_MAJOR_OP_HMAC | CPT_DMA_MODE; 484 vq_cmd_w0.s.param1 = key_len; 485 vq_cmd_w0.s.dlen = data_len + ROUNDUP8(key_len); 486 } else { 487 opcode.s.major = CPT_MAJOR_OP_HASH | CPT_DMA_MODE; 488 vq_cmd_w0.s.param1 = 0; 489 vq_cmd_w0.s.dlen = data_len; 490 } 491 492 opcode.s.minor = 0; 493 494 /* Null auth only case enters the if */ 495 if (unlikely(!hash_type && !ctx->enc_cipher)) { 496 opcode.s.major = CPT_MAJOR_OP_MISC; 497 /* Minor op is passthrough */ 498 opcode.s.minor = 0x03; 499 /* Send out completion code only */ 500 vq_cmd_w0.s.param2 = 0x1; 501 } 502 503 vq_cmd_w0.s.opcode = opcode.flags; 504 505 /* DPTR has SG list */ 506 in_buffer = m_vaddr; 507 dptr_dma = m_dma; 508 509 ((uint16_t *)in_buffer)[0] = 0; 510 ((uint16_t *)in_buffer)[1] = 0; 511 512 /* TODO Add error check if space will be sufficient */ 513 gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 514 515 /* 516 * Input gather list 517 */ 518 519 i = 0; 520 521 if (ctx->hmac) { 522 uint64_t k_dma = params->ctx_buf.dma_addr + 523 offsetof(struct cpt_ctx, auth_key); 524 /* Key */ 525 i = fill_sg_comp(gather_comp, i, k_dma, ROUNDUP8(key_len)); 526 } 527 528 /* input data */ 529 size = data_len; 530 if (size) { 531 i = fill_sg_comp_from_iov(gather_comp, i, params->src_iov, 532 0, &size, NULL, 0); 533 if (unlikely(size)) { 534 CPT_LOG_DP_DEBUG("Insufficient dst IOV size, short" 535 " by %dB", size); 536 return; 537 } 538 } else { 539 /* 540 * Looks like we need to support zero data 541 * gather ptr in case of hash & hmac 542 */ 543 i++; 544 } 545 ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 546 g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 547 548 /* 549 * Output Gather list 550 */ 551 552 i = 0; 553 scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 554 555 if (flags & VALID_MAC_BUF) { 556 if (unlikely(params->mac_buf.size < mac_len)) { 557 CPT_LOG_DP_ERR("Insufficient MAC size"); 558 return; 559 } 560 561 size = mac_len; 562 i = fill_sg_comp_from_buf_min(scatter_comp, i, 563 ¶ms->mac_buf, &size); 564 } else { 565 size = mac_len; 566 i = fill_sg_comp_from_iov(scatter_comp, i, 567 params->src_iov, data_len, 568 &size, NULL, 0); 569 if (unlikely(size)) { 570 CPT_LOG_DP_ERR("Insufficient dst IOV size, short by" 571 " %dB", size); 572 return; 573 } 574 } 575 576 ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 577 s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 578 579 size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 580 581 /* This is DPTR len incase of SG mode */ 582 vq_cmd_w0.s.dlen = size; 583 584 m_vaddr = (uint8_t *)m_vaddr + size; 585 m_dma += size; 586 587 /* cpt alternate completion address saved earlier */ 588 req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 589 *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 590 rptr_dma = c_dma - 8; 591 592 req->ist.ei1 = dptr_dma; 593 req->ist.ei2 = rptr_dma; 594 595 /* vq command w3 */ 596 vq_cmd_w3.u64 = 0; 597 598 /* 16 byte aligned cpt res address */ 599 req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 600 *req->completion_addr = COMPLETION_CODE_INIT; 601 req->comp_baddr = c_dma; 602 603 /* Fill microcode part of instruction */ 604 req->ist.ei0 = vq_cmd_w0.u64; 605 req->ist.ei3 = vq_cmd_w3.u64; 606 607 req->op = op; 608 609 *prep_req = req; 610 return; 611 } 612 613 static __rte_always_inline void 614 cpt_enc_hmac_prep(uint32_t flags, 615 uint64_t d_offs, 616 uint64_t d_lens, 617 fc_params_t *fc_params, 618 void *op, 619 void **prep_req) 620 { 621 uint32_t iv_offset = 0; 622 int32_t inputlen, outputlen, enc_dlen, auth_dlen; 623 struct cpt_ctx *cpt_ctx; 624 uint32_t cipher_type, hash_type; 625 uint32_t mac_len, size; 626 uint8_t iv_len = 16; 627 struct cpt_request_info *req; 628 buf_ptr_t *meta_p, *aad_buf = NULL; 629 uint32_t encr_offset, auth_offset; 630 uint32_t encr_data_len, auth_data_len, aad_len = 0; 631 uint32_t passthrough_len = 0; 632 void *m_vaddr, *offset_vaddr; 633 uint64_t m_dma, offset_dma, ctx_dma; 634 vq_cmd_word0_t vq_cmd_w0; 635 vq_cmd_word3_t vq_cmd_w3; 636 void *c_vaddr; 637 uint64_t c_dma; 638 opcode_info_t opcode; 639 640 meta_p = &fc_params->meta_buf; 641 m_vaddr = meta_p->vaddr; 642 m_dma = meta_p->dma_addr; 643 644 encr_offset = ENCR_OFFSET(d_offs); 645 auth_offset = AUTH_OFFSET(d_offs); 646 encr_data_len = ENCR_DLEN(d_lens); 647 auth_data_len = AUTH_DLEN(d_lens); 648 if (unlikely(flags & VALID_AAD_BUF)) { 649 /* 650 * We dont support both aad 651 * and auth data separately 652 */ 653 auth_data_len = 0; 654 auth_offset = 0; 655 aad_len = fc_params->aad_buf.size; 656 aad_buf = &fc_params->aad_buf; 657 } 658 cpt_ctx = fc_params->ctx_buf.vaddr; 659 cipher_type = cpt_ctx->enc_cipher; 660 hash_type = cpt_ctx->hash_type; 661 mac_len = cpt_ctx->mac_len; 662 663 /* 664 * Save initial space that followed app data for completion code & 665 * alternate completion code to fall in same cache line as app data 666 */ 667 m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 668 m_dma += COMPLETION_CODE_SIZE; 669 size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 670 (uint8_t *)m_vaddr; 671 672 c_vaddr = (uint8_t *)m_vaddr + size; 673 c_dma = m_dma + size; 674 size += sizeof(cpt_res_s_t); 675 676 m_vaddr = (uint8_t *)m_vaddr + size; 677 m_dma += size; 678 679 /* start cpt request info struct at 8 byte boundary */ 680 size = (uint8_t *)RTE_PTR_ALIGN(m_vaddr, 8) - 681 (uint8_t *)m_vaddr; 682 683 req = (struct cpt_request_info *)((uint8_t *)m_vaddr + size); 684 685 size += sizeof(struct cpt_request_info); 686 m_vaddr = (uint8_t *)m_vaddr + size; 687 m_dma += size; 688 689 if (unlikely(!(flags & VALID_IV_BUF))) { 690 iv_len = 0; 691 iv_offset = ENCR_IV_OFFSET(d_offs); 692 } 693 694 if (unlikely(flags & VALID_AAD_BUF)) { 695 /* 696 * When AAD is given, data above encr_offset is pass through 697 * Since AAD is given as separate pointer and not as offset, 698 * this is a special case as we need to fragment input data 699 * into passthrough + encr_data and then insert AAD in between. 700 */ 701 if (hash_type != GMAC_TYPE) { 702 passthrough_len = encr_offset; 703 auth_offset = passthrough_len + iv_len; 704 encr_offset = passthrough_len + aad_len + iv_len; 705 auth_data_len = aad_len + encr_data_len; 706 } else { 707 passthrough_len = 16 + aad_len; 708 auth_offset = passthrough_len + iv_len; 709 auth_data_len = aad_len; 710 } 711 } else { 712 encr_offset += iv_len; 713 auth_offset += iv_len; 714 } 715 716 /* Encryption */ 717 opcode.s.major = CPT_MAJOR_OP_FC; 718 opcode.s.minor = 0; 719 720 if (hash_type == GMAC_TYPE) { 721 encr_offset = 0; 722 encr_data_len = 0; 723 } 724 725 auth_dlen = auth_offset + auth_data_len; 726 enc_dlen = encr_data_len + encr_offset; 727 if (unlikely(encr_data_len & 0xf)) { 728 if ((cipher_type == DES3_CBC) || (cipher_type == DES3_ECB)) 729 enc_dlen = ROUNDUP8(encr_data_len) + encr_offset; 730 else if (likely((cipher_type == AES_CBC) || 731 (cipher_type == AES_ECB))) 732 enc_dlen = ROUNDUP16(encr_data_len) + encr_offset; 733 } 734 735 if (unlikely(auth_dlen > enc_dlen)) { 736 inputlen = auth_dlen; 737 outputlen = auth_dlen + mac_len; 738 } else { 739 inputlen = enc_dlen; 740 outputlen = enc_dlen + mac_len; 741 } 742 743 /* GP op header */ 744 vq_cmd_w0.u64 = 0; 745 vq_cmd_w0.s.param1 = encr_data_len; 746 vq_cmd_w0.s.param2 = auth_data_len; 747 /* 748 * In 83XX since we have a limitation of 749 * IV & Offset control word not part of instruction 750 * and need to be part of Data Buffer, we check if 751 * head room is there and then only do the Direct mode processing 752 */ 753 if (likely((flags & SINGLE_BUF_INPLACE) && 754 (flags & SINGLE_BUF_HEADTAILROOM))) { 755 void *dm_vaddr = fc_params->bufs[0].vaddr; 756 uint64_t dm_dma_addr = fc_params->bufs[0].dma_addr; 757 /* 758 * This flag indicates that there is 24 bytes head room and 759 * 8 bytes tail room available, so that we get to do 760 * DIRECT MODE with limitation 761 */ 762 763 offset_vaddr = (uint8_t *)dm_vaddr - OFF_CTRL_LEN - iv_len; 764 offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len; 765 766 /* DPTR */ 767 req->ist.ei1 = offset_dma; 768 /* RPTR should just exclude offset control word */ 769 req->ist.ei2 = dm_dma_addr - iv_len; 770 req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr 771 + outputlen - iv_len); 772 773 vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN; 774 775 vq_cmd_w0.s.opcode = opcode.flags; 776 777 if (likely(iv_len)) { 778 uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr 779 + OFF_CTRL_LEN); 780 uint64_t *src = fc_params->iv_buf; 781 dest[0] = src[0]; 782 dest[1] = src[1]; 783 } 784 785 *(uint64_t *)offset_vaddr = 786 rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | 787 ((uint64_t)iv_offset << 8) | 788 ((uint64_t)auth_offset)); 789 790 } else { 791 uint32_t i, g_size_bytes, s_size_bytes; 792 uint64_t dptr_dma, rptr_dma; 793 sg_comp_t *gather_comp; 794 sg_comp_t *scatter_comp; 795 uint8_t *in_buffer; 796 797 /* This falls under strict SG mode */ 798 offset_vaddr = m_vaddr; 799 offset_dma = m_dma; 800 size = OFF_CTRL_LEN + iv_len; 801 802 m_vaddr = (uint8_t *)m_vaddr + size; 803 m_dma += size; 804 805 opcode.s.major |= CPT_DMA_MODE; 806 807 vq_cmd_w0.s.opcode = opcode.flags; 808 809 if (likely(iv_len)) { 810 uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr 811 + OFF_CTRL_LEN); 812 uint64_t *src = fc_params->iv_buf; 813 dest[0] = src[0]; 814 dest[1] = src[1]; 815 } 816 817 *(uint64_t *)offset_vaddr = 818 rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | 819 ((uint64_t)iv_offset << 8) | 820 ((uint64_t)auth_offset)); 821 822 /* DPTR has SG list */ 823 in_buffer = m_vaddr; 824 dptr_dma = m_dma; 825 826 ((uint16_t *)in_buffer)[0] = 0; 827 ((uint16_t *)in_buffer)[1] = 0; 828 829 /* TODO Add error check if space will be sufficient */ 830 gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 831 832 /* 833 * Input Gather List 834 */ 835 836 i = 0; 837 838 /* Offset control word that includes iv */ 839 i = fill_sg_comp(gather_comp, i, offset_dma, 840 OFF_CTRL_LEN + iv_len); 841 842 /* Add input data */ 843 size = inputlen - iv_len; 844 if (likely(size)) { 845 uint32_t aad_offset = aad_len ? passthrough_len : 0; 846 847 if (unlikely(flags & SINGLE_BUF_INPLACE)) { 848 i = fill_sg_comp_from_buf_min(gather_comp, i, 849 fc_params->bufs, 850 &size); 851 } else { 852 i = fill_sg_comp_from_iov(gather_comp, i, 853 fc_params->src_iov, 854 0, &size, 855 aad_buf, aad_offset); 856 } 857 858 if (unlikely(size)) { 859 CPT_LOG_DP_ERR("Insufficient buffer space," 860 " size %d needed", size); 861 return; 862 } 863 } 864 ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 865 g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 866 867 /* 868 * Output Scatter list 869 */ 870 i = 0; 871 scatter_comp = 872 (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 873 874 /* Add IV */ 875 if (likely(iv_len)) { 876 i = fill_sg_comp(scatter_comp, i, 877 offset_dma + OFF_CTRL_LEN, 878 iv_len); 879 } 880 881 /* output data or output data + digest*/ 882 if (unlikely(flags & VALID_MAC_BUF)) { 883 size = outputlen - iv_len - mac_len; 884 if (size) { 885 uint32_t aad_offset = 886 aad_len ? passthrough_len : 0; 887 888 if (unlikely(flags & SINGLE_BUF_INPLACE)) { 889 i = fill_sg_comp_from_buf_min( 890 scatter_comp, 891 i, 892 fc_params->bufs, 893 &size); 894 } else { 895 i = fill_sg_comp_from_iov(scatter_comp, 896 i, 897 fc_params->dst_iov, 898 0, 899 &size, 900 aad_buf, 901 aad_offset); 902 } 903 if (unlikely(size)) { 904 CPT_LOG_DP_ERR("Insufficient buffer" 905 " space, size %d needed", 906 size); 907 return; 908 } 909 } 910 /* mac_data */ 911 if (mac_len) { 912 i = fill_sg_comp_from_buf(scatter_comp, i, 913 &fc_params->mac_buf); 914 } 915 } else { 916 /* Output including mac */ 917 size = outputlen - iv_len; 918 if (likely(size)) { 919 uint32_t aad_offset = 920 aad_len ? passthrough_len : 0; 921 922 if (unlikely(flags & SINGLE_BUF_INPLACE)) { 923 i = fill_sg_comp_from_buf_min( 924 scatter_comp, 925 i, 926 fc_params->bufs, 927 &size); 928 } else { 929 i = fill_sg_comp_from_iov(scatter_comp, 930 i, 931 fc_params->dst_iov, 932 0, 933 &size, 934 aad_buf, 935 aad_offset); 936 } 937 if (unlikely(size)) { 938 CPT_LOG_DP_ERR("Insufficient buffer" 939 " space, size %d needed", 940 size); 941 return; 942 } 943 } 944 } 945 ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 946 s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 947 948 size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 949 950 /* This is DPTR len incase of SG mode */ 951 vq_cmd_w0.s.dlen = size; 952 953 m_vaddr = (uint8_t *)m_vaddr + size; 954 m_dma += size; 955 956 /* cpt alternate completion address saved earlier */ 957 req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 958 *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 959 rptr_dma = c_dma - 8; 960 961 req->ist.ei1 = dptr_dma; 962 req->ist.ei2 = rptr_dma; 963 } 964 965 ctx_dma = fc_params->ctx_buf.dma_addr + 966 offsetof(struct cpt_ctx, fctx); 967 /* vq command w3 */ 968 vq_cmd_w3.u64 = 0; 969 vq_cmd_w3.s.grp = 0; 970 vq_cmd_w3.s.cptr = ctx_dma; 971 972 /* 16 byte aligned cpt res address */ 973 req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 974 *req->completion_addr = COMPLETION_CODE_INIT; 975 req->comp_baddr = c_dma; 976 977 /* Fill microcode part of instruction */ 978 req->ist.ei0 = vq_cmd_w0.u64; 979 req->ist.ei3 = vq_cmd_w3.u64; 980 981 req->op = op; 982 983 *prep_req = req; 984 return; 985 } 986 987 static __rte_always_inline void 988 cpt_dec_hmac_prep(uint32_t flags, 989 uint64_t d_offs, 990 uint64_t d_lens, 991 fc_params_t *fc_params, 992 void *op, 993 void **prep_req) 994 { 995 uint32_t iv_offset = 0, size; 996 int32_t inputlen, outputlen, enc_dlen, auth_dlen; 997 struct cpt_ctx *cpt_ctx; 998 int32_t hash_type, mac_len; 999 uint8_t iv_len = 16; 1000 struct cpt_request_info *req; 1001 buf_ptr_t *meta_p, *aad_buf = NULL; 1002 uint32_t encr_offset, auth_offset; 1003 uint32_t encr_data_len, auth_data_len, aad_len = 0; 1004 uint32_t passthrough_len = 0; 1005 void *m_vaddr, *offset_vaddr; 1006 uint64_t m_dma, offset_dma, ctx_dma; 1007 opcode_info_t opcode; 1008 vq_cmd_word0_t vq_cmd_w0; 1009 vq_cmd_word3_t vq_cmd_w3; 1010 void *c_vaddr; 1011 uint64_t c_dma; 1012 1013 meta_p = &fc_params->meta_buf; 1014 m_vaddr = meta_p->vaddr; 1015 m_dma = meta_p->dma_addr; 1016 1017 encr_offset = ENCR_OFFSET(d_offs); 1018 auth_offset = AUTH_OFFSET(d_offs); 1019 encr_data_len = ENCR_DLEN(d_lens); 1020 auth_data_len = AUTH_DLEN(d_lens); 1021 1022 if (unlikely(flags & VALID_AAD_BUF)) { 1023 /* 1024 * We dont support both aad 1025 * and auth data separately 1026 */ 1027 auth_data_len = 0; 1028 auth_offset = 0; 1029 aad_len = fc_params->aad_buf.size; 1030 aad_buf = &fc_params->aad_buf; 1031 } 1032 1033 cpt_ctx = fc_params->ctx_buf.vaddr; 1034 hash_type = cpt_ctx->hash_type; 1035 mac_len = cpt_ctx->mac_len; 1036 1037 if (unlikely(!(flags & VALID_IV_BUF))) { 1038 iv_len = 0; 1039 iv_offset = ENCR_IV_OFFSET(d_offs); 1040 } 1041 1042 if (unlikely(flags & VALID_AAD_BUF)) { 1043 /* 1044 * When AAD is given, data above encr_offset is pass through 1045 * Since AAD is given as separate pointer and not as offset, 1046 * this is a special case as we need to fragment input data 1047 * into passthrough + encr_data and then insert AAD in between. 1048 */ 1049 if (hash_type != GMAC_TYPE) { 1050 passthrough_len = encr_offset; 1051 auth_offset = passthrough_len + iv_len; 1052 encr_offset = passthrough_len + aad_len + iv_len; 1053 auth_data_len = aad_len + encr_data_len; 1054 } else { 1055 passthrough_len = 16 + aad_len; 1056 auth_offset = passthrough_len + iv_len; 1057 auth_data_len = aad_len; 1058 } 1059 } else { 1060 encr_offset += iv_len; 1061 auth_offset += iv_len; 1062 } 1063 1064 /* 1065 * Save initial space that followed app data for completion code & 1066 * alternate completion code to fall in same cache line as app data 1067 */ 1068 m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 1069 m_dma += COMPLETION_CODE_SIZE; 1070 size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 1071 (uint8_t *)m_vaddr; 1072 c_vaddr = (uint8_t *)m_vaddr + size; 1073 c_dma = m_dma + size; 1074 size += sizeof(cpt_res_s_t); 1075 1076 m_vaddr = (uint8_t *)m_vaddr + size; 1077 m_dma += size; 1078 1079 /* start cpt request info structure at 8 byte alignment */ 1080 size = (uint8_t *)RTE_PTR_ALIGN(m_vaddr, 8) - 1081 (uint8_t *)m_vaddr; 1082 1083 req = (struct cpt_request_info *)((uint8_t *)m_vaddr + size); 1084 1085 size += sizeof(struct cpt_request_info); 1086 m_vaddr = (uint8_t *)m_vaddr + size; 1087 m_dma += size; 1088 1089 /* Decryption */ 1090 opcode.s.major = CPT_MAJOR_OP_FC; 1091 opcode.s.minor = 1; 1092 1093 if (hash_type == GMAC_TYPE) { 1094 encr_offset = 0; 1095 encr_data_len = 0; 1096 } 1097 1098 enc_dlen = encr_offset + encr_data_len; 1099 auth_dlen = auth_offset + auth_data_len; 1100 1101 if (auth_dlen > enc_dlen) { 1102 inputlen = auth_dlen + mac_len; 1103 outputlen = auth_dlen; 1104 } else { 1105 inputlen = enc_dlen + mac_len; 1106 outputlen = enc_dlen; 1107 } 1108 1109 vq_cmd_w0.u64 = 0; 1110 vq_cmd_w0.s.param1 = encr_data_len; 1111 vq_cmd_w0.s.param2 = auth_data_len; 1112 1113 /* 1114 * In 83XX since we have a limitation of 1115 * IV & Offset control word not part of instruction 1116 * and need to be part of Data Buffer, we check if 1117 * head room is there and then only do the Direct mode processing 1118 */ 1119 if (likely((flags & SINGLE_BUF_INPLACE) && 1120 (flags & SINGLE_BUF_HEADTAILROOM))) { 1121 void *dm_vaddr = fc_params->bufs[0].vaddr; 1122 uint64_t dm_dma_addr = fc_params->bufs[0].dma_addr; 1123 /* 1124 * This flag indicates that there is 24 bytes head room and 1125 * 8 bytes tail room available, so that we get to do 1126 * DIRECT MODE with limitation 1127 */ 1128 1129 offset_vaddr = (uint8_t *)dm_vaddr - OFF_CTRL_LEN - iv_len; 1130 offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len; 1131 req->ist.ei1 = offset_dma; 1132 1133 /* RPTR should just exclude offset control word */ 1134 req->ist.ei2 = dm_dma_addr - iv_len; 1135 1136 req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr + 1137 outputlen - iv_len); 1138 /* since this is decryption, 1139 * don't touch the content of 1140 * alternate ccode space as it contains 1141 * hmac. 1142 */ 1143 1144 vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN; 1145 1146 vq_cmd_w0.s.opcode = opcode.flags; 1147 1148 if (likely(iv_len)) { 1149 uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr + 1150 OFF_CTRL_LEN); 1151 uint64_t *src = fc_params->iv_buf; 1152 dest[0] = src[0]; 1153 dest[1] = src[1]; 1154 } 1155 1156 *(uint64_t *)offset_vaddr = 1157 rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | 1158 ((uint64_t)iv_offset << 8) | 1159 ((uint64_t)auth_offset)); 1160 1161 } else { 1162 uint64_t dptr_dma, rptr_dma; 1163 uint32_t g_size_bytes, s_size_bytes; 1164 sg_comp_t *gather_comp; 1165 sg_comp_t *scatter_comp; 1166 uint8_t *in_buffer; 1167 uint8_t i = 0; 1168 1169 /* This falls under strict SG mode */ 1170 offset_vaddr = m_vaddr; 1171 offset_dma = m_dma; 1172 size = OFF_CTRL_LEN + iv_len; 1173 1174 m_vaddr = (uint8_t *)m_vaddr + size; 1175 m_dma += size; 1176 1177 opcode.s.major |= CPT_DMA_MODE; 1178 1179 vq_cmd_w0.s.opcode = opcode.flags; 1180 1181 if (likely(iv_len)) { 1182 uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr + 1183 OFF_CTRL_LEN); 1184 uint64_t *src = fc_params->iv_buf; 1185 dest[0] = src[0]; 1186 dest[1] = src[1]; 1187 } 1188 1189 *(uint64_t *)offset_vaddr = 1190 rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | 1191 ((uint64_t)iv_offset << 8) | 1192 ((uint64_t)auth_offset)); 1193 1194 /* DPTR has SG list */ 1195 in_buffer = m_vaddr; 1196 dptr_dma = m_dma; 1197 1198 ((uint16_t *)in_buffer)[0] = 0; 1199 ((uint16_t *)in_buffer)[1] = 0; 1200 1201 /* TODO Add error check if space will be sufficient */ 1202 gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 1203 1204 /* 1205 * Input Gather List 1206 */ 1207 i = 0; 1208 1209 /* Offset control word that includes iv */ 1210 i = fill_sg_comp(gather_comp, i, offset_dma, 1211 OFF_CTRL_LEN + iv_len); 1212 1213 /* Add input data */ 1214 if (flags & VALID_MAC_BUF) { 1215 size = inputlen - iv_len - mac_len; 1216 if (size) { 1217 /* input data only */ 1218 if (unlikely(flags & SINGLE_BUF_INPLACE)) { 1219 i = fill_sg_comp_from_buf_min( 1220 gather_comp, i, 1221 fc_params->bufs, 1222 &size); 1223 } else { 1224 uint32_t aad_offset = aad_len ? 1225 passthrough_len : 0; 1226 1227 i = fill_sg_comp_from_iov(gather_comp, 1228 i, 1229 fc_params->src_iov, 1230 0, &size, 1231 aad_buf, 1232 aad_offset); 1233 } 1234 if (unlikely(size)) { 1235 CPT_LOG_DP_ERR("Insufficient buffer" 1236 " space, size %d needed", 1237 size); 1238 return; 1239 } 1240 } 1241 1242 /* mac data */ 1243 if (mac_len) { 1244 i = fill_sg_comp_from_buf(gather_comp, i, 1245 &fc_params->mac_buf); 1246 } 1247 } else { 1248 /* input data + mac */ 1249 size = inputlen - iv_len; 1250 if (size) { 1251 if (unlikely(flags & SINGLE_BUF_INPLACE)) { 1252 i = fill_sg_comp_from_buf_min( 1253 gather_comp, i, 1254 fc_params->bufs, 1255 &size); 1256 } else { 1257 uint32_t aad_offset = aad_len ? 1258 passthrough_len : 0; 1259 1260 if (unlikely(!fc_params->src_iov)) { 1261 CPT_LOG_DP_ERR("Bad input args"); 1262 return; 1263 } 1264 1265 i = fill_sg_comp_from_iov( 1266 gather_comp, i, 1267 fc_params->src_iov, 1268 0, &size, 1269 aad_buf, 1270 aad_offset); 1271 } 1272 1273 if (unlikely(size)) { 1274 CPT_LOG_DP_ERR("Insufficient buffer" 1275 " space, size %d needed", 1276 size); 1277 return; 1278 } 1279 } 1280 } 1281 ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 1282 g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 1283 1284 /* 1285 * Output Scatter List 1286 */ 1287 1288 i = 0; 1289 scatter_comp = 1290 (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 1291 1292 /* Add iv */ 1293 if (iv_len) { 1294 i = fill_sg_comp(scatter_comp, i, 1295 offset_dma + OFF_CTRL_LEN, 1296 iv_len); 1297 } 1298 1299 /* Add output data */ 1300 size = outputlen - iv_len; 1301 if (size) { 1302 if (unlikely(flags & SINGLE_BUF_INPLACE)) { 1303 /* handle single buffer here */ 1304 i = fill_sg_comp_from_buf_min(scatter_comp, i, 1305 fc_params->bufs, 1306 &size); 1307 } else { 1308 uint32_t aad_offset = aad_len ? 1309 passthrough_len : 0; 1310 1311 if (unlikely(!fc_params->dst_iov)) { 1312 CPT_LOG_DP_ERR("Bad input args"); 1313 return; 1314 } 1315 1316 i = fill_sg_comp_from_iov(scatter_comp, i, 1317 fc_params->dst_iov, 0, 1318 &size, aad_buf, 1319 aad_offset); 1320 } 1321 1322 if (unlikely(size)) { 1323 CPT_LOG_DP_ERR("Insufficient buffer space," 1324 " size %d needed", size); 1325 return; 1326 } 1327 } 1328 1329 ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 1330 s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 1331 1332 size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 1333 1334 /* This is DPTR len incase of SG mode */ 1335 vq_cmd_w0.s.dlen = size; 1336 1337 m_vaddr = (uint8_t *)m_vaddr + size; 1338 m_dma += size; 1339 1340 /* cpt alternate completion address saved earlier */ 1341 req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 1342 *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 1343 rptr_dma = c_dma - 8; 1344 size += COMPLETION_CODE_SIZE; 1345 1346 req->ist.ei1 = dptr_dma; 1347 req->ist.ei2 = rptr_dma; 1348 } 1349 1350 ctx_dma = fc_params->ctx_buf.dma_addr + 1351 offsetof(struct cpt_ctx, fctx); 1352 /* vq command w3 */ 1353 vq_cmd_w3.u64 = 0; 1354 vq_cmd_w3.s.grp = 0; 1355 vq_cmd_w3.s.cptr = ctx_dma; 1356 1357 /* 16 byte aligned cpt res address */ 1358 req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 1359 *req->completion_addr = COMPLETION_CODE_INIT; 1360 req->comp_baddr = c_dma; 1361 1362 /* Fill microcode part of instruction */ 1363 req->ist.ei0 = vq_cmd_w0.u64; 1364 req->ist.ei3 = vq_cmd_w3.u64; 1365 1366 req->op = op; 1367 1368 *prep_req = req; 1369 return; 1370 } 1371 1372 static __rte_always_inline void 1373 cpt_zuc_snow3g_enc_prep(uint32_t req_flags, 1374 uint64_t d_offs, 1375 uint64_t d_lens, 1376 fc_params_t *params, 1377 void *op, 1378 void **prep_req) 1379 { 1380 uint32_t size; 1381 int32_t inputlen, outputlen; 1382 struct cpt_ctx *cpt_ctx; 1383 uint32_t mac_len = 0; 1384 uint8_t snow3g, j; 1385 struct cpt_request_info *req; 1386 buf_ptr_t *buf_p; 1387 uint32_t encr_offset = 0, auth_offset = 0; 1388 uint32_t encr_data_len = 0, auth_data_len = 0; 1389 int flags, iv_len = 16; 1390 void *m_vaddr, *c_vaddr; 1391 uint64_t m_dma, c_dma, offset_ctrl; 1392 uint64_t *offset_vaddr, offset_dma; 1393 uint32_t *iv_s, iv[4]; 1394 vq_cmd_word0_t vq_cmd_w0; 1395 vq_cmd_word3_t vq_cmd_w3; 1396 opcode_info_t opcode; 1397 1398 buf_p = ¶ms->meta_buf; 1399 m_vaddr = buf_p->vaddr; 1400 m_dma = buf_p->dma_addr; 1401 1402 cpt_ctx = params->ctx_buf.vaddr; 1403 flags = cpt_ctx->zsk_flags; 1404 mac_len = cpt_ctx->mac_len; 1405 snow3g = cpt_ctx->snow3g; 1406 1407 /* 1408 * Save initial space that followed app data for completion code & 1409 * alternate completion code to fall in same cache line as app data 1410 */ 1411 m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 1412 m_dma += COMPLETION_CODE_SIZE; 1413 size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 1414 (uint8_t *)m_vaddr; 1415 1416 c_vaddr = (uint8_t *)m_vaddr + size; 1417 c_dma = m_dma + size; 1418 size += sizeof(cpt_res_s_t); 1419 1420 m_vaddr = (uint8_t *)m_vaddr + size; 1421 m_dma += size; 1422 1423 /* Reserve memory for cpt request info */ 1424 req = m_vaddr; 1425 1426 size = sizeof(struct cpt_request_info); 1427 m_vaddr = (uint8_t *)m_vaddr + size; 1428 m_dma += size; 1429 1430 opcode.s.major = CPT_MAJOR_OP_ZUC_SNOW3G; 1431 1432 /* indicates CPTR ctx, operation type, KEY & IV mode from DPTR */ 1433 1434 opcode.s.minor = ((1 << 7) | (snow3g << 5) | (0 << 4) | 1435 (0 << 3) | (flags & 0x7)); 1436 1437 if (flags == 0x1) { 1438 /* 1439 * Microcode expects offsets in bytes 1440 * TODO: Rounding off 1441 */ 1442 auth_data_len = AUTH_DLEN(d_lens); 1443 1444 /* EIA3 or UIA2 */ 1445 auth_offset = AUTH_OFFSET(d_offs); 1446 auth_offset = auth_offset / 8; 1447 1448 /* consider iv len */ 1449 auth_offset += iv_len; 1450 1451 inputlen = auth_offset + (RTE_ALIGN(auth_data_len, 8) / 8); 1452 outputlen = mac_len; 1453 1454 offset_ctrl = rte_cpu_to_be_64((uint64_t)auth_offset); 1455 1456 } else { 1457 /* EEA3 or UEA2 */ 1458 /* 1459 * Microcode expects offsets in bytes 1460 * TODO: Rounding off 1461 */ 1462 encr_data_len = ENCR_DLEN(d_lens); 1463 1464 encr_offset = ENCR_OFFSET(d_offs); 1465 encr_offset = encr_offset / 8; 1466 /* consider iv len */ 1467 encr_offset += iv_len; 1468 1469 inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8); 1470 outputlen = inputlen; 1471 1472 /* iv offset is 0 */ 1473 offset_ctrl = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 1474 } 1475 1476 /* IV */ 1477 iv_s = (flags == 0x1) ? params->auth_iv_buf : 1478 params->iv_buf; 1479 1480 if (snow3g) { 1481 /* 1482 * DPDK seems to provide it in form of IV3 IV2 IV1 IV0 1483 * and BigEndian, MC needs it as IV0 IV1 IV2 IV3 1484 */ 1485 1486 for (j = 0; j < 4; j++) 1487 iv[j] = iv_s[3 - j]; 1488 } else { 1489 /* ZUC doesn't need a swap */ 1490 for (j = 0; j < 4; j++) 1491 iv[j] = iv_s[j]; 1492 } 1493 1494 /* 1495 * GP op header, lengths are expected in bits. 1496 */ 1497 vq_cmd_w0.u64 = 0; 1498 vq_cmd_w0.s.param1 = encr_data_len; 1499 vq_cmd_w0.s.param2 = auth_data_len; 1500 1501 /* 1502 * In 83XX since we have a limitation of 1503 * IV & Offset control word not part of instruction 1504 * and need to be part of Data Buffer, we check if 1505 * head room is there and then only do the Direct mode processing 1506 */ 1507 if (likely((req_flags & SINGLE_BUF_INPLACE) && 1508 (req_flags & SINGLE_BUF_HEADTAILROOM))) { 1509 void *dm_vaddr = params->bufs[0].vaddr; 1510 uint64_t dm_dma_addr = params->bufs[0].dma_addr; 1511 /* 1512 * This flag indicates that there is 24 bytes head room and 1513 * 8 bytes tail room available, so that we get to do 1514 * DIRECT MODE with limitation 1515 */ 1516 1517 offset_vaddr = (uint64_t *)((uint8_t *)dm_vaddr - 1518 OFF_CTRL_LEN - iv_len); 1519 offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len; 1520 1521 /* DPTR */ 1522 req->ist.ei1 = offset_dma; 1523 /* RPTR should just exclude offset control word */ 1524 req->ist.ei2 = dm_dma_addr - iv_len; 1525 req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr 1526 + outputlen - iv_len); 1527 1528 vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN; 1529 1530 vq_cmd_w0.s.opcode = opcode.flags; 1531 1532 if (likely(iv_len)) { 1533 uint32_t *iv_d = (uint32_t *)((uint8_t *)offset_vaddr 1534 + OFF_CTRL_LEN); 1535 memcpy(iv_d, iv, 16); 1536 } 1537 1538 *offset_vaddr = offset_ctrl; 1539 } else { 1540 uint32_t i, g_size_bytes, s_size_bytes; 1541 uint64_t dptr_dma, rptr_dma; 1542 sg_comp_t *gather_comp; 1543 sg_comp_t *scatter_comp; 1544 uint8_t *in_buffer; 1545 uint32_t *iv_d; 1546 1547 /* save space for iv */ 1548 offset_vaddr = m_vaddr; 1549 offset_dma = m_dma; 1550 1551 m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len; 1552 m_dma += OFF_CTRL_LEN + iv_len; 1553 1554 opcode.s.major |= CPT_DMA_MODE; 1555 1556 vq_cmd_w0.s.opcode = opcode.flags; 1557 1558 /* DPTR has SG list */ 1559 in_buffer = m_vaddr; 1560 dptr_dma = m_dma; 1561 1562 ((uint16_t *)in_buffer)[0] = 0; 1563 ((uint16_t *)in_buffer)[1] = 0; 1564 1565 /* TODO Add error check if space will be sufficient */ 1566 gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 1567 1568 /* 1569 * Input Gather List 1570 */ 1571 i = 0; 1572 1573 /* Offset control word followed by iv */ 1574 1575 i = fill_sg_comp(gather_comp, i, offset_dma, 1576 OFF_CTRL_LEN + iv_len); 1577 1578 /* iv offset is 0 */ 1579 *offset_vaddr = offset_ctrl; 1580 1581 iv_d = (uint32_t *)((uint8_t *)offset_vaddr + OFF_CTRL_LEN); 1582 memcpy(iv_d, iv, 16); 1583 1584 /* input data */ 1585 size = inputlen - iv_len; 1586 if (size) { 1587 i = fill_sg_comp_from_iov(gather_comp, i, 1588 params->src_iov, 1589 0, &size, NULL, 0); 1590 if (unlikely(size)) { 1591 CPT_LOG_DP_ERR("Insufficient buffer space," 1592 " size %d needed", size); 1593 return; 1594 } 1595 } 1596 ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 1597 g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 1598 1599 /* 1600 * Output Scatter List 1601 */ 1602 1603 i = 0; 1604 scatter_comp = 1605 (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 1606 1607 if (flags == 0x1) { 1608 /* IV in SLIST only for EEA3 & UEA2 */ 1609 iv_len = 0; 1610 } 1611 1612 if (iv_len) { 1613 i = fill_sg_comp(scatter_comp, i, 1614 offset_dma + OFF_CTRL_LEN, iv_len); 1615 } 1616 1617 /* Add output data */ 1618 if (req_flags & VALID_MAC_BUF) { 1619 size = outputlen - iv_len - mac_len; 1620 if (size) { 1621 i = fill_sg_comp_from_iov(scatter_comp, i, 1622 params->dst_iov, 0, 1623 &size, NULL, 0); 1624 1625 if (unlikely(size)) { 1626 CPT_LOG_DP_ERR("Insufficient buffer space," 1627 " size %d needed", size); 1628 return; 1629 } 1630 } 1631 1632 /* mac data */ 1633 if (mac_len) { 1634 i = fill_sg_comp_from_buf(scatter_comp, i, 1635 ¶ms->mac_buf); 1636 } 1637 } else { 1638 /* Output including mac */ 1639 size = outputlen - iv_len; 1640 if (size) { 1641 i = fill_sg_comp_from_iov(scatter_comp, i, 1642 params->dst_iov, 0, 1643 &size, NULL, 0); 1644 1645 if (unlikely(size)) { 1646 CPT_LOG_DP_ERR("Insufficient buffer space," 1647 " size %d needed", size); 1648 return; 1649 } 1650 } 1651 } 1652 ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 1653 s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 1654 1655 size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 1656 1657 /* This is DPTR len incase of SG mode */ 1658 vq_cmd_w0.s.dlen = size; 1659 1660 m_vaddr = (uint8_t *)m_vaddr + size; 1661 m_dma += size; 1662 1663 /* cpt alternate completion address saved earlier */ 1664 req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 1665 *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 1666 rptr_dma = c_dma - 8; 1667 1668 req->ist.ei1 = dptr_dma; 1669 req->ist.ei2 = rptr_dma; 1670 } 1671 1672 /* vq command w3 */ 1673 vq_cmd_w3.u64 = 0; 1674 vq_cmd_w3.s.grp = 0; 1675 vq_cmd_w3.s.cptr = params->ctx_buf.dma_addr + 1676 offsetof(struct cpt_ctx, zs_ctx); 1677 1678 /* 16 byte aligned cpt res address */ 1679 req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 1680 *req->completion_addr = COMPLETION_CODE_INIT; 1681 req->comp_baddr = c_dma; 1682 1683 /* Fill microcode part of instruction */ 1684 req->ist.ei0 = vq_cmd_w0.u64; 1685 req->ist.ei3 = vq_cmd_w3.u64; 1686 1687 req->op = op; 1688 1689 *prep_req = req; 1690 return; 1691 } 1692 1693 static __rte_always_inline void 1694 cpt_zuc_snow3g_dec_prep(uint32_t req_flags, 1695 uint64_t d_offs, 1696 uint64_t d_lens, 1697 fc_params_t *params, 1698 void *op, 1699 void **prep_req) 1700 { 1701 uint32_t size; 1702 int32_t inputlen = 0, outputlen; 1703 struct cpt_ctx *cpt_ctx; 1704 uint8_t snow3g, iv_len = 16; 1705 struct cpt_request_info *req; 1706 buf_ptr_t *buf_p; 1707 uint32_t encr_offset; 1708 uint32_t encr_data_len; 1709 int flags; 1710 void *m_vaddr, *c_vaddr; 1711 uint64_t m_dma, c_dma; 1712 uint64_t *offset_vaddr, offset_dma; 1713 uint32_t *iv_s, iv[4], j; 1714 vq_cmd_word0_t vq_cmd_w0; 1715 vq_cmd_word3_t vq_cmd_w3; 1716 opcode_info_t opcode; 1717 1718 buf_p = ¶ms->meta_buf; 1719 m_vaddr = buf_p->vaddr; 1720 m_dma = buf_p->dma_addr; 1721 1722 /* 1723 * Microcode expects offsets in bytes 1724 * TODO: Rounding off 1725 */ 1726 encr_offset = ENCR_OFFSET(d_offs) / 8; 1727 encr_data_len = ENCR_DLEN(d_lens); 1728 1729 cpt_ctx = params->ctx_buf.vaddr; 1730 flags = cpt_ctx->zsk_flags; 1731 snow3g = cpt_ctx->snow3g; 1732 /* 1733 * Save initial space that followed app data for completion code & 1734 * alternate completion code to fall in same cache line as app data 1735 */ 1736 m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 1737 m_dma += COMPLETION_CODE_SIZE; 1738 size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 1739 (uint8_t *)m_vaddr; 1740 1741 c_vaddr = (uint8_t *)m_vaddr + size; 1742 c_dma = m_dma + size; 1743 size += sizeof(cpt_res_s_t); 1744 1745 m_vaddr = (uint8_t *)m_vaddr + size; 1746 m_dma += size; 1747 1748 /* Reserve memory for cpt request info */ 1749 req = m_vaddr; 1750 1751 size = sizeof(struct cpt_request_info); 1752 m_vaddr = (uint8_t *)m_vaddr + size; 1753 m_dma += size; 1754 1755 opcode.s.major = CPT_MAJOR_OP_ZUC_SNOW3G; 1756 1757 /* indicates CPTR ctx, operation type, KEY & IV mode from DPTR */ 1758 1759 opcode.s.minor = ((1 << 7) | (snow3g << 5) | (0 << 4) | 1760 (0 << 3) | (flags & 0x7)); 1761 1762 /* consider iv len */ 1763 encr_offset += iv_len; 1764 1765 inputlen = encr_offset + 1766 (RTE_ALIGN(encr_data_len, 8) / 8); 1767 outputlen = inputlen; 1768 1769 /* IV */ 1770 iv_s = params->iv_buf; 1771 if (snow3g) { 1772 /* 1773 * DPDK seems to provide it in form of IV3 IV2 IV1 IV0 1774 * and BigEndian, MC needs it as IV0 IV1 IV2 IV3 1775 */ 1776 1777 for (j = 0; j < 4; j++) 1778 iv[j] = iv_s[3 - j]; 1779 } else { 1780 /* ZUC doesn't need a swap */ 1781 for (j = 0; j < 4; j++) 1782 iv[j] = iv_s[j]; 1783 } 1784 1785 /* 1786 * GP op header, lengths are expected in bits. 1787 */ 1788 vq_cmd_w0.u64 = 0; 1789 vq_cmd_w0.s.param1 = encr_data_len; 1790 1791 /* 1792 * In 83XX since we have a limitation of 1793 * IV & Offset control word not part of instruction 1794 * and need to be part of Data Buffer, we check if 1795 * head room is there and then only do the Direct mode processing 1796 */ 1797 if (likely((req_flags & SINGLE_BUF_INPLACE) && 1798 (req_flags & SINGLE_BUF_HEADTAILROOM))) { 1799 void *dm_vaddr = params->bufs[0].vaddr; 1800 uint64_t dm_dma_addr = params->bufs[0].dma_addr; 1801 /* 1802 * This flag indicates that there is 24 bytes head room and 1803 * 8 bytes tail room available, so that we get to do 1804 * DIRECT MODE with limitation 1805 */ 1806 1807 offset_vaddr = (uint64_t *)((uint8_t *)dm_vaddr - 1808 OFF_CTRL_LEN - iv_len); 1809 offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len; 1810 1811 /* DPTR */ 1812 req->ist.ei1 = offset_dma; 1813 /* RPTR should just exclude offset control word */ 1814 req->ist.ei2 = dm_dma_addr - iv_len; 1815 req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr 1816 + outputlen - iv_len); 1817 1818 vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN; 1819 1820 vq_cmd_w0.s.opcode = opcode.flags; 1821 1822 if (likely(iv_len)) { 1823 uint32_t *iv_d = (uint32_t *)((uint8_t *)offset_vaddr 1824 + OFF_CTRL_LEN); 1825 memcpy(iv_d, iv, 16); 1826 } 1827 1828 /* iv offset is 0 */ 1829 *offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 1830 } else { 1831 uint32_t i, g_size_bytes, s_size_bytes; 1832 uint64_t dptr_dma, rptr_dma; 1833 sg_comp_t *gather_comp; 1834 sg_comp_t *scatter_comp; 1835 uint8_t *in_buffer; 1836 uint32_t *iv_d; 1837 1838 /* save space for offset and iv... */ 1839 offset_vaddr = m_vaddr; 1840 offset_dma = m_dma; 1841 1842 m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len; 1843 m_dma += OFF_CTRL_LEN + iv_len; 1844 1845 opcode.s.major |= CPT_DMA_MODE; 1846 1847 vq_cmd_w0.s.opcode = opcode.flags; 1848 1849 /* DPTR has SG list */ 1850 in_buffer = m_vaddr; 1851 dptr_dma = m_dma; 1852 1853 ((uint16_t *)in_buffer)[0] = 0; 1854 ((uint16_t *)in_buffer)[1] = 0; 1855 1856 /* TODO Add error check if space will be sufficient */ 1857 gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 1858 1859 /* 1860 * Input Gather List 1861 */ 1862 i = 0; 1863 1864 /* Offset control word */ 1865 1866 /* iv offset is 0 */ 1867 *offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 1868 1869 i = fill_sg_comp(gather_comp, i, offset_dma, 1870 OFF_CTRL_LEN + iv_len); 1871 1872 iv_d = (uint32_t *)((uint8_t *)offset_vaddr + OFF_CTRL_LEN); 1873 memcpy(iv_d, iv, 16); 1874 1875 /* Add input data */ 1876 size = inputlen - iv_len; 1877 if (size) { 1878 i = fill_sg_comp_from_iov(gather_comp, i, 1879 params->src_iov, 1880 0, &size, NULL, 0); 1881 if (unlikely(size)) { 1882 CPT_LOG_DP_ERR("Insufficient buffer space," 1883 " size %d needed", size); 1884 return; 1885 } 1886 } 1887 ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 1888 g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 1889 1890 /* 1891 * Output Scatter List 1892 */ 1893 1894 i = 0; 1895 scatter_comp = 1896 (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 1897 1898 /* IV */ 1899 i = fill_sg_comp(scatter_comp, i, 1900 offset_dma + OFF_CTRL_LEN, 1901 iv_len); 1902 1903 /* Add output data */ 1904 size = outputlen - iv_len; 1905 if (size) { 1906 i = fill_sg_comp_from_iov(scatter_comp, i, 1907 params->dst_iov, 0, 1908 &size, NULL, 0); 1909 1910 if (unlikely(size)) { 1911 CPT_LOG_DP_ERR("Insufficient buffer space," 1912 " size %d needed", size); 1913 return; 1914 } 1915 } 1916 ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 1917 s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 1918 1919 size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 1920 1921 /* This is DPTR len incase of SG mode */ 1922 vq_cmd_w0.s.dlen = size; 1923 1924 m_vaddr = (uint8_t *)m_vaddr + size; 1925 m_dma += size; 1926 1927 /* cpt alternate completion address saved earlier */ 1928 req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 1929 *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 1930 rptr_dma = c_dma - 8; 1931 1932 req->ist.ei1 = dptr_dma; 1933 req->ist.ei2 = rptr_dma; 1934 } 1935 1936 /* vq command w3 */ 1937 vq_cmd_w3.u64 = 0; 1938 vq_cmd_w3.s.grp = 0; 1939 vq_cmd_w3.s.cptr = params->ctx_buf.dma_addr + 1940 offsetof(struct cpt_ctx, zs_ctx); 1941 1942 /* 16 byte aligned cpt res address */ 1943 req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 1944 *req->completion_addr = COMPLETION_CODE_INIT; 1945 req->comp_baddr = c_dma; 1946 1947 /* Fill microcode part of instruction */ 1948 req->ist.ei0 = vq_cmd_w0.u64; 1949 req->ist.ei3 = vq_cmd_w3.u64; 1950 1951 req->op = op; 1952 1953 *prep_req = req; 1954 return; 1955 } 1956 1957 static __rte_always_inline void 1958 cpt_kasumi_enc_prep(uint32_t req_flags, 1959 uint64_t d_offs, 1960 uint64_t d_lens, 1961 fc_params_t *params, 1962 void *op, 1963 void **prep_req) 1964 { 1965 uint32_t size; 1966 int32_t inputlen = 0, outputlen = 0; 1967 struct cpt_ctx *cpt_ctx; 1968 uint32_t mac_len = 0; 1969 uint8_t i = 0; 1970 struct cpt_request_info *req; 1971 buf_ptr_t *buf_p; 1972 uint32_t encr_offset, auth_offset; 1973 uint32_t encr_data_len, auth_data_len; 1974 int flags; 1975 uint8_t *iv_s, *iv_d, iv_len = 8; 1976 uint8_t dir = 0; 1977 void *m_vaddr, *c_vaddr; 1978 uint64_t m_dma, c_dma; 1979 uint64_t *offset_vaddr, offset_dma; 1980 vq_cmd_word0_t vq_cmd_w0; 1981 vq_cmd_word3_t vq_cmd_w3; 1982 opcode_info_t opcode; 1983 uint8_t *in_buffer; 1984 uint32_t g_size_bytes, s_size_bytes; 1985 uint64_t dptr_dma, rptr_dma; 1986 sg_comp_t *gather_comp; 1987 sg_comp_t *scatter_comp; 1988 1989 buf_p = ¶ms->meta_buf; 1990 m_vaddr = buf_p->vaddr; 1991 m_dma = buf_p->dma_addr; 1992 1993 encr_offset = ENCR_OFFSET(d_offs) / 8; 1994 auth_offset = AUTH_OFFSET(d_offs) / 8; 1995 encr_data_len = ENCR_DLEN(d_lens); 1996 auth_data_len = AUTH_DLEN(d_lens); 1997 1998 cpt_ctx = params->ctx_buf.vaddr; 1999 flags = cpt_ctx->zsk_flags; 2000 mac_len = cpt_ctx->mac_len; 2001 2002 if (flags == 0x0) 2003 iv_s = params->iv_buf; 2004 else 2005 iv_s = params->auth_iv_buf; 2006 2007 dir = iv_s[8] & 0x1; 2008 2009 /* 2010 * Save initial space that followed app data for completion code & 2011 * alternate completion code to fall in same cache line as app data 2012 */ 2013 m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 2014 m_dma += COMPLETION_CODE_SIZE; 2015 size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 2016 (uint8_t *)m_vaddr; 2017 2018 c_vaddr = (uint8_t *)m_vaddr + size; 2019 c_dma = m_dma + size; 2020 size += sizeof(cpt_res_s_t); 2021 2022 m_vaddr = (uint8_t *)m_vaddr + size; 2023 m_dma += size; 2024 2025 /* Reserve memory for cpt request info */ 2026 req = m_vaddr; 2027 2028 size = sizeof(struct cpt_request_info); 2029 m_vaddr = (uint8_t *)m_vaddr + size; 2030 m_dma += size; 2031 2032 opcode.s.major = CPT_MAJOR_OP_KASUMI | CPT_DMA_MODE; 2033 2034 /* indicates ECB/CBC, direction, ctx from cptr, iv from dptr */ 2035 opcode.s.minor = ((1 << 6) | (cpt_ctx->k_ecb << 5) | 2036 (dir << 4) | (0 << 3) | (flags & 0x7)); 2037 2038 /* 2039 * GP op header, lengths are expected in bits. 2040 */ 2041 vq_cmd_w0.u64 = 0; 2042 vq_cmd_w0.s.param1 = encr_data_len; 2043 vq_cmd_w0.s.param2 = auth_data_len; 2044 vq_cmd_w0.s.opcode = opcode.flags; 2045 2046 /* consider iv len */ 2047 if (flags == 0x0) { 2048 encr_offset += iv_len; 2049 auth_offset += iv_len; 2050 } 2051 2052 /* save space for offset ctrl and iv */ 2053 offset_vaddr = m_vaddr; 2054 offset_dma = m_dma; 2055 2056 m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len; 2057 m_dma += OFF_CTRL_LEN + iv_len; 2058 2059 /* DPTR has SG list */ 2060 in_buffer = m_vaddr; 2061 dptr_dma = m_dma; 2062 2063 ((uint16_t *)in_buffer)[0] = 0; 2064 ((uint16_t *)in_buffer)[1] = 0; 2065 2066 /* TODO Add error check if space will be sufficient */ 2067 gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 2068 2069 /* 2070 * Input Gather List 2071 */ 2072 i = 0; 2073 2074 /* Offset control word followed by iv */ 2075 2076 if (flags == 0x0) { 2077 inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8); 2078 outputlen = inputlen; 2079 /* iv offset is 0 */ 2080 *offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 2081 } else { 2082 inputlen = auth_offset + (RTE_ALIGN(auth_data_len, 8) / 8); 2083 outputlen = mac_len; 2084 /* iv offset is 0 */ 2085 *offset_vaddr = rte_cpu_to_be_64((uint64_t)auth_offset); 2086 } 2087 2088 i = fill_sg_comp(gather_comp, i, offset_dma, OFF_CTRL_LEN + iv_len); 2089 2090 /* IV */ 2091 iv_d = (uint8_t *)offset_vaddr + OFF_CTRL_LEN; 2092 memcpy(iv_d, iv_s, iv_len); 2093 2094 /* input data */ 2095 size = inputlen - iv_len; 2096 if (size) { 2097 i = fill_sg_comp_from_iov(gather_comp, i, 2098 params->src_iov, 0, 2099 &size, NULL, 0); 2100 2101 if (unlikely(size)) { 2102 CPT_LOG_DP_ERR("Insufficient buffer space," 2103 " size %d needed", size); 2104 return; 2105 } 2106 } 2107 ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 2108 g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 2109 2110 /* 2111 * Output Scatter List 2112 */ 2113 2114 i = 0; 2115 scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 2116 2117 if (flags == 0x1) { 2118 /* IV in SLIST only for F8 */ 2119 iv_len = 0; 2120 } 2121 2122 /* IV */ 2123 if (iv_len) { 2124 i = fill_sg_comp(scatter_comp, i, 2125 offset_dma + OFF_CTRL_LEN, 2126 iv_len); 2127 } 2128 2129 /* Add output data */ 2130 if (req_flags & VALID_MAC_BUF) { 2131 size = outputlen - iv_len - mac_len; 2132 if (size) { 2133 i = fill_sg_comp_from_iov(scatter_comp, i, 2134 params->dst_iov, 0, 2135 &size, NULL, 0); 2136 2137 if (unlikely(size)) { 2138 CPT_LOG_DP_ERR("Insufficient buffer space," 2139 " size %d needed", size); 2140 return; 2141 } 2142 } 2143 2144 /* mac data */ 2145 if (mac_len) { 2146 i = fill_sg_comp_from_buf(scatter_comp, i, 2147 ¶ms->mac_buf); 2148 } 2149 } else { 2150 /* Output including mac */ 2151 size = outputlen - iv_len; 2152 if (size) { 2153 i = fill_sg_comp_from_iov(scatter_comp, i, 2154 params->dst_iov, 0, 2155 &size, NULL, 0); 2156 2157 if (unlikely(size)) { 2158 CPT_LOG_DP_ERR("Insufficient buffer space," 2159 " size %d needed", size); 2160 return; 2161 } 2162 } 2163 } 2164 ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 2165 s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 2166 2167 size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 2168 2169 /* This is DPTR len incase of SG mode */ 2170 vq_cmd_w0.s.dlen = size; 2171 2172 m_vaddr = (uint8_t *)m_vaddr + size; 2173 m_dma += size; 2174 2175 /* cpt alternate completion address saved earlier */ 2176 req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 2177 *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 2178 rptr_dma = c_dma - 8; 2179 2180 req->ist.ei1 = dptr_dma; 2181 req->ist.ei2 = rptr_dma; 2182 2183 /* vq command w3 */ 2184 vq_cmd_w3.u64 = 0; 2185 vq_cmd_w3.s.grp = 0; 2186 vq_cmd_w3.s.cptr = params->ctx_buf.dma_addr + 2187 offsetof(struct cpt_ctx, k_ctx); 2188 2189 /* 16 byte aligned cpt res address */ 2190 req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 2191 *req->completion_addr = COMPLETION_CODE_INIT; 2192 req->comp_baddr = c_dma; 2193 2194 /* Fill microcode part of instruction */ 2195 req->ist.ei0 = vq_cmd_w0.u64; 2196 req->ist.ei3 = vq_cmd_w3.u64; 2197 2198 req->op = op; 2199 2200 *prep_req = req; 2201 return; 2202 } 2203 2204 static __rte_always_inline void 2205 cpt_kasumi_dec_prep(uint64_t d_offs, 2206 uint64_t d_lens, 2207 fc_params_t *params, 2208 void *op, 2209 void **prep_req) 2210 { 2211 uint32_t size; 2212 int32_t inputlen = 0, outputlen; 2213 struct cpt_ctx *cpt_ctx; 2214 uint8_t i = 0, iv_len = 8; 2215 struct cpt_request_info *req; 2216 buf_ptr_t *buf_p; 2217 uint32_t encr_offset; 2218 uint32_t encr_data_len; 2219 int flags; 2220 uint8_t dir = 0; 2221 void *m_vaddr, *c_vaddr; 2222 uint64_t m_dma, c_dma; 2223 uint64_t *offset_vaddr, offset_dma; 2224 vq_cmd_word0_t vq_cmd_w0; 2225 vq_cmd_word3_t vq_cmd_w3; 2226 opcode_info_t opcode; 2227 uint8_t *in_buffer; 2228 uint32_t g_size_bytes, s_size_bytes; 2229 uint64_t dptr_dma, rptr_dma; 2230 sg_comp_t *gather_comp; 2231 sg_comp_t *scatter_comp; 2232 2233 buf_p = ¶ms->meta_buf; 2234 m_vaddr = buf_p->vaddr; 2235 m_dma = buf_p->dma_addr; 2236 2237 encr_offset = ENCR_OFFSET(d_offs) / 8; 2238 encr_data_len = ENCR_DLEN(d_lens); 2239 2240 cpt_ctx = params->ctx_buf.vaddr; 2241 flags = cpt_ctx->zsk_flags; 2242 /* 2243 * Save initial space that followed app data for completion code & 2244 * alternate completion code to fall in same cache line as app data 2245 */ 2246 m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; 2247 m_dma += COMPLETION_CODE_SIZE; 2248 size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - 2249 (uint8_t *)m_vaddr; 2250 2251 c_vaddr = (uint8_t *)m_vaddr + size; 2252 c_dma = m_dma + size; 2253 size += sizeof(cpt_res_s_t); 2254 2255 m_vaddr = (uint8_t *)m_vaddr + size; 2256 m_dma += size; 2257 2258 /* Reserve memory for cpt request info */ 2259 req = m_vaddr; 2260 2261 size = sizeof(struct cpt_request_info); 2262 m_vaddr = (uint8_t *)m_vaddr + size; 2263 m_dma += size; 2264 2265 opcode.s.major = CPT_MAJOR_OP_KASUMI | CPT_DMA_MODE; 2266 2267 /* indicates ECB/CBC, direction, ctx from cptr, iv from dptr */ 2268 opcode.s.minor = ((1 << 6) | (cpt_ctx->k_ecb << 5) | 2269 (dir << 4) | (0 << 3) | (flags & 0x7)); 2270 2271 /* 2272 * GP op header, lengths are expected in bits. 2273 */ 2274 vq_cmd_w0.u64 = 0; 2275 vq_cmd_w0.s.param1 = encr_data_len; 2276 vq_cmd_w0.s.opcode = opcode.flags; 2277 2278 /* consider iv len */ 2279 encr_offset += iv_len; 2280 2281 inputlen = iv_len + (RTE_ALIGN(encr_data_len, 8) / 8); 2282 outputlen = inputlen; 2283 2284 /* save space for offset ctrl & iv */ 2285 offset_vaddr = m_vaddr; 2286 offset_dma = m_dma; 2287 2288 m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len; 2289 m_dma += OFF_CTRL_LEN + iv_len; 2290 2291 /* DPTR has SG list */ 2292 in_buffer = m_vaddr; 2293 dptr_dma = m_dma; 2294 2295 ((uint16_t *)in_buffer)[0] = 0; 2296 ((uint16_t *)in_buffer)[1] = 0; 2297 2298 /* TODO Add error check if space will be sufficient */ 2299 gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); 2300 2301 /* 2302 * Input Gather List 2303 */ 2304 i = 0; 2305 2306 /* Offset control word followed by iv */ 2307 *offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16); 2308 2309 i = fill_sg_comp(gather_comp, i, offset_dma, OFF_CTRL_LEN + iv_len); 2310 2311 /* IV */ 2312 memcpy((uint8_t *)offset_vaddr + OFF_CTRL_LEN, 2313 params->iv_buf, iv_len); 2314 2315 /* Add input data */ 2316 size = inputlen - iv_len; 2317 if (size) { 2318 i = fill_sg_comp_from_iov(gather_comp, i, 2319 params->src_iov, 2320 0, &size, NULL, 0); 2321 if (unlikely(size)) { 2322 CPT_LOG_DP_ERR("Insufficient buffer space," 2323 " size %d needed", size); 2324 return; 2325 } 2326 } 2327 ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); 2328 g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 2329 2330 /* 2331 * Output Scatter List 2332 */ 2333 2334 i = 0; 2335 scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); 2336 2337 /* IV */ 2338 i = fill_sg_comp(scatter_comp, i, 2339 offset_dma + OFF_CTRL_LEN, 2340 iv_len); 2341 2342 /* Add output data */ 2343 size = outputlen - iv_len; 2344 if (size) { 2345 i = fill_sg_comp_from_iov(scatter_comp, i, 2346 params->dst_iov, 0, 2347 &size, NULL, 0); 2348 if (unlikely(size)) { 2349 CPT_LOG_DP_ERR("Insufficient buffer space," 2350 " size %d needed", size); 2351 return; 2352 } 2353 } 2354 ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); 2355 s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); 2356 2357 size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; 2358 2359 /* This is DPTR len incase of SG mode */ 2360 vq_cmd_w0.s.dlen = size; 2361 2362 m_vaddr = (uint8_t *)m_vaddr + size; 2363 m_dma += size; 2364 2365 /* cpt alternate completion address saved earlier */ 2366 req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); 2367 *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 2368 rptr_dma = c_dma - 8; 2369 2370 req->ist.ei1 = dptr_dma; 2371 req->ist.ei2 = rptr_dma; 2372 2373 /* vq command w3 */ 2374 vq_cmd_w3.u64 = 0; 2375 vq_cmd_w3.s.grp = 0; 2376 vq_cmd_w3.s.cptr = params->ctx_buf.dma_addr + 2377 offsetof(struct cpt_ctx, k_ctx); 2378 2379 /* 16 byte aligned cpt res address */ 2380 req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); 2381 *req->completion_addr = COMPLETION_CODE_INIT; 2382 req->comp_baddr = c_dma; 2383 2384 /* Fill microcode part of instruction */ 2385 req->ist.ei0 = vq_cmd_w0.u64; 2386 req->ist.ei3 = vq_cmd_w3.u64; 2387 2388 req->op = op; 2389 2390 *prep_req = req; 2391 return; 2392 } 2393 2394 static __rte_always_inline void * 2395 cpt_fc_dec_hmac_prep(uint32_t flags, 2396 uint64_t d_offs, 2397 uint64_t d_lens, 2398 fc_params_t *fc_params, 2399 void *op) 2400 { 2401 struct cpt_ctx *ctx = fc_params->ctx_buf.vaddr; 2402 uint8_t fc_type; 2403 void *prep_req = NULL; 2404 2405 fc_type = ctx->fc_type; 2406 2407 if (likely(fc_type == FC_GEN)) { 2408 cpt_dec_hmac_prep(flags, d_offs, d_lens, fc_params, op, 2409 &prep_req); 2410 } else if (fc_type == ZUC_SNOW3G) { 2411 cpt_zuc_snow3g_dec_prep(flags, d_offs, d_lens, fc_params, op, 2412 &prep_req); 2413 } else if (fc_type == KASUMI) { 2414 cpt_kasumi_dec_prep(d_offs, d_lens, fc_params, op, &prep_req); 2415 } 2416 2417 /* 2418 * For AUTH_ONLY case, 2419 * MC only supports digest generation and verification 2420 * should be done in software by memcmp() 2421 */ 2422 2423 return prep_req; 2424 } 2425 2426 static __rte_always_inline void *__rte_hot 2427 cpt_fc_enc_hmac_prep(uint32_t flags, uint64_t d_offs, uint64_t d_lens, 2428 fc_params_t *fc_params, void *op) 2429 { 2430 struct cpt_ctx *ctx = fc_params->ctx_buf.vaddr; 2431 uint8_t fc_type; 2432 void *prep_req = NULL; 2433 2434 fc_type = ctx->fc_type; 2435 2436 /* Common api for rest of the ops */ 2437 if (likely(fc_type == FC_GEN)) { 2438 cpt_enc_hmac_prep(flags, d_offs, d_lens, fc_params, op, 2439 &prep_req); 2440 } else if (fc_type == ZUC_SNOW3G) { 2441 cpt_zuc_snow3g_enc_prep(flags, d_offs, d_lens, fc_params, op, 2442 &prep_req); 2443 } else if (fc_type == KASUMI) { 2444 cpt_kasumi_enc_prep(flags, d_offs, d_lens, fc_params, op, 2445 &prep_req); 2446 } else if (fc_type == HASH_HMAC) { 2447 cpt_digest_gen_prep(flags, d_lens, fc_params, op, &prep_req); 2448 } 2449 2450 return prep_req; 2451 } 2452 2453 static __rte_always_inline int 2454 cpt_fc_auth_set_key(void *ctx, auth_type_t type, const uint8_t *key, 2455 uint16_t key_len, uint16_t mac_len) 2456 { 2457 struct cpt_ctx *cpt_ctx = ctx; 2458 mc_fc_context_t *fctx = &cpt_ctx->fctx; 2459 2460 if ((type >= ZUC_EIA3) && (type <= KASUMI_F9_ECB)) { 2461 uint32_t keyx[4]; 2462 2463 if (key_len != 16) 2464 return -1; 2465 /* No support for AEAD yet */ 2466 if (cpt_ctx->enc_cipher) 2467 return -1; 2468 /* For ZUC/SNOW3G/Kasumi */ 2469 switch (type) { 2470 case SNOW3G_UIA2: 2471 cpt_ctx->snow3g = 1; 2472 gen_key_snow3g(key, keyx); 2473 memcpy(cpt_ctx->zs_ctx.ci_key, keyx, key_len); 2474 cpt_ctx->fc_type = ZUC_SNOW3G; 2475 cpt_ctx->zsk_flags = 0x1; 2476 break; 2477 case ZUC_EIA3: 2478 cpt_ctx->snow3g = 0; 2479 memcpy(cpt_ctx->zs_ctx.ci_key, key, key_len); 2480 memcpy(cpt_ctx->zs_ctx.zuc_const, zuc_d, 32); 2481 cpt_ctx->fc_type = ZUC_SNOW3G; 2482 cpt_ctx->zsk_flags = 0x1; 2483 break; 2484 case KASUMI_F9_ECB: 2485 /* Kasumi ECB mode */ 2486 cpt_ctx->k_ecb = 1; 2487 memcpy(cpt_ctx->k_ctx.ci_key, key, key_len); 2488 cpt_ctx->fc_type = KASUMI; 2489 cpt_ctx->zsk_flags = 0x1; 2490 break; 2491 case KASUMI_F9_CBC: 2492 memcpy(cpt_ctx->k_ctx.ci_key, key, key_len); 2493 cpt_ctx->fc_type = KASUMI; 2494 cpt_ctx->zsk_flags = 0x1; 2495 break; 2496 default: 2497 return -1; 2498 } 2499 cpt_ctx->mac_len = 4; 2500 cpt_ctx->hash_type = type; 2501 return 0; 2502 } 2503 2504 if (!(cpt_ctx->fc_type == FC_GEN && !type)) { 2505 if (!cpt_ctx->fc_type || !cpt_ctx->enc_cipher) 2506 cpt_ctx->fc_type = HASH_HMAC; 2507 } 2508 2509 if (cpt_ctx->fc_type == FC_GEN && key_len > 64) 2510 return -1; 2511 2512 /* For GMAC auth, cipher must be NULL */ 2513 if (type == GMAC_TYPE) 2514 fctx->enc.enc_cipher = 0; 2515 2516 fctx->enc.hash_type = cpt_ctx->hash_type = type; 2517 fctx->enc.mac_len = cpt_ctx->mac_len = mac_len; 2518 2519 if (key_len) { 2520 cpt_ctx->hmac = 1; 2521 memset(cpt_ctx->auth_key, 0, sizeof(cpt_ctx->auth_key)); 2522 memcpy(cpt_ctx->auth_key, key, key_len); 2523 cpt_ctx->auth_key_len = key_len; 2524 memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad)); 2525 memset(fctx->hmac.opad, 0, sizeof(fctx->hmac.opad)); 2526 2527 if (key_len <= 64) 2528 memcpy(fctx->hmac.opad, key, key_len); 2529 fctx->enc.auth_input_type = 1; 2530 } 2531 return 0; 2532 } 2533 2534 static __rte_always_inline int 2535 fill_sess_aead(struct rte_crypto_sym_xform *xform, 2536 struct cpt_sess_misc *sess) 2537 { 2538 struct rte_crypto_aead_xform *aead_form; 2539 cipher_type_t enc_type = 0; /* NULL Cipher type */ 2540 auth_type_t auth_type = 0; /* NULL Auth type */ 2541 uint32_t cipher_key_len = 0; 2542 uint8_t aes_gcm = 0; 2543 aead_form = &xform->aead; 2544 void *ctx = SESS_PRIV(sess); 2545 2546 if (aead_form->op == RTE_CRYPTO_AEAD_OP_ENCRYPT) { 2547 sess->cpt_op |= CPT_OP_CIPHER_ENCRYPT; 2548 sess->cpt_op |= CPT_OP_AUTH_GENERATE; 2549 } else if (aead_form->op == RTE_CRYPTO_AEAD_OP_DECRYPT) { 2550 sess->cpt_op |= CPT_OP_CIPHER_DECRYPT; 2551 sess->cpt_op |= CPT_OP_AUTH_VERIFY; 2552 } else { 2553 CPT_LOG_DP_ERR("Unknown aead operation\n"); 2554 return -1; 2555 } 2556 switch (aead_form->algo) { 2557 case RTE_CRYPTO_AEAD_AES_GCM: 2558 enc_type = AES_GCM; 2559 cipher_key_len = 16; 2560 aes_gcm = 1; 2561 break; 2562 case RTE_CRYPTO_AEAD_AES_CCM: 2563 CPT_LOG_DP_ERR("Crypto: Unsupported cipher algo %u", 2564 aead_form->algo); 2565 return -1; 2566 case RTE_CRYPTO_AEAD_CHACHA20_POLY1305: 2567 enc_type = CHACHA20; 2568 auth_type = POLY1305; 2569 cipher_key_len = 32; 2570 sess->chacha_poly = 1; 2571 break; 2572 default: 2573 CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified", 2574 aead_form->algo); 2575 return -1; 2576 } 2577 if (aead_form->key.length < cipher_key_len) { 2578 CPT_LOG_DP_ERR("Invalid cipher params keylen %lu", 2579 (unsigned int long)aead_form->key.length); 2580 return -1; 2581 } 2582 sess->zsk_flag = 0; 2583 sess->aes_gcm = aes_gcm; 2584 sess->mac_len = aead_form->digest_length; 2585 sess->iv_offset = aead_form->iv.offset; 2586 sess->iv_length = aead_form->iv.length; 2587 sess->aad_length = aead_form->aad_length; 2588 2589 if (unlikely(cpt_fc_ciph_set_key(ctx, enc_type, aead_form->key.data, 2590 aead_form->key.length, NULL))) 2591 return -1; 2592 2593 if (unlikely(cpt_fc_auth_set_key(ctx, auth_type, NULL, 0, 2594 aead_form->digest_length))) 2595 return -1; 2596 2597 return 0; 2598 } 2599 2600 static __rte_always_inline int 2601 fill_sess_cipher(struct rte_crypto_sym_xform *xform, 2602 struct cpt_sess_misc *sess) 2603 { 2604 struct rte_crypto_cipher_xform *c_form; 2605 cipher_type_t enc_type = 0; /* NULL Cipher type */ 2606 uint32_t cipher_key_len = 0; 2607 uint8_t zsk_flag = 0, aes_ctr = 0, is_null = 0; 2608 2609 c_form = &xform->cipher; 2610 2611 if (c_form->op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) 2612 sess->cpt_op |= CPT_OP_CIPHER_ENCRYPT; 2613 else if (c_form->op == RTE_CRYPTO_CIPHER_OP_DECRYPT) 2614 sess->cpt_op |= CPT_OP_CIPHER_DECRYPT; 2615 else { 2616 CPT_LOG_DP_ERR("Unknown cipher operation\n"); 2617 return -1; 2618 } 2619 2620 switch (c_form->algo) { 2621 case RTE_CRYPTO_CIPHER_AES_CBC: 2622 enc_type = AES_CBC; 2623 cipher_key_len = 16; 2624 break; 2625 case RTE_CRYPTO_CIPHER_3DES_CBC: 2626 enc_type = DES3_CBC; 2627 cipher_key_len = 24; 2628 break; 2629 case RTE_CRYPTO_CIPHER_DES_CBC: 2630 /* DES is implemented using 3DES in hardware */ 2631 enc_type = DES3_CBC; 2632 cipher_key_len = 8; 2633 break; 2634 case RTE_CRYPTO_CIPHER_AES_CTR: 2635 enc_type = AES_CTR; 2636 cipher_key_len = 16; 2637 aes_ctr = 1; 2638 break; 2639 case RTE_CRYPTO_CIPHER_NULL: 2640 enc_type = 0; 2641 is_null = 1; 2642 break; 2643 case RTE_CRYPTO_CIPHER_KASUMI_F8: 2644 enc_type = KASUMI_F8_ECB; 2645 cipher_key_len = 16; 2646 zsk_flag = K_F8; 2647 break; 2648 case RTE_CRYPTO_CIPHER_SNOW3G_UEA2: 2649 enc_type = SNOW3G_UEA2; 2650 cipher_key_len = 16; 2651 zsk_flag = ZS_EA; 2652 break; 2653 case RTE_CRYPTO_CIPHER_ZUC_EEA3: 2654 enc_type = ZUC_EEA3; 2655 cipher_key_len = 16; 2656 zsk_flag = ZS_EA; 2657 break; 2658 case RTE_CRYPTO_CIPHER_AES_XTS: 2659 enc_type = AES_XTS; 2660 cipher_key_len = 16; 2661 break; 2662 case RTE_CRYPTO_CIPHER_3DES_ECB: 2663 enc_type = DES3_ECB; 2664 cipher_key_len = 24; 2665 break; 2666 case RTE_CRYPTO_CIPHER_AES_ECB: 2667 enc_type = AES_ECB; 2668 cipher_key_len = 16; 2669 break; 2670 case RTE_CRYPTO_CIPHER_3DES_CTR: 2671 case RTE_CRYPTO_CIPHER_AES_F8: 2672 case RTE_CRYPTO_CIPHER_ARC4: 2673 CPT_LOG_DP_ERR("Crypto: Unsupported cipher algo %u", 2674 c_form->algo); 2675 return -1; 2676 default: 2677 CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified", 2678 c_form->algo); 2679 return -1; 2680 } 2681 2682 if (c_form->key.length < cipher_key_len) { 2683 CPT_LOG_DP_ERR("Invalid cipher params keylen %lu", 2684 (unsigned long) c_form->key.length); 2685 return -1; 2686 } 2687 2688 sess->zsk_flag = zsk_flag; 2689 sess->aes_gcm = 0; 2690 sess->aes_ctr = aes_ctr; 2691 sess->iv_offset = c_form->iv.offset; 2692 sess->iv_length = c_form->iv.length; 2693 sess->is_null = is_null; 2694 2695 if (unlikely(cpt_fc_ciph_set_key(SESS_PRIV(sess), enc_type, 2696 c_form->key.data, c_form->key.length, NULL))) 2697 return -1; 2698 2699 return 0; 2700 } 2701 2702 static __rte_always_inline int 2703 fill_sess_auth(struct rte_crypto_sym_xform *xform, 2704 struct cpt_sess_misc *sess) 2705 { 2706 struct rte_crypto_auth_xform *a_form; 2707 auth_type_t auth_type = 0; /* NULL Auth type */ 2708 uint8_t zsk_flag = 0, aes_gcm = 0, is_null = 0; 2709 2710 a_form = &xform->auth; 2711 2712 if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY) 2713 sess->cpt_op |= CPT_OP_AUTH_VERIFY; 2714 else if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE) 2715 sess->cpt_op |= CPT_OP_AUTH_GENERATE; 2716 else { 2717 CPT_LOG_DP_ERR("Unknown auth operation"); 2718 return -1; 2719 } 2720 2721 switch (a_form->algo) { 2722 case RTE_CRYPTO_AUTH_SHA1_HMAC: 2723 /* Fall through */ 2724 case RTE_CRYPTO_AUTH_SHA1: 2725 auth_type = SHA1_TYPE; 2726 break; 2727 case RTE_CRYPTO_AUTH_SHA256_HMAC: 2728 case RTE_CRYPTO_AUTH_SHA256: 2729 auth_type = SHA2_SHA256; 2730 break; 2731 case RTE_CRYPTO_AUTH_SHA512_HMAC: 2732 case RTE_CRYPTO_AUTH_SHA512: 2733 auth_type = SHA2_SHA512; 2734 break; 2735 case RTE_CRYPTO_AUTH_AES_GMAC: 2736 auth_type = GMAC_TYPE; 2737 aes_gcm = 1; 2738 break; 2739 case RTE_CRYPTO_AUTH_SHA224_HMAC: 2740 case RTE_CRYPTO_AUTH_SHA224: 2741 auth_type = SHA2_SHA224; 2742 break; 2743 case RTE_CRYPTO_AUTH_SHA384_HMAC: 2744 case RTE_CRYPTO_AUTH_SHA384: 2745 auth_type = SHA2_SHA384; 2746 break; 2747 case RTE_CRYPTO_AUTH_MD5_HMAC: 2748 case RTE_CRYPTO_AUTH_MD5: 2749 auth_type = MD5_TYPE; 2750 break; 2751 case RTE_CRYPTO_AUTH_KASUMI_F9: 2752 auth_type = KASUMI_F9_ECB; 2753 /* 2754 * Indicate that direction needs to be taken out 2755 * from end of src 2756 */ 2757 zsk_flag = K_F9; 2758 break; 2759 case RTE_CRYPTO_AUTH_SNOW3G_UIA2: 2760 auth_type = SNOW3G_UIA2; 2761 zsk_flag = ZS_IA; 2762 break; 2763 case RTE_CRYPTO_AUTH_ZUC_EIA3: 2764 auth_type = ZUC_EIA3; 2765 zsk_flag = ZS_IA; 2766 break; 2767 case RTE_CRYPTO_AUTH_NULL: 2768 auth_type = 0; 2769 is_null = 1; 2770 break; 2771 case RTE_CRYPTO_AUTH_AES_XCBC_MAC: 2772 case RTE_CRYPTO_AUTH_AES_CMAC: 2773 case RTE_CRYPTO_AUTH_AES_CBC_MAC: 2774 CPT_LOG_DP_ERR("Crypto: Unsupported hash algo %u", 2775 a_form->algo); 2776 return -1; 2777 default: 2778 CPT_LOG_DP_ERR("Crypto: Undefined Hash algo %u specified", 2779 a_form->algo); 2780 return -1; 2781 } 2782 2783 sess->zsk_flag = zsk_flag; 2784 sess->aes_gcm = aes_gcm; 2785 sess->mac_len = a_form->digest_length; 2786 sess->is_null = is_null; 2787 if (zsk_flag) { 2788 sess->auth_iv_offset = a_form->iv.offset; 2789 sess->auth_iv_length = a_form->iv.length; 2790 } 2791 if (unlikely(cpt_fc_auth_set_key(SESS_PRIV(sess), auth_type, 2792 a_form->key.data, a_form->key.length, 2793 a_form->digest_length))) 2794 return -1; 2795 2796 return 0; 2797 } 2798 2799 static __rte_always_inline int 2800 fill_sess_gmac(struct rte_crypto_sym_xform *xform, 2801 struct cpt_sess_misc *sess) 2802 { 2803 struct rte_crypto_auth_xform *a_form; 2804 cipher_type_t enc_type = 0; /* NULL Cipher type */ 2805 auth_type_t auth_type = 0; /* NULL Auth type */ 2806 void *ctx = SESS_PRIV(sess); 2807 2808 a_form = &xform->auth; 2809 2810 if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE) 2811 sess->cpt_op |= CPT_OP_ENCODE; 2812 else if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY) 2813 sess->cpt_op |= CPT_OP_DECODE; 2814 else { 2815 CPT_LOG_DP_ERR("Unknown auth operation"); 2816 return -1; 2817 } 2818 2819 switch (a_form->algo) { 2820 case RTE_CRYPTO_AUTH_AES_GMAC: 2821 enc_type = AES_GCM; 2822 auth_type = GMAC_TYPE; 2823 break; 2824 default: 2825 CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified", 2826 a_form->algo); 2827 return -1; 2828 } 2829 2830 sess->zsk_flag = 0; 2831 sess->aes_gcm = 0; 2832 sess->is_gmac = 1; 2833 sess->iv_offset = a_form->iv.offset; 2834 sess->iv_length = a_form->iv.length; 2835 sess->mac_len = a_form->digest_length; 2836 2837 if (unlikely(cpt_fc_ciph_set_key(ctx, enc_type, a_form->key.data, 2838 a_form->key.length, NULL))) 2839 return -1; 2840 2841 if (unlikely(cpt_fc_auth_set_key(ctx, auth_type, NULL, 0, 2842 a_form->digest_length))) 2843 return -1; 2844 2845 return 0; 2846 } 2847 2848 static __rte_always_inline void * 2849 alloc_op_meta(struct rte_mbuf *m_src, 2850 buf_ptr_t *buf, 2851 int32_t len, 2852 struct rte_mempool *cpt_meta_pool) 2853 { 2854 uint8_t *mdata; 2855 2856 #ifndef CPT_ALWAYS_USE_SEPARATE_BUF 2857 if (likely(m_src && (m_src->nb_segs == 1))) { 2858 int32_t tailroom; 2859 phys_addr_t mphys; 2860 2861 /* Check if tailroom is sufficient to hold meta data */ 2862 tailroom = rte_pktmbuf_tailroom(m_src); 2863 if (likely(tailroom > len + 8)) { 2864 mdata = (uint8_t *)m_src->buf_addr + m_src->buf_len; 2865 mphys = m_src->buf_iova + m_src->buf_len; 2866 mdata -= len; 2867 mphys -= len; 2868 buf->vaddr = mdata; 2869 buf->dma_addr = mphys; 2870 buf->size = len; 2871 /* Indicate that this is a mbuf allocated mdata */ 2872 mdata = (uint8_t *)((uint64_t)mdata | 1ull); 2873 return mdata; 2874 } 2875 } 2876 #else 2877 RTE_SET_USED(m_src); 2878 #endif 2879 2880 if (unlikely(rte_mempool_get(cpt_meta_pool, (void **)&mdata) < 0)) 2881 return NULL; 2882 2883 buf->vaddr = mdata; 2884 buf->dma_addr = rte_mempool_virt2iova(mdata); 2885 buf->size = len; 2886 2887 return mdata; 2888 } 2889 2890 /** 2891 * cpt_free_metabuf - free metabuf to mempool. 2892 * @param instance: pointer to instance. 2893 * @param objp: pointer to the metabuf. 2894 */ 2895 static __rte_always_inline void 2896 free_op_meta(void *mdata, struct rte_mempool *cpt_meta_pool) 2897 { 2898 bool nofree = ((uintptr_t)mdata & 1ull); 2899 2900 if (likely(nofree)) 2901 return; 2902 rte_mempool_put(cpt_meta_pool, mdata); 2903 } 2904 2905 static __rte_always_inline uint32_t 2906 prepare_iov_from_pkt(struct rte_mbuf *pkt, 2907 iov_ptr_t *iovec, uint32_t start_offset) 2908 { 2909 uint16_t index = 0; 2910 void *seg_data = NULL; 2911 phys_addr_t seg_phys; 2912 int32_t seg_size = 0; 2913 2914 if (!pkt) { 2915 iovec->buf_cnt = 0; 2916 return 0; 2917 } 2918 2919 if (!start_offset) { 2920 seg_data = rte_pktmbuf_mtod(pkt, void *); 2921 seg_phys = rte_pktmbuf_iova(pkt); 2922 seg_size = pkt->data_len; 2923 } else { 2924 while (start_offset >= pkt->data_len) { 2925 start_offset -= pkt->data_len; 2926 pkt = pkt->next; 2927 } 2928 2929 seg_data = rte_pktmbuf_mtod_offset(pkt, void *, start_offset); 2930 seg_phys = rte_pktmbuf_iova_offset(pkt, start_offset); 2931 seg_size = pkt->data_len - start_offset; 2932 if (!seg_size) 2933 return 1; 2934 } 2935 2936 /* first seg */ 2937 iovec->bufs[index].vaddr = seg_data; 2938 iovec->bufs[index].dma_addr = seg_phys; 2939 iovec->bufs[index].size = seg_size; 2940 index++; 2941 pkt = pkt->next; 2942 2943 while (unlikely(pkt != NULL)) { 2944 seg_data = rte_pktmbuf_mtod(pkt, void *); 2945 seg_phys = rte_pktmbuf_iova(pkt); 2946 seg_size = pkt->data_len; 2947 if (!seg_size) 2948 break; 2949 2950 iovec->bufs[index].vaddr = seg_data; 2951 iovec->bufs[index].dma_addr = seg_phys; 2952 iovec->bufs[index].size = seg_size; 2953 2954 index++; 2955 2956 pkt = pkt->next; 2957 } 2958 2959 iovec->buf_cnt = index; 2960 return 0; 2961 } 2962 2963 static __rte_always_inline uint32_t 2964 prepare_iov_from_pkt_inplace(struct rte_mbuf *pkt, 2965 fc_params_t *param, 2966 uint32_t *flags) 2967 { 2968 uint16_t index = 0; 2969 void *seg_data = NULL; 2970 phys_addr_t seg_phys; 2971 uint32_t seg_size = 0; 2972 iov_ptr_t *iovec; 2973 2974 seg_data = rte_pktmbuf_mtod(pkt, void *); 2975 seg_phys = rte_pktmbuf_iova(pkt); 2976 seg_size = pkt->data_len; 2977 2978 /* first seg */ 2979 if (likely(!pkt->next)) { 2980 uint32_t headroom, tailroom; 2981 2982 *flags |= SINGLE_BUF_INPLACE; 2983 headroom = rte_pktmbuf_headroom(pkt); 2984 tailroom = rte_pktmbuf_tailroom(pkt); 2985 if (likely((headroom >= 24) && 2986 (tailroom >= 8))) { 2987 /* In 83XX this is prerequivisit for Direct mode */ 2988 *flags |= SINGLE_BUF_HEADTAILROOM; 2989 } 2990 param->bufs[0].vaddr = seg_data; 2991 param->bufs[0].dma_addr = seg_phys; 2992 param->bufs[0].size = seg_size; 2993 return 0; 2994 } 2995 iovec = param->src_iov; 2996 iovec->bufs[index].vaddr = seg_data; 2997 iovec->bufs[index].dma_addr = seg_phys; 2998 iovec->bufs[index].size = seg_size; 2999 index++; 3000 pkt = pkt->next; 3001 3002 while (unlikely(pkt != NULL)) { 3003 seg_data = rte_pktmbuf_mtod(pkt, void *); 3004 seg_phys = rte_pktmbuf_iova(pkt); 3005 seg_size = pkt->data_len; 3006 3007 if (!seg_size) 3008 break; 3009 3010 iovec->bufs[index].vaddr = seg_data; 3011 iovec->bufs[index].dma_addr = seg_phys; 3012 iovec->bufs[index].size = seg_size; 3013 3014 index++; 3015 3016 pkt = pkt->next; 3017 } 3018 3019 iovec->buf_cnt = index; 3020 return 0; 3021 } 3022 3023 static __rte_always_inline int 3024 fill_fc_params(struct rte_crypto_op *cop, 3025 struct cpt_sess_misc *sess_misc, 3026 struct cpt_qp_meta_info *m_info, 3027 void **mdata_ptr, 3028 void **prep_req) 3029 { 3030 uint32_t space = 0; 3031 struct rte_crypto_sym_op *sym_op = cop->sym; 3032 void *mdata = NULL; 3033 uintptr_t *op; 3034 uint32_t mc_hash_off; 3035 uint32_t flags = 0; 3036 uint64_t d_offs, d_lens; 3037 struct rte_mbuf *m_src, *m_dst; 3038 uint8_t cpt_op = sess_misc->cpt_op; 3039 #ifdef CPT_ALWAYS_USE_SG_MODE 3040 uint8_t inplace = 0; 3041 #else 3042 uint8_t inplace = 1; 3043 #endif 3044 fc_params_t fc_params; 3045 char src[SRC_IOV_SIZE]; 3046 char dst[SRC_IOV_SIZE]; 3047 uint32_t iv_buf[4]; 3048 int ret; 3049 3050 if (likely(sess_misc->iv_length)) { 3051 flags |= VALID_IV_BUF; 3052 fc_params.iv_buf = rte_crypto_op_ctod_offset(cop, 3053 uint8_t *, sess_misc->iv_offset); 3054 if (sess_misc->aes_ctr && 3055 unlikely(sess_misc->iv_length != 16)) { 3056 memcpy((uint8_t *)iv_buf, 3057 rte_crypto_op_ctod_offset(cop, 3058 uint8_t *, sess_misc->iv_offset), 12); 3059 iv_buf[3] = rte_cpu_to_be_32(0x1); 3060 fc_params.iv_buf = iv_buf; 3061 } 3062 } 3063 3064 if (sess_misc->zsk_flag) { 3065 fc_params.auth_iv_buf = rte_crypto_op_ctod_offset(cop, 3066 uint8_t *, 3067 sess_misc->auth_iv_offset); 3068 if (sess_misc->zsk_flag != ZS_EA) 3069 inplace = 0; 3070 } 3071 m_src = sym_op->m_src; 3072 m_dst = sym_op->m_dst; 3073 3074 if (sess_misc->aes_gcm || sess_misc->chacha_poly) { 3075 uint8_t *salt; 3076 uint8_t *aad_data; 3077 uint16_t aad_len; 3078 3079 d_offs = sym_op->aead.data.offset; 3080 d_lens = sym_op->aead.data.length; 3081 mc_hash_off = sym_op->aead.data.offset + 3082 sym_op->aead.data.length; 3083 3084 aad_data = sym_op->aead.aad.data; 3085 aad_len = sess_misc->aad_length; 3086 if (likely((aad_data + aad_len) == 3087 rte_pktmbuf_mtod_offset(m_src, 3088 uint8_t *, 3089 sym_op->aead.data.offset))) { 3090 d_offs = (d_offs - aad_len) | (d_offs << 16); 3091 d_lens = (d_lens + aad_len) | (d_lens << 32); 3092 } else { 3093 fc_params.aad_buf.vaddr = sym_op->aead.aad.data; 3094 fc_params.aad_buf.dma_addr = sym_op->aead.aad.phys_addr; 3095 fc_params.aad_buf.size = aad_len; 3096 flags |= VALID_AAD_BUF; 3097 inplace = 0; 3098 d_offs = d_offs << 16; 3099 d_lens = d_lens << 32; 3100 } 3101 3102 salt = fc_params.iv_buf; 3103 if (unlikely(*(uint32_t *)salt != sess_misc->salt)) { 3104 cpt_fc_salt_update(SESS_PRIV(sess_misc), salt); 3105 sess_misc->salt = *(uint32_t *)salt; 3106 } 3107 fc_params.iv_buf = salt + 4; 3108 if (likely(sess_misc->mac_len)) { 3109 struct rte_mbuf *m = (cpt_op & CPT_OP_ENCODE) ? m_dst : 3110 m_src; 3111 3112 if (!m) 3113 m = m_src; 3114 3115 /* hmac immediately following data is best case */ 3116 if (unlikely(rte_pktmbuf_mtod(m, uint8_t *) + 3117 mc_hash_off != 3118 (uint8_t *)sym_op->aead.digest.data)) { 3119 flags |= VALID_MAC_BUF; 3120 fc_params.mac_buf.size = sess_misc->mac_len; 3121 fc_params.mac_buf.vaddr = 3122 sym_op->aead.digest.data; 3123 fc_params.mac_buf.dma_addr = 3124 sym_op->aead.digest.phys_addr; 3125 inplace = 0; 3126 } 3127 } 3128 } else { 3129 d_offs = sym_op->cipher.data.offset; 3130 d_lens = sym_op->cipher.data.length; 3131 mc_hash_off = sym_op->cipher.data.offset + 3132 sym_op->cipher.data.length; 3133 d_offs = (d_offs << 16) | sym_op->auth.data.offset; 3134 d_lens = (d_lens << 32) | sym_op->auth.data.length; 3135 3136 if (mc_hash_off < (sym_op->auth.data.offset + 3137 sym_op->auth.data.length)){ 3138 mc_hash_off = (sym_op->auth.data.offset + 3139 sym_op->auth.data.length); 3140 } 3141 /* for gmac, salt should be updated like in gcm */ 3142 if (unlikely(sess_misc->is_gmac)) { 3143 uint8_t *salt; 3144 salt = fc_params.iv_buf; 3145 if (unlikely(*(uint32_t *)salt != sess_misc->salt)) { 3146 cpt_fc_salt_update(SESS_PRIV(sess_misc), salt); 3147 sess_misc->salt = *(uint32_t *)salt; 3148 } 3149 fc_params.iv_buf = salt + 4; 3150 } 3151 if (likely(sess_misc->mac_len)) { 3152 struct rte_mbuf *m; 3153 3154 m = (cpt_op & CPT_OP_ENCODE) ? m_dst : m_src; 3155 if (!m) 3156 m = m_src; 3157 3158 /* hmac immediately following data is best case */ 3159 if (unlikely(rte_pktmbuf_mtod(m, uint8_t *) + 3160 mc_hash_off != 3161 (uint8_t *)sym_op->auth.digest.data)) { 3162 flags |= VALID_MAC_BUF; 3163 fc_params.mac_buf.size = 3164 sess_misc->mac_len; 3165 fc_params.mac_buf.vaddr = 3166 sym_op->auth.digest.data; 3167 fc_params.mac_buf.dma_addr = 3168 sym_op->auth.digest.phys_addr; 3169 inplace = 0; 3170 } 3171 } 3172 } 3173 fc_params.ctx_buf.vaddr = SESS_PRIV(sess_misc); 3174 fc_params.ctx_buf.dma_addr = sess_misc->ctx_dma_addr; 3175 3176 if (unlikely(sess_misc->is_null || sess_misc->cpt_op == CPT_OP_DECODE)) 3177 inplace = 0; 3178 3179 if (likely(!m_dst && inplace)) { 3180 /* Case of single buffer without AAD buf or 3181 * separate mac buf in place and 3182 * not air crypto 3183 */ 3184 fc_params.dst_iov = fc_params.src_iov = (void *)src; 3185 3186 if (unlikely(prepare_iov_from_pkt_inplace(m_src, 3187 &fc_params, 3188 &flags))) { 3189 CPT_LOG_DP_ERR("Prepare inplace src iov failed"); 3190 ret = -EINVAL; 3191 goto err_exit; 3192 } 3193 3194 } else { 3195 /* Out of place processing */ 3196 fc_params.src_iov = (void *)src; 3197 fc_params.dst_iov = (void *)dst; 3198 3199 /* Store SG I/O in the api for reuse */ 3200 if (prepare_iov_from_pkt(m_src, fc_params.src_iov, 0)) { 3201 CPT_LOG_DP_ERR("Prepare src iov failed"); 3202 ret = -EINVAL; 3203 goto err_exit; 3204 } 3205 3206 if (unlikely(m_dst != NULL)) { 3207 uint32_t pkt_len; 3208 3209 /* Try to make room as much as src has */ 3210 pkt_len = rte_pktmbuf_pkt_len(m_dst); 3211 3212 if (unlikely(pkt_len < rte_pktmbuf_pkt_len(m_src))) { 3213 pkt_len = rte_pktmbuf_pkt_len(m_src) - pkt_len; 3214 if (!rte_pktmbuf_append(m_dst, pkt_len)) { 3215 CPT_LOG_DP_ERR("Not enough space in " 3216 "m_dst %p, need %u" 3217 " more", 3218 m_dst, pkt_len); 3219 ret = -EINVAL; 3220 goto err_exit; 3221 } 3222 } 3223 3224 if (prepare_iov_from_pkt(m_dst, fc_params.dst_iov, 0)) { 3225 CPT_LOG_DP_ERR("Prepare dst iov failed for " 3226 "m_dst %p", m_dst); 3227 ret = -EINVAL; 3228 goto err_exit; 3229 } 3230 } else { 3231 fc_params.dst_iov = (void *)src; 3232 } 3233 } 3234 3235 if (likely(flags & SINGLE_BUF_HEADTAILROOM)) 3236 mdata = alloc_op_meta(m_src, &fc_params.meta_buf, 3237 m_info->lb_mlen, m_info->pool); 3238 else 3239 mdata = alloc_op_meta(NULL, &fc_params.meta_buf, 3240 m_info->sg_mlen, m_info->pool); 3241 3242 if (unlikely(mdata == NULL)) { 3243 CPT_LOG_DP_ERR("Error allocating meta buffer for request"); 3244 ret = -ENOMEM; 3245 goto err_exit; 3246 } 3247 3248 op = (uintptr_t *)((uintptr_t)mdata & (uintptr_t)~1ull); 3249 op[0] = (uintptr_t)mdata; 3250 op[1] = (uintptr_t)cop; 3251 op[2] = op[3] = 0; /* Used to indicate auth verify */ 3252 space += 4 * sizeof(uint64_t); 3253 3254 fc_params.meta_buf.vaddr = (uint8_t *)op + space; 3255 fc_params.meta_buf.dma_addr += space; 3256 fc_params.meta_buf.size -= space; 3257 3258 /* Finally prepare the instruction */ 3259 if (cpt_op & CPT_OP_ENCODE) 3260 *prep_req = cpt_fc_enc_hmac_prep(flags, d_offs, d_lens, 3261 &fc_params, op); 3262 else 3263 *prep_req = cpt_fc_dec_hmac_prep(flags, d_offs, d_lens, 3264 &fc_params, op); 3265 3266 if (unlikely(*prep_req == NULL)) { 3267 CPT_LOG_DP_ERR("Preparing request failed due to bad input arg"); 3268 ret = -EINVAL; 3269 goto free_mdata_and_exit; 3270 } 3271 3272 *mdata_ptr = mdata; 3273 3274 return 0; 3275 3276 free_mdata_and_exit: 3277 free_op_meta(mdata, m_info->pool); 3278 err_exit: 3279 return ret; 3280 } 3281 3282 static __rte_always_inline void 3283 compl_auth_verify(struct rte_crypto_op *op, 3284 uint8_t *gen_mac, 3285 uint64_t mac_len) 3286 { 3287 uint8_t *mac; 3288 struct rte_crypto_sym_op *sym_op = op->sym; 3289 3290 if (sym_op->auth.digest.data) 3291 mac = sym_op->auth.digest.data; 3292 else 3293 mac = rte_pktmbuf_mtod_offset(sym_op->m_src, 3294 uint8_t *, 3295 sym_op->auth.data.length + 3296 sym_op->auth.data.offset); 3297 if (!mac) { 3298 op->status = RTE_CRYPTO_OP_STATUS_ERROR; 3299 return; 3300 } 3301 3302 if (memcmp(mac, gen_mac, mac_len)) 3303 op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; 3304 else 3305 op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; 3306 } 3307 3308 static __rte_always_inline void 3309 find_kasumif9_direction_and_length(uint8_t *src, 3310 uint32_t counter_num_bytes, 3311 uint32_t *addr_length_in_bits, 3312 uint8_t *addr_direction) 3313 { 3314 uint8_t found = 0; 3315 uint32_t pos; 3316 uint8_t last_byte; 3317 while (!found && counter_num_bytes > 0) { 3318 counter_num_bytes--; 3319 if (src[counter_num_bytes] == 0x00) 3320 continue; 3321 pos = rte_bsf32(src[counter_num_bytes]); 3322 if (pos == 7) { 3323 if (likely(counter_num_bytes > 0)) { 3324 last_byte = src[counter_num_bytes - 1]; 3325 *addr_direction = last_byte & 0x1; 3326 *addr_length_in_bits = counter_num_bytes * 8 3327 - 1; 3328 } 3329 } else { 3330 last_byte = src[counter_num_bytes]; 3331 *addr_direction = (last_byte >> (pos + 1)) & 0x1; 3332 *addr_length_in_bits = counter_num_bytes * 8 3333 + (8 - (pos + 2)); 3334 } 3335 found = 1; 3336 } 3337 } 3338 3339 /* 3340 * This handles all auth only except AES_GMAC 3341 */ 3342 static __rte_always_inline int 3343 fill_digest_params(struct rte_crypto_op *cop, 3344 struct cpt_sess_misc *sess, 3345 struct cpt_qp_meta_info *m_info, 3346 void **mdata_ptr, 3347 void **prep_req) 3348 { 3349 uint32_t space = 0; 3350 struct rte_crypto_sym_op *sym_op = cop->sym; 3351 void *mdata; 3352 phys_addr_t mphys; 3353 uint64_t *op; 3354 uint32_t auth_range_off; 3355 uint32_t flags = 0; 3356 uint64_t d_offs = 0, d_lens; 3357 struct rte_mbuf *m_src, *m_dst; 3358 uint16_t auth_op = sess->cpt_op & CPT_OP_AUTH_MASK; 3359 uint16_t mac_len = sess->mac_len; 3360 fc_params_t params; 3361 char src[SRC_IOV_SIZE]; 3362 uint8_t iv_buf[16]; 3363 int ret; 3364 3365 memset(¶ms, 0, sizeof(fc_params_t)); 3366 3367 m_src = sym_op->m_src; 3368 3369 /* For just digest lets force mempool alloc */ 3370 mdata = alloc_op_meta(NULL, ¶ms.meta_buf, m_info->sg_mlen, 3371 m_info->pool); 3372 if (mdata == NULL) { 3373 ret = -ENOMEM; 3374 goto err_exit; 3375 } 3376 3377 mphys = params.meta_buf.dma_addr; 3378 3379 op = mdata; 3380 op[0] = (uintptr_t)mdata; 3381 op[1] = (uintptr_t)cop; 3382 op[2] = op[3] = 0; /* Used to indicate auth verify */ 3383 space += 4 * sizeof(uint64_t); 3384 3385 auth_range_off = sym_op->auth.data.offset; 3386 3387 flags = VALID_MAC_BUF; 3388 params.src_iov = (void *)src; 3389 if (unlikely(sess->zsk_flag)) { 3390 /* 3391 * Since for Zuc, Kasumi, Snow3g offsets are in bits 3392 * we will send pass through even for auth only case, 3393 * let MC handle it 3394 */ 3395 d_offs = auth_range_off; 3396 auth_range_off = 0; 3397 params.auth_iv_buf = rte_crypto_op_ctod_offset(cop, 3398 uint8_t *, sess->auth_iv_offset); 3399 if (sess->zsk_flag == K_F9) { 3400 uint32_t length_in_bits, num_bytes; 3401 uint8_t *src, direction = 0; 3402 3403 memcpy(iv_buf, rte_pktmbuf_mtod(cop->sym->m_src, 3404 uint8_t *), 8); 3405 /* 3406 * This is kasumi f9, take direction from 3407 * source buffer 3408 */ 3409 length_in_bits = cop->sym->auth.data.length; 3410 num_bytes = (length_in_bits >> 3); 3411 src = rte_pktmbuf_mtod(cop->sym->m_src, uint8_t *); 3412 find_kasumif9_direction_and_length(src, 3413 num_bytes, 3414 &length_in_bits, 3415 &direction); 3416 length_in_bits -= 64; 3417 cop->sym->auth.data.offset += 64; 3418 d_offs = cop->sym->auth.data.offset; 3419 auth_range_off = d_offs / 8; 3420 cop->sym->auth.data.length = length_in_bits; 3421 3422 /* Store it at end of auth iv */ 3423 iv_buf[8] = direction; 3424 params.auth_iv_buf = iv_buf; 3425 } 3426 } 3427 3428 d_lens = sym_op->auth.data.length; 3429 3430 params.ctx_buf.vaddr = SESS_PRIV(sess); 3431 params.ctx_buf.dma_addr = sess->ctx_dma_addr; 3432 3433 if (auth_op == CPT_OP_AUTH_GENERATE) { 3434 if (sym_op->auth.digest.data) { 3435 /* 3436 * Digest to be generated 3437 * in separate buffer 3438 */ 3439 params.mac_buf.size = 3440 sess->mac_len; 3441 params.mac_buf.vaddr = 3442 sym_op->auth.digest.data; 3443 params.mac_buf.dma_addr = 3444 sym_op->auth.digest.phys_addr; 3445 } else { 3446 uint32_t off = sym_op->auth.data.offset + 3447 sym_op->auth.data.length; 3448 int32_t dlen, space; 3449 3450 m_dst = sym_op->m_dst ? 3451 sym_op->m_dst : sym_op->m_src; 3452 dlen = rte_pktmbuf_pkt_len(m_dst); 3453 3454 space = off + mac_len - dlen; 3455 if (space > 0) 3456 if (!rte_pktmbuf_append(m_dst, space)) { 3457 CPT_LOG_DP_ERR("Failed to extend " 3458 "mbuf by %uB", space); 3459 ret = -EINVAL; 3460 goto free_mdata_and_exit; 3461 } 3462 3463 params.mac_buf.vaddr = 3464 rte_pktmbuf_mtod_offset(m_dst, void *, off); 3465 params.mac_buf.dma_addr = 3466 rte_pktmbuf_iova_offset(m_dst, off); 3467 params.mac_buf.size = mac_len; 3468 } 3469 } else { 3470 /* Need space for storing generated mac */ 3471 params.mac_buf.vaddr = (uint8_t *)mdata + space; 3472 params.mac_buf.dma_addr = mphys + space; 3473 params.mac_buf.size = mac_len; 3474 space += RTE_ALIGN_CEIL(mac_len, 8); 3475 op[2] = (uintptr_t)params.mac_buf.vaddr; 3476 op[3] = mac_len; 3477 } 3478 3479 params.meta_buf.vaddr = (uint8_t *)mdata + space; 3480 params.meta_buf.dma_addr = mphys + space; 3481 params.meta_buf.size -= space; 3482 3483 /* Out of place processing */ 3484 params.src_iov = (void *)src; 3485 3486 /*Store SG I/O in the api for reuse */ 3487 if (prepare_iov_from_pkt(m_src, params.src_iov, auth_range_off)) { 3488 CPT_LOG_DP_ERR("Prepare src iov failed"); 3489 ret = -EINVAL; 3490 goto free_mdata_and_exit; 3491 } 3492 3493 *prep_req = cpt_fc_enc_hmac_prep(flags, d_offs, d_lens, ¶ms, op); 3494 if (unlikely(*prep_req == NULL)) { 3495 ret = -EINVAL; 3496 goto free_mdata_and_exit; 3497 } 3498 3499 *mdata_ptr = mdata; 3500 3501 return 0; 3502 3503 free_mdata_and_exit: 3504 free_op_meta(mdata, m_info->pool); 3505 err_exit: 3506 return ret; 3507 } 3508 3509 #endif /*_CPT_UCODE_H_ */ 3510