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 14/15] tests/qtest/aspeed-hace: Test the crypto command on the AST2700
Date: Tue, 14 Jul 2026 07:29:22 +0000 [thread overview]
Message-ID: <20260714072900.3023742-15-jamin_lin@aspeedtech.com> (raw)
In-Reply-To: <20260714072900.3023742-1-jamin_lin@aspeedtech.com>
Cover the AST2700 crypto engine, which drives 64-bit scatter-gather DMA
and adds AES-GCM on top of the ECB/CBC/CTR modes shared with the AST2600.
Add AES-128 and AES-256 GCM known-answer vectors (GCM specification /
NIST SP 800-38D, no associated data) and a dedicated GCM runner that
programs the tag buffer and reads the tag back, checking it after both
encryption and decryption. Register the AST2700 with all four modes.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
tests/qtest/aspeed-hace-utils.h | 1 +
tests/qtest/aspeed-hace-utils.c | 159 +++++++++++++++++++++++++++++++-
tests/qtest/ast2700-hace-test.c | 9 ++
3 files changed, 168 insertions(+), 1 deletion(-)
diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
index 82b0b3f93d..a5601a3d65 100644
--- a/tests/qtest/aspeed-hace-utils.h
+++ b/tests/qtest/aspeed-hace-utils.h
@@ -86,6 +86,7 @@ enum {
CRYPT_MODE_ECB = 1 << 0,
CRYPT_MODE_CBC = 1 << 1,
CRYPT_MODE_CTR = 1 << 2,
+ CRYPT_MODE_GCM = 1 << 3,
};
/*
diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
index 0b91a4e61a..b421221c79 100644
--- a/tests/qtest/aspeed-hace-utils.c
+++ b/tests/qtest/aspeed-hace-utils.c
@@ -653,6 +653,8 @@ void aspeed_test_addresses(const char *machine, const uint32_t base,
#define HACE_CRYPTO_CONTEXT 0x08
#define HACE_CRYPTO_DATA_LEN 0x0c
#define HACE_CRYPTO_CMD 0x10
+#define HACE_CRYPTO_GCM_ADD_LEN 0x14
+#define HACE_CRYPTO_GCM_TAG 0x18
/* Crypto command bits */
#define HACE_CMD_ENCRYPT BIT(7)
@@ -665,7 +667,9 @@ void aspeed_test_addresses(const char *machine, const uint32_t base,
#define HACE_CMD_ECB (0x0 << 4)
#define HACE_CMD_CBC (0x1 << 4)
#define HACE_CMD_CTR (0x4 << 4)
+#define HACE_CMD_GCM (0x5 << 4)
#define HACE_CMD_AES128 (0x0 << 2)
+#define HACE_CMD_AES256 (0x2 << 2)
/* Context buffer layout: IV (DES at +8), key at +0x10 */
#define HACE_CTX_KEY_OFFSET 0x10
@@ -793,11 +797,66 @@ static const uint8_t tdes_ctr_ctext[8] = {
static const uint8_t tdes_ctr_ivout[8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+/*
+ * aes_gcm_tv_template[2] (AES-128) and [9] (AES-256), from the McGrew & Viega
+ * GCM spec (also NIST SP 800-38D), no AAD. Both cases share this plaintext/IV.
+ */
+static const uint8_t aes_gcm_ptext[64] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 };
+static const uint8_t aes_gcm_iv[12] = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 };
+
+/* aes_gcm_tv_template[2] (AES-128) */
+static const uint8_t aes128_gcm_key[16] = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 };
+static const uint8_t aes128_gcm_ctext[64] = {
+ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+ 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+ 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+ 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+ 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+ 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+ 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+ 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 };
+static const uint8_t aes128_gcm_tag[16] = {
+ 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
+ 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 };
+
+/* aes_gcm_tv_template[9] (AES-256) */
+static const uint8_t aes256_gcm_key[32] = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 };
+static const uint8_t aes256_gcm_ctext[64] = {
+ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+ 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+ 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+ 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+ 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+ 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+ 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+ 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad };
+static const uint8_t aes256_gcm_tag[16] = {
+ 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
+ 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c };
+
typedef struct CryptTest {
const uint8_t *ptext;
const uint8_t *ctext;
/* expected context IV after encrypt, or NULL */
const uint8_t *iv_out;
+ /* expected GCM authentication tag, or NULL for non-AEAD modes */
+ const uint8_t *tag;
const uint8_t *key;
const uint8_t *iv;
const char *name;
@@ -805,6 +864,7 @@ typedef struct CryptTest {
uint32_t cmd;
size_t keylen;
size_t ivlen;
+ size_t taglen;
size_t len;
} CryptTest;
@@ -906,6 +966,32 @@ static const CryptTest crypt_tests[] = {
.iv_out = tdes_ctr_ivout,
.len = sizeof(tdes_ctr_ptext),
},
+ {
+ .name = "aes128-gcm",
+ .cmd = HACE_CMD_AES128 | HACE_CMD_GCM,
+ .key = aes128_gcm_key,
+ .keylen = sizeof(aes128_gcm_key),
+ .iv = aes_gcm_iv,
+ .ivlen = sizeof(aes_gcm_iv),
+ .ptext = aes_gcm_ptext,
+ .ctext = aes128_gcm_ctext,
+ .tag = aes128_gcm_tag,
+ .taglen = sizeof(aes128_gcm_tag),
+ .len = sizeof(aes_gcm_ptext),
+ },
+ {
+ .name = "aes256-gcm",
+ .cmd = HACE_CMD_AES256 | HACE_CMD_GCM,
+ .key = aes256_gcm_key,
+ .keylen = sizeof(aes256_gcm_key),
+ .iv = aes_gcm_iv,
+ .ivlen = sizeof(aes_gcm_iv),
+ .ptext = aes_gcm_ptext,
+ .ctext = aes256_gcm_ctext,
+ .tag = aes256_gcm_tag,
+ .taglen = sizeof(aes256_gcm_tag),
+ .len = sizeof(aes_gcm_ptext),
+ },
};
/* DRAM offsets for the crypto test source, destination and context buffers. */
@@ -923,6 +1009,8 @@ static const CryptTest crypt_tests[] = {
*/
#define CRYPT_SG_FRAGS 3
#define CRYPT_SG_FRAG_STRIDE 0x1000
+/* DRAM offset for the AES-GCM authentication tag write buffer. */
+#define CRYPT_OFF_TAG 0x60000
/* Describes one registered crypto test (qtest_add_data_func() data pointer). */
typedef struct AspeedCryptoTest {
@@ -943,6 +1031,8 @@ static uint32_t crypt_mode_flag(uint32_t cmd)
return CRYPT_MODE_CBC;
case HACE_CMD_CTR:
return CRYPT_MODE_CTR;
+ case HACE_CMD_GCM:
+ return CRYPT_MODE_GCM;
default:
return 0;
}
@@ -1088,6 +1178,47 @@ static void crypt_run_sg(QTestState *s, uint32_t base, uint64_t dram,
crypt_gather_sg(s, dram, CRYPT_OFF_DST, out, t->len);
}
+/*
+ * Run one AES-GCM operation in scatter-gather mode: like crypt_run_sg() but
+ * also program the tag write buffer (HACE18) with no associated data, and read
+ * the authentication tag back into @out_tag.
+ */
+static void crypt_run_gcm(QTestState *s, uint32_t base, uint64_t dram,
+ const CryptTest *t, bool encrypt, uint8_t *out,
+ uint8_t *out_tag)
+{
+ const uint8_t *in = encrypt ? t->ptext : t->ctext;
+ uint64_t src_sg = dram + CRYPT_OFF_SRC_SG;
+ uint64_t dst_sg = dram + CRYPT_OFF_DST_SG;
+ uint64_t ctx = dram + CRYPT_OFF_CTX;
+ uint32_t cmd = t->cmd | HACE_CMD_ISR_EN | HACE_CMD_SRC_SG_CTRL |
+ HACE_CMD_DST_SG_CTRL;
+
+ if (encrypt) {
+ cmd |= HACE_CMD_ENCRYPT;
+ }
+
+ crypt_write_ctx(s, ctx, t);
+ crypt_make_sg(s, dram, CRYPT_OFF_SRC, src_sg, in, t->len);
+ crypt_make_sg(s, dram, CRYPT_OFF_DST, dst_sg, NULL, t->len);
+
+ qtest_writel(s, base + HACE_CRYPTO_SRC, (uint32_t)src_sg);
+ qtest_writel(s, base + HACE_CRYPTO_DEST, (uint32_t)dst_sg);
+ qtest_writel(s, base + HACE_CRYPTO_CONTEXT, (uint32_t)ctx);
+ qtest_writel(s, base + HACE_CRYPTO_DATA_LEN, t->len);
+ qtest_writel(s, base + HACE_CRYPTO_GCM_ADD_LEN, 0);
+ qtest_writel(s, base + HACE_CRYPTO_GCM_TAG,
+ (uint32_t)(dram + CRYPT_OFF_TAG));
+ qtest_writel(s, base + HACE_CRYPTO_CMD, cmd);
+
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS) & HACE_CRYPTO_ISR, ==,
+ HACE_CRYPTO_ISR);
+ qtest_writel(s, base + HACE_STS, HACE_CRYPTO_ISR);
+
+ crypt_gather_sg(s, dram, CRYPT_OFF_DST, out, t->len);
+ qtest_memread(s, dram + CRYPT_OFF_TAG, out_tag, t->taglen);
+}
+
static void aspeed_test_crypto(const void *data)
{
const AspeedCryptoTest *c = data;
@@ -1124,6 +1255,29 @@ static void aspeed_test_crypto(const void *data)
qtest_quit(s);
}
+static void aspeed_test_crypto_gcm(const void *data)
+{
+ const AspeedCryptoTest *c = data;
+ const CryptTest *t = &crypt_tests[c->index];
+ QTestState *s = qtest_init(c->machine);
+ uint8_t out[64];
+ uint8_t tag[16];
+
+ g_assert_cmpuint(t->len, <=, sizeof(out));
+
+ /* Encrypt: ptext -> ctext, then check the authentication tag. */
+ crypt_run_gcm(s, c->base, c->dram, t, true, out, tag);
+ g_assert_cmpmem(out, t->len, t->ctext, t->len);
+ g_assert_cmpmem(tag, t->taglen, t->tag, t->taglen);
+
+ /* Decrypt: ctext -> ptext, the recomputed tag must match. */
+ crypt_run_gcm(s, c->base, c->dram, t, false, out, tag);
+ g_assert_cmpmem(out, t->len, t->ptext, t->len);
+ g_assert_cmpmem(tag, t->taglen, t->tag, t->taglen);
+
+ qtest_quit(s);
+}
+
void aspeed_add_crypto_tests(const char *prefix, const char *machine,
uint32_t base, uint64_t dram, uint32_t modes,
bool sg)
@@ -1131,6 +1285,7 @@ void aspeed_add_crypto_tests(const char *prefix, const char *machine,
int i;
for (i = 0; i < ARRAY_SIZE(crypt_tests); i++) {
+ bool is_gcm = crypt_mode_flag(crypt_tests[i].cmd) == CRYPT_MODE_GCM;
g_autofree char *path = NULL;
AspeedCryptoTest *t;
@@ -1146,7 +1301,9 @@ void aspeed_add_crypto_tests(const char *prefix, const char *machine,
t->dram = dram;
t->index = i;
t->sg = sg;
- qtest_add_data_func_full(path, t, aspeed_test_crypto, g_free);
+ qtest_add_data_func_full(path, t,
+ is_gcm ? aspeed_test_crypto_gcm :
+ aspeed_test_crypto, g_free);
}
}
diff --git a/tests/qtest/ast2700-hace-test.c b/tests/qtest/ast2700-hace-test.c
index 508a34dd6c..3f0217d635 100644
--- a/tests/qtest/ast2700-hace-test.c
+++ b/tests/qtest/ast2700-hace-test.c
@@ -94,5 +94,14 @@ int main(int argc, char **argv)
qtest_add_func("ast2700/hace/sha384_accum", test_sha384_accum_ast2700);
qtest_add_func("ast2700/hace/sha256_accum", test_sha256_accum_ast2700);
+ /*
+ * The AST2700 crypto engine uses scatter-gather with 64-bit DMA and adds
+ * AES-GCM on top of the ECB/CBC/CTR modes shared with the AST2600.
+ */
+ aspeed_add_crypto_tests("ast2700", "-machine ast2700-evb", 0x12070000,
+ 0x400000000,
+ CRYPT_MODE_ECB | CRYPT_MODE_CBC | CRYPT_MODE_CTR |
+ CRYPT_MODE_GCM, true);
+
return g_test_run();
}
--
2.43.0
next prev parent reply other threads:[~2026-07-14 7:30 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-14 7:29 [PATCH v1 00/15] Support the ASPEED HACE crypto command Jamin Lin
2026-07-14 7:29 ` [PATCH v1 01/15] hw/misc/aspeed_hace: Support the crypto command in direct access mode Jamin Lin
2026-07-14 7:29 ` [PATCH v1 02/15] tests/qtest/aspeed-hace: Test the crypto command on the AST2500 Jamin Lin
2026-07-14 7:29 ` [PATCH v1 03/15] hw/misc/aspeed_hace: Support scatter-gather mode for the crypto command Jamin Lin
2026-07-14 7:29 ` [PATCH v1 04/15] hw/misc/aspeed_hace: Support the CTR " Jamin Lin
2026-07-14 7:29 ` [PATCH v1 05/15] tests/qtest/aspeed-hace: Test the crypto command on the AST2600 Jamin Lin
2026-07-14 10:16 ` Cédric Le Goater
2026-07-14 7:29 ` [PATCH v1 06/15] tests/qtest/aspeed-hace: Test the crypto command on the AST1030 Jamin Lin
2026-07-14 7:29 ` [PATCH v1 07/15] crypto/cipher: Add GCM to QCryptoCipherMode Jamin Lin
2026-07-14 8:37 ` Daniel P. Berrangé
2026-07-14 7:29 ` [PATCH v1 08/15] crypto/cipher: Add setaad/gettag for AEAD modes Jamin Lin
2026-07-14 8:37 ` Daniel P. Berrangé
2026-07-14 7:29 ` [PATCH v1 09/15] crypto/cipher-gcrypt: Implement AES-GCM Jamin Lin
2026-07-14 8:39 ` Daniel P. Berrangé
2026-07-14 8:57 ` Jamin Lin
2026-07-14 9:31 ` Daniel P. Berrangé
2026-07-14 7:29 ` [PATCH v1 10/15] tests/unit/test-crypto-cipher: Test AES-GCM mode Jamin Lin
2026-07-14 7:29 ` [PATCH v1 11/15] hw/misc/aspeed_hace: Support 64-bit DMA for the crypto command Jamin Lin
2026-07-14 7:29 ` [PATCH v1 12/15] hw/misc/aspeed_hace: Support the AES-GCM mode " Jamin Lin
2026-07-14 7:29 ` [PATCH v1 13/15] hw/misc/aspeed_hace: Enable the crypto command on the AST2700 Jamin Lin
2026-07-14 7:29 ` Jamin Lin [this message]
2026-07-14 7:29 ` [PATCH v1 15/15] tests/functional/aarch64/test_aspeed_ast2700: Drop the AST2700 crypto self-test workaround Jamin Lin
2026-07-14 8:47 ` [PATCH v1 00/15] Support the ASPEED HACE crypto command Daniel P. Berrangé
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=20260714072900.3023742-15-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.