Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
+19
View File
@@ -0,0 +1,19 @@
# SPDX-License-Identifier: GPL-2.0-only
config CRYPTO_DEV_TI_DTHEV2
tristate "Support for TI DTHE V2 cryptography engine"
depends on ARCH_K3 || COMPILE_TEST
select CRYPTO_ENGINE
select CRYPTO_SKCIPHER
select CRYPTO_ECB
select CRYPTO_CBC
select CRYPTO_CTR
select CRYPTO_XTS
select CRYPTO_GCM
select CRYPTO_CCM
select SG_SPLIT
help
This enables support for the TI DTHE V2 hw cryptography engine
which can be found on TI K3 SOCs. Selecting this enables use
of hardware offloading for cryptographic algorithms on
these devices, providing enhanced resistance against side-channel
attacks.
+3
View File
@@ -0,0 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_CRYPTO_DEV_TI_DTHEV2) += dthev2.o
dthev2-objs := dthev2-common.o dthev2-aes.o
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,235 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* K3 DTHE V2 crypto accelerator driver
*
* Copyright (C) Texas Instruments 2025 - https://www.ti.com
* Author: T Pratham <t-pratham@ti.com>
*/
#include <crypto/aes.h>
#include <crypto/algapi.h>
#include <crypto/engine.h>
#include <crypto/internal/aead.h>
#include <crypto/internal/skcipher.h>
#include "dthev2-common.h"
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/dmapool.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#define DRIVER_NAME "dthev2"
static struct dthe_list dthe_dev_list = {
.dev_list = LIST_HEAD_INIT(dthe_dev_list.dev_list),
.lock = __SPIN_LOCK_UNLOCKED(dthe_dev_list.lock),
};
struct dthe_data *dthe_get_dev(struct dthe_tfm_ctx *ctx)
{
struct dthe_data *dev_data;
if (ctx->dev_data)
return ctx->dev_data;
spin_lock_bh(&dthe_dev_list.lock);
dev_data = list_first_entry(&dthe_dev_list.dev_list, struct dthe_data, list);
if (dev_data)
list_move_tail(&dev_data->list, &dthe_dev_list.dev_list);
spin_unlock_bh(&dthe_dev_list.lock);
return dev_data;
}
struct scatterlist *dthe_copy_sg(struct scatterlist *dst,
struct scatterlist *src,
int buflen)
{
struct scatterlist *from_sg, *to_sg;
int sglen;
for (to_sg = dst, from_sg = src; buflen && from_sg; buflen -= sglen) {
sglen = from_sg->length;
if (sglen > buflen)
sglen = buflen;
sg_set_buf(to_sg, sg_virt(from_sg), sglen);
from_sg = sg_next(from_sg);
to_sg = sg_next(to_sg);
}
return to_sg;
}
static int dthe_dma_init(struct dthe_data *dev_data)
{
int ret;
struct dma_slave_config cfg;
dev_data->dma_aes_rx = NULL;
dev_data->dma_aes_tx = NULL;
dev_data->dma_sha_tx = NULL;
dev_data->dma_aes_rx = dma_request_chan(dev_data->dev, "rx");
if (IS_ERR(dev_data->dma_aes_rx)) {
return dev_err_probe(dev_data->dev, PTR_ERR(dev_data->dma_aes_rx),
"Unable to request rx DMA channel\n");
}
dev_data->dma_aes_tx = dma_request_chan(dev_data->dev, "tx1");
if (IS_ERR(dev_data->dma_aes_tx)) {
ret = dev_err_probe(dev_data->dev, PTR_ERR(dev_data->dma_aes_tx),
"Unable to request tx1 DMA channel\n");
goto err_dma_aes_tx;
}
dev_data->dma_sha_tx = dma_request_chan(dev_data->dev, "tx2");
if (IS_ERR(dev_data->dma_sha_tx)) {
ret = dev_err_probe(dev_data->dev, PTR_ERR(dev_data->dma_sha_tx),
"Unable to request tx2 DMA channel\n");
goto err_dma_sha_tx;
}
memzero_explicit(&cfg, sizeof(cfg));
cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
cfg.src_maxburst = 4;
ret = dmaengine_slave_config(dev_data->dma_aes_rx, &cfg);
if (ret) {
dev_err(dev_data->dev, "Can't configure IN dmaengine slave: %d\n", ret);
goto err_dma_config;
}
cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
cfg.dst_maxburst = 4;
ret = dmaengine_slave_config(dev_data->dma_aes_tx, &cfg);
if (ret) {
dev_err(dev_data->dev, "Can't configure OUT dmaengine slave: %d\n", ret);
goto err_dma_config;
}
return 0;
err_dma_config:
dma_release_channel(dev_data->dma_sha_tx);
err_dma_sha_tx:
dma_release_channel(dev_data->dma_aes_tx);
err_dma_aes_tx:
dma_release_channel(dev_data->dma_aes_rx);
return ret;
}
static int dthe_register_algs(void)
{
return dthe_register_aes_algs();
}
static void dthe_unregister_algs(void)
{
dthe_unregister_aes_algs();
}
static int dthe_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct dthe_data *dev_data;
int ret;
dev_data = devm_kzalloc(dev, sizeof(*dev_data), GFP_KERNEL);
if (!dev_data)
return -ENOMEM;
dev_data->dev = dev;
dev_data->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(dev_data->regs))
return PTR_ERR(dev_data->regs);
platform_set_drvdata(pdev, dev_data);
spin_lock(&dthe_dev_list.lock);
list_add(&dev_data->list, &dthe_dev_list.dev_list);
spin_unlock(&dthe_dev_list.lock);
ret = dthe_dma_init(dev_data);
if (ret)
goto probe_dma_err;
dev_data->engine = crypto_engine_alloc_init(dev, 1);
if (!dev_data->engine) {
ret = -ENOMEM;
goto probe_engine_err;
}
ret = crypto_engine_start(dev_data->engine);
if (ret) {
dev_err(dev, "Failed to start crypto engine\n");
goto probe_engine_start_err;
}
ret = dthe_register_algs();
if (ret) {
dev_err(dev, "Failed to register algs\n");
goto probe_engine_start_err;
}
return 0;
probe_engine_start_err:
crypto_engine_exit(dev_data->engine);
probe_engine_err:
dma_release_channel(dev_data->dma_aes_rx);
dma_release_channel(dev_data->dma_aes_tx);
dma_release_channel(dev_data->dma_sha_tx);
probe_dma_err:
spin_lock(&dthe_dev_list.lock);
list_del(&dev_data->list);
spin_unlock(&dthe_dev_list.lock);
return ret;
}
static void dthe_remove(struct platform_device *pdev)
{
struct dthe_data *dev_data = platform_get_drvdata(pdev);
spin_lock(&dthe_dev_list.lock);
list_del(&dev_data->list);
spin_unlock(&dthe_dev_list.lock);
dthe_unregister_algs();
crypto_engine_exit(dev_data->engine);
dma_release_channel(dev_data->dma_aes_rx);
dma_release_channel(dev_data->dma_aes_tx);
dma_release_channel(dev_data->dma_sha_tx);
}
static const struct of_device_id dthe_of_match[] = {
{ .compatible = "ti,am62l-dthev2", },
{},
};
MODULE_DEVICE_TABLE(of, dthe_of_match);
static struct platform_driver dthe_driver = {
.probe = dthe_probe,
.remove = dthe_remove,
.driver = {
.name = DRIVER_NAME,
.of_match_table = dthe_of_match,
},
};
module_platform_driver(dthe_driver);
MODULE_AUTHOR("T Pratham <t-pratham@ti.com>");
MODULE_DESCRIPTION("Texas Instruments DTHE V2 driver");
MODULE_LICENSE("GPL");
@@ -0,0 +1,134 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* K3 DTHE V2 crypto accelerator driver
*
* Copyright (C) Texas Instruments 2025 - https://www.ti.com
* Author: T Pratham <t-pratham@ti.com>
*/
#ifndef __TI_DTHEV2_H__
#define __TI_DTHEV2_H__
#include <crypto/aead.h>
#include <crypto/aes.h>
#include <crypto/algapi.h>
#include <crypto/engine.h>
#include <crypto/hash.h>
#include <crypto/internal/aead.h>
#include <crypto/internal/hash.h>
#include <crypto/internal/skcipher.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/dmapool.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/scatterlist.h>
#define DTHE_REG_SIZE 4
#define DTHE_DMA_TIMEOUT_MS 2000
/*
* Size of largest possible key (of all algorithms) to be stored in dthe_tfm_ctx
* This is currently the keysize of XTS-AES-256 which is 512 bits (64 bytes)
*/
#define DTHE_MAX_KEYSIZE (AES_MAX_KEY_SIZE * 2)
enum dthe_aes_mode {
DTHE_AES_ECB = 0,
DTHE_AES_CBC,
DTHE_AES_CTR,
DTHE_AES_XTS,
DTHE_AES_GCM,
DTHE_AES_CCM,
};
/* Driver specific struct definitions */
/**
* struct dthe_data - DTHE_V2 driver instance data
* @dev: Device pointer
* @regs: Base address of the register space
* @list: list node for dev
* @engine: Crypto engine instance
* @dma_aes_rx: AES Rx DMA Channel
* @dma_aes_tx: AES Tx DMA Channel
* @dma_sha_tx: SHA Tx DMA Channel
*/
struct dthe_data {
struct device *dev;
void __iomem *regs;
struct list_head list;
struct crypto_engine *engine;
struct dma_chan *dma_aes_rx;
struct dma_chan *dma_aes_tx;
struct dma_chan *dma_sha_tx;
};
/**
* struct dthe_list - device data list head
* @dev_list: linked list head
* @lock: Spinlock protecting accesses to the list
*/
struct dthe_list {
struct list_head dev_list;
spinlock_t lock;
};
/**
* struct dthe_tfm_ctx - Transform ctx struct containing ctx for all sub-components of DTHE V2
* @dev_data: Device data struct pointer
* @keylen: AES key length
* @authsize: Authentication size for modes with authentication
* @key: AES key
* @aes_mode: AES mode
* @aead_fb: Fallback crypto aead handle
* @skcipher_fb: Fallback crypto skcipher handle for AES-XTS mode
*/
struct dthe_tfm_ctx {
struct dthe_data *dev_data;
unsigned int keylen;
unsigned int authsize;
u32 key[DTHE_MAX_KEYSIZE / sizeof(u32)];
enum dthe_aes_mode aes_mode;
union {
struct crypto_sync_aead *aead_fb;
struct crypto_sync_skcipher *skcipher_fb;
};
};
/**
* struct dthe_aes_req_ctx - AES engine req ctx struct
* @enc: flag indicating encryption or decryption operation
* @padding: padding buffer for handling unaligned data
* @aes_compl: Completion variable for use in manual completion in case of DMA callback failure
*/
struct dthe_aes_req_ctx {
int enc;
u8 padding[2 * AES_BLOCK_SIZE];
struct completion aes_compl;
};
/* Struct definitions end */
struct dthe_data *dthe_get_dev(struct dthe_tfm_ctx *ctx);
/**
* dthe_copy_sg - Copy sg entries from src to dst
* @dst: Destination sg to be filled
* @src: Source sg to be copied from
* @buflen: Number of bytes to be copied
*
* Description:
* Copy buflen bytes of data from src to dst.
*
**/
struct scatterlist *dthe_copy_sg(struct scatterlist *dst,
struct scatterlist *src,
int buflen);
int dthe_register_aes_algs(void);
void dthe_unregister_aes_algs(void);
#endif