xref: /aosp_15_r20/external/vboot_reference/tests/vb2_sha256_x86_tests.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
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