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