xref: /qemu/tests/qtest/aspeed-hace-utils.c (revision 70985b0ea776e0cd7d7ab2a173d9d35d31e8c21f)
1*70985b0eSJamin Lin /*
2*70985b0eSJamin Lin  * QTest testcase for the ASPEED Hash and Crypto Engine
3*70985b0eSJamin Lin  *
4*70985b0eSJamin Lin  * SPDX-License-Identifier: GPL-2.0-or-later
5*70985b0eSJamin Lin  * Copyright 2021 IBM Corp.
6*70985b0eSJamin Lin  */
7*70985b0eSJamin Lin 
8*70985b0eSJamin Lin #include "qemu/osdep.h"
9*70985b0eSJamin Lin #include "libqtest.h"
10*70985b0eSJamin Lin #include "qemu/bitops.h"
11*70985b0eSJamin Lin #include "aspeed-hace-utils.h"
12*70985b0eSJamin Lin 
13*70985b0eSJamin Lin /*
14*70985b0eSJamin Lin  * Test vector is the ascii "abc"
15*70985b0eSJamin Lin  *
16*70985b0eSJamin Lin  * Expected results were generated using command line utitiles:
17*70985b0eSJamin Lin  *
18*70985b0eSJamin Lin  *  echo -n -e 'abc' | dd of=/tmp/test
19*70985b0eSJamin Lin  *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
20*70985b0eSJamin Lin  *
21*70985b0eSJamin Lin  */
22*70985b0eSJamin Lin static const uint8_t test_vector[] = {0x61, 0x62, 0x63};
23*70985b0eSJamin Lin 
24*70985b0eSJamin Lin static const uint8_t test_result_sha512[] = {
25*70985b0eSJamin Lin     0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
26*70985b0eSJamin Lin     0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
27*70985b0eSJamin Lin     0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
28*70985b0eSJamin Lin     0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
29*70985b0eSJamin Lin     0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
30*70985b0eSJamin Lin     0xa5, 0x4c, 0xa4, 0x9f};
31*70985b0eSJamin Lin 
32*70985b0eSJamin Lin static const uint8_t test_result_sha256[] = {
33*70985b0eSJamin Lin     0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
34*70985b0eSJamin Lin     0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
35*70985b0eSJamin Lin     0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
36*70985b0eSJamin Lin 
37*70985b0eSJamin Lin static const uint8_t test_result_md5[] = {
38*70985b0eSJamin Lin     0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
39*70985b0eSJamin Lin     0x28, 0xe1, 0x7f, 0x72};
40*70985b0eSJamin Lin 
41*70985b0eSJamin Lin /*
42*70985b0eSJamin Lin  * The Scatter-Gather Test vector is the ascii "abc" "def" "ghi", broken
43*70985b0eSJamin Lin  * into blocks of 3 characters as shown
44*70985b0eSJamin Lin  *
45*70985b0eSJamin Lin  * Expected results were generated using command line utitiles:
46*70985b0eSJamin Lin  *
47*70985b0eSJamin Lin  *  echo -n -e 'abcdefghijkl' | dd of=/tmp/test
48*70985b0eSJamin Lin  *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
49*70985b0eSJamin Lin  *
50*70985b0eSJamin Lin  */
51*70985b0eSJamin Lin static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
52*70985b0eSJamin Lin static const uint8_t test_vector_sg2[] = {0x67, 0x68, 0x69};
53*70985b0eSJamin Lin static const uint8_t test_vector_sg3[] = {0x6a, 0x6b, 0x6c};
54*70985b0eSJamin Lin 
55*70985b0eSJamin Lin static const uint8_t test_result_sg_sha512[] = {
56*70985b0eSJamin Lin     0x17, 0x80, 0x7c, 0x72, 0x8e, 0xe3, 0xba, 0x35, 0xe7, 0xcf, 0x7a, 0xf8,
57*70985b0eSJamin Lin     0x23, 0x11, 0x6d, 0x26, 0xe4, 0x1e, 0x5d, 0x4d, 0x6c, 0x2f, 0xf1, 0xf3,
58*70985b0eSJamin Lin     0x72, 0x0d, 0x3d, 0x96, 0xaa, 0xcb, 0x6f, 0x69, 0xde, 0x64, 0x2e, 0x63,
59*70985b0eSJamin Lin     0xd5, 0xb7, 0x3f, 0xc3, 0x96, 0xc1, 0x2b, 0xe3, 0x8b, 0x2b, 0xd5, 0xd8,
60*70985b0eSJamin Lin     0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6, 0xb5, 0x40,
61*70985b0eSJamin Lin     0xf8, 0x6d, 0xda, 0x2e};
62*70985b0eSJamin Lin 
63*70985b0eSJamin Lin static const uint8_t test_result_sg_sha256[] = {
64*70985b0eSJamin Lin     0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec, 0x94, 0xf1,
65*70985b0eSJamin Lin     0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd, 0xe9, 0xf3,
66*70985b0eSJamin Lin     0xd3, 0x5e, 0x6e, 0x4a, 0x71, 0x7f, 0xbd, 0xe4};
67*70985b0eSJamin Lin 
68*70985b0eSJamin Lin /*
69*70985b0eSJamin Lin  * The accumulative mode requires firmware to provide internal initial state
70*70985b0eSJamin Lin  * and message padding (including length L at the end of padding).
71*70985b0eSJamin Lin  *
72*70985b0eSJamin Lin  * This test vector is a ascii text "abc" with padding message.
73*70985b0eSJamin Lin  *
74*70985b0eSJamin Lin  * Expected results were generated using command line utitiles:
75*70985b0eSJamin Lin  *
76*70985b0eSJamin Lin  *  echo -n -e 'abc' | dd of=/tmp/test
77*70985b0eSJamin Lin  *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
78*70985b0eSJamin Lin  */
79*70985b0eSJamin Lin static const uint8_t test_vector_accum_512[] = {
80*70985b0eSJamin Lin     0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
81*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
96*70985b0eSJamin Lin 
97*70985b0eSJamin Lin static const uint8_t test_vector_accum_256[] = {
98*70985b0eSJamin Lin     0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
99*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105*70985b0eSJamin Lin     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
106*70985b0eSJamin Lin 
107*70985b0eSJamin Lin static const uint8_t test_result_accum_sha512[] = {
108*70985b0eSJamin Lin     0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
109*70985b0eSJamin Lin     0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
110*70985b0eSJamin Lin     0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
111*70985b0eSJamin Lin     0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
112*70985b0eSJamin Lin     0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
113*70985b0eSJamin Lin     0xa5, 0x4c, 0xa4, 0x9f};
114*70985b0eSJamin Lin 
115*70985b0eSJamin Lin static const uint8_t test_result_accum_sha256[] = {
116*70985b0eSJamin Lin     0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
117*70985b0eSJamin Lin     0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
118*70985b0eSJamin Lin     0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
119*70985b0eSJamin Lin 
120*70985b0eSJamin Lin static void write_regs(QTestState *s, uint32_t base, uint32_t src,
121*70985b0eSJamin Lin                        uint32_t length, uint32_t out, uint32_t method)
122*70985b0eSJamin Lin {
123*70985b0eSJamin Lin         qtest_writel(s, base + HACE_HASH_SRC, src);
124*70985b0eSJamin Lin         qtest_writel(s, base + HACE_HASH_DIGEST, out);
125*70985b0eSJamin Lin         qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
126*70985b0eSJamin Lin         qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
127*70985b0eSJamin Lin }
128*70985b0eSJamin Lin 
129*70985b0eSJamin Lin void aspeed_test_md5(const char *machine, const uint32_t base,
130*70985b0eSJamin Lin                      const uint32_t src_addr)
131*70985b0eSJamin Lin 
132*70985b0eSJamin Lin {
133*70985b0eSJamin Lin     QTestState *s = qtest_init(machine);
134*70985b0eSJamin Lin 
135*70985b0eSJamin Lin     uint32_t digest_addr = src_addr + 0x01000000;
136*70985b0eSJamin Lin     uint8_t digest[16] = {0};
137*70985b0eSJamin Lin 
138*70985b0eSJamin Lin     /* Check engine is idle, no busy or irq bits set */
139*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
140*70985b0eSJamin Lin 
141*70985b0eSJamin Lin     /* Write test vector into memory */
142*70985b0eSJamin Lin     qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
143*70985b0eSJamin Lin 
144*70985b0eSJamin Lin     write_regs(s, base, src_addr, sizeof(test_vector),
145*70985b0eSJamin Lin                digest_addr, HACE_ALGO_MD5);
146*70985b0eSJamin Lin 
147*70985b0eSJamin Lin     /* Check hash IRQ status is asserted */
148*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
149*70985b0eSJamin Lin 
150*70985b0eSJamin Lin     /* Clear IRQ status and check status is deasserted */
151*70985b0eSJamin Lin     qtest_writel(s, base + HACE_STS, 0x00000200);
152*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
153*70985b0eSJamin Lin 
154*70985b0eSJamin Lin     /* Read computed digest from memory */
155*70985b0eSJamin Lin     qtest_memread(s, digest_addr, digest, sizeof(digest));
156*70985b0eSJamin Lin 
157*70985b0eSJamin Lin     /* Check result of computation */
158*70985b0eSJamin Lin     g_assert_cmpmem(digest, sizeof(digest),
159*70985b0eSJamin Lin                     test_result_md5, sizeof(digest));
160*70985b0eSJamin Lin 
161*70985b0eSJamin Lin     qtest_quit(s);
162*70985b0eSJamin Lin }
163*70985b0eSJamin Lin 
164*70985b0eSJamin Lin void aspeed_test_sha256(const char *machine, const uint32_t base,
165*70985b0eSJamin Lin                         const uint32_t src_addr)
166*70985b0eSJamin Lin {
167*70985b0eSJamin Lin     QTestState *s = qtest_init(machine);
168*70985b0eSJamin Lin 
169*70985b0eSJamin Lin     const uint32_t digest_addr = src_addr + 0x1000000;
170*70985b0eSJamin Lin     uint8_t digest[32] = {0};
171*70985b0eSJamin Lin 
172*70985b0eSJamin Lin     /* Check engine is idle, no busy or irq bits set */
173*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
174*70985b0eSJamin Lin 
175*70985b0eSJamin Lin     /* Write test vector into memory */
176*70985b0eSJamin Lin     qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
177*70985b0eSJamin Lin 
178*70985b0eSJamin Lin     write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
179*70985b0eSJamin Lin                HACE_ALGO_SHA256);
180*70985b0eSJamin Lin 
181*70985b0eSJamin Lin     /* Check hash IRQ status is asserted */
182*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
183*70985b0eSJamin Lin 
184*70985b0eSJamin Lin     /* Clear IRQ status and check status is deasserted */
185*70985b0eSJamin Lin     qtest_writel(s, base + HACE_STS, 0x00000200);
186*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
187*70985b0eSJamin Lin 
188*70985b0eSJamin Lin     /* Read computed digest from memory */
189*70985b0eSJamin Lin     qtest_memread(s, digest_addr, digest, sizeof(digest));
190*70985b0eSJamin Lin 
191*70985b0eSJamin Lin     /* Check result of computation */
192*70985b0eSJamin Lin     g_assert_cmpmem(digest, sizeof(digest),
193*70985b0eSJamin Lin                     test_result_sha256, sizeof(digest));
194*70985b0eSJamin Lin 
195*70985b0eSJamin Lin     qtest_quit(s);
196*70985b0eSJamin Lin }
197*70985b0eSJamin Lin 
198*70985b0eSJamin Lin void aspeed_test_sha512(const char *machine, const uint32_t base,
199*70985b0eSJamin Lin                         const uint32_t src_addr)
200*70985b0eSJamin Lin {
201*70985b0eSJamin Lin     QTestState *s = qtest_init(machine);
202*70985b0eSJamin Lin 
203*70985b0eSJamin Lin     const uint32_t digest_addr = src_addr + 0x1000000;
204*70985b0eSJamin Lin     uint8_t digest[64] = {0};
205*70985b0eSJamin Lin 
206*70985b0eSJamin Lin     /* Check engine is idle, no busy or irq bits set */
207*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
208*70985b0eSJamin Lin 
209*70985b0eSJamin Lin     /* Write test vector into memory */
210*70985b0eSJamin Lin     qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
211*70985b0eSJamin Lin 
212*70985b0eSJamin Lin     write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
213*70985b0eSJamin Lin                HACE_ALGO_SHA512);
214*70985b0eSJamin Lin 
215*70985b0eSJamin Lin     /* Check hash IRQ status is asserted */
216*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
217*70985b0eSJamin Lin 
218*70985b0eSJamin Lin     /* Clear IRQ status and check status is deasserted */
219*70985b0eSJamin Lin     qtest_writel(s, base + HACE_STS, 0x00000200);
220*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
221*70985b0eSJamin Lin 
222*70985b0eSJamin Lin     /* Read computed digest from memory */
223*70985b0eSJamin Lin     qtest_memread(s, digest_addr, digest, sizeof(digest));
224*70985b0eSJamin Lin 
225*70985b0eSJamin Lin     /* Check result of computation */
226*70985b0eSJamin Lin     g_assert_cmpmem(digest, sizeof(digest),
227*70985b0eSJamin Lin                     test_result_sha512, sizeof(digest));
228*70985b0eSJamin Lin 
229*70985b0eSJamin Lin     qtest_quit(s);
230*70985b0eSJamin Lin }
231*70985b0eSJamin Lin 
232*70985b0eSJamin Lin void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
233*70985b0eSJamin Lin                            const uint32_t src_addr)
234*70985b0eSJamin Lin {
235*70985b0eSJamin Lin     QTestState *s = qtest_init(machine);
236*70985b0eSJamin Lin 
237*70985b0eSJamin Lin     const uint32_t src_addr_1 = src_addr + 0x1000000;
238*70985b0eSJamin Lin     const uint32_t src_addr_2 = src_addr + 0x2000000;
239*70985b0eSJamin Lin     const uint32_t src_addr_3 = src_addr + 0x3000000;
240*70985b0eSJamin Lin     const uint32_t digest_addr = src_addr + 0x4000000;
241*70985b0eSJamin Lin     uint8_t digest[32] = {0};
242*70985b0eSJamin Lin     struct AspeedSgList array[] = {
243*70985b0eSJamin Lin         {  cpu_to_le32(sizeof(test_vector_sg1)),
244*70985b0eSJamin Lin            cpu_to_le32(src_addr_1) },
245*70985b0eSJamin Lin         {  cpu_to_le32(sizeof(test_vector_sg2)),
246*70985b0eSJamin Lin            cpu_to_le32(src_addr_2) },
247*70985b0eSJamin Lin         {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
248*70985b0eSJamin Lin            cpu_to_le32(src_addr_3) },
249*70985b0eSJamin Lin     };
250*70985b0eSJamin Lin 
251*70985b0eSJamin Lin     /* Check engine is idle, no busy or irq bits set */
252*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
253*70985b0eSJamin Lin 
254*70985b0eSJamin Lin     /* Write test vector into memory */
255*70985b0eSJamin Lin     qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
256*70985b0eSJamin Lin     qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
257*70985b0eSJamin Lin     qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
258*70985b0eSJamin Lin     qtest_memwrite(s, src_addr, array, sizeof(array));
259*70985b0eSJamin Lin 
260*70985b0eSJamin Lin     write_regs(s, base, src_addr,
261*70985b0eSJamin Lin                (sizeof(test_vector_sg1)
262*70985b0eSJamin Lin                 + sizeof(test_vector_sg2)
263*70985b0eSJamin Lin                 + sizeof(test_vector_sg3)),
264*70985b0eSJamin Lin                digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN);
265*70985b0eSJamin Lin 
266*70985b0eSJamin Lin     /* Check hash IRQ status is asserted */
267*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
268*70985b0eSJamin Lin 
269*70985b0eSJamin Lin     /* Clear IRQ status and check status is deasserted */
270*70985b0eSJamin Lin     qtest_writel(s, base + HACE_STS, 0x00000200);
271*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
272*70985b0eSJamin Lin 
273*70985b0eSJamin Lin     /* Read computed digest from memory */
274*70985b0eSJamin Lin     qtest_memread(s, digest_addr, digest, sizeof(digest));
275*70985b0eSJamin Lin 
276*70985b0eSJamin Lin     /* Check result of computation */
277*70985b0eSJamin Lin     g_assert_cmpmem(digest, sizeof(digest),
278*70985b0eSJamin Lin                     test_result_sg_sha256, sizeof(digest));
279*70985b0eSJamin Lin 
280*70985b0eSJamin Lin     qtest_quit(s);
281*70985b0eSJamin Lin }
282*70985b0eSJamin Lin 
283*70985b0eSJamin Lin void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
284*70985b0eSJamin Lin                            const uint32_t src_addr)
285*70985b0eSJamin Lin {
286*70985b0eSJamin Lin     QTestState *s = qtest_init(machine);
287*70985b0eSJamin Lin 
288*70985b0eSJamin Lin     const uint32_t src_addr_1 = src_addr + 0x1000000;
289*70985b0eSJamin Lin     const uint32_t src_addr_2 = src_addr + 0x2000000;
290*70985b0eSJamin Lin     const uint32_t src_addr_3 = src_addr + 0x3000000;
291*70985b0eSJamin Lin     const uint32_t digest_addr = src_addr + 0x4000000;
292*70985b0eSJamin Lin     uint8_t digest[64] = {0};
293*70985b0eSJamin Lin     struct AspeedSgList array[] = {
294*70985b0eSJamin Lin         {  cpu_to_le32(sizeof(test_vector_sg1)),
295*70985b0eSJamin Lin            cpu_to_le32(src_addr_1) },
296*70985b0eSJamin Lin         {  cpu_to_le32(sizeof(test_vector_sg2)),
297*70985b0eSJamin Lin            cpu_to_le32(src_addr_2) },
298*70985b0eSJamin Lin         {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
299*70985b0eSJamin Lin            cpu_to_le32(src_addr_3) },
300*70985b0eSJamin Lin     };
301*70985b0eSJamin Lin 
302*70985b0eSJamin Lin     /* Check engine is idle, no busy or irq bits set */
303*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
304*70985b0eSJamin Lin 
305*70985b0eSJamin Lin     /* Write test vector into memory */
306*70985b0eSJamin Lin     qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
307*70985b0eSJamin Lin     qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
308*70985b0eSJamin Lin     qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
309*70985b0eSJamin Lin     qtest_memwrite(s, src_addr, array, sizeof(array));
310*70985b0eSJamin Lin 
311*70985b0eSJamin Lin     write_regs(s, base, src_addr,
312*70985b0eSJamin Lin                (sizeof(test_vector_sg1)
313*70985b0eSJamin Lin                 + sizeof(test_vector_sg2)
314*70985b0eSJamin Lin                 + sizeof(test_vector_sg3)),
315*70985b0eSJamin Lin                digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN);
316*70985b0eSJamin Lin 
317*70985b0eSJamin Lin     /* Check hash IRQ status is asserted */
318*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
319*70985b0eSJamin Lin 
320*70985b0eSJamin Lin     /* Clear IRQ status and check status is deasserted */
321*70985b0eSJamin Lin     qtest_writel(s, base + HACE_STS, 0x00000200);
322*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
323*70985b0eSJamin Lin 
324*70985b0eSJamin Lin     /* Read computed digest from memory */
325*70985b0eSJamin Lin     qtest_memread(s, digest_addr, digest, sizeof(digest));
326*70985b0eSJamin Lin 
327*70985b0eSJamin Lin     /* Check result of computation */
328*70985b0eSJamin Lin     g_assert_cmpmem(digest, sizeof(digest),
329*70985b0eSJamin Lin                     test_result_sg_sha512, sizeof(digest));
330*70985b0eSJamin Lin 
331*70985b0eSJamin Lin     qtest_quit(s);
332*70985b0eSJamin Lin }
333*70985b0eSJamin Lin 
334*70985b0eSJamin Lin void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
335*70985b0eSJamin Lin                               const uint32_t src_addr)
336*70985b0eSJamin Lin {
337*70985b0eSJamin Lin     QTestState *s = qtest_init(machine);
338*70985b0eSJamin Lin 
339*70985b0eSJamin Lin     const uint32_t buffer_addr = src_addr + 0x1000000;
340*70985b0eSJamin Lin     const uint32_t digest_addr = src_addr + 0x4000000;
341*70985b0eSJamin Lin     uint8_t digest[32] = {0};
342*70985b0eSJamin Lin     struct AspeedSgList array[] = {
343*70985b0eSJamin Lin         {  cpu_to_le32(sizeof(test_vector_accum_256) | SG_LIST_LEN_LAST),
344*70985b0eSJamin Lin            cpu_to_le32(buffer_addr) },
345*70985b0eSJamin Lin     };
346*70985b0eSJamin Lin 
347*70985b0eSJamin Lin     /* Check engine is idle, no busy or irq bits set */
348*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
349*70985b0eSJamin Lin 
350*70985b0eSJamin Lin     /* Write test vector into memory */
351*70985b0eSJamin Lin     qtest_memwrite(s, buffer_addr, test_vector_accum_256,
352*70985b0eSJamin Lin                    sizeof(test_vector_accum_256));
353*70985b0eSJamin Lin     qtest_memwrite(s, src_addr, array, sizeof(array));
354*70985b0eSJamin Lin 
355*70985b0eSJamin Lin     write_regs(s, base, src_addr, sizeof(test_vector_accum_256),
356*70985b0eSJamin Lin                digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN | HACE_ACCUM_EN);
357*70985b0eSJamin Lin 
358*70985b0eSJamin Lin     /* Check hash IRQ status is asserted */
359*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
360*70985b0eSJamin Lin 
361*70985b0eSJamin Lin     /* Clear IRQ status and check status is deasserted */
362*70985b0eSJamin Lin     qtest_writel(s, base + HACE_STS, 0x00000200);
363*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
364*70985b0eSJamin Lin 
365*70985b0eSJamin Lin     /* Read computed digest from memory */
366*70985b0eSJamin Lin     qtest_memread(s, digest_addr, digest, sizeof(digest));
367*70985b0eSJamin Lin 
368*70985b0eSJamin Lin     /* Check result of computation */
369*70985b0eSJamin Lin     g_assert_cmpmem(digest, sizeof(digest),
370*70985b0eSJamin Lin                     test_result_accum_sha256, sizeof(digest));
371*70985b0eSJamin Lin 
372*70985b0eSJamin Lin     qtest_quit(s);
373*70985b0eSJamin Lin }
374*70985b0eSJamin Lin 
375*70985b0eSJamin Lin void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
376*70985b0eSJamin Lin                               const uint32_t src_addr)
377*70985b0eSJamin Lin {
378*70985b0eSJamin Lin     QTestState *s = qtest_init(machine);
379*70985b0eSJamin Lin 
380*70985b0eSJamin Lin     const uint32_t buffer_addr = src_addr + 0x1000000;
381*70985b0eSJamin Lin     const uint32_t digest_addr = src_addr + 0x4000000;
382*70985b0eSJamin Lin     uint8_t digest[64] = {0};
383*70985b0eSJamin Lin     struct AspeedSgList array[] = {
384*70985b0eSJamin Lin         {  cpu_to_le32(sizeof(test_vector_accum_512) | SG_LIST_LEN_LAST),
385*70985b0eSJamin Lin            cpu_to_le32(buffer_addr) },
386*70985b0eSJamin Lin     };
387*70985b0eSJamin Lin 
388*70985b0eSJamin Lin     /* Check engine is idle, no busy or irq bits set */
389*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
390*70985b0eSJamin Lin 
391*70985b0eSJamin Lin     /* Write test vector into memory */
392*70985b0eSJamin Lin     qtest_memwrite(s, buffer_addr, test_vector_accum_512,
393*70985b0eSJamin Lin                    sizeof(test_vector_accum_512));
394*70985b0eSJamin Lin     qtest_memwrite(s, src_addr, array, sizeof(array));
395*70985b0eSJamin Lin 
396*70985b0eSJamin Lin     write_regs(s, base, src_addr, sizeof(test_vector_accum_512),
397*70985b0eSJamin Lin                digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN | HACE_ACCUM_EN);
398*70985b0eSJamin Lin 
399*70985b0eSJamin Lin     /* Check hash IRQ status is asserted */
400*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
401*70985b0eSJamin Lin 
402*70985b0eSJamin Lin     /* Clear IRQ status and check status is deasserted */
403*70985b0eSJamin Lin     qtest_writel(s, base + HACE_STS, 0x00000200);
404*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
405*70985b0eSJamin Lin 
406*70985b0eSJamin Lin     /* Read computed digest from memory */
407*70985b0eSJamin Lin     qtest_memread(s, digest_addr, digest, sizeof(digest));
408*70985b0eSJamin Lin 
409*70985b0eSJamin Lin     /* Check result of computation */
410*70985b0eSJamin Lin     g_assert_cmpmem(digest, sizeof(digest),
411*70985b0eSJamin Lin                     test_result_accum_sha512, sizeof(digest));
412*70985b0eSJamin Lin 
413*70985b0eSJamin Lin     qtest_quit(s);
414*70985b0eSJamin Lin }
415*70985b0eSJamin Lin 
416*70985b0eSJamin Lin void aspeed_test_addresses(const char *machine, const uint32_t base,
417*70985b0eSJamin Lin                            const struct AspeedMasks *expected)
418*70985b0eSJamin Lin {
419*70985b0eSJamin Lin     QTestState *s = qtest_init(machine);
420*70985b0eSJamin Lin 
421*70985b0eSJamin Lin     /*
422*70985b0eSJamin Lin      * Check command mode is zero, meaning engine is in direct access mode,
423*70985b0eSJamin Lin      * as this affects the masking behavior of the HASH_SRC register.
424*70985b0eSJamin Lin      */
425*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
426*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
427*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
428*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
429*70985b0eSJamin Lin 
430*70985b0eSJamin Lin 
431*70985b0eSJamin Lin     /* Check that the address masking is correct */
432*70985b0eSJamin Lin     qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
433*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, expected->src);
434*70985b0eSJamin Lin 
435*70985b0eSJamin Lin     qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
436*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==,
437*70985b0eSJamin Lin                     expected->dest);
438*70985b0eSJamin Lin 
439*70985b0eSJamin Lin     qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
440*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
441*70985b0eSJamin Lin                     expected->len);
442*70985b0eSJamin Lin 
443*70985b0eSJamin Lin     /* Reset to zero */
444*70985b0eSJamin Lin     qtest_writel(s, base + HACE_HASH_SRC, 0);
445*70985b0eSJamin Lin     qtest_writel(s, base + HACE_HASH_DIGEST, 0);
446*70985b0eSJamin Lin     qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
447*70985b0eSJamin Lin 
448*70985b0eSJamin Lin     /* Check that all bits are now zero */
449*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
450*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
451*70985b0eSJamin Lin     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
452*70985b0eSJamin Lin 
453*70985b0eSJamin Lin     qtest_quit(s);
454*70985b0eSJamin Lin }
455*70985b0eSJamin Lin 
456