xref: /aosp_15_r20/external/vboot_reference/firmware/2lib/include/2sha.h (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  * These APIs may be called by external firmware as well as vboot.  External
6  * firmware must NOT include this header file directly; instead, import
7  * the external-facing vb2_sha.h.  This is permissible because the
8  * SHA library routines below don't interact with the rest of vboot.
9  */
10 
11 #ifndef VBOOT_REFERENCE_2SHA_H_
12 #define VBOOT_REFERENCE_2SHA_H_
13 
14 #include "2crypto.h"
15 #include "2return_codes.h"
16 
17 /* Hash algorithms may be disabled individually to save code space */
18 
19 #ifndef VB2_SUPPORT_SHA1
20 #define VB2_SUPPORT_SHA1 1
21 #endif
22 
23 #ifndef VB2_SUPPORT_SHA256
24 #define VB2_SUPPORT_SHA256 1
25 #endif
26 
27 #ifndef VB2_SUPPORT_SHA512
28 #define VB2_SUPPORT_SHA512 1
29 #endif
30 
31 /* These are set to the biggest values among the supported hash algorithms.
32  * They have to be updated as we add new hash algorithms */
33 #define VB2_MAX_DIGEST_SIZE	VB2_SHA512_DIGEST_SIZE
34 #define VB2_MAX_BLOCK_SIZE	VB2_SHA512_BLOCK_SIZE
35 #define VB2_INVALID_ALG_NAME	"INVALID"
36 
37 #define VB2_SHA1_DIGEST_SIZE 20
38 #define VB2_SHA1_BLOCK_SIZE 64
39 #define VB2_SHA1_ALG_NAME	"SHA1"
40 
41 /* Context structs for hash algorithms */
42 
43 struct vb2_sha1_context {
44 	uint32_t count;
45 	uint32_t state[5];
46 #if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
47 	union {
48 		uint8_t b[VB2_SHA1_BLOCK_SIZE];
49 		uint32_t w[VB2_SHA1_BLOCK_SIZE / sizeof(uint32_t)];
50 	} buf;
51 #else
52 	uint8_t buf[VB2_SHA1_BLOCK_SIZE];
53 #endif
54 };
55 
56 #define VB2_SHA256_DIGEST_SIZE 32
57 #define VB2_SHA256_BLOCK_SIZE 64
58 #define VB2_SHA256_ALG_NAME	"SHA256"
59 
60 struct vb2_sha256_context {
61 	uint32_t h[8];
62 	uint32_t total_size;
63 	uint32_t size;
64 	uint8_t block[2 * VB2_SHA256_BLOCK_SIZE];
65 };
66 
67 #define VB2_SHA512_DIGEST_SIZE 64
68 #define VB2_SHA512_BLOCK_SIZE 128
69 #define VB2_SHA512_ALG_NAME	"SHA512"
70 
71 struct vb2_sha512_context {
72 	uint64_t h[8];
73 	uint32_t total_size;
74 	uint32_t size;
75 	uint8_t block[2 * VB2_SHA512_BLOCK_SIZE];
76 };
77 
78 /*
79  * SHA224/SHA384 are variants of SHA256/SHA512 that use almost all the same code
80  * (and the same context structures), so no separate "SUPPORT" flags for them.
81  */
82 #define VB2_SHA224_DIGEST_SIZE 28
83 #define VB2_SHA224_ALG_NAME "SHA224"
84 #define VB2_SHA384_DIGEST_SIZE 48
85 #define VB2_SHA384_ALG_NAME "SHA384"
86 
87 /* Hash algorithm independent digest context; includes all of the above. */
88 struct vb2_digest_context {
89 	/* Context union for all algorithms */
90 	union {
91 #if VB2_SUPPORT_SHA1
92 		struct vb2_sha1_context sha1;
93 #endif
94 #if VB2_SUPPORT_SHA256
95 		struct vb2_sha256_context sha256;
96 #endif
97 #if VB2_SUPPORT_SHA512
98 		struct vb2_sha512_context sha512;
99 #endif
100 	};
101 
102 	/* Current hash algorithm */
103 	enum vb2_hash_algorithm hash_alg;
104 
105 	/* `true` if digest is computed with vb2ex_hwcrypto routines */
106 	bool using_hwcrypto;
107 };
108 
109 /*
110  * Serializable data structure that can store any vboot hash. Layout used in
111  * CBFS attributes that need to be backwards-compatible -- do not change!
112  * When serializing/deserizaling this, you should store/load (offsetof(raw) +
113  * vb2_digest_size(algo)), not the full size of this structure. vboot functions
114  * taking a pointer to this should only access the |raw| array up to
115  * vb2_digest_size(algo) and not assume that the whole structure is accessible.
116  */
117 struct vb2_hash {
118 	/* Padding to match existing 4-byte big-endian from CBFS.
119 	   Could be reused for other stuff later (e.g. flags or something). */
120 	uint8_t reserved[3];
121 	/* enum vb2_hash_algorithm. Single byte to avoid endianness issues. */
122 	uint8_t algo;
123 	/* The actual digest. Can add new types here as required. */
124 	union {
125 		uint8_t raw[0];
126 #if VB2_SUPPORT_SHA1
127 		uint8_t sha1[VB2_SHA1_DIGEST_SIZE];
128 #endif
129 #if VB2_SUPPORT_SHA256
130 		uint8_t sha256[VB2_SHA256_DIGEST_SIZE];
131 #endif
132 #if VB2_SUPPORT_SHA512
133 		uint8_t sha512[VB2_SHA512_DIGEST_SIZE];
134 #endif
135 	};
136 };
137 _Static_assert(sizeof(struct vb2_hash) - offsetof(struct vb2_hash, raw)
138 	<= VB2_MAX_DIGEST_SIZE, "Update VB2_MAX_DIGEST_SIZE for new digests!");
139 _Static_assert(VB2_HASH_ALG_COUNT <= UINT8_MAX, "vb2_hash.algo overflow!");
140 
141 /**
142  * Initialize a hash context.
143  *
144  * @param ctx		Hash context
145  * @param algo		Hash algorithm (only for overloaded functions)
146  */
147 void vb2_sha1_init(struct vb2_sha1_context *ctx);
148 void vb2_sha256_init(struct vb2_sha256_context *ctx,
149 		     enum vb2_hash_algorithm algo);
150 void vb2_sha512_init(struct vb2_sha512_context *ctx,
151 		     enum vb2_hash_algorithm algo);
152 
153 /**
154  * Update (extend) a hash.
155  *
156  * @param ctx		Hash context
157  * @param data		Data to hash
158  * @param size		Length of data in bytes
159  */
160 void vb2_sha1_update(struct vb2_sha1_context *ctx,
161 		     const uint8_t *data,
162 		     uint32_t size);
163 void vb2_sha256_update(struct vb2_sha256_context *ctx,
164 		       const uint8_t *data,
165 		       uint32_t size);
166 void vb2_sha512_update(struct vb2_sha512_context *ctx,
167 		       const uint8_t *data,
168 		       uint32_t size);
169 
170 /**
171  * Finalize a hash digest.
172  *
173  * @param ctx		Hash context
174  * @param digest	Destination for hash; must be VB_SHA*_DIGEST_SIZE bytes
175  * @param algo		Hash algorithm (only for overloaded functions)
176  */
177 void vb2_sha1_finalize(struct vb2_sha1_context *ctx, uint8_t *digest);
178 void vb2_sha256_finalize(struct vb2_sha256_context *ctx, uint8_t *digest,
179 			 enum vb2_hash_algorithm algo);
180 void vb2_sha512_finalize(struct vb2_sha512_context *ctx, uint8_t *digest,
181 			 enum vb2_hash_algorithm algo);
182 
183 /**
184  * Hash-extend data
185  *
186  * @param from	Hash to be extended. It has to be the hash size.
187  * @param by	Block to be extended by. It has to be the hash block size.
188  * @param to	Destination for extended data
189  */
190 void vb2_sha256_extend(const uint8_t *from, const uint8_t *by, uint8_t *to);
191 
192 /**
193  * Return the size of the digest for a hash algorithm.
194  *
195  * @param hash_alg	Hash algorithm
196  * @return The size of the digest, or 0 if error.
197  */
198 size_t vb2_digest_size(enum vb2_hash_algorithm hash_alg);
199 
200 /**
201  * Return the block size of a hash algorithm.
202  *
203  * @param hash_alg	Hash algorithm
204  * @return The block size of the algorithm, or 0 if error.
205  */
206 size_t vb2_hash_block_size(enum vb2_hash_algorithm alg);
207 
208 /**
209  * Initialize a digest context for doing block-style digesting, potentially
210  * making use of the vb2ex_hwcrypto APIs. Whether HW crypto is allowed by policy
211  * in the current context depends on the caller and can be passed in. If HW
212  * crypto is not allowed or not supported, will automatically fall back to SW.
213  *
214  * @param dc		Digest context
215  * @param allow_hwcrypto  false to forbid HW crypto by policy; true to allow.
216  * @param algo		Hash algorithm
217  * @return VB2_SUCCESS, or non-zero on error.
218  */
219 vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, bool allow_hwcrypto,
220 			    enum vb2_hash_algorithm algo, uint32_t data_size);
221 
222 /**
223  * Extend a digest's hash with another block of data.
224  *
225  * @param dc		Digest context
226  * @param buf		Data to hash
227  * @param size		Length of data in bytes
228  * @return VB2_SUCCESS, or non-zero on error.
229  */
230 vb2_error_t vb2_digest_extend(struct vb2_digest_context *dc, const uint8_t *buf,
231 			      uint32_t size);
232 
233 /**
234  * Finalize a digest and store the result.
235  *
236  * The destination digest should be at least vb2_digest_size(algorithm).
237  *
238  * @param dc		Digest context
239  * @param digest	Destination for digest
240  * @param digest_size	Length of digest buffer in bytes.
241  * @return VB2_SUCCESS, or non-zero on error.
242  */
243 vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc,
244 				uint8_t *digest, uint32_t digest_size);
245 
246 /**
247  * Fill a vb2_hash structure with the hash of a buffer.
248  *
249  * @param allow_hwcrypto  false to forbid HW crypto by policy; true to allow.
250  * @param buf		Buffer to hash
251  * @param size		Size of |buf| in bytes
252  * @param algo		The hash algorithm to use (and store in |hash|)
253  * @param hash		vb2_hash structure to fill with the hash of |buf|
254  * @return VB2_SUCCESS, or non-zero on error.
255  */
256 vb2_error_t vb2_hash_calculate(bool allow_hwcrypto, const void *buf,
257 			       uint32_t size, enum vb2_hash_algorithm algo,
258 			       struct vb2_hash *hash);
259 
260 /**
261  * Verify that a vb2_hash matches a buffer.
262  *
263  * @param allow_hwcrypto  false to forbid HW crypto by policy; true to allow.
264  * @param buf		Buffer to hash and match to |hash|
265  * @param size		Size of |buf| in bytes
266  * @param hash		Hash to compare to the buffer
267  * @return VB2_SUCCESS if hash matches, VB2_ERROR_SHA_MISMATCH if hash doesn't
268  *  match, or non-zero on other error.
269  */
270 vb2_error_t vb2_hash_verify(bool allow_hwcrypto, const void *buf, uint32_t size,
271 			    const struct vb2_hash *hash);
272 
273 #endif  /* VBOOT_REFERENCE_2SHA_H_ */
274