1 /* Copyright 2021 The ChromiumOS Authors
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 /* FIPS 180-2 Tests for message digest functions. */
7
8 #include <cpuid.h>
9 #include <stdio.h>
10
11 #include "2api.h"
12 #include "2sha.h"
13 #include "common/tests.h"
14 #include "sha_test_vectors.h"
15
vb2_digest_buffer(const uint8_t * buf,uint32_t size,enum vb2_hash_algorithm hash_alg,uint8_t * digest,uint32_t digest_size)16 static vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size,
17 enum vb2_hash_algorithm hash_alg,
18 uint8_t *digest, uint32_t digest_size)
19 {
20 VB2_TRY(vb2ex_hwcrypto_digest_init(hash_alg, size));
21 VB2_TRY(vb2ex_hwcrypto_digest_extend(buf, size));
22
23 return vb2ex_hwcrypto_digest_finalize(digest, digest_size);
24
25 }
26
sha256_tests(void)27 static void sha256_tests(void)
28 {
29 uint8_t digest[VB2_SHA256_DIGEST_SIZE];
30 uint8_t *test_inputs[3];
31 const uint8_t expect_multiple[VB2_SHA256_DIGEST_SIZE] = {
32 0x07, 0x08, 0xb4, 0xca, 0x46, 0x4c, 0x40, 0x39,
33 0x07, 0x06, 0x88, 0x80, 0x30, 0x55, 0x5d, 0x86,
34 0x0e, 0x4a, 0x0d, 0x2b, 0xc6, 0xc4, 0x87, 0x39,
35 0x2c, 0x16, 0x55, 0xb0, 0x82, 0x13, 0x16, 0x29 };
36 int i;
37
38 test_inputs[0] = (uint8_t *) oneblock_msg;
39 test_inputs[1] = (uint8_t *) multiblock_msg1;
40 test_inputs[2] = (uint8_t *) long_msg;
41
42 for (i = 0; i < 3; i++) {
43 TEST_SUCC(vb2_digest_buffer(test_inputs[i],
44 strlen((char *)test_inputs[i]),
45 VB2_HASH_SHA256,
46 digest, sizeof(digest)),
47 "vb2_digest_buffer() SHA256");
48 TEST_EQ(memcmp(digest, sha256_results[i], sizeof(digest)),
49 0, "SHA-256 digest");
50 }
51
52 TEST_EQ(vb2_digest_buffer(test_inputs[0],
53 strlen((char *)test_inputs[0]),
54 VB2_HASH_SHA256, digest, sizeof(digest) - 1),
55 VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE,
56 "vb2_digest_buffer() too small");
57
58 /* Test multiple small extends */
59 vb2ex_hwcrypto_digest_init(VB2_HASH_SHA256, 15);
60 vb2ex_hwcrypto_digest_extend((uint8_t *)"test1", 5);
61 vb2ex_hwcrypto_digest_extend((uint8_t *)"test2", 5);
62 vb2ex_hwcrypto_digest_extend((uint8_t *)"test3", 5);
63 vb2ex_hwcrypto_digest_finalize(digest, VB2_SHA256_DIGEST_SIZE);
64 TEST_EQ(memcmp(digest, expect_multiple, sizeof(digest)), 0,
65 "SHA-256 multiple extends");
66
67 TEST_EQ(vb2_hash_block_size(VB2_HASH_SHA256), VB2_SHA256_BLOCK_SIZE,
68 "vb2_hash_block_size(VB2_HASH_SHA256)");
69
70 }
71
known_value_tests(void)72 static void known_value_tests(void)
73 {
74 const char sentinel[] = "keepme";
75 union {
76 struct vb2_hash hash;
77 char overflow[sizeof(struct vb2_hash) + 8];
78 } test;
79
80 #define TEST_KNOWN_VALUE(algo, str, value) \
81 TEST_EQ(vb2_digest_size(algo), sizeof(value) - 1, \
82 "Known hash size " #algo ": " #str); \
83 { \
84 char *sent_base = test.overflow + \
85 offsetof(struct vb2_hash, raw) + sizeof(value) - 1; \
86 strcpy(sent_base, sentinel); \
87 strcpy(sent_base, sentinel); \
88 TEST_SUCC(vb2_digest_buffer((const uint8_t *)str, \
89 sizeof(str) - 1, \
90 algo, test.hash.raw, \
91 vb2_digest_size(algo)), \
92 "Calculate known hash " #algo ": " #str); \
93 TEST_EQ(memcmp(test.hash.raw, value, sizeof(value) - 1), 0, \
94 "Known hash " #algo ": " #str); \
95 TEST_EQ(strcmp(sent_base, sentinel), 0, \
96 "Overflow known hash " #algo ": " #str); \
97 }
98
99 TEST_KNOWN_VALUE(VB2_HASH_SHA256, "",
100 "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9"
101 "\x24\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52"
102 "\xb8\x55");
103
104 const char long_test_string[] = "abcdefghbcdefghicdefghijdefghijkefgh"
105 "ijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs"
106 "mnopqrstnopqrstu";
107 TEST_KNOWN_VALUE(VB2_HASH_SHA256, long_test_string,
108 "\xcf\x5b\x16\xa7\x78\xaf\x83\x80\x03\x6c\xe5\x9e\x7b\x04\x92"
109 "\x37\x0b\x24\x9b\x11\xe8\xf0\x7a\x51\xaf\xac\x45\x03\x7a\xfe"
110 "\xe9\xd1");
111
112 /* vim helper to escape hex: <Shift+V>:s/\([a-f0-9]\{2\}\)/\\x\1/g */
113 #undef TEST_KNOWN_VALUE
114 }
115
main(int argc,char * argv[])116 int main(int argc, char *argv[])
117 {
118 uint32_t a, b = 0, c, d;
119 /* EAX = 07H, sub-leaf 0 */
120 __get_cpuid_count(7, 0, &a, &b, &c, &d);
121 if ((b & bit_SHA) == 0) {
122 fprintf(stderr, "SHA-NI not supported.\n");
123 return 254;
124 }
125
126 /* Initialize long_msg with 'a' x 1,000,000 */
127 long_msg = (char *) malloc(1000001);
128 memset(long_msg, 'a', 1000000);
129 long_msg[1000000]=0;
130
131 sha256_tests();
132 known_value_tests();
133
134 free(long_msg);
135
136 return gTestSuccess ? 0 : 255;
137 }
138