xref: /qemu/tests/qtest/aspeed_hace-test.c (revision 907b5105)
166609952SJoel Stanley /*
266609952SJoel Stanley  * QTest testcase for the ASPEED Hash and Crypto Engine
366609952SJoel Stanley  *
466609952SJoel Stanley  * SPDX-License-Identifier: GPL-2.0-or-later
566609952SJoel Stanley  * Copyright 2021 IBM Corp.
666609952SJoel Stanley  */
766609952SJoel Stanley 
866609952SJoel Stanley #include "qemu/osdep.h"
966609952SJoel Stanley 
10*907b5105SMarc-André Lureau #include "libqtest.h"
1166609952SJoel Stanley #include "qemu/bitops.h"
1266609952SJoel Stanley 
1366609952SJoel Stanley #define HACE_CMD                 0x10
1466609952SJoel Stanley #define  HACE_SHA_BE_EN          BIT(3)
1566609952SJoel Stanley #define  HACE_MD5_LE_EN          BIT(2)
1666609952SJoel Stanley #define  HACE_ALGO_MD5           0
1766609952SJoel Stanley #define  HACE_ALGO_SHA1          BIT(5)
1866609952SJoel Stanley #define  HACE_ALGO_SHA224        BIT(6)
1966609952SJoel Stanley #define  HACE_ALGO_SHA256        (BIT(4) | BIT(6))
2066609952SJoel Stanley #define  HACE_ALGO_SHA512        (BIT(5) | BIT(6))
2166609952SJoel Stanley #define  HACE_ALGO_SHA384        (BIT(5) | BIT(6) | BIT(10))
2266609952SJoel Stanley #define  HACE_SG_EN              BIT(18)
2366609952SJoel Stanley #define  HACE_ACCUM_EN           BIT(8)
2466609952SJoel Stanley 
2566609952SJoel Stanley #define HACE_STS                 0x1c
2666609952SJoel Stanley #define  HACE_RSA_ISR            BIT(13)
2766609952SJoel Stanley #define  HACE_CRYPTO_ISR         BIT(12)
2866609952SJoel Stanley #define  HACE_HASH_ISR           BIT(9)
2966609952SJoel Stanley #define  HACE_RSA_BUSY           BIT(2)
3066609952SJoel Stanley #define  HACE_CRYPTO_BUSY        BIT(1)
3166609952SJoel Stanley #define  HACE_HASH_BUSY          BIT(0)
3266609952SJoel Stanley #define HACE_HASH_SRC            0x20
3366609952SJoel Stanley #define HACE_HASH_DIGEST         0x24
3466609952SJoel Stanley #define HACE_HASH_KEY_BUFF       0x28
3566609952SJoel Stanley #define HACE_HASH_DATA_LEN       0x2c
3666609952SJoel Stanley #define HACE_HASH_CMD            0x30
3766609952SJoel Stanley /* Scatter-Gather Hash */
3866609952SJoel Stanley #define SG_LIST_LEN_LAST         BIT(31)
3966609952SJoel Stanley struct AspeedSgList {
4066609952SJoel Stanley         uint32_t len;
4166609952SJoel Stanley         uint32_t addr;
4266609952SJoel Stanley } __attribute__ ((__packed__));
4366609952SJoel Stanley 
4466609952SJoel Stanley /*
4566609952SJoel Stanley  * Test vector is the ascii "abc"
4666609952SJoel Stanley  *
4766609952SJoel Stanley  * Expected results were generated using command line utitiles:
4866609952SJoel Stanley  *
4966609952SJoel Stanley  *  echo -n -e 'abc' | dd of=/tmp/test
5066609952SJoel Stanley  *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
5166609952SJoel Stanley  *
5266609952SJoel Stanley  */
5366609952SJoel Stanley static const uint8_t test_vector[] = {0x61, 0x62, 0x63};
5466609952SJoel Stanley 
5566609952SJoel Stanley static const uint8_t test_result_sha512[] = {
5666609952SJoel Stanley     0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
5766609952SJoel Stanley     0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
5866609952SJoel Stanley     0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
5966609952SJoel Stanley     0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
6066609952SJoel Stanley     0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
6166609952SJoel Stanley     0xa5, 0x4c, 0xa4, 0x9f};
6266609952SJoel Stanley 
6366609952SJoel Stanley static const uint8_t test_result_sha256[] = {
6466609952SJoel Stanley     0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
6566609952SJoel Stanley     0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
6666609952SJoel Stanley     0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
6766609952SJoel Stanley 
6866609952SJoel Stanley static const uint8_t test_result_md5[] = {
6966609952SJoel Stanley     0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
7066609952SJoel Stanley     0x28, 0xe1, 0x7f, 0x72};
7166609952SJoel Stanley 
7266609952SJoel Stanley /*
7366609952SJoel Stanley  * The Scatter-Gather Test vector is the ascii "abc" "def" "ghi", broken
7466609952SJoel Stanley  * into blocks of 3 characters as shown
7566609952SJoel Stanley  *
7666609952SJoel Stanley  * Expected results were generated using command line utitiles:
7766609952SJoel Stanley  *
7866609952SJoel Stanley  *  echo -n -e 'abcdefghijkl' | dd of=/tmp/test
7966609952SJoel Stanley  *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
8066609952SJoel Stanley  *
8166609952SJoel Stanley  */
8266609952SJoel Stanley static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
8366609952SJoel Stanley static const uint8_t test_vector_sg2[] = {0x67, 0x68, 0x69};
8466609952SJoel Stanley static const uint8_t test_vector_sg3[] = {0x6a, 0x6b, 0x6c};
8566609952SJoel Stanley 
8666609952SJoel Stanley static const uint8_t test_result_sg_sha512[] = {
8766609952SJoel Stanley     0x17, 0x80, 0x7c, 0x72, 0x8e, 0xe3, 0xba, 0x35, 0xe7, 0xcf, 0x7a, 0xf8,
8866609952SJoel Stanley     0x23, 0x11, 0x6d, 0x26, 0xe4, 0x1e, 0x5d, 0x4d, 0x6c, 0x2f, 0xf1, 0xf3,
8966609952SJoel Stanley     0x72, 0x0d, 0x3d, 0x96, 0xaa, 0xcb, 0x6f, 0x69, 0xde, 0x64, 0x2e, 0x63,
9066609952SJoel Stanley     0xd5, 0xb7, 0x3f, 0xc3, 0x96, 0xc1, 0x2b, 0xe3, 0x8b, 0x2b, 0xd5, 0xd8,
9166609952SJoel Stanley     0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6, 0xb5, 0x40,
9266609952SJoel Stanley     0xf8, 0x6d, 0xda, 0x2e};
9366609952SJoel Stanley 
9466609952SJoel Stanley static const uint8_t test_result_sg_sha256[] = {
9566609952SJoel Stanley     0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec, 0x94, 0xf1,
9666609952SJoel Stanley     0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd, 0xe9, 0xf3,
9766609952SJoel Stanley     0xd3, 0x5e, 0x6e, 0x4a, 0x71, 0x7f, 0xbd, 0xe4};
9866609952SJoel Stanley 
9966609952SJoel Stanley /*
10066609952SJoel Stanley  * The accumulative mode requires firmware to provide internal initial state
10166609952SJoel Stanley  * and message padding (including length L at the end of padding).
10266609952SJoel Stanley  *
10366609952SJoel Stanley  * This test vector is a ascii text "abc" with padding message.
10466609952SJoel Stanley  *
10566609952SJoel Stanley  * Expected results were generated using command line utitiles:
10666609952SJoel Stanley  *
10766609952SJoel Stanley  *  echo -n -e 'abc' | dd of=/tmp/test
10866609952SJoel Stanley  *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
10966609952SJoel Stanley  */
11066609952SJoel Stanley static const uint8_t test_vector_accum_512[] = {
11166609952SJoel Stanley     0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
11266609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11366609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11466609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11566609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11666609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11766609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11866609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11966609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12066609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12166609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12266609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12366609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12466609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12566609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12666609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
12766609952SJoel Stanley 
12866609952SJoel Stanley static const uint8_t test_vector_accum_256[] = {
12966609952SJoel Stanley     0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
13066609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13166609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13266609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13366609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13466609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13566609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13666609952SJoel Stanley     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
13766609952SJoel Stanley 
13866609952SJoel Stanley static const uint8_t test_result_accum_sha512[] = {
13966609952SJoel Stanley     0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
14066609952SJoel Stanley     0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
14166609952SJoel Stanley     0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
14266609952SJoel Stanley     0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
14366609952SJoel Stanley     0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
14466609952SJoel Stanley     0xa5, 0x4c, 0xa4, 0x9f};
14566609952SJoel Stanley 
14666609952SJoel Stanley static const uint8_t test_result_accum_sha256[] = {
14766609952SJoel Stanley     0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
14866609952SJoel Stanley     0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
14966609952SJoel Stanley     0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
15066609952SJoel Stanley 
write_regs(QTestState * s,uint32_t base,uint32_t src,uint32_t length,uint32_t out,uint32_t method)15166609952SJoel Stanley static void write_regs(QTestState *s, uint32_t base, uint32_t src,
15266609952SJoel Stanley                        uint32_t length, uint32_t out, uint32_t method)
15366609952SJoel Stanley {
15466609952SJoel Stanley         qtest_writel(s, base + HACE_HASH_SRC, src);
15566609952SJoel Stanley         qtest_writel(s, base + HACE_HASH_DIGEST, out);
15666609952SJoel Stanley         qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
15766609952SJoel Stanley         qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
15866609952SJoel Stanley }
15966609952SJoel Stanley 
test_md5(const char * machine,const uint32_t base,const uint32_t src_addr)16066609952SJoel Stanley static void test_md5(const char *machine, const uint32_t base,
16166609952SJoel Stanley                      const uint32_t src_addr)
16266609952SJoel Stanley 
16366609952SJoel Stanley {
16466609952SJoel Stanley     QTestState *s = qtest_init(machine);
16566609952SJoel Stanley 
16666609952SJoel Stanley     uint32_t digest_addr = src_addr + 0x01000000;
16766609952SJoel Stanley     uint8_t digest[16] = {0};
16866609952SJoel Stanley 
16966609952SJoel Stanley     /* Check engine is idle, no busy or irq bits set */
17066609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
17166609952SJoel Stanley 
17266609952SJoel Stanley     /* Write test vector into memory */
17366609952SJoel Stanley     qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
17466609952SJoel Stanley 
17566609952SJoel Stanley     write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_MD5);
17666609952SJoel Stanley 
17766609952SJoel Stanley     /* Check hash IRQ status is asserted */
17866609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
17966609952SJoel Stanley 
18066609952SJoel Stanley     /* Clear IRQ status and check status is deasserted */
18166609952SJoel Stanley     qtest_writel(s, base + HACE_STS, 0x00000200);
18266609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
18366609952SJoel Stanley 
18466609952SJoel Stanley     /* Read computed digest from memory */
18566609952SJoel Stanley     qtest_memread(s, digest_addr, digest, sizeof(digest));
18666609952SJoel Stanley 
18766609952SJoel Stanley     /* Check result of computation */
18866609952SJoel Stanley     g_assert_cmpmem(digest, sizeof(digest),
18966609952SJoel Stanley                     test_result_md5, sizeof(digest));
19066609952SJoel Stanley 
19166609952SJoel Stanley     qtest_quit(s);
19266609952SJoel Stanley }
19366609952SJoel Stanley 
test_sha256(const char * machine,const uint32_t base,const uint32_t src_addr)19466609952SJoel Stanley static void test_sha256(const char *machine, const uint32_t base,
19566609952SJoel Stanley                         const uint32_t src_addr)
19666609952SJoel Stanley {
19766609952SJoel Stanley     QTestState *s = qtest_init(machine);
19866609952SJoel Stanley 
19966609952SJoel Stanley     const uint32_t digest_addr = src_addr + 0x1000000;
20066609952SJoel Stanley     uint8_t digest[32] = {0};
20166609952SJoel Stanley 
20266609952SJoel Stanley     /* Check engine is idle, no busy or irq bits set */
20366609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
20466609952SJoel Stanley 
20566609952SJoel Stanley     /* Write test vector into memory */
20666609952SJoel Stanley     qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
20766609952SJoel Stanley 
20866609952SJoel Stanley     write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_SHA256);
20966609952SJoel Stanley 
21066609952SJoel Stanley     /* Check hash IRQ status is asserted */
21166609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
21266609952SJoel Stanley 
21366609952SJoel Stanley     /* Clear IRQ status and check status is deasserted */
21466609952SJoel Stanley     qtest_writel(s, base + HACE_STS, 0x00000200);
21566609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
21666609952SJoel Stanley 
21766609952SJoel Stanley     /* Read computed digest from memory */
21866609952SJoel Stanley     qtest_memread(s, digest_addr, digest, sizeof(digest));
21966609952SJoel Stanley 
22066609952SJoel Stanley     /* Check result of computation */
22166609952SJoel Stanley     g_assert_cmpmem(digest, sizeof(digest),
22266609952SJoel Stanley                     test_result_sha256, sizeof(digest));
22366609952SJoel Stanley 
22466609952SJoel Stanley     qtest_quit(s);
22566609952SJoel Stanley }
22666609952SJoel Stanley 
test_sha512(const char * machine,const uint32_t base,const uint32_t src_addr)22766609952SJoel Stanley static void test_sha512(const char *machine, const uint32_t base,
22866609952SJoel Stanley                         const uint32_t src_addr)
22966609952SJoel Stanley {
23066609952SJoel Stanley     QTestState *s = qtest_init(machine);
23166609952SJoel Stanley 
23266609952SJoel Stanley     const uint32_t digest_addr = src_addr + 0x1000000;
23366609952SJoel Stanley     uint8_t digest[64] = {0};
23466609952SJoel Stanley 
23566609952SJoel Stanley     /* Check engine is idle, no busy or irq bits set */
23666609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
23766609952SJoel Stanley 
23866609952SJoel Stanley     /* Write test vector into memory */
23966609952SJoel Stanley     qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
24066609952SJoel Stanley 
24166609952SJoel Stanley     write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_SHA512);
24266609952SJoel Stanley 
24366609952SJoel Stanley     /* Check hash IRQ status is asserted */
24466609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
24566609952SJoel Stanley 
24666609952SJoel Stanley     /* Clear IRQ status and check status is deasserted */
24766609952SJoel Stanley     qtest_writel(s, base + HACE_STS, 0x00000200);
24866609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
24966609952SJoel Stanley 
25066609952SJoel Stanley     /* Read computed digest from memory */
25166609952SJoel Stanley     qtest_memread(s, digest_addr, digest, sizeof(digest));
25266609952SJoel Stanley 
25366609952SJoel Stanley     /* Check result of computation */
25466609952SJoel Stanley     g_assert_cmpmem(digest, sizeof(digest),
25566609952SJoel Stanley                     test_result_sha512, sizeof(digest));
25666609952SJoel Stanley 
25766609952SJoel Stanley     qtest_quit(s);
25866609952SJoel Stanley }
25966609952SJoel Stanley 
test_sha256_sg(const char * machine,const uint32_t base,const uint32_t src_addr)26066609952SJoel Stanley static void test_sha256_sg(const char *machine, const uint32_t base,
26166609952SJoel Stanley                         const uint32_t src_addr)
26266609952SJoel Stanley {
26366609952SJoel Stanley     QTestState *s = qtest_init(machine);
26466609952SJoel Stanley 
26566609952SJoel Stanley     const uint32_t src_addr_1 = src_addr + 0x1000000;
26666609952SJoel Stanley     const uint32_t src_addr_2 = src_addr + 0x2000000;
26766609952SJoel Stanley     const uint32_t src_addr_3 = src_addr + 0x3000000;
26866609952SJoel Stanley     const uint32_t digest_addr = src_addr + 0x4000000;
26966609952SJoel Stanley     uint8_t digest[32] = {0};
27066609952SJoel Stanley     struct AspeedSgList array[] = {
27166609952SJoel Stanley         {  cpu_to_le32(sizeof(test_vector_sg1)),
27266609952SJoel Stanley            cpu_to_le32(src_addr_1) },
27366609952SJoel Stanley         {  cpu_to_le32(sizeof(test_vector_sg2)),
27466609952SJoel Stanley            cpu_to_le32(src_addr_2) },
27566609952SJoel Stanley         {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
27666609952SJoel Stanley            cpu_to_le32(src_addr_3) },
27766609952SJoel Stanley     };
27866609952SJoel Stanley 
27966609952SJoel Stanley     /* Check engine is idle, no busy or irq bits set */
28066609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
28166609952SJoel Stanley 
28266609952SJoel Stanley     /* Write test vector into memory */
28366609952SJoel Stanley     qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
28466609952SJoel Stanley     qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
28566609952SJoel Stanley     qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
28666609952SJoel Stanley     qtest_memwrite(s, src_addr, array, sizeof(array));
28766609952SJoel Stanley 
28866609952SJoel Stanley     write_regs(s, base, src_addr,
28966609952SJoel Stanley                (sizeof(test_vector_sg1)
29066609952SJoel Stanley                 + sizeof(test_vector_sg2)
29166609952SJoel Stanley                 + sizeof(test_vector_sg3)),
29266609952SJoel Stanley                digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN);
29366609952SJoel Stanley 
29466609952SJoel Stanley     /* Check hash IRQ status is asserted */
29566609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
29666609952SJoel Stanley 
29766609952SJoel Stanley     /* Clear IRQ status and check status is deasserted */
29866609952SJoel Stanley     qtest_writel(s, base + HACE_STS, 0x00000200);
29966609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
30066609952SJoel Stanley 
30166609952SJoel Stanley     /* Read computed digest from memory */
30266609952SJoel Stanley     qtest_memread(s, digest_addr, digest, sizeof(digest));
30366609952SJoel Stanley 
30466609952SJoel Stanley     /* Check result of computation */
30566609952SJoel Stanley     g_assert_cmpmem(digest, sizeof(digest),
30666609952SJoel Stanley                     test_result_sg_sha256, sizeof(digest));
30766609952SJoel Stanley 
30866609952SJoel Stanley     qtest_quit(s);
30966609952SJoel Stanley }
31066609952SJoel Stanley 
test_sha512_sg(const char * machine,const uint32_t base,const uint32_t src_addr)31166609952SJoel Stanley static void test_sha512_sg(const char *machine, const uint32_t base,
31266609952SJoel Stanley                         const uint32_t src_addr)
31366609952SJoel Stanley {
31466609952SJoel Stanley     QTestState *s = qtest_init(machine);
31566609952SJoel Stanley 
31666609952SJoel Stanley     const uint32_t src_addr_1 = src_addr + 0x1000000;
31766609952SJoel Stanley     const uint32_t src_addr_2 = src_addr + 0x2000000;
31866609952SJoel Stanley     const uint32_t src_addr_3 = src_addr + 0x3000000;
31966609952SJoel Stanley     const uint32_t digest_addr = src_addr + 0x4000000;
32066609952SJoel Stanley     uint8_t digest[64] = {0};
32166609952SJoel Stanley     struct AspeedSgList array[] = {
32266609952SJoel Stanley         {  cpu_to_le32(sizeof(test_vector_sg1)),
32366609952SJoel Stanley            cpu_to_le32(src_addr_1) },
32466609952SJoel Stanley         {  cpu_to_le32(sizeof(test_vector_sg2)),
32566609952SJoel Stanley            cpu_to_le32(src_addr_2) },
32666609952SJoel Stanley         {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
32766609952SJoel Stanley            cpu_to_le32(src_addr_3) },
32866609952SJoel Stanley     };
32966609952SJoel Stanley 
33066609952SJoel Stanley     /* Check engine is idle, no busy or irq bits set */
33166609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
33266609952SJoel Stanley 
33366609952SJoel Stanley     /* Write test vector into memory */
33466609952SJoel Stanley     qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
33566609952SJoel Stanley     qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
33666609952SJoel Stanley     qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
33766609952SJoel Stanley     qtest_memwrite(s, src_addr, array, sizeof(array));
33866609952SJoel Stanley 
33966609952SJoel Stanley     write_regs(s, base, src_addr,
34066609952SJoel Stanley                (sizeof(test_vector_sg1)
34166609952SJoel Stanley                 + sizeof(test_vector_sg2)
34266609952SJoel Stanley                 + sizeof(test_vector_sg3)),
34366609952SJoel Stanley                digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN);
34466609952SJoel Stanley 
34566609952SJoel Stanley     /* Check hash IRQ status is asserted */
34666609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
34766609952SJoel Stanley 
34866609952SJoel Stanley     /* Clear IRQ status and check status is deasserted */
34966609952SJoel Stanley     qtest_writel(s, base + HACE_STS, 0x00000200);
35066609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
35166609952SJoel Stanley 
35266609952SJoel Stanley     /* Read computed digest from memory */
35366609952SJoel Stanley     qtest_memread(s, digest_addr, digest, sizeof(digest));
35466609952SJoel Stanley 
35566609952SJoel Stanley     /* Check result of computation */
35666609952SJoel Stanley     g_assert_cmpmem(digest, sizeof(digest),
35766609952SJoel Stanley                     test_result_sg_sha512, sizeof(digest));
35866609952SJoel Stanley 
35966609952SJoel Stanley     qtest_quit(s);
36066609952SJoel Stanley }
36166609952SJoel Stanley 
test_sha256_accum(const char * machine,const uint32_t base,const uint32_t src_addr)36266609952SJoel Stanley static void test_sha256_accum(const char *machine, const uint32_t base,
36366609952SJoel Stanley                         const uint32_t src_addr)
36466609952SJoel Stanley {
36566609952SJoel Stanley     QTestState *s = qtest_init(machine);
36666609952SJoel Stanley 
36766609952SJoel Stanley     const uint32_t buffer_addr = src_addr + 0x1000000;
36866609952SJoel Stanley     const uint32_t digest_addr = src_addr + 0x4000000;
36966609952SJoel Stanley     uint8_t digest[32] = {0};
37066609952SJoel Stanley     struct AspeedSgList array[] = {
37166609952SJoel Stanley         {  cpu_to_le32(sizeof(test_vector_accum_256) | SG_LIST_LEN_LAST),
37266609952SJoel Stanley            cpu_to_le32(buffer_addr) },
37366609952SJoel Stanley     };
37466609952SJoel Stanley 
37566609952SJoel Stanley     /* Check engine is idle, no busy or irq bits set */
37666609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
37766609952SJoel Stanley 
37866609952SJoel Stanley     /* Write test vector into memory */
37966609952SJoel Stanley     qtest_memwrite(s, buffer_addr, test_vector_accum_256,
38066609952SJoel Stanley                    sizeof(test_vector_accum_256));
38166609952SJoel Stanley     qtest_memwrite(s, src_addr, array, sizeof(array));
38266609952SJoel Stanley 
38366609952SJoel Stanley     write_regs(s, base, src_addr, sizeof(test_vector_accum_256),
38466609952SJoel Stanley                digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN | HACE_ACCUM_EN);
38566609952SJoel Stanley 
38666609952SJoel Stanley     /* Check hash IRQ status is asserted */
38766609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
38866609952SJoel Stanley 
38966609952SJoel Stanley     /* Clear IRQ status and check status is deasserted */
39066609952SJoel Stanley     qtest_writel(s, base + HACE_STS, 0x00000200);
39166609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
39266609952SJoel Stanley 
39366609952SJoel Stanley     /* Read computed digest from memory */
39466609952SJoel Stanley     qtest_memread(s, digest_addr, digest, sizeof(digest));
39566609952SJoel Stanley 
39666609952SJoel Stanley     /* Check result of computation */
39766609952SJoel Stanley     g_assert_cmpmem(digest, sizeof(digest),
39866609952SJoel Stanley                     test_result_accum_sha256, sizeof(digest));
39966609952SJoel Stanley 
40066609952SJoel Stanley     qtest_quit(s);
40166609952SJoel Stanley }
40266609952SJoel Stanley 
test_sha512_accum(const char * machine,const uint32_t base,const uint32_t src_addr)40366609952SJoel Stanley static void test_sha512_accum(const char *machine, const uint32_t base,
40466609952SJoel Stanley                         const uint32_t src_addr)
40566609952SJoel Stanley {
40666609952SJoel Stanley     QTestState *s = qtest_init(machine);
40766609952SJoel Stanley 
40866609952SJoel Stanley     const uint32_t buffer_addr = src_addr + 0x1000000;
40966609952SJoel Stanley     const uint32_t digest_addr = src_addr + 0x4000000;
41066609952SJoel Stanley     uint8_t digest[64] = {0};
41166609952SJoel Stanley     struct AspeedSgList array[] = {
41266609952SJoel Stanley         {  cpu_to_le32(sizeof(test_vector_accum_512) | SG_LIST_LEN_LAST),
41366609952SJoel Stanley            cpu_to_le32(buffer_addr) },
41466609952SJoel Stanley     };
41566609952SJoel Stanley 
41666609952SJoel Stanley     /* Check engine is idle, no busy or irq bits set */
41766609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
41866609952SJoel Stanley 
41966609952SJoel Stanley     /* Write test vector into memory */
42066609952SJoel Stanley     qtest_memwrite(s, buffer_addr, test_vector_accum_512,
42166609952SJoel Stanley                    sizeof(test_vector_accum_512));
42266609952SJoel Stanley     qtest_memwrite(s, src_addr, array, sizeof(array));
42366609952SJoel Stanley 
42466609952SJoel Stanley     write_regs(s, base, src_addr, sizeof(test_vector_accum_512),
42566609952SJoel Stanley                digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN | HACE_ACCUM_EN);
42666609952SJoel Stanley 
42766609952SJoel Stanley     /* Check hash IRQ status is asserted */
42866609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
42966609952SJoel Stanley 
43066609952SJoel Stanley     /* Clear IRQ status and check status is deasserted */
43166609952SJoel Stanley     qtest_writel(s, base + HACE_STS, 0x00000200);
43266609952SJoel Stanley     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
43366609952SJoel Stanley 
43466609952SJoel Stanley     /* Read computed digest from memory */
43566609952SJoel Stanley     qtest_memread(s, digest_addr, digest, sizeof(digest));
43666609952SJoel Stanley 
43766609952SJoel Stanley     /* Check result of computation */
43866609952SJoel Stanley     g_assert_cmpmem(digest, sizeof(digest),
43966609952SJoel Stanley                     test_result_accum_sha512, sizeof(digest));
44066609952SJoel Stanley 
44166609952SJoel Stanley     qtest_quit(s);
44266609952SJoel Stanley }
44366609952SJoel Stanley 
44466609952SJoel Stanley struct masks {
44566609952SJoel Stanley     uint32_t src;
44666609952SJoel Stanley     uint32_t dest;
44766609952SJoel Stanley     uint32_t len;
44866609952SJoel Stanley };
44966609952SJoel Stanley 
45066609952SJoel Stanley static const struct masks ast2600_masks = {
45166609952SJoel Stanley     .src  = 0x7fffffff,
45266609952SJoel Stanley     .dest = 0x7ffffff8,
45366609952SJoel Stanley     .len  = 0x0fffffff,
45466609952SJoel Stanley };
45566609952SJoel Stanley 
45666609952SJoel Stanley static const struct masks ast2500_masks = {
45766609952SJoel Stanley     .src  = 0x3fffffff,
45866609952SJoel Stanley     .dest = 0x3ffffff8,
45966609952SJoel Stanley     .len  = 0x0fffffff,
46066609952SJoel Stanley };
46166609952SJoel Stanley 
46266609952SJoel Stanley static const struct masks ast2400_masks = {
46366609952SJoel Stanley     .src  = 0x0fffffff,
46466609952SJoel Stanley     .dest = 0x0ffffff8,
46566609952SJoel Stanley     .len  = 0x0fffffff,
46666609952SJoel Stanley };
46766609952SJoel Stanley 
test_addresses(const char * machine,const uint32_t base,const struct masks * expected)46866609952SJoel Stanley static void test_addresses(const char *machine, const uint32_t base,
469                            const struct masks *expected)
470 {
471     QTestState *s = qtest_init(machine);
472 
473     /*
474      * Check command mode is zero, meaning engine is in direct access mode,
475      * as this affects the masking behavior of the HASH_SRC register.
476      */
477     g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
478     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
479     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
480     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
481 
482 
483     /* Check that the address masking is correct */
484     qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
485     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, expected->src);
486 
487     qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
488     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, expected->dest);
489 
490     qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
491     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, expected->len);
492 
493     /* Reset to zero */
494     qtest_writel(s, base + HACE_HASH_SRC, 0);
495     qtest_writel(s, base + HACE_HASH_DIGEST, 0);
496     qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
497 
498     /* Check that all bits are now zero */
499     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
500     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
501     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
502 
503     qtest_quit(s);
504 }
505 
506 /* ast2600 */
test_md5_ast2600(void)507 static void test_md5_ast2600(void)
508 {
509     test_md5("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
510 }
511 
test_sha256_ast2600(void)512 static void test_sha256_ast2600(void)
513 {
514     test_sha256("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
515 }
516 
test_sha256_sg_ast2600(void)517 static void test_sha256_sg_ast2600(void)
518 {
519     test_sha256_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
520 }
521 
test_sha512_ast2600(void)522 static void test_sha512_ast2600(void)
523 {
524     test_sha512("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
525 }
526 
test_sha512_sg_ast2600(void)527 static void test_sha512_sg_ast2600(void)
528 {
529     test_sha512_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
530 }
531 
test_sha256_accum_ast2600(void)532 static void test_sha256_accum_ast2600(void)
533 {
534     test_sha256_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
535 }
536 
test_sha512_accum_ast2600(void)537 static void test_sha512_accum_ast2600(void)
538 {
539     test_sha512_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
540 }
541 
test_addresses_ast2600(void)542 static void test_addresses_ast2600(void)
543 {
544     test_addresses("-machine ast2600-evb", 0x1e6d0000, &ast2600_masks);
545 }
546 
547 /* ast2500 */
test_md5_ast2500(void)548 static void test_md5_ast2500(void)
549 {
550     test_md5("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
551 }
552 
test_sha256_ast2500(void)553 static void test_sha256_ast2500(void)
554 {
555     test_sha256("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
556 }
557 
test_sha512_ast2500(void)558 static void test_sha512_ast2500(void)
559 {
560     test_sha512("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
561 }
562 
test_addresses_ast2500(void)563 static void test_addresses_ast2500(void)
564 {
565     test_addresses("-machine ast2500-evb", 0x1e6e3000, &ast2500_masks);
566 }
567 
568 /* ast2400 */
test_md5_ast2400(void)569 static void test_md5_ast2400(void)
570 {
571     test_md5("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
572 }
573 
test_sha256_ast2400(void)574 static void test_sha256_ast2400(void)
575 {
576     test_sha256("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
577 }
578 
test_sha512_ast2400(void)579 static void test_sha512_ast2400(void)
580 {
581     test_sha512("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
582 }
583 
test_addresses_ast2400(void)584 static void test_addresses_ast2400(void)
585 {
586     test_addresses("-machine palmetto-bmc", 0x1e6e3000, &ast2400_masks);
587 }
588 
main(int argc,char ** argv)589 int main(int argc, char **argv)
590 {
591     g_test_init(&argc, &argv, NULL);
592 
593     qtest_add_func("ast2600/hace/addresses", test_addresses_ast2600);
594     qtest_add_func("ast2600/hace/sha512", test_sha512_ast2600);
595     qtest_add_func("ast2600/hace/sha256", test_sha256_ast2600);
596     qtest_add_func("ast2600/hace/md5", test_md5_ast2600);
597 
598     qtest_add_func("ast2600/hace/sha512_sg", test_sha512_sg_ast2600);
599     qtest_add_func("ast2600/hace/sha256_sg", test_sha256_sg_ast2600);
600 
601     qtest_add_func("ast2600/hace/sha512_accum", test_sha512_accum_ast2600);
602     qtest_add_func("ast2600/hace/sha256_accum", test_sha256_accum_ast2600);
603 
604     qtest_add_func("ast2500/hace/addresses", test_addresses_ast2500);
605     qtest_add_func("ast2500/hace/sha512", test_sha512_ast2500);
606     qtest_add_func("ast2500/hace/sha256", test_sha256_ast2500);
607     qtest_add_func("ast2500/hace/md5", test_md5_ast2500);
608 
609     qtest_add_func("ast2400/hace/addresses", test_addresses_ast2400);
610     qtest_add_func("ast2400/hace/sha512", test_sha512_ast2400);
611     qtest_add_func("ast2400/hace/sha256", test_sha256_ast2400);
612     qtest_add_func("ast2400/hace/md5", test_md5_ast2400);
613 
614     return g_test_run();
615 }
616