summaryrefslogtreecommitdiff
path: root/drivers/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/aspeed/Kconfig10
-rw-r--r--drivers/crypto/aspeed/Makefile1
-rw-r--r--drivers/crypto/aspeed/cptra_ecdsa.c184
-rw-r--r--drivers/crypto/fsl/Makefile2
-rw-r--r--drivers/crypto/fsl/jobdesc.c2
-rw-r--r--drivers/crypto/fsl/jr.c6
6 files changed, 200 insertions, 5 deletions
diff --git a/drivers/crypto/aspeed/Kconfig b/drivers/crypto/aspeed/Kconfig
index 473e3e5a863..6efcd7da738 100644
--- a/drivers/crypto/aspeed/Kconfig
+++ b/drivers/crypto/aspeed/Kconfig
@@ -28,3 +28,13 @@ config ASPEED_CPTRA_SHA
Enabling this allows the use of SHA operations in hardware. Note that only
SHA384 and SHA512 are supported by Caliptra 1.0.
+
+config ASPEED_CPTRA_ECDSA
+ bool "Caliptra ECDSA384 signature verifier for Aspeed SoCs"
+ depends on ECDSA_VERIFY || SPL_ECDSA_VERIFY
+ help
+ Select this option to enable a driver for using the ECDSA384_SIGNATURE_VERIFY
+ feature of Caliptra, which is integrated in AST27xx BMC SoCs.
+
+ Enabling this allows the use of ECDSA384 signature verification in hardware.
+ Note that only ECDSA384 is supported by Caliptra.
diff --git a/drivers/crypto/aspeed/Makefile b/drivers/crypto/aspeed/Makefile
index 570587e744f..00def358ddf 100644
--- a/drivers/crypto/aspeed/Makefile
+++ b/drivers/crypto/aspeed/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_ASPEED_HACE) += aspeed_hace.o
obj-$(CONFIG_ASPEED_ACRY) += aspeed_acry.o
obj-$(CONFIG_ASPEED_CPTRA_SHA) += cptra_sha.o
+obj-$(CONFIG_ASPEED_CPTRA_ECDSA) += cptra_ecdsa.o
diff --git a/drivers/crypto/aspeed/cptra_ecdsa.c b/drivers/crypto/aspeed/cptra_ecdsa.c
new file mode 100644
index 00000000000..4b70d89def7
--- /dev/null
+++ b/drivers/crypto/aspeed/cptra_ecdsa.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2024 ASPEED Technology Inc.
+ */
+#include <asm/io.h>
+#include <config.h>
+#include <crypto/ecdsa-uclass.h>
+#include <dm.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/iopoll.h>
+#include <malloc.h>
+#include <u-boot/ecdsa.h>
+
+/* SCU register offsets */
+#define SCU1_CPTRA 0x130
+#define SCU1_CPTRA_RDY_FOR_RT BIT(18)
+
+/* CPTRA MBOX register offsets */
+#define CPTRA_MBOX_LOCK 0x00
+#define CPTRA_MBOX_USER 0x04
+#define CPTRA_MBOX_CMD 0x08
+#define CPTRA_MBOX_DLEN 0x0c
+#define CPTRA_MBOX_DATAIN 0x10
+#define CPTRA_MBOX_DATAOUT 0x14
+#define CPTRA_MBOX_EXEC 0x18
+#define CPTRA_MBOX_STS 0x1c
+#define CPTRA_MBOX_STS_SOC_LOCK BIT(9)
+#define CPTRA_MBOX_STS_FSM_PS GENMASK(8, 6)
+#define CPTRA_MBOX_STS_PS GENMASK(3, 0)
+#define CPTRA_MBOX_UNLOCK 0x20
+
+#define CPTRA_ECDSA_SIG_LEN 96 /* ECDSA384 */
+#define CPTRA_ECDSA_SHA_LEN 48 /* SHA384 */
+
+#define CPTRA_MBCMD_ECDSA384_SIGNATURE_VERIFY 0x53494756
+
+enum cptra_mbox_sts {
+ CPTRA_MBSTS_CMD_BUSY,
+ CPTRA_MBSTS_DATA_READY,
+ CPTRA_MBSTS_CMD_COMPLETE,
+ CPTRA_MBSTS_CMD_FAILURE,
+};
+
+enum cptra_mbox_fsm {
+ CPTRA_MBFSM_IDLE,
+ CPTRA_MBFSM_RDY_FOR_CMD,
+ CPTRA_MBFSM_RDY_FOR_DLEN,
+ CPTRA_MBFSM_RDY_FOR_DATA,
+ CPTRA_MBFSM_EXEC_UC,
+ CPTRA_MBFSM_EXEC_SOC,
+ CPTRA_MBFSM_ERROR,
+};
+
+struct cptra_ecdsa {
+ void *regs;
+};
+
+static uint32_t mbox_csum(uint32_t csum, uint8_t *data, uint32_t dlen)
+{
+ uint32_t i;
+
+ for (i = 0; i < dlen; ++i)
+ csum -= data[i];
+
+ return csum;
+}
+
+static int cptra_ecdsa_verify(struct udevice *dev, const struct ecdsa_public_key *pubkey,
+ const void *hash, size_t hash_len,
+ const void *signature, size_t sig_len)
+{
+ struct cptra_ecdsa *ce;
+ uint8_t *x, *y, *r, *s;
+ uint32_t cmd, csum;
+ uint32_t reg, sts;
+ uint32_t *p32;
+ int i;
+
+ if (hash_len != CPTRA_ECDSA_SHA_LEN || sig_len != CPTRA_ECDSA_SIG_LEN)
+ return -EINVAL;
+
+ if ((strcmp(pubkey->curve_name, "secp384r1") && strcmp(pubkey->curve_name, "prime384v1")) ||
+ pubkey->size_bits != ((CPTRA_ECDSA_SIG_LEN / 2) << 3))
+ return -EINVAL;
+
+ ce = dev_get_priv(dev);
+
+ /* get CPTRA MBOX lock */
+ if (readl_poll_timeout(ce->regs + CPTRA_MBOX_LOCK, reg, reg == 0, 1000000))
+ return -EBUSY;
+
+ /* check MBOX is ready for command */
+ sts = readl(ce->regs + CPTRA_MBOX_STS);
+ if (FIELD_GET(CPTRA_MBOX_STS_FSM_PS, sts) != CPTRA_MBFSM_RDY_FOR_CMD)
+ return -EACCES;
+
+ /* init mbox parameters */
+ cmd = CPTRA_MBCMD_ECDSA384_SIGNATURE_VERIFY;
+ csum = 0;
+ x = (uint8_t *)pubkey->x;
+ y = (uint8_t *)pubkey->y;
+ r = (uint8_t *)signature;
+ s = (uint8_t *)signature + (CPTRA_ECDSA_SIG_LEN / 2);
+
+ /* calculate checksum */
+ csum = mbox_csum(csum, (uint8_t *)&cmd, sizeof(cmd));
+ csum = mbox_csum(csum, x, CPTRA_ECDSA_SIG_LEN / 2);
+ csum = mbox_csum(csum, y, CPTRA_ECDSA_SIG_LEN / 2);
+ csum = mbox_csum(csum, r, CPTRA_ECDSA_SIG_LEN / 2);
+ csum = mbox_csum(csum, s, CPTRA_ECDSA_SIG_LEN / 2);
+
+ /* write command, data length */
+ writel(cmd, ce->regs + CPTRA_MBOX_CMD);
+ writel(sizeof(csum) + (CPTRA_ECDSA_SIG_LEN << 1), ce->regs + CPTRA_MBOX_DLEN);
+
+ /* write ECDSA384_SIGNATURE_VERIFY command parameters */
+ writel(csum, ce->regs + CPTRA_MBOX_DATAIN);
+
+ for (i = 0, p32 = (uint32_t *)x; i < ((CPTRA_ECDSA_SIG_LEN / 2) / sizeof(*p32)); ++i)
+ writel(p32[i], ce->regs + CPTRA_MBOX_DATAIN);
+
+ for (i = 0, p32 = (uint32_t *)y; i < ((CPTRA_ECDSA_SIG_LEN / 2) / sizeof(*p32)); ++i)
+ writel(p32[i], ce->regs + CPTRA_MBOX_DATAIN);
+
+ for (i = 0, p32 = (uint32_t *)r; i < ((CPTRA_ECDSA_SIG_LEN / 2) / sizeof(*p32)); ++i)
+ writel(p32[i], ce->regs + CPTRA_MBOX_DATAIN);
+
+ for (i = 0, p32 = (uint32_t *)s; i < ((CPTRA_ECDSA_SIG_LEN / 2) / sizeof(*p32)); ++i)
+ writel(p32[i], ce->regs + CPTRA_MBOX_DATAIN);
+
+ /* trigger mbox command */
+ writel(0x1, ce->regs + CPTRA_MBOX_EXEC);
+
+ /* poll for result */
+ while (1) {
+ sts = FIELD_GET(CPTRA_MBOX_STS_PS, readl(ce->regs + CPTRA_MBOX_STS));
+ if (sts != CPTRA_MBSTS_CMD_BUSY)
+ break;
+ }
+
+ /* unlock mbox */
+ writel(0x0, ce->regs + CPTRA_MBOX_EXEC);
+
+ return (sts == CPTRA_MBSTS_CMD_FAILURE) ? sts : 0;
+}
+
+static int cptra_ecdsa_probe(struct udevice *dev)
+{
+ struct cptra_ecdsa *ce = dev_get_priv(dev);
+
+ ce->regs = (void *)devfdt_get_addr(dev);
+ if (ce->regs == (void *)FDT_ADDR_T_NONE) {
+ debug("cannot map Caliptra mailbox registers\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int cptra_ecdsa_remove(struct udevice *dev)
+{
+ return 0;
+}
+
+static const struct ecdsa_ops cptra_ecdsa_ops = {
+ .verify = cptra_ecdsa_verify,
+};
+
+static const struct udevice_id cptra_ecdsa_ids[] = {
+ { .compatible = "aspeed,ast2700-cptra-ecdsa" },
+ { }
+};
+
+U_BOOT_DRIVER(aspeed_cptra_ecdsa) = {
+ .name = "aspeed_cptra_ecdsa",
+ .id = UCLASS_ECDSA,
+ .of_match = cptra_ecdsa_ids,
+ .ops = &cptra_ecdsa_ops,
+ .probe = cptra_ecdsa_probe,
+ .remove = cptra_ecdsa_remove,
+ .priv_auto = sizeof(struct cptra_ecdsa),
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile
index 4fbce519a0b..965c4938c8c 100644
--- a/drivers/crypto/fsl/Makefile
+++ b/drivers/crypto/fsl/Makefile
@@ -6,6 +6,6 @@ obj-y += sec.o
obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
obj-$(CONFIG_CMD_BLOB)$(CONFIG_IMX_CAAM_DEK_ENCAP) += fsl_blob.o
obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
-obj-$(CONFIG_$(SPL_TPL_)FSL_CAAM_RNG) += rng.o
+obj-$(CONFIG_$(PHASE_)FSL_CAAM_RNG) += rng.o
obj-$(CONFIG_FSL_DCP_RNG) += dcp_rng.o
obj-$(CONFIG_FSL_MFGPROT) += fsl_mfgprot.o
diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c
index 55191736931..9c4ff4960fc 100644
--- a/drivers/crypto/fsl/jobdesc.c
+++ b/drivers/crypto/fsl/jobdesc.c
@@ -207,7 +207,7 @@ void inline_cnstr_jobdesc_hash(uint32_t *desc,
append_store(desc, dma_addr_out, storelen,
LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT);
}
-#ifndef CONFIG_SPL_BUILD
+#ifndef CONFIG_XPL_BUILD
void inline_cnstr_jobdesc_blob_encap(uint32_t *desc, uint8_t *key_idnfr,
uint8_t *plain_txt, uint8_t *enc_blob,
uint32_t in_sz)
diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
index 27e24808946..c45481bef0b 100644
--- a/drivers/crypto/fsl/jr.c
+++ b/drivers/crypto/fsl/jr.c
@@ -713,7 +713,7 @@ int sec_init_idx(uint8_t sec_idx)
ccsr_sec_t *sec = caam->sec;
uint32_t mcr = sec_in32(&sec->mcfgr);
-#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_IMX8M)
+#if defined(CONFIG_XPL_BUILD) && defined(CONFIG_IMX8M)
uint32_t jrdid_ms = 0;
#endif
#ifdef CONFIG_FSL_CORENET
@@ -745,14 +745,14 @@ int sec_init_idx(uint8_t sec_idx)
mcr |= (1 << MCFGR_PS_SHIFT);
#endif
sec_out32(&sec->mcfgr, mcr);
-#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_IMX8M)
+#if defined(CONFIG_XPL_BUILD) && defined(CONFIG_IMX8M)
jrdid_ms = JRDID_MS_TZ_OWN | JRDID_MS_PRIM_TZ | JRDID_MS_PRIM_DID;
sec_out32(&sec->jrliodnr[caam->jrid].ms, jrdid_ms);
#endif
jr_reset();
#ifdef CONFIG_FSL_CORENET
-#ifdef CONFIG_SPL_BUILD
+#ifdef CONFIG_XPL_BUILD
/*
* For SPL Build, Set the Liodns in SEC JR0 for
* creating PAMU entries corresponding to these.