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