xref: /openbmc/google-misc/subprojects/libcr51sign/include/libcr51sign/libcr51sign.h (revision 0155b43110b09f75c326ac306888aa4ce0eb1238)
1 /*
2  * Copyright 2021 Google LLC
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef PLATFORMS_HAVEN_LIBCR51SIGN_LIBCR51SIGN_H_
17 #define PLATFORMS_HAVEN_LIBCR51SIGN_LIBCR51SIGN_H_
18 
19 #include <libcr51sign/cr51_image_descriptor.h>
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #ifdef __cplusplus
25 extern "C"
26 {
27 #endif
28 
29 #define LIBCR51SIGN_SHA256_DIGEST_SIZE 32
30 #define LIBCR51SIGN_SHA512_DIGEST_SIZE 64
31 
32 #define LIBCR51SIGN_MAX_REGION_COUNT 16
33 
34 // Currently RSA4096 (in bytes).
35 #define LIBCR51SIGN_MAX_SIGNATURE_SIZE 512
36 
37 // LINT.IfChange(image_mauv_max_size_def)
38 #define IMAGE_MAUV_DATA_MAX_SIZE (128)
39 // LINT.ThenChange()
40 
41 // State of the image.
42 enum libcr51sign_validation_state
43 {
44     LIBCR51SIGN_IMAGE_UNSPECIFIED = 0,
45     // The image fails at least one descriptor or region check.
46     LIBCR51SIGN_IMAGE_INVALID = 1,
47     // The image passes all descriptor and region checks. Note that this does
48     // not mean that the image is valid for update. For example, the image may
49     // not pass MAUV checks.
50     LIBCR51SIGN_IMAGE_VALID = 2,
51 };
52 
53 // List of common error codes that can be returned
54 enum libcr51sign_validation_failure_reason
55 {
56     // All PayloadRegionState fields are valid & authenticated.
57     LIBCR51SIGN_SUCCESS = 0,
58 
59     // Descriptor sanity check failed. None of the following
60     // PayloadRegionState fields are valid/populated.
61     LIBCR51SIGN_ERROR_RUNTIME_FAILURE = 1,
62     LIBCR51SIGN_ERROR_UNSUPPORTED_DESCRIPTOR = 2,
63     LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR = 3,
64 
65     // All fields are populated but may not be authentic.
66     LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY = 4,
67     LIBCR51SIGN_ERROR_IMAGE_TYPE_DISALLOWED = 5,
68     LIBCR51SIGN_ERROR_DEV_DOWNGRADE_DISALLOWED = 6,
69     LIBCR51SIGN_ERROR_UNTRUSTED_KEY = 7,
70     LIBCR51SIGN_ERROR_INVALID_SIGNATURE = 8,
71     LIBCR51SIGN_ERROR_INVALID_HASH = 9,
72     LIBCR51SIGN_ERROR_INVALID_HASH_TYPE = 10,
73     // Invalid argument
74     LIBCR51SIGN_ERROR_INVALID_ARGUMENT = 11,
75     LIBCR51SIGN_ERROR_FAILED_TO_LOCATE_MAGIC = 12,
76     LIBCR51SIGN_ERROR_INVALID_CONTEXT = 13,
77     LIBCR51SIGN_ERROR_INVALID_INTERFACE = 14,
78     LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME = 15,
79     // Invalid image region
80     LIBCR51SIGN_ERROR_INVALID_REGION_INPUT = 16,
81     LIBCR51SIGN_ERROR_INVALID_REGION_SIZE = 17,
82     LIBCR51SIGN_ERROR_INVALID_IMAGE_MAUV_DATA = 18,
83     LIBCR51SIGN_ERROR_RETRIEVING_STORED_IMAGE_MAUV_DATA = 19,
84     LIBCR51SIGN_ERROR_STORING_NEW_IMAGE_MAUV_DATA = 20,
85     LIBCR51SIGN_ERROR_STORED_IMAGE_MAUV_DOES_NOT_ALLOW_UPDATE_TO_PAYLOAD = 21,
86     LIBCR51SIGN_ERROR_VALID_IMAGE_BUT_NEW_IMAGE_MAUV_DATA_NOT_STORED = 22,
87     LIBCR51SIGN_ERROR_STORED_IMAGE_MAUV_EXPECTS_PAYLOAD_IMAGE_MAUV = 23,
88     // Client did not find any stored MAUV in system
89     LIBCR51SIGN_NO_STORED_MAUV_FOUND = 24,
90     LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR_BLOBS = 25,
91     LIBCR51SIGN_ERROR_MAX = 26,
92 };
93 
94 struct libcr51sign_ctx
95 {
96     // Expectations needed to validate an image. Users must set these fields
97     // before calling libcr51sign_validate().
98     uint32_t start_offset;                  // Absolute image start offset
99     uint32_t end_offset;                    // Absolute image end offset
100     enum image_family current_image_family; // Expected image family
101     enum image_type current_image_type;     // Expected image type
102     int keyring_len;     // keyring_len - number of keys in @a keyring
103     const void* keyring; // keyring - array of pointers to public keys
104     void* priv;          // opaque context data (used for hash state)
105 
106     // Data that is accessible if the image is valid after calling
107     // libcr51sign_validate().
108     enum libcr51sign_validation_state validation_state;
109     size_t* valid_key; // valid_key - index of valid key
110     // Note: `descriptor` needs to be the last member of this struct due to the
111     // flexible array member in struct image_descriptor.
112     struct image_descriptor descriptor; // Cr51 image descriptor.
113 };
114 
115 struct libcr51sign_intf
116 {
117     // @func read read data from the image into a buffer
118     //
119     // @param[in] ctx - context struct
120     // @param[in] offset - bytes to seek into the image before reading
121     // @param[in] count - number of bytes to read
122     // @param[out] buf - pointer to buffer where result will be written
123     //
124     // @return nonzero on error, zero on success
125 
126     int (*read)(const void*, uint32_t, uint32_t, uint8_t*);
127 
128     // @func hash_init get ready to compute a hash
129     //
130     // @param[in] ctx - context struct
131     // @param[in] hash_type - type of hash function to use
132     //
133     // @return nonzero on error, zero on success
134 
135     int (*hash_init)(const void*, enum hash_type);
136 
137     // @func hash_update add data to the hash
138     //
139     // @param[in] ctx - context struct
140     // @param[in] buf - data to add to hash
141     // @param[in] count - number of bytes of data to add
142     // @param[in] hash_type - type of hash function to use
143     //
144     // @return nonzero on error, zero on success
145 
146     int (*hash_update)(void*, const uint8_t*, size_t);
147 
148     // Note this is a combination of an spi_nor_read() with spi_transaction()
149     // It is the responsibility of the caller to synchronize with other
150     // potential SPI clients / transactions. Collapsing the SPI stack results in
151     // a 2x throughput improvement (~20s -> ~10s to verify an Indus image with
152     // SHA256 HW acceleration).
153     //
154     // The caller is responsible for calling DCRYPTO_init()/HASH_final().
155 
156     int (*read_and_hash_update)(void* ctx, uint32_t offset, uint32_t size);
157 
158     // @func hash_final finish hash calculation
159     //
160     // @param[in] ctx - context struct
161     // @param[out] hash - buffer to write hash to
162     // @param[in] hash_type - type of hash function to use
163     //
164     // @return nonzero on error, zero on success
165 
166     int (*hash_final)(void*, uint8_t*);
167 
168     // @func verify check that the signature is valid for given hashed data
169     //
170     // @param[in] ctx - context struct
171     // @param[in] scheme - type of signature, hash, etc.
172     // @param[in] sig - signature blob
173     // @param[in] sig_len - length of signature in bytes
174     // @param[in] data - pre-hashed data to verify
175     // @param[in] data_len - length of hashed data in bytes
176     //
177     // @return nonzero on error, zero on success
178 
179     int (*verify_signature)(const void*, enum signature_scheme, const uint8_t*,
180                             size_t, const uint8_t*, size_t);
181 
182     // @func verify check that if the prod to dev downgrade/ hardware allowlist
183     // is allowed
184     // @return  true: if allowed
185     //          false: if not allowed
186     // BMC would return always false or pass a NULL pointer
187     // If NULL, treated as if the function always returns false.
188 
189     bool (*prod_to_dev_downgrade_allowed)();
190 
191     // @func returns true if the current firmware is running in production mode.
192     // @return true: if in production mode
193     //         false: if in any non-production mode
194 
195     bool (*is_production_mode)();
196 
197     // @func returns true if the descriptor image size is valid.
198     bool (*image_size_valid)(size_t);
199 
200     // @func Retrieve MAUV data currently stored in the system
201     // @param[in]  ctx - context struct
202     // @param[out] current_image_mauv - Buffer to store the retrieved MAUV data
203     // @param[out] current_image_mauv_size - Number of bytes retrieved and
204     // stored
205     //                                       in `current_image_mauv`
206     // @param[in]  max_image_mauv_size - Maximum number of bytes to retrieve for
207     //                                   MAUV data
208     //
209     // @return LIBCR51SIGN_SUCCESS: when MAUV is present in the system and
210     //                              retrieved successfully
211     //         LIBCR51SIGN_NO_STORED_MAUV_FOUND: when MAUV is not present in the
212     //                                           system (we are trusting the
213     //                                           client here to return this
214     //                                           value truthfully)
215     //         other non-zero values: any other error scenario (like read
216     //         failure,
217     //                                data corruption, etc.)
218     int (*retrieve_stored_image_mauv_data)(const void*, uint8_t* const,
219                                            uint32_t* const, const uint32_t);
220 
221     // @func Store new MAUV data in the system
222     // @param[in]  ctx - context struct
223     // @param[in]  new_image_mauv - Buffer containing new MAUV data to be stored
224     // @param[in]  new_image_mauv_size - Size of MAUV data in `new_image_mauv`
225     //                                   buffer
226     //
227     // @return LIBCR51SIGN_SUCCESS: when new MAUV data is stored successfully.
228     //                              Non-zero value otherwise
229     int (*store_new_image_mauv_data)(const void*, const uint8_t* const,
230                                      const uint32_t);
231 
232     // @func trust descriptor hash
233     // @param[in]  ctx - context struct
234     // @param[in]  descriptor_hash - Buffer containing descriptor hash
235     // @param[in]  descriptor_hash_size - Size of descriptor hash
236     //
237     // @return true: if the external key is trusted
238     //         false: if the external key is not trusted
239     bool (*trust_descriptor_hash)(const void*, const uint8_t*, size_t);
240 
241     // @func Trust key in the signature structure
242     // @param[in]  ctx - context struct
243     // @param[in]  scheme - signature scheme
244     // @param[in]  signature_structure - signature structure
245     // @param[in]  signature_structure_size - Size of signature structure in
246     // bytes
247     //
248     // @return true: if the key in signature structure is trusted
249     //         false: if the key in signature structure is not trusted
250     bool (*trust_key_in_signature_structure)(
251         void*, enum signature_scheme scheme, const void*, size_t);
252 
253     // @func Verify RSA signature with modulus and exponent
254     // @param[in]  ctx - context struct
255     // @param[in]  sig_scheme - signature scheme
256     // @param[in]  modulus - modulus of the RSA key, MSB (big-endian)
257     // @param[in]  modulus_len - length of modulus in bytes
258     // @param[in]  exponent - exponent of the RSA key
259     // @param[in]  sig - signature blob
260     // @param[in]  sig_len - length of signature in bytes
261     // @param[in]  digest - digest to verify
262     // @param[in]  digest_len - digest size
263     //
264     // @return true: if the signature is verified
265     //         false: otherwise
266     bool (*verify_rsa_signature_with_modulus_and_exponent)(
267         const void* ctx, enum signature_scheme scheme, const uint8_t* modulus,
268         int modulus_len, uint32_t exponent, const uint8_t* sig, int sig_len,
269         const uint8_t* digest, int digest_len);
270 };
271 
272 struct libcr51sign_validated_regions
273 {
274     uint32_t region_count;
275     struct image_region image_regions[LIBCR51SIGN_MAX_REGION_COUNT];
276 };
277 
278 // Check whether the signature on the image is valid.
279 // Validates the authenticity of an EEPROM image. Scans for & validates the
280 // signature on the image descriptor. If the descriptor validates, hashes the
281 // rest of the image to verify its integrity.
282 //
283 // @param[in] ctx - context which describes the image and holds opaque private
284 //                  data for the user of the library
285 // @param[in] intf - function pointers which interface to the current system
286 //                   and environment
287 // @param[out] image_regions - image_region pointer to an array for the output
288 //
289 // @return nonzero on error, zero on success
290 
291 enum libcr51sign_validation_failure_reason libcr51sign_validate(
292     struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf,
293     struct libcr51sign_validated_regions* image_regions);
294 
295 // Function to convert error code to string format
296 // @param[in] ec - error code
297 // @return error code in string format
298 
299 const char* libcr51sign_errorcode_to_string(
300     enum libcr51sign_validation_failure_reason ec);
301 
302 // Returns the hash_type for a given signature scheme
303 // @param[in] scheme - signature scheme
304 // @param[out] type - hash_type supported by given signature_scheme
305 //
306 // @return nonzero on error, zero on success
307 
308 enum libcr51sign_validation_failure_reason get_hash_type_from_signature(
309     enum signature_scheme scheme, enum hash_type* type);
310 
311 #ifdef __cplusplus
312 } //  extern "C"
313 #endif
314 
315 #endif // PLATFORMS_HAVEN_LIBCR51SIGN_LIBCR51SIGN_H_
316