Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nfp: add support CHACHA20-POLY1305 offload for ipsec

Add the configuration of CHACHA20-POLY1305 to the driver and send the
message to hardware so that the NIC supports the algorithm.

Signed-off-by: Shihong Wang <shihong.wang@corigine.com>
Signed-off-by: Louis Peens <louis.peens@corigine.com>
Link: https://lore.kernel.org/r/20231009080946.7655-2-louis.peens@corigine.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Shihong Wang and committed by
Paolo Abeni
04317b12 21b2e262

+42 -3
+42 -3
drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
··· 378 378 /* Encryption */ 379 379 switch (x->props.ealgo) { 380 380 case SADB_EALG_NONE: 381 + /* The xfrm descriptor for CHACAH20_POLY1305 does not set the algorithm id, which 382 + * is the default value SADB_EALG_NONE. In the branch of SADB_EALG_NONE, driver 383 + * uses algorithm name to identify CHACAH20_POLY1305's algorithm. 384 + */ 385 + if (x->aead && !strcmp(x->aead->alg_name, "rfc7539esp(chacha20,poly1305)")) { 386 + if (nn->pdev->device != PCI_DEVICE_ID_NFP3800) { 387 + NL_SET_ERR_MSG_MOD(extack, 388 + "Unsupported encryption algorithm for offload"); 389 + return -EINVAL; 390 + } 391 + if (x->aead->alg_icv_len != 128) { 392 + NL_SET_ERR_MSG_MOD(extack, 393 + "ICV must be 128bit with CHACHA20_POLY1305"); 394 + return -EINVAL; 395 + } 396 + 397 + /* Aead->alg_key_len includes 32-bit salt */ 398 + if (x->aead->alg_key_len - 32 != 256) { 399 + NL_SET_ERR_MSG_MOD(extack, "Unsupported CHACHA20 key length"); 400 + return -EINVAL; 401 + } 402 + 403 + /* The CHACHA20's mode is not configured */ 404 + cfg->ctrl_word.hash = NFP_IPSEC_HASH_POLY1305_128; 405 + cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_CHACHA20; 406 + break; 407 + } 408 + fallthrough; 381 409 case SADB_EALG_NULL: 382 410 cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CBC; 383 411 cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_NULL; ··· 455 427 } 456 428 457 429 if (x->aead) { 430 + int key_offset = 0; 458 431 int salt_len = 4; 459 432 460 433 key_len = DIV_ROUND_UP(x->aead->alg_key_len, BITS_PER_BYTE); ··· 466 437 return -EINVAL; 467 438 } 468 439 469 - for (i = 0; i < key_len / sizeof(cfg->ciph_key[0]) ; i++) 470 - cfg->ciph_key[i] = get_unaligned_be32(x->aead->alg_key + 471 - sizeof(cfg->ciph_key[0]) * i); 440 + /* The CHACHA20's key order needs to be adjusted based on hardware design. 441 + * Other's key order: {K0, K1, K2, K3, K4, K5, K6, K7} 442 + * CHACHA20's key order: {K4, K5, K6, K7, K0, K1, K2, K3} 443 + */ 444 + if (!strcmp(x->aead->alg_name, "rfc7539esp(chacha20,poly1305)")) 445 + key_offset = key_len / sizeof(cfg->ciph_key[0]) >> 1; 446 + 447 + for (i = 0; i < key_len / sizeof(cfg->ciph_key[0]); i++) { 448 + int index = (i + key_offset) % (key_len / sizeof(cfg->ciph_key[0])); 449 + 450 + cfg->ciph_key[index] = get_unaligned_be32(x->aead->alg_key + 451 + sizeof(cfg->ciph_key[0]) * i); 452 + } 472 453 473 454 /* Load up the salt */ 474 455 cfg->aesgcm_fields.salt = get_unaligned_be32(x->aead->alg_key + key_len);