xref: /aosp_15_r20/external/vboot_reference/tests/vb2_sha_api_tests.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1 /* Copyright 2019 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  * Tests for vb2_hash_(calculate|verify) functions, and hwcrypto handling
6  * of vb2_digest_*.
7  */
8 
9 #include "2api.h"
10 #include "2return_codes.h"
11 #include "2sha.h"
12 #include "2sysincludes.h"
13 #include "common/tests.h"
14 
15 uint8_t mock_sha1[] = {0x1, 0x3, 0x5, 0x2, 0x4, 0x6, 0xa, 0xb, 0xc, 0xd,
16 		       0xd, 0xe, 0xa, 0xd, 0xb, 0xe, 0xe, 0xf, 0x0, 0xf0};
17 _Static_assert(sizeof(mock_sha1) == VB2_SHA1_DIGEST_SIZE, "");
18 
19 struct vb2_hash mock_hash;
20 uint8_t mock_buffer[] = "Mock Buffer";
21 
22 static enum hwcrypto_state {
23 	HWCRYPTO_OK,
24 	HWCRYPTO_NOTSUPPORTED,
25 	HWCRYPTO_ERROR,
26 	HWCRYPTO_ABORT,
27 } hwcrypto_state;
28 
hwcrypto_mock(enum hwcrypto_state * state)29 static vb2_error_t hwcrypto_mock(enum hwcrypto_state *state)
30 {
31 	switch (*state) {
32 	case HWCRYPTO_OK:
33 		return VB2_SUCCESS;
34 	case HWCRYPTO_NOTSUPPORTED:
35 		return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
36 	case HWCRYPTO_ERROR:
37 		return VB2_ERROR_MOCK;
38 	case HWCRYPTO_ABORT:
39 		vb2ex_abort();
40 		/* shouldn't reach here but added for compiler */
41 		return VB2_ERROR_MOCK;
42 	}
43 	return VB2_ERROR_MOCK;
44 }
45 
reset_common_data(enum hwcrypto_state state)46 static void reset_common_data(enum hwcrypto_state state)
47 {
48 	hwcrypto_state = state;
49 	memset(&mock_hash, 0xaa, sizeof(mock_hash));
50 }
51 
vb2_sha1_init(struct vb2_sha1_context * ctx)52 void vb2_sha1_init(struct vb2_sha1_context *ctx)
53 {
54 	TEST_TRUE(hwcrypto_state == HWCRYPTO_NOTSUPPORTED ||
55 		  hwcrypto_state == HWCRYPTO_ABORT,
56 		  "    hwcrypto_state in SW init");
57 }
58 
vb2_sha1_update(struct vb2_sha1_context * ctx,const uint8_t * data,uint32_t size)59 void vb2_sha1_update(struct vb2_sha1_context *ctx,
60 		     const uint8_t *data,
61 		     uint32_t size)
62 {
63 	TEST_TRUE(hwcrypto_state == HWCRYPTO_NOTSUPPORTED ||
64 		  hwcrypto_state == HWCRYPTO_ABORT,
65 		  "    hwcrypto_state in SW extend");
66 	TEST_PTR_EQ(data, mock_buffer, "    digest_extend buf");
67 	TEST_EQ(size, sizeof(mock_buffer), "    digest_extend size");
68 }
69 
vb2_sha1_finalize(struct vb2_sha1_context * ctx,uint8_t * digest)70 void vb2_sha1_finalize(struct vb2_sha1_context *ctx, uint8_t *digest)
71 {
72 	TEST_TRUE(hwcrypto_state == HWCRYPTO_NOTSUPPORTED ||
73 		  hwcrypto_state == HWCRYPTO_ABORT,
74 		  "    hwcrypto_state in SW finalize");
75 	memcpy(digest, mock_sha1, sizeof(mock_sha1));
76 }
77 
vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,uint32_t data_size)78 vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
79 				       uint32_t data_size)
80 {
81 	if (data_size)
82 		TEST_EQ(data_size, sizeof(mock_buffer),
83 			"    hwcrypto_digest_init size");
84 	return hwcrypto_mock(&hwcrypto_state);
85 }
86 
vb2ex_hwcrypto_digest_extend(const uint8_t * buf,uint32_t size)87 vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
88 {
89 	TEST_PTR_EQ(buf, mock_buffer, "    hwcrypto_digest_extend buf");
90 	TEST_EQ(size, sizeof(mock_buffer), "    hwcrypto_digest_extend size");
91 	return hwcrypto_mock(&hwcrypto_state);
92 }
93 
vb2ex_hwcrypto_digest_finalize(uint8_t * digest,uint32_t digest_size)94 vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
95 					   uint32_t digest_size)
96 {
97 	memcpy(digest, mock_sha1, sizeof(mock_sha1));
98 	return hwcrypto_mock(&hwcrypto_state);
99 }
100 
vb2_hash_cbfs_compatibility_test(void)101 static void vb2_hash_cbfs_compatibility_test(void)
102 {
103 	/* 'algo' used to be represented as a 4-byte big-endian in CBFS. Confirm
104 	   that the new representation is binary compatible for small values. */
105 	union {
106 		struct vb2_hash hash;
107 		struct {
108 			uint32_t be32;
109 			uint8_t bytes[0];
110 		};
111 	} test = {0};
112 
113 	test.be32 = htobe32(0xa5);
114 	TEST_EQ(test.hash.algo, 0xa5, "vb2_hash algo compatible to CBFS attr");
115 	TEST_PTR_EQ(&test.hash.raw, &test.bytes, "  digest offset matches");
116 }
117 
vb2_hash_calculate_tests(void)118 static void vb2_hash_calculate_tests(void)
119 {
120 	reset_common_data(HWCRYPTO_ABORT);
121 	TEST_SUCC(vb2_hash_calculate(false, &mock_buffer, sizeof(mock_buffer),
122 				     VB2_HASH_SHA1, &mock_hash),
123 		  "hash_calculate success");
124 	TEST_SUCC(memcmp(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)),
125 		  "  got the right hash");
126 	TEST_EQ(mock_hash.algo, VB2_HASH_SHA1, "  set algo correctly");
127 
128 	reset_common_data(HWCRYPTO_ABORT);
129 	TEST_EQ(vb2_hash_calculate(false, mock_buffer, sizeof(mock_buffer),
130 				   -1, &mock_hash),
131 		VB2_ERROR_SHA_INIT_ALGORITHM, "hash_calculate wrong algo");
132 }
133 
vb2_hash_verify_tests(void)134 static void vb2_hash_verify_tests(void)
135 {
136 	reset_common_data(HWCRYPTO_ABORT);
137 
138 	memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1));
139 	mock_hash.algo = VB2_HASH_SHA1;
140 	TEST_SUCC(vb2_hash_verify(false, mock_buffer, sizeof(mock_buffer),
141 				  &mock_hash), "hash_verify success");
142 
143 	memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1));
144 	mock_hash.algo = -1;
145 	TEST_EQ(vb2_hash_verify(false, mock_buffer, sizeof(mock_buffer),
146 				&mock_hash), VB2_ERROR_SHA_INIT_ALGORITHM,
147 		"hash_verify wrong algo");
148 
149 	memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1));
150 	mock_hash.sha1[5] = 0xfe;
151 	mock_hash.algo = VB2_HASH_SHA1;
152 	TEST_EQ(vb2_hash_verify(false, mock_buffer, sizeof(mock_buffer),
153 				&mock_hash), VB2_ERROR_SHA_MISMATCH,
154 		"hash_verify mismatch");
155 }
156 
vb2_hash_hwcrypto_tests(void)157 static void vb2_hash_hwcrypto_tests(void)
158 {
159 	struct vb2_digest_context dc;
160 
161 	reset_common_data(HWCRYPTO_OK);
162 	TEST_SUCC(vb2_digest_init(&dc, true, VB2_HASH_SHA1,
163 				  sizeof(mock_buffer)),
164 		  "digest_init, HW enabled");
165 	TEST_EQ(dc.using_hwcrypto, 1, "  using_hwcrypto set");
166 	TEST_SUCC(vb2_digest_extend(&dc, mock_buffer, sizeof(mock_buffer)),
167 		  "digest_extend, HW enabled");
168 	TEST_SUCC(vb2_digest_finalize(&dc, mock_hash.raw, VB2_SHA1_DIGEST_SIZE),
169 		  "digest_finalize, HW enabled ");
170 	TEST_SUCC(memcmp(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)),
171 		  "  got the right hash");
172 
173 	reset_common_data(HWCRYPTO_OK);
174 	TEST_SUCC(vb2_hash_calculate(true, mock_buffer, sizeof(mock_buffer),
175 				     VB2_HASH_SHA1, &mock_hash),
176 		  "hash_calculate, HW enabled");
177 	TEST_SUCC(memcmp(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)),
178 		  "  got the right hash");
179 	TEST_EQ(mock_hash.algo, VB2_HASH_SHA1, "  algo set");
180 
181 	reset_common_data(HWCRYPTO_ERROR);
182 	TEST_EQ(vb2_hash_calculate(true, mock_buffer, sizeof(mock_buffer),
183 				   VB2_HASH_SHA1, &mock_hash),
184 		VB2_ERROR_MOCK, "hash_calculate, HW error");
185 
186 	reset_common_data(HWCRYPTO_NOTSUPPORTED);
187 	TEST_SUCC(vb2_hash_calculate(true, mock_buffer, sizeof(mock_buffer),
188 				     VB2_HASH_SHA1, &mock_hash),
189 		  "hash_calculate, HW unsupported");
190 	TEST_SUCC(memcmp(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)),
191 		  "  got the right hash");
192 
193 	reset_common_data(HWCRYPTO_OK);
194 	memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1));
195 	mock_hash.algo = VB2_HASH_SHA1;
196 	TEST_SUCC(vb2_hash_verify(true, mock_buffer, sizeof(mock_buffer),
197 				  &mock_hash), "hash_verify, HW enabled");
198 
199 	memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1));
200 	mock_hash.sha1[5] = 0xfe;
201 	mock_hash.algo = VB2_HASH_SHA1;
202 	TEST_EQ(vb2_hash_verify(true, mock_buffer, sizeof(mock_buffer),
203 				&mock_hash), VB2_ERROR_SHA_MISMATCH,
204 		"hash_verify HW mismatch");
205 }
206 
main(int argc,char * argv[])207 int main(int argc, char *argv[])
208 {
209 	TEST_EQ(sizeof(mock_hash),
210 		offsetof(struct vb2_hash, raw) + VB2_SHA512_DIGEST_SIZE,
211 		"tests run with all SHA algorithms enabled");
212 
213 	vb2_hash_cbfs_compatibility_test();
214 	vb2_hash_calculate_tests();
215 	vb2_hash_verify_tests();
216 	vb2_hash_hwcrypto_tests();
217 
218 	return gTestSuccess ? 0 : 255;
219 }
220