From: Jamin Lin <jamin_lin@aspeedtech.com>
To: "Daniel P. Berrangé" <berrange@redhat.com>,
"Cédric Le Goater" <clg@kaod.org>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Steven Lee" <steven_lee@aspeedtech.com>,
"Troy Lee" <leetroy@gmail.com>,
"Kane Chen" <kane_chen@aspeedtech.com>,
"Andrew Jeffery" <andrew@codeconstruct.com.au>,
"Joel Stanley" <joel@jms.id.au>, "Eric Blake" <eblake@redhat.com>,
"Markus Armbruster" <armbru@redhat.com>,
"Fabiano Rosas" <farosas@suse.de>,
"Laurent Vivier" <lvivier@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"open list:All patches CC here" <qemu-devel@nongnu.org>,
"open list:ASPEED BMCs" <qemu-arm@nongnu.org>
Cc: Jamin Lin <jamin_lin@aspeedtech.com>, Troy Lee <troy_lee@aspeedtech.com>
Subject: [PATCH v1 8/8] tests/qtest: Add ASPEED SBC ECDSA engine test
Date: Tue, 18 Aug 2026 09:23:04 +0000 [thread overview]
Message-ID: <20260818092249.602137-9-jamin_lin@aspeedtech.com> (raw)
In-Reply-To: <20260818092249.602137-1-jamin_lin@aspeedtech.com>
Add a qtest for the ASPEED secure boot controller ECDSA engine. It stages
the public key, signature and SHA-384 digest of a secp384r1 known-answer
vector (from the Linux kernel crypto self-test manager,
ecdsa_nist_p384_tv_template) into the SEC SRAM, triggers the engine's
verify command and checks the status register: a valid signature reports
done + pass, and a tampered signature reports done without pass.
The test is skipped when the crypto backend does not support ECDSA, via
qcrypto_akcipher_supports().
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
tests/qtest/aspeed-sbc-test.c | 190 ++++++++++++++++++++++++++++++++++
tests/qtest/meson.build | 2 +
2 files changed, 192 insertions(+)
create mode 100644 tests/qtest/aspeed-sbc-test.c
diff --git a/tests/qtest/aspeed-sbc-test.c b/tests/qtest/aspeed-sbc-test.c
new file mode 100644
index 0000000000..927a54dffb
--- /dev/null
+++ b/tests/qtest/aspeed-sbc-test.c
@@ -0,0 +1,190 @@
+/*
+ * QTest testcase for the ASPEED Secure Boot Controller (SBC)
+ *
+ * Copyright (C) 2026 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "qemu/bitops.h"
+#include "crypto/akcipher.h"
+
+/* SBC register block */
+#define SBC_STATUS 0x014
+#define SBC_ECDSA_VERIFY_PASS BIT(21)
+#define SBC_ECDSA_VERIFY_DONE BIT(20)
+#define SBC_ECDSA_CMD 0x0bc
+#define SBC_ECDSA_CMD_TRIGGER BIT(1)
+
+/*
+ * SEC SRAM operand offsets for a secp384r1 ECDSA verify. Every operand is a
+ * 48-byte big-endian integer.
+ */
+#define ECDSA_SRAM_QX 0x2080
+#define ECDSA_SRAM_QY 0x20c0
+#define ECDSA_SRAM_R 0x21c0
+#define ECDSA_SRAM_S 0x2200
+#define ECDSA_SRAM_M 0x2240
+
+/*
+ * ECDSA secp384r1 / SHA-384 known-answer vector from the Linux kernel crypto
+ * self-test manager (ecdsa_nist_p384_tv_template, sha384 entry in
+ * crypto/testmgr.h, v6.18), decoded into raw big-endian form: public key
+ * Qx || Qy, signature r || s and the SHA-384 message digest.
+ *
+ * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/crypto/testmgr.h?h=v6.18
+ */
+static const uint8_t ecdsa_p384_pubkey[96] = {
+ /* Qx */
+ 0x3a, 0x2f, 0x62, 0xe7, 0x1a, 0xcf, 0x24, 0xd0,
+ 0x0b, 0x7c, 0xe0, 0xed, 0x46, 0x0a, 0x4f, 0x74,
+ 0x16, 0x43, 0xe9, 0x1a, 0x25, 0x7c, 0x55, 0xff,
+ 0xf0, 0x29, 0x68, 0x66, 0x20, 0x91, 0xf9, 0xdb,
+ 0x2b, 0xf6, 0xb3, 0x6c, 0x54, 0x01, 0xca, 0xc7,
+ 0x6a, 0x5c, 0x0d, 0xeb, 0x68, 0xd9, 0x3c, 0xf1,
+ /* Qy */
+ 0x01, 0x74, 0x1f, 0xf9, 0x6c, 0xe5, 0x5b, 0x60,
+ 0xe9, 0x7f, 0x5d, 0xb3, 0x12, 0x80, 0x2a, 0xd8,
+ 0x67, 0x92, 0xc9, 0x0e, 0x4c, 0x4c, 0x6b, 0xa1,
+ 0xb2, 0xa8, 0x1e, 0xac, 0x1c, 0x97, 0xd9, 0x21,
+ 0x67, 0xe5, 0x1b, 0x5a, 0x52, 0x31, 0x68, 0xd6,
+ 0xee, 0xf0, 0x19, 0xb0, 0x55, 0xed, 0x89, 0x9e,
+};
+
+static const uint8_t ecdsa_p384_signature[96] = {
+ /* r */
+ 0x9b, 0x28, 0x68, 0xc0, 0xa1, 0xea, 0x8c, 0x50,
+ 0xee, 0x2e, 0x62, 0x35, 0x46, 0xfa, 0x00, 0xd8,
+ 0x2d, 0x7a, 0x91, 0x5f, 0x49, 0x2d, 0x22, 0x08,
+ 0x29, 0xe6, 0xfb, 0xca, 0x8c, 0xd6, 0xb6, 0xb4,
+ 0x3b, 0x1f, 0x07, 0x8f, 0x15, 0x02, 0xfe, 0x1d,
+ 0xa2, 0xa4, 0xc8, 0xf2, 0xea, 0x9d, 0x11, 0x1f,
+ /* s */
+ 0xfc, 0x50, 0xf6, 0x43, 0xbd, 0x50, 0x82, 0x0e,
+ 0xbf, 0xe3, 0x75, 0x24, 0x49, 0xac, 0xfb, 0xc8,
+ 0x71, 0xcd, 0x8f, 0x18, 0x99, 0xf0, 0x0f, 0x13,
+ 0x44, 0x92, 0x8c, 0x86, 0x99, 0x65, 0xb3, 0x97,
+ 0x96, 0x17, 0x04, 0xc9, 0x05, 0x77, 0xf1, 0x8e,
+ 0xab, 0x8d, 0x4e, 0xde, 0xe6, 0x6d, 0x9b, 0x66,
+};
+
+static const uint8_t ecdsa_p384_dgst[48] = {
+ 0x8d, 0xf2, 0xc0, 0xe9, 0xa8, 0xf3, 0x8e, 0x44,
+ 0xc4, 0x8c, 0x1a, 0xa0, 0xb8, 0xd7, 0x17, 0xdf,
+ 0xf2, 0x37, 0x1b, 0xc6, 0xe3, 0xf5, 0x62, 0xcc,
+ 0x68, 0xf5, 0xd5, 0x0b, 0xbf, 0x73, 0x2b, 0xb1,
+ 0xb0, 0x4c, 0x04, 0x00, 0x31, 0xab, 0xfe, 0xc8,
+ 0xd6, 0x09, 0xc8, 0xf2, 0xea, 0xd3, 0x28, 0xff,
+};
+
+typedef struct AspeedSBCECDSA {
+ const char *name;
+ QCryptoCurveID curve_id;
+ const uint8_t *pubkey;
+ const uint8_t *signature;
+ const uint8_t *dgst;
+ size_t coord_len;
+} AspeedSBCECDSA;
+
+static const AspeedSBCECDSA sbc_ecdsa_tests[] = {
+ {
+ .name = "secp384r1",
+ .curve_id = QCRYPTO_CURVE_ID_SECP384R1,
+ .pubkey = ecdsa_p384_pubkey,
+ .signature = ecdsa_p384_signature,
+ .dgst = ecdsa_p384_dgst,
+ .coord_len = 48,
+ },
+};
+
+typedef struct AspeedSBCTest {
+ const char *machine;
+ uint32_t base;
+ uint64_t sram_base;
+ int index;
+} AspeedSBCTest;
+
+static void sbc_ecdsa_stage(QTestState *qts, const AspeedSBCTest *c,
+ const AspeedSBCECDSA *t)
+{
+ size_t len = t->coord_len;
+
+ qtest_memwrite(qts, c->sram_base + ECDSA_SRAM_QX, t->pubkey, len);
+ qtest_memwrite(qts, c->sram_base + ECDSA_SRAM_QY, t->pubkey + len, len);
+ qtest_memwrite(qts, c->sram_base + ECDSA_SRAM_R, t->signature, len);
+ qtest_memwrite(qts, c->sram_base + ECDSA_SRAM_S, t->signature + len, len);
+ qtest_memwrite(qts, c->sram_base + ECDSA_SRAM_M, t->dgst, len);
+}
+
+/*
+ * Drive one ECDSA verify through the engine the way the guest firmware does:
+ * stage the operands in the SEC SRAM, trigger the command register and read
+ * back the done/pass bits in the status register.
+ */
+static void test_ecdsa_verify(const void *opaque)
+{
+ const AspeedSBCTest *c = opaque;
+ const AspeedSBCECDSA *t = &sbc_ecdsa_tests[c->index];
+ QTestState *qts = qtest_init(c->machine);
+ uint32_t status;
+ uint8_t bad;
+
+ /* A valid signature verifies */
+ sbc_ecdsa_stage(qts, c, t);
+ qtest_writel(qts, c->base + SBC_ECDSA_CMD, SBC_ECDSA_CMD_TRIGGER);
+ status = qtest_readl(qts, c->base + SBC_STATUS);
+ g_assert_cmphex(status & (SBC_ECDSA_VERIFY_DONE | SBC_ECDSA_VERIFY_PASS),
+ ==, SBC_ECDSA_VERIFY_DONE | SBC_ECDSA_VERIFY_PASS);
+
+ /* A tampered signature must fail */
+ bad = t->signature[0] ^ 0xff;
+ qtest_memwrite(qts, c->sram_base + ECDSA_SRAM_R, &bad, 1);
+ qtest_writel(qts, c->base + SBC_ECDSA_CMD, SBC_ECDSA_CMD_TRIGGER);
+ status = qtest_readl(qts, c->base + SBC_STATUS);
+ g_assert_cmphex(status & SBC_ECDSA_VERIFY_DONE, ==, SBC_ECDSA_VERIFY_DONE);
+ g_assert_cmphex(status & SBC_ECDSA_VERIFY_PASS, ==, 0);
+
+ qtest_quit(qts);
+}
+
+static void aspeed_add_sbc_ecdsa_tests(const char *prefix, const char *machine,
+ uint32_t base, uint64_t sram_base)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sbc_ecdsa_tests); i++) {
+ QCryptoAkCipherOptions opts = {
+ .alg = QCRYPTO_AK_CIPHER_ALGO_ECDSA,
+ .u.ecdsa.curve_id = sbc_ecdsa_tests[i].curve_id,
+ };
+ g_autofree char *path = NULL;
+ AspeedSBCTest *t;
+
+ if (!qcrypto_akcipher_supports(&opts)) {
+ g_printerr("# skip SBC ECDSA %s test: not supported by the crypto "
+ "backend\n", sbc_ecdsa_tests[i].name);
+ continue;
+ }
+
+ path = g_strdup_printf("%s/sbc/ecdsa/%s", prefix,
+ sbc_ecdsa_tests[i].name);
+ t = g_new0(AspeedSBCTest, 1);
+ t->machine = machine;
+ t->base = base;
+ t->sram_base = sram_base;
+ t->index = i;
+ qtest_add_data_func_full(path, t, test_ecdsa_verify, g_free);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+ aspeed_add_sbc_ecdsa_tests("ast1030", "-machine ast1030-evb",
+ 0x7e6f2000, 0x79000000);
+
+ return g_test_run();
+}
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index f7c7d06620..af7a460e08 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -222,6 +222,7 @@ qtests_npcm8xx = \
qtests_aspeed = \
['aspeed_gpio-test',
'aspeed_hace-test',
+ 'aspeed-sbc-test',
'aspeed_scu-test',
'aspeed_smc-test']
qtests_aspeed64 = \
@@ -394,6 +395,7 @@ endif
qtests = {
'aspeed_hace-test': [files('aspeed-hace-utils.c', 'aspeed_hace-test.c'),
crypto],
+ 'aspeed-sbc-test': [files('aspeed-sbc-test.c'), crypto],
'aspeed_smc-test': files('aspeed-smc-utils.c', 'aspeed_smc-test.c'),
'ast2700-hace-test': [files('aspeed-hace-utils.c', 'ast2700-hace-test.c'),
crypto],
--
2.53.0
prev parent reply other threads:[~2026-08-18 9:24 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-18 9:22 [PATCH v1 0/8] Add ECDSA akcipher support and the ASPEED SBC ECDSA engine for AST10x0 Jamin Lin
2026-08-18 9:22 ` [PATCH v1 1/8] qapi/crypto: Add ECDSA algorithm and curve id Jamin Lin
2026-08-18 9:22 ` [PATCH v1 2/8] crypto/akcipher: Support ECDSA sign/verify with gcrypt Jamin Lin
2026-08-18 9:22 ` [PATCH v1 3/8] crypto/akcipher: Support ECDSA sign/verify with nettle Jamin Lin
2026-08-18 9:22 ` [PATCH v1 4/8] tests/crypto: Add ECDSA sign/verify tests Jamin Lin
2026-08-18 9:22 ` [PATCH v1 5/8] hw/misc/aspeed_sbc: Support the ECDSA verify command Jamin Lin
2026-08-18 9:23 ` [PATCH v1 6/8] hw/misc/aspeed_sbc: Increase register space to 0x1000 Jamin Lin
2026-08-18 9:23 ` [PATCH v1 7/8] hw/arm/aspeed_ast10x0: Wire SEC SRAM to the SBC model Jamin Lin
2026-08-18 9:23 ` Jamin Lin [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260818092249.602137-9-jamin_lin@aspeedtech.com \
--to=jamin_lin@aspeedtech.com \
--cc=andrew@codeconstruct.com.au \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=clg@kaod.org \
--cc=eblake@redhat.com \
--cc=farosas@suse.de \
--cc=joel@jms.id.au \
--cc=kane_chen@aspeedtech.com \
--cc=leetroy@gmail.com \
--cc=lvivier@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=steven_lee@aspeedtech.com \
--cc=troy_lee@aspeedtech.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.