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

Configure Feed

Select the types of activity you want to include in your feed.

crypto: caam - Add support of paes algorithm

PAES algorithm uses protected key for encryption/decryption operations.

Signed-off-by: Gaurav Jain <gaurav.jain@nxp.com>
Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Meenakshi Aggarwal and committed by
Herbert Xu
66b9a095 a703a4c2

+220 -16
+117 -11
drivers/crypto/caam/caamalg.c
··· 3 3 * caam - Freescale FSL CAAM support for crypto API 4 4 * 5 5 * Copyright 2008-2011 Freescale Semiconductor, Inc. 6 - * Copyright 2016-2019, 2023 NXP 6 + * Copyright 2016-2019, 2023, 2025 NXP 7 7 * 8 8 * Based on talitos crypto API driver. 9 9 * ··· 61 61 #include <crypto/internal/engine.h> 62 62 #include <crypto/internal/skcipher.h> 63 63 #include <crypto/xts.h> 64 + #include <keys/trusted-type.h> 64 65 #include <linux/dma-mapping.h> 65 66 #include <linux/device.h> 66 67 #include <linux/err.h> 67 68 #include <linux/module.h> 68 69 #include <linux/kernel.h> 70 + #include <linux/key-type.h> 69 71 #include <linux/slab.h> 70 72 #include <linux/string.h> 73 + #include <soc/fsl/caam-blob.h> 71 74 72 75 /* 73 76 * crypto alg ··· 122 119 dma_addr_t sh_desc_enc_dma; 123 120 dma_addr_t sh_desc_dec_dma; 124 121 dma_addr_t key_dma; 122 + u8 protected_key[CAAM_MAX_KEY_SIZE]; 123 + dma_addr_t protected_key_dma; 125 124 enum dma_data_direction dir; 126 125 struct device *jrdev; 127 126 struct alginfo adata; 128 127 struct alginfo cdata; 129 128 unsigned int authsize; 130 129 bool xts_key_fallback; 130 + bool is_blob; 131 131 struct crypto_skcipher *fallback; 132 132 }; 133 133 ··· 757 751 print_hex_dump_debug("key in @"__stringify(__LINE__)": ", 758 752 DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); 759 753 754 + /* Here keylen is actual key length */ 760 755 ctx->cdata.keylen = keylen; 761 756 ctx->cdata.key_virt = key; 762 757 ctx->cdata.key_inline = true; 758 + /* Here protected key len is plain key length */ 759 + ctx->cdata.plain_keylen = keylen; 760 + ctx->cdata.key_cmd_opt = 0; 761 + 763 762 764 763 /* skcipher_encrypt shared descriptor */ 765 764 desc = ctx->sh_desc_enc; ··· 779 768 ctx1_iv_off); 780 769 dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma, 781 770 desc_bytes(desc), ctx->dir); 771 + 772 + return 0; 773 + } 774 + 775 + static int paes_skcipher_setkey(struct crypto_skcipher *skcipher, 776 + const u8 *key, 777 + unsigned int keylen) 778 + { 779 + struct caam_pkey_info *pkey_info = (struct caam_pkey_info *)key; 780 + struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher); 781 + struct device *jrdev = ctx->jrdev; 782 + int err; 783 + 784 + ctx->cdata.key_inline = false; 785 + 786 + keylen = keylen - CAAM_PKEY_HEADER; 787 + 788 + /* Retrieve the length of key */ 789 + ctx->cdata.plain_keylen = pkey_info->plain_key_sz; 790 + 791 + /* Retrieve the length of blob*/ 792 + ctx->cdata.keylen = keylen; 793 + 794 + /* Retrieve the address of the blob */ 795 + ctx->cdata.key_virt = pkey_info->key_buf; 796 + 797 + /* Validate key length for AES algorithms */ 798 + err = aes_check_keylen(ctx->cdata.plain_keylen); 799 + if (err) { 800 + dev_err(jrdev, "bad key length\n"); 801 + return err; 802 + } 803 + 804 + /* set command option */ 805 + ctx->cdata.key_cmd_opt |= KEY_ENC; 806 + 807 + /* check if the Protected-Key is CCM key */ 808 + if (pkey_info->key_enc_algo == CAAM_ENC_ALGO_CCM) 809 + ctx->cdata.key_cmd_opt |= KEY_EKT; 810 + 811 + memcpy(ctx->key, ctx->cdata.key_virt, keylen); 812 + dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, DMA_TO_DEVICE); 813 + ctx->cdata.key_dma = ctx->key_dma; 814 + 815 + if (pkey_info->key_enc_algo == CAAM_ENC_ALGO_CCM) 816 + ctx->protected_key_dma = dma_map_single(jrdev, ctx->protected_key, 817 + ctx->cdata.plain_keylen + 818 + CAAM_CCM_OVERHEAD, 819 + DMA_FROM_DEVICE); 820 + else 821 + ctx->protected_key_dma = dma_map_single(jrdev, ctx->protected_key, 822 + ctx->cdata.plain_keylen, 823 + DMA_FROM_DEVICE); 824 + 825 + ctx->cdata.protected_key_dma = ctx->protected_key_dma; 826 + ctx->is_blob = true; 782 827 783 828 return 0; 784 829 } ··· 1321 1254 struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher); 1322 1255 struct device *jrdev = ctx->jrdev; 1323 1256 int ivsize = crypto_skcipher_ivsize(skcipher); 1324 - u32 *desc = edesc->hw_desc; 1257 + u32 *desc = !ctx->is_blob ? edesc->hw_desc : 1258 + (u32 *)((u8 *)edesc->hw_desc + CAAM_DESC_BYTES_MAX); 1259 + dma_addr_t desc_dma; 1325 1260 u32 *sh_desc; 1326 1261 u32 in_options = 0, out_options = 0; 1327 1262 dma_addr_t src_dma, dst_dma, ptr; ··· 1338 1269 DUMP_PREFIX_ADDRESS, 16, 4, req->src, 1339 1270 edesc->src_nents > 1 ? 100 : req->cryptlen, 1); 1340 1271 1341 - sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec; 1342 - ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma; 1343 - 1344 - len = desc_len(sh_desc); 1345 - init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE); 1346 1272 1347 1273 if (ivsize || edesc->mapped_src_nents > 1) { 1348 1274 src_dma = edesc->sec4_sg_dma; ··· 1346 1282 } else { 1347 1283 src_dma = sg_dma_address(req->src); 1348 1284 } 1349 - 1350 - append_seq_in_ptr(desc, src_dma, req->cryptlen + ivsize, in_options); 1351 1285 1352 1286 if (likely(req->src == req->dst)) { 1353 1287 dst_dma = src_dma + !!ivsize * sizeof(struct sec4_sg_entry); ··· 1358 1296 out_options = LDST_SGF; 1359 1297 } 1360 1298 1361 - append_seq_out_ptr(desc, dst_dma, req->cryptlen + ivsize, out_options); 1299 + if (ctx->is_blob) { 1300 + cnstr_desc_skcipher_enc_dec(desc, &ctx->cdata, 1301 + src_dma, dst_dma, req->cryptlen + ivsize, 1302 + in_options, out_options, 1303 + ivsize, encrypt); 1304 + 1305 + desc_dma = dma_map_single(jrdev, desc, desc_bytes(desc), DMA_TO_DEVICE); 1306 + 1307 + cnstr_desc_protected_blob_decap(edesc->hw_desc, &ctx->cdata, desc_dma); 1308 + } else { 1309 + sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec; 1310 + ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma; 1311 + 1312 + len = desc_len(sh_desc); 1313 + init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE); 1314 + append_seq_in_ptr(desc, src_dma, req->cryptlen + ivsize, in_options); 1315 + 1316 + append_seq_out_ptr(desc, dst_dma, req->cryptlen + ivsize, out_options); 1317 + } 1362 1318 } 1363 1319 1364 1320 /* ··· 1897 1817 struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent); 1898 1818 u32 *desc; 1899 1819 int ret = 0; 1820 + int len; 1900 1821 1901 1822 /* 1902 1823 * XTS is expected to return an error even for input length = 0 ··· 1923 1842 crypto_skcipher_decrypt(&rctx->fallback_req); 1924 1843 } 1925 1844 1845 + len = DESC_JOB_IO_LEN * CAAM_CMD_SZ; 1846 + if (ctx->is_blob) 1847 + len += CAAM_DESC_BYTES_MAX; 1848 + 1926 1849 /* allocate extended descriptor */ 1927 - edesc = skcipher_edesc_alloc(req, DESC_JOB_IO_LEN * CAAM_CMD_SZ); 1850 + edesc = skcipher_edesc_alloc(req, len); 1928 1851 if (IS_ERR(edesc)) 1929 1852 return PTR_ERR(edesc); 1930 1853 ··· 1970 1885 } 1971 1886 1972 1887 static struct caam_skcipher_alg driver_algs[] = { 1888 + { 1889 + .skcipher.base = { 1890 + .base = { 1891 + .cra_name = "cbc(paes)", 1892 + .cra_driver_name = "cbc-paes-caam", 1893 + .cra_blocksize = AES_BLOCK_SIZE, 1894 + }, 1895 + .setkey = paes_skcipher_setkey, 1896 + .encrypt = skcipher_encrypt, 1897 + .decrypt = skcipher_decrypt, 1898 + .min_keysize = AES_MIN_KEY_SIZE + CAAM_BLOB_OVERHEAD + 1899 + CAAM_PKEY_HEADER, 1900 + .max_keysize = AES_MAX_KEY_SIZE + CAAM_BLOB_OVERHEAD + 1901 + CAAM_PKEY_HEADER, 1902 + .ivsize = AES_BLOCK_SIZE, 1903 + }, 1904 + .skcipher.op = { 1905 + .do_one_request = skcipher_do_one_req, 1906 + }, 1907 + .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 1908 + }, 1973 1909 { 1974 1910 .skcipher.base = { 1975 1911 .base = {
+84 -3
drivers/crypto/caam/caamalg_desc.c
··· 2 2 /* 3 3 * Shared descriptors for aead, skcipher algorithms 4 4 * 5 - * Copyright 2016-2019 NXP 5 + * Copyright 2016-2019, 2025 NXP 6 6 */ 7 7 8 8 #include "compat.h" 9 9 #include "desc_constr.h" 10 10 #include "caamalg_desc.h" 11 + #include <soc/fsl/caam-blob.h> 11 12 12 13 /* 13 14 * For aead functions, read payload and write payload, ··· 1365 1364 append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF); 1366 1365 } 1367 1366 1367 + void cnstr_desc_skcipher_enc_dec(u32 * const desc, struct alginfo *cdata, 1368 + dma_addr_t src, dma_addr_t dst, unsigned int data_sz, 1369 + unsigned int in_options, unsigned int out_options, 1370 + unsigned int ivsize, const bool encrypt) 1371 + { 1372 + u32 options = cdata->algtype | OP_ALG_AS_INIT; 1373 + 1374 + if (encrypt) 1375 + options |= OP_ALG_ENCRYPT; 1376 + else 1377 + options |= OP_ALG_DECRYPT; 1378 + 1379 + init_job_desc(desc, 0); 1380 + 1381 + append_jump(desc, JUMP_JSL | JUMP_TYPE_LOCAL | 1382 + JUMP_COND_NOP | JUMP_TEST_ALL | 1); 1383 + 1384 + append_key(desc, cdata->protected_key_dma, cdata->plain_keylen, 1385 + CLASS_1 | KEY_DEST_CLASS_REG | cdata->key_cmd_opt); 1386 + 1387 + append_seq_in_ptr(desc, src, data_sz, in_options); 1388 + 1389 + append_seq_out_ptr(desc, dst, data_sz, out_options); 1390 + 1391 + /* Load IV, if there is one */ 1392 + if (ivsize) 1393 + append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT | 1394 + LDST_CLASS_1_CCB); 1395 + 1396 + append_operation(desc, options); 1397 + 1398 + skcipher_append_src_dst(desc); 1399 + 1400 + /* Store IV */ 1401 + if (ivsize) 1402 + append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT | 1403 + LDST_CLASS_1_CCB); 1404 + 1405 + print_hex_dump_debug("skcipher_enc_dec job desc@" __stringify(__LINE__)": ", 1406 + DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1407 + 1); 1408 + } 1409 + EXPORT_SYMBOL(cnstr_desc_skcipher_enc_dec); 1410 + 1411 + void cnstr_desc_protected_blob_decap(u32 * const desc, struct alginfo *cdata, 1412 + dma_addr_t next_desc_addr) 1413 + { 1414 + u32 protected_store; 1415 + 1416 + init_job_desc(desc, 0); 1417 + 1418 + /* Load key modifier */ 1419 + append_load_as_imm(desc, KEYMOD, sizeof(KEYMOD) - 1, 1420 + LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY); 1421 + 1422 + append_seq_in_ptr_intlen(desc, cdata->key_dma, 1423 + cdata->plain_keylen + CAAM_BLOB_OVERHEAD, 0); 1424 + 1425 + append_seq_out_ptr_intlen(desc, cdata->protected_key_dma, 1426 + cdata->plain_keylen, 0); 1427 + 1428 + protected_store = OP_PCLID_BLOB | OP_PCL_BLOB_BLACK; 1429 + if ((cdata->key_cmd_opt >> KEY_EKT_OFFSET) & 1) 1430 + protected_store |= OP_PCL_BLOB_EKT; 1431 + 1432 + append_operation(desc, OP_TYPE_DECAP_PROTOCOL | protected_store); 1433 + 1434 + if (next_desc_addr) { 1435 + append_jump(desc, JUMP_TYPE_NONLOCAL | JUMP_TEST_ALL); 1436 + append_ptr(desc, next_desc_addr); 1437 + } 1438 + 1439 + print_hex_dump_debug("protected blob decap job desc@" __stringify(__LINE__) ":", 1440 + DUMP_PREFIX_ADDRESS, 16, 4, desc, 1441 + desc_bytes(desc), 1); 1442 + } 1443 + EXPORT_SYMBOL(cnstr_desc_protected_blob_decap); 1444 + 1368 1445 /** 1369 1446 * cnstr_shdsc_skcipher_encap - skcipher encapsulation shared descriptor 1370 1447 * @desc: pointer to buffer used for descriptor construction ··· 1470 1391 1471 1392 /* Load class1 key only */ 1472 1393 append_key_as_imm(desc, cdata->key_virt, cdata->keylen, 1473 - cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG); 1394 + cdata->plain_keylen, CLASS_1 | KEY_DEST_CLASS_REG 1395 + | cdata->key_cmd_opt); 1474 1396 1475 1397 /* Load nonce into CONTEXT1 reg */ 1476 1398 if (is_rfc3686) { ··· 1546 1466 1547 1467 /* Load class1 key only */ 1548 1468 append_key_as_imm(desc, cdata->key_virt, cdata->keylen, 1549 - cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG); 1469 + cdata->plain_keylen, CLASS_1 | KEY_DEST_CLASS_REG 1470 + | cdata->key_cmd_opt); 1550 1471 1551 1472 /* Load nonce into CONTEXT1 reg */ 1552 1473 if (is_rfc3686) {
+12 -1
drivers/crypto/caam/caamalg_desc.h
··· 2 2 /* 3 3 * Shared descriptors for aead, skcipher algorithms 4 4 * 5 - * Copyright 2016 NXP 5 + * Copyright 2016, 2025 NXP 6 6 */ 7 7 8 8 #ifndef _CAAMALG_DESC_H_ ··· 47 47 21 * CAAM_CMD_SZ) 48 48 #define DESC_SKCIPHER_DEC_LEN (DESC_SKCIPHER_BASE + \ 49 49 16 * CAAM_CMD_SZ) 50 + 51 + /* Key modifier for CAAM Protected blobs */ 52 + #define KEYMOD "SECURE_KEY" 50 53 51 54 void cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata, 52 55 unsigned int icvsize, int era); ··· 115 112 void cnstr_shdsc_xts_skcipher_encap(u32 * const desc, struct alginfo *cdata); 116 113 117 114 void cnstr_shdsc_xts_skcipher_decap(u32 * const desc, struct alginfo *cdata); 115 + 116 + void cnstr_desc_protected_blob_decap(u32 * const desc, struct alginfo *cdata, 117 + dma_addr_t next_desc); 118 + 119 + void cnstr_desc_skcipher_enc_dec(u32 * const desc, struct alginfo *cdata, 120 + dma_addr_t src, dma_addr_t dst, unsigned int data_sz, 121 + unsigned int in_options, unsigned int out_options, 122 + unsigned int ivsize, const bool encrypt); 118 123 119 124 #endif /* _CAAMALG_DESC_H_ */
+7 -1
drivers/crypto/caam/desc_constr.h
··· 3 3 * caam descriptor construction helper functions 4 4 * 5 5 * Copyright 2008-2012 Freescale Semiconductor, Inc. 6 - * Copyright 2019 NXP 6 + * Copyright 2019, 2025 NXP 7 7 */ 8 8 9 9 #ifndef DESC_CONSTR_H ··· 498 498 * @keylen: length of the provided algorithm key, in bytes 499 499 * @keylen_pad: padded length of the provided algorithm key, in bytes 500 500 * @key_dma: dma (bus) address where algorithm key resides 501 + * @protected_key_dma: dma (bus) address where protected key resides 501 502 * @key_virt: virtual address where algorithm key resides 502 503 * @key_inline: true - key can be inlined in the descriptor; false - key is 503 504 * referenced by the descriptor 505 + * @plain_keylen: size of the key to be loaded by the CAAM 506 + * @key_cmd_opt: optional parameters for KEY command 504 507 */ 505 508 struct alginfo { 506 509 u32 algtype; 507 510 unsigned int keylen; 508 511 unsigned int keylen_pad; 509 512 dma_addr_t key_dma; 513 + dma_addr_t protected_key_dma; 510 514 const void *key_virt; 511 515 bool key_inline; 516 + u32 plain_keylen; 517 + u32 key_cmd_opt; 512 518 }; 513 519 514 520 /**