mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-19 11:24:42 +00:00
crypto/fsl: add RNG support
Register the random number generator with the rng subsystem in u-boot. This way it can be used by EFI as well as for the 'rng' command. Signed-off-by: Michael Walle <michael@walle.cc> Tested-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
This commit is contained in:
parent
b980f9e259
commit
ea95f2142e
6 changed files with 125 additions and 0 deletions
|
@ -45,3 +45,17 @@ config SYS_FSL_SEC_COMPAT
|
||||||
|
|
||||||
config SYS_FSL_SEC_LE
|
config SYS_FSL_SEC_LE
|
||||||
bool "Little-endian access to Freescale Secure Boot"
|
bool "Little-endian access to Freescale Secure Boot"
|
||||||
|
|
||||||
|
if FSL_CAAM
|
||||||
|
|
||||||
|
config FSL_CAAM_RNG
|
||||||
|
bool "Enable Random Number Generator support"
|
||||||
|
depends on DM_RNG
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable support for the hardware based random number generator
|
||||||
|
module of the CAAM. The random data is fetched from the DRGB
|
||||||
|
using the prediction resistance flag which means the DRGB is
|
||||||
|
reseeded from the TRNG every time random data is generated.
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
|
@ -7,3 +7,4 @@ obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
|
||||||
obj-$(CONFIG_CMD_BLOB) += fsl_blob.o
|
obj-$(CONFIG_CMD_BLOB) += fsl_blob.o
|
||||||
obj-$(CONFIG_CMD_DEKBLOB) += fsl_blob.o
|
obj-$(CONFIG_CMD_DEKBLOB) += fsl_blob.o
|
||||||
obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
|
obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
|
||||||
|
obj-$(CONFIG_FSL_CAAM_RNG) += rng.o
|
||||||
|
|
|
@ -296,6 +296,16 @@ void inline_cnstr_jobdesc_rng_deinstantiation(u32 *desc, int handle)
|
||||||
(handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INITFINAL);
|
(handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INITFINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void inline_cnstr_jobdesc_rng(u32 *desc, void *data_out, u32 size)
|
||||||
|
{
|
||||||
|
dma_addr_t dma_data_out = virt_to_phys(data_out);
|
||||||
|
|
||||||
|
init_job_desc(desc, 0);
|
||||||
|
append_operation(desc, OP_ALG_ALGSEL_RNG | OP_TYPE_CLASS1_ALG |
|
||||||
|
OP_ALG_PR_ON);
|
||||||
|
append_fifo_store(desc, dma_data_out, size, FIFOST_TYPE_RNGSTORE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Change key size to bytes form bits in calling function*/
|
/* Change key size to bytes form bits in calling function*/
|
||||||
void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
|
void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
|
||||||
struct pk_in_params *pkin, uint8_t *out,
|
struct pk_in_params *pkin, uint8_t *out,
|
||||||
|
|
|
@ -43,7 +43,10 @@ void inline_cnstr_jobdesc_rng_instantiation(u32 *desc, int handle, int do_sk);
|
||||||
|
|
||||||
void inline_cnstr_jobdesc_rng_deinstantiation(u32 *desc, int handle);
|
void inline_cnstr_jobdesc_rng_deinstantiation(u32 *desc, int handle);
|
||||||
|
|
||||||
|
void inline_cnstr_jobdesc_rng(u32 *desc, void *data_out, u32 size);
|
||||||
|
|
||||||
void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
|
void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
|
||||||
struct pk_in_params *pkin, uint8_t *out,
|
struct pk_in_params *pkin, uint8_t *out,
|
||||||
uint32_t out_siz);
|
uint32_t out_siz);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <asm/cache.h>
|
#include <asm/cache.h>
|
||||||
#include <asm/fsl_pamu.h>
|
#include <asm/fsl_pamu.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <dm/lists.h>
|
||||||
|
|
||||||
#define CIRC_CNT(head, tail, size) (((head) - (tail)) & (size - 1))
|
#define CIRC_CNT(head, tail, size) (((head) - (tail)) & (size - 1))
|
||||||
#define CIRC_SPACE(head, tail, size) CIRC_CNT((tail), (head) + 1, (size))
|
#define CIRC_SPACE(head, tail, size) CIRC_CNT((tail), (head) + 1, (size))
|
||||||
|
@ -721,6 +722,14 @@ int sec_init_idx(uint8_t sec_idx)
|
||||||
printf("SEC%u: RNG instantiation failed\n", sec_idx);
|
printf("SEC%u: RNG instantiation failed\n", sec_idx);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_DM_RNG)) {
|
||||||
|
ret = device_bind_driver(NULL, "caam-rng", "caam-rng",
|
||||||
|
NULL);
|
||||||
|
if (ret)
|
||||||
|
printf("Couldn't bind rng driver (%d)\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
printf("SEC%u: RNG instantiated\n", sec_idx);
|
printf("SEC%u: RNG instantiated\n", sec_idx);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
88
drivers/crypto/fsl/rng.c
Normal file
88
drivers/crypto/fsl/rng.c
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Michael Walle <michael@walle.cc>
|
||||||
|
*
|
||||||
|
* Driver for Freescale Cryptographic Accelerator and Assurance
|
||||||
|
* Module (CAAM) hardware random number generator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm/cache.h>
|
||||||
|
#include <common.h>
|
||||||
|
#include <cpu_func.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <rng.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include "desc_constr.h"
|
||||||
|
#include "jobdesc.h"
|
||||||
|
#include "jr.h"
|
||||||
|
|
||||||
|
#define CAAM_RNG_MAX_FIFO_STORE_SIZE 16
|
||||||
|
#define CAAM_RNG_DESC_LEN (3 * CAAM_CMD_SZ + CAAM_PTR_SZ)
|
||||||
|
|
||||||
|
struct caam_rng_priv {
|
||||||
|
u32 desc[CAAM_RNG_DESC_LEN / 4];
|
||||||
|
u8 data[CAAM_RNG_MAX_FIFO_STORE_SIZE] __aligned(ARCH_DMA_MINALIGN);
|
||||||
|
};
|
||||||
|
|
||||||
|
static int caam_rng_read_one(struct caam_rng_priv *priv)
|
||||||
|
{
|
||||||
|
int size = ALIGN(CAAM_RNG_MAX_FIFO_STORE_SIZE, ARCH_DMA_MINALIGN);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = run_descriptor_jr(priv->desc);
|
||||||
|
if (ret < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
invalidate_dcache_range((unsigned long)priv->data,
|
||||||
|
(unsigned long)priv->data + size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int caam_rng_read(struct udevice *dev, void *data, size_t len)
|
||||||
|
{
|
||||||
|
struct caam_rng_priv *priv = dev_get_priv(dev);
|
||||||
|
u8 *buffer = data;
|
||||||
|
size_t size;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
while (len) {
|
||||||
|
ret = caam_rng_read_one(priv);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
size = min(len, (size_t)CAAM_RNG_MAX_FIFO_STORE_SIZE);
|
||||||
|
|
||||||
|
memcpy(buffer, priv->data, size);
|
||||||
|
buffer += size;
|
||||||
|
len -= size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int caam_rng_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct caam_rng_priv *priv = dev_get_priv(dev);
|
||||||
|
ulong size = ALIGN(CAAM_RNG_DESC_LEN, ARCH_DMA_MINALIGN);
|
||||||
|
|
||||||
|
inline_cnstr_jobdesc_rng(priv->desc, priv->data,
|
||||||
|
CAAM_RNG_MAX_FIFO_STORE_SIZE);
|
||||||
|
flush_dcache_range((unsigned long)priv->desc,
|
||||||
|
(unsigned long)priv->desc + size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dm_rng_ops caam_rng_ops = {
|
||||||
|
.read = caam_rng_read,
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(caam_rng) = {
|
||||||
|
.name = "caam-rng",
|
||||||
|
.id = UCLASS_RNG,
|
||||||
|
.ops = &caam_rng_ops,
|
||||||
|
.probe = caam_rng_probe,
|
||||||
|
.priv_auto_alloc_size = sizeof(struct caam_rng_priv),
|
||||||
|
.flags = DM_FLAG_ALLOC_PRIV_DMA,
|
||||||
|
};
|
Loading…
Add table
Reference in a new issue