xref: /aosp_15_r20/external/vboot_reference/firmware/2lib/2sha_utility.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1 /* Copyright 2014 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  * Utility functions for message digest functions.
6  */
7 
8 #include "2common.h"
9 #include "2sha.h"
10 #include "2sysincludes.h"
11 
vb2_digest_size(enum vb2_hash_algorithm hash_alg)12 size_t vb2_digest_size(enum vb2_hash_algorithm hash_alg)
13 {
14 	switch (hash_alg) {
15 #if VB2_SUPPORT_SHA1
16 	case VB2_HASH_SHA1:
17 		return VB2_SHA1_DIGEST_SIZE;
18 #endif
19 #if VB2_SUPPORT_SHA256
20 	case VB2_HASH_SHA224:
21 		return VB2_SHA224_DIGEST_SIZE;
22 	case VB2_HASH_SHA256:
23 		return VB2_SHA256_DIGEST_SIZE;
24 #endif
25 #if VB2_SUPPORT_SHA512
26 	case VB2_HASH_SHA384:
27 		return VB2_SHA384_DIGEST_SIZE;
28 	case VB2_HASH_SHA512:
29 		return VB2_SHA512_DIGEST_SIZE;
30 #endif
31 	default:
32 		return 0;
33 	}
34 }
35 
vb2_hash_block_size(enum vb2_hash_algorithm alg)36 size_t vb2_hash_block_size(enum vb2_hash_algorithm alg)
37 {
38 	switch (alg) {
39 #if VB2_SUPPORT_SHA1
40 	case VB2_HASH_SHA1:
41 		return VB2_SHA1_BLOCK_SIZE;
42 #endif
43 #if VB2_SUPPORT_SHA256
44 	case VB2_HASH_SHA224:	/* SHA224 reuses SHA256 internal structures */
45 	case VB2_HASH_SHA256:
46 		return VB2_SHA256_BLOCK_SIZE;
47 #endif
48 #if VB2_SUPPORT_SHA512
49 	case VB2_HASH_SHA384:	/* SHA384 reuses SHA512 internal structures */
50 	case VB2_HASH_SHA512:
51 		return VB2_SHA512_BLOCK_SIZE;
52 #endif
53 	default:
54 		return 0;
55 	}
56 }
57 
58 test_mockable
vb2_digest_init(struct vb2_digest_context * dc,bool allow_hwcrypto,enum vb2_hash_algorithm algo,uint32_t data_size)59 vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, bool allow_hwcrypto,
60 			    enum vb2_hash_algorithm algo, uint32_t data_size)
61 {
62 	const char msg[] = "%u bytes, hash algo %d, HW acceleration %s";
63 
64 	dc->hash_alg = algo;
65 	dc->using_hwcrypto = 0;
66 
67 	if (allow_hwcrypto) {
68 		vb2_error_t rv = vb2ex_hwcrypto_digest_init(algo, data_size);
69 		if (rv == VB2_SUCCESS) {
70 			VB2_DEBUG(msg, data_size, algo, "enabled\n");
71 			dc->using_hwcrypto = 1;
72 			return VB2_SUCCESS;
73 		}
74 		if (rv != VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED) {
75 			VB2_DEBUG(msg, data_size, algo, "initialization error");
76 			VB2_DEBUG_RAW(": %#x\n", rv);
77 			return rv;
78 		}
79 		VB2_DEBUG(msg, data_size, algo, "unsupported\n");
80 	} else {
81 		VB2_DEBUG(msg, data_size, algo, "forbidden\n");
82 	}
83 
84 	switch (algo) {
85 #if VB2_SUPPORT_SHA1
86 	case VB2_HASH_SHA1:
87 		vb2_sha1_init(&dc->sha1);
88 		return VB2_SUCCESS;
89 #endif
90 #if VB2_SUPPORT_SHA256
91 	case VB2_HASH_SHA224:
92 	case VB2_HASH_SHA256:
93 		vb2_sha256_init(&dc->sha256, algo);
94 		return VB2_SUCCESS;
95 #endif
96 #if VB2_SUPPORT_SHA512
97 	case VB2_HASH_SHA384:
98 	case VB2_HASH_SHA512:
99 		vb2_sha512_init(&dc->sha512, algo);
100 		return VB2_SUCCESS;
101 #endif
102 	default:
103 		return VB2_ERROR_SHA_INIT_ALGORITHM;
104 	}
105 }
106 
107 test_mockable
vb2_digest_extend(struct vb2_digest_context * dc,const uint8_t * buf,uint32_t size)108 vb2_error_t vb2_digest_extend(struct vb2_digest_context *dc, const uint8_t *buf,
109 			      uint32_t size)
110 {
111 	if (dc->using_hwcrypto)
112 		return vb2ex_hwcrypto_digest_extend(buf, size);
113 
114 	switch (dc->hash_alg) {
115 #if VB2_SUPPORT_SHA1
116 	case VB2_HASH_SHA1:
117 		vb2_sha1_update(&dc->sha1, buf, size);
118 		return VB2_SUCCESS;
119 #endif
120 #if VB2_SUPPORT_SHA256
121 	case VB2_HASH_SHA224:
122 	case VB2_HASH_SHA256:
123 		vb2_sha256_update(&dc->sha256, buf, size);
124 		return VB2_SUCCESS;
125 #endif
126 #if VB2_SUPPORT_SHA512
127 	case VB2_HASH_SHA384:
128 	case VB2_HASH_SHA512:
129 		vb2_sha512_update(&dc->sha512, buf, size);
130 		return VB2_SUCCESS;
131 #endif
132 	default:
133 		return VB2_ERROR_SHA_EXTEND_ALGORITHM;
134 	}
135 }
136 
137 test_mockable
vb2_digest_finalize(struct vb2_digest_context * dc,uint8_t * digest,uint32_t digest_size)138 vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest,
139 				uint32_t digest_size)
140 {
141 	if (dc->using_hwcrypto)
142 		return vb2ex_hwcrypto_digest_finalize(digest, digest_size);
143 
144 	if (digest_size < vb2_digest_size(dc->hash_alg))
145 		return VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE;
146 
147 	switch (dc->hash_alg) {
148 #if VB2_SUPPORT_SHA1
149 	case VB2_HASH_SHA1:
150 		vb2_sha1_finalize(&dc->sha1, digest);
151 		return VB2_SUCCESS;
152 #endif
153 #if VB2_SUPPORT_SHA256
154 	case VB2_HASH_SHA224:
155 	case VB2_HASH_SHA256:
156 		vb2_sha256_finalize(&dc->sha256, digest, dc->hash_alg);
157 		return VB2_SUCCESS;
158 #endif
159 #if VB2_SUPPORT_SHA512
160 	case VB2_HASH_SHA384:
161 	case VB2_HASH_SHA512:
162 		vb2_sha512_finalize(&dc->sha512, digest, dc->hash_alg);
163 		return VB2_SUCCESS;
164 #endif
165 	default:
166 		return VB2_ERROR_SHA_FINALIZE_ALGORITHM;
167 	}
168 }
169 
vb2_hash_calculate(bool allow_hwcrypto,const void * buf,uint32_t size,enum vb2_hash_algorithm algo,struct vb2_hash * hash)170 vb2_error_t vb2_hash_calculate(bool allow_hwcrypto, const void *buf,
171 			       uint32_t size, enum vb2_hash_algorithm algo,
172 			       struct vb2_hash *hash)
173 {
174 	struct vb2_digest_context dc;
175 	hash->algo = algo;
176 
177 	VB2_TRY(vb2_digest_init(&dc, allow_hwcrypto, algo, size));
178 	VB2_TRY(vb2_digest_extend(&dc, buf, size));
179 
180 	return vb2_digest_finalize(&dc, hash->raw, vb2_digest_size(algo));
181 }
182 
vb2_hash_verify(bool allow_hwcrypto,const void * buf,uint32_t size,const struct vb2_hash * hash)183 vb2_error_t vb2_hash_verify(bool allow_hwcrypto, const void *buf, uint32_t size,
184 			    const struct vb2_hash *hash)
185 {
186 	struct vb2_hash tmp;
187 
188 	VB2_TRY(vb2_hash_calculate(allow_hwcrypto, buf, size, hash->algo, &tmp));
189 	if (memcmp(tmp.raw, hash->raw, vb2_digest_size(hash->algo)))
190 		return VB2_ERROR_SHA_MISMATCH;
191 	else
192 		return VB2_SUCCESS;
193 }
194