xref: /openbmc/google-misc/subprojects/libcr51sign/src/libcr51sign.c (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 #include <assert.h>
17 #include <libcr51sign/cr51_image_descriptor.h>
18 #include <libcr51sign/libcr51sign.h>
19 #include <libcr51sign/libcr51sign_internal.h>
20 #include <libcr51sign/libcr51sign_mauv.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #ifdef __cplusplus
28 extern "C"
29 {
30 #endif
31 
32 // True of x is a power of two
33 #define POWER_OF_TWO(x) ((x) && !((x) & ((x) - 1)))
34 
35 // Maximum version supported. Major revisions are not backwards compatible.
36 #define MAX_MAJOR_VERSION 1
37 
38 // Descriptor alignment on the external EEPROM.
39 #define DESCRIPTOR_ALIGNMENT (64 * 1024)
40 
41 // SPS EEPROM sector size is 4KiB, since this is the smallest erasable size.
42 #define IMAGE_REGION_ALIGNMENT 4096
43 
44 #define MAX_READ_SIZE 1024
45 
46 #ifndef ARRAY_SIZE
47 #define ARRAY_SIZE(t) (sizeof(t) / sizeof(t[0]))
48 #endif
49 
50 // Values of SIGNATURE_OFFSET should be same for all sig types (2048,3072,4096)
51 #define SIGNATURE_OFFSET offsetof(struct signature_rsa3072_pkcs15, modulus)
52 
53 #ifndef BUILD_ASSERT
54 #define BUILD_ASSERT(cond) ((void)sizeof(char[1 - 2 * !(cond)]))
55 #endif
56 
57 // Returns the bytes size of keys used in the given signature_scheme.
58 // Return error if signature_scheme is invalid.
59 //
get_key_size(enum signature_scheme signature_scheme,uint16_t * key_size)60 static failure_reason get_key_size(enum signature_scheme signature_scheme,
61                                    uint16_t* key_size)
62 {
63     switch (signature_scheme)
64     {
65         case SIGNATURE_RSA2048_PKCS15:
66             *key_size = 256;
67             return LIBCR51SIGN_SUCCESS;
68         case SIGNATURE_RSA3072_PKCS15:
69             *key_size = 384;
70             return LIBCR51SIGN_SUCCESS;
71         case SIGNATURE_RSA4096_PKCS15:
72         case SIGNATURE_RSA4096_PKCS15_SHA512:
73             *key_size = 512;
74             return LIBCR51SIGN_SUCCESS;
75         default:
76             return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME;
77     }
78 }
79 
80 // Returns the hash_type for a given signature scheme
81 // Returns error if scheme is invalid.
get_hash_type_from_signature(enum signature_scheme scheme,enum hash_type * type)82 failure_reason get_hash_type_from_signature(enum signature_scheme scheme,
83                                             enum hash_type* type)
84 {
85     switch (scheme)
86     {
87         case SIGNATURE_RSA2048_PKCS15:
88         case SIGNATURE_RSA3072_PKCS15:
89         case SIGNATURE_RSA4096_PKCS15:
90             *type = HASH_SHA2_256;
91             return LIBCR51SIGN_SUCCESS;
92         case SIGNATURE_RSA4096_PKCS15_SHA512:
93             *type = HASH_SHA2_512;
94             return LIBCR51SIGN_SUCCESS;
95         default:
96             return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME;
97     }
98 }
99 
100 // Check if the given hash_type is supported.
101 // Returns error if hash_type is not supported.
is_hash_type_supported(enum hash_type type)102 static failure_reason is_hash_type_supported(enum hash_type type)
103 {
104     switch (type)
105     {
106         case HASH_SHA2_256:
107         case HASH_SHA2_512:
108             return LIBCR51SIGN_SUCCESS;
109         default:
110             return LIBCR51SIGN_ERROR_INVALID_HASH_TYPE;
111     }
112 }
113 
114 // Determines digest size for a given hash_type.
115 // Returns error if hash_type is not supported.
get_hash_digest_size(enum hash_type type,uint32_t * size)116 static failure_reason get_hash_digest_size(enum hash_type type, uint32_t* size)
117 {
118     switch (type)
119     {
120         case HASH_SHA2_256:
121             *size = LIBCR51SIGN_SHA256_DIGEST_SIZE;
122             return LIBCR51SIGN_SUCCESS;
123         case HASH_SHA2_512:
124             *size = LIBCR51SIGN_SHA512_DIGEST_SIZE;
125             return LIBCR51SIGN_SUCCESS;
126         default:
127             return LIBCR51SIGN_ERROR_INVALID_HASH_TYPE;
128     }
129 }
130 
131 // Determines hash struct size for a given hash_type.
132 // Returns error if hash_type is not supported.
get_hash_struct_size(enum hash_type type,uint32_t * size)133 static failure_reason get_hash_struct_size(enum hash_type type, uint32_t* size)
134 {
135     switch (type)
136     {
137         case HASH_SHA2_256:
138             *size = sizeof(struct hash_sha256);
139             return LIBCR51SIGN_SUCCESS;
140         case HASH_SHA2_512:
141             *size = sizeof(struct hash_sha512);
142             return LIBCR51SIGN_SUCCESS;
143         default:
144             return LIBCR51SIGN_ERROR_INVALID_HASH_TYPE;
145     }
146 }
147 
148 // Checks that:
149 //  - The signing key is trusted
150 //  - The target version is not denylisted
151 // If validating a staged update, also checks that:
152 //  - The target image family matches the current image family
153 //  - The image type transition is legal (i.e. dev -> *|| prod -> prod) or
154 //    alternatively that the hardware ID is allowlisted
155 // Assuming the caller has performed following:
156 // board_get_base_key_index();
157 // board_get_key_array
158 // Possible return codes:
159 // LIBCR51SIGN_SUCCESS = 0,
160 // LIBCR51SIGN_ERROR_RUNTIME_FAILURE = 1,
161 // LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR = 3,
162 // LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY = 4,
163 // LIBCR51SIGN_ERROR_IMAGE_TYPE_DISALLOWED = 5,
164 
validate_transition(const struct libcr51sign_ctx * ctx,const struct libcr51sign_intf * intf,uint32_t signature_struct_offset)165 static failure_reason validate_transition(const struct libcr51sign_ctx* ctx,
166                                           const struct libcr51sign_intf* intf,
167                                           uint32_t signature_struct_offset)
168 {
169     BUILD_ASSERT((offsetof(struct signature_rsa2048_pkcs15, modulus) ==
170                       SIGNATURE_OFFSET &&
171                   offsetof(struct signature_rsa3072_pkcs15, modulus) ==
172                       SIGNATURE_OFFSET &&
173                   offsetof(struct signature_rsa4096_pkcs15, modulus) ==
174                       SIGNATURE_OFFSET));
175 
176     // Read up to the modulus.
177     enum
178     {
179         read_len = SIGNATURE_OFFSET
180     };
181     uint32_t buffer[read_len / sizeof(uint32_t)];
182     int rv;
183     rv = intf->read(ctx, signature_struct_offset, read_len, (uint8_t*)buffer);
184     if (rv != LIBCR51SIGN_SUCCESS)
185     {
186         CPRINTS(ctx, "%s: failed to read signature struct\n", __FUNCTION__);
187         return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
188     }
189     if (*buffer != SIGNATURE_MAGIC)
190     {
191         CPRINTS(ctx, "%s: bad signature magic\n", __FUNCTION__);
192         return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
193     }
194 
195     if (ctx->descriptor.image_family != ctx->current_image_family &&
196         ctx->descriptor.image_family != IMAGE_FAMILY_ALL &&
197         ctx->current_image_family != IMAGE_FAMILY_ALL)
198     {
199         CPRINTS(ctx, "%s: invalid image family\n", __FUNCTION__);
200         return LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY;
201     }
202 
203     if (intf->is_production_mode == NULL)
204     {
205         CPRINTS(ctx, "%s: missing is_production_mode\n", __FUNCTION__);
206         return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
207     }
208     if (intf->is_production_mode() && (ctx->descriptor.image_type == IMAGE_DEV))
209     {
210         CPRINTS(ctx, "%s: checking exemption allowlist\n", __FUNCTION__);
211 
212         // If function is NULL or if the function call return false, return
213         // error
214         if (intf->prod_to_dev_downgrade_allowed == NULL ||
215             !intf->prod_to_dev_downgrade_allowed())
216         {
217             CPRINTS(ctx, "%s: illegal image type\n", __FUNCTION__);
218             return LIBCR51SIGN_ERROR_DEV_DOWNGRADE_DISALLOWED;
219         }
220     }
221     return LIBCR51SIGN_SUCCESS;
222 }
223 
224 // If caller had provided read_and_hash_update call that, otherwise call read
225 // and then update.
226 
read_and_hash_update(struct libcr51sign_ctx * ctx,const struct libcr51sign_intf * intf,uint32_t offset,uint32_t size)227 static failure_reason read_and_hash_update(struct libcr51sign_ctx* ctx,
228                                            const struct libcr51sign_intf* intf,
229                                            uint32_t offset, uint32_t size)
230 {
231     uint8_t read_buffer[MAX_READ_SIZE];
232     int rv;
233     uint32_t read_size;
234 
235     if (intf->read_and_hash_update)
236     {
237         rv = intf->read_and_hash_update(ctx, offset, size);
238     }
239     else
240     {
241         if (!intf->hash_update)
242         {
243             CPRINTS(ctx, "%s: missing hash_update\n", __FUNCTION__);
244             return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
245         }
246         do
247         {
248             read_size = size < MAX_READ_SIZE ? size : MAX_READ_SIZE;
249             rv = intf->read(ctx, offset, read_size, read_buffer);
250             if (rv != LIBCR51SIGN_SUCCESS)
251             {
252                 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
253             }
254             rv = intf->hash_update(ctx, read_buffer, read_size);
255             if (rv != LIBCR51SIGN_SUCCESS)
256             {
257                 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
258             }
259             offset += read_size;
260             size -= read_size;
261         } while (size > 0);
262     }
263     return rv;
264 }
265 
266 // Validates the image_region array, namely that:
267 //  - The regions are aligned, contiguous & exhaustive
268 //  - That the image descriptor resides in a static region
269 //
270 // If the array is consistent, proceeds to hash the static regions and
271 // validates the hash. d_offset is the absolute image descriptor offset
272 
validate_payload_regions(struct libcr51sign_ctx * ctx,struct libcr51sign_intf * intf,uint32_t d_offset,struct libcr51sign_validated_regions * image_regions)273 static failure_reason validate_payload_regions(
274     struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf,
275     uint32_t d_offset, struct libcr51sign_validated_regions* image_regions)
276 {
277     // Allocate buffer to accommodate largest supported hash-type(SHA512)
278     uint8_t magic_and_digest[MEMBER_SIZE(struct hash_sha512, hash_magic) +
279                              LIBCR51SIGN_SHA512_DIGEST_SIZE];
280     uint8_t dcrypto_digest[LIBCR51SIGN_SHA512_DIGEST_SIZE];
281     uint32_t byte_count, region_count, image_size, hash_offset, digest_size;
282     uint32_t i;
283     uint32_t d_region_num = 0;
284     int rv;
285     struct image_region const* region;
286 
287     if (image_regions == NULL)
288     {
289         CPRINTS(ctx, "%s: Missing image region input\n", __FUNCTION__);
290         return LIBCR51SIGN_ERROR_INVALID_REGION_INPUT;
291     }
292 
293     BUILD_ASSERT((MEMBER_SIZE(struct hash_sha256, hash_magic) ==
294                   MEMBER_SIZE(struct hash_sha512, hash_magic)));
295     image_size = ctx->descriptor.image_size;
296     region_count = ctx->descriptor.region_count;
297     hash_offset = d_offset + sizeof(struct image_descriptor) +
298                   region_count * sizeof(struct image_region);
299     // Read the image_region array.
300 
301     if (region_count > ARRAY_SIZE(image_regions->image_regions))
302     {
303         CPRINTS(ctx,
304                 "%s: ctx->descriptor.region_count is greater "
305                 "than LIBCR51SIGN_MAX_REGION_COUNT\n",
306                 __FUNCTION__);
307         return LIBCR51SIGN_ERROR_INVALID_REGION_SIZE;
308     }
309 
310     rv = intf->read(ctx, d_offset + sizeof(struct image_descriptor),
311                     region_count * sizeof(struct image_region),
312                     (uint8_t*)&image_regions->image_regions);
313 
314     image_regions->region_count = region_count;
315 
316     if (rv != LIBCR51SIGN_SUCCESS)
317     {
318         CPRINTS(ctx, "%s: failed to read region array\n", __FUNCTION__);
319         return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
320     }
321 
322     // Validate that the regions are contiguous & exhaustive.
323     for (i = 0, byte_count = 0; i < region_count; i++)
324     {
325         region = image_regions->image_regions + i;
326 
327         CPRINTS(ctx, "%s: region #%d \"%s\" (%x - %x)\n", __FUNCTION__, i,
328                 (const char*)region->region_name, region->region_offset,
329                 region->region_offset + region->region_size);
330         if ((region->region_offset % IMAGE_REGION_ALIGNMENT) != 0 ||
331             (region->region_size % IMAGE_REGION_ALIGNMENT) != 0)
332         {
333             CPRINTS(ctx, "%s: regions must be sector aligned\n", __FUNCTION__);
334             return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
335         }
336         if (region->region_offset != byte_count ||
337             region->region_size > image_size - byte_count)
338         {
339             CPRINTS(ctx, "%s: invalid region array\n", __FUNCTION__);
340             return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
341         }
342         byte_count += region->region_size;
343         // The image descriptor must be part of a static region.
344         if (d_offset >= region->region_offset && d_offset < byte_count)
345         {
346             d_region_num = i;
347             CPRINTS(ctx, "%s: image descriptor in region %d\n", __FUNCTION__,
348                     i);
349             // The descriptor can't span regions.
350             if ((ctx->descriptor.descriptor_area_size >
351                  (byte_count - d_offset)) ||
352                 !(region->region_attributes & IMAGE_REGION_STATIC))
353             {
354                 CPRINTS(ctx,
355                         "%s: descriptor must reside in "
356                         "static region\n",
357                         __FUNCTION__);
358                 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
359             }
360         }
361     }
362     if (byte_count != image_size)
363     {
364         CPRINTS(ctx, "%s: invalid image size\n", __FUNCTION__);
365         return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
366     }
367 
368     rv = get_hash_digest_size(ctx->descriptor.hash_type, &digest_size);
369     if (rv != LIBCR51SIGN_SUCCESS)
370     {
371         return rv;
372     }
373 
374     rv = intf->read(ctx, hash_offset,
375                     MEMBER_SIZE(struct hash_sha256, hash_magic) + digest_size,
376                     magic_and_digest);
377     if (rv != LIBCR51SIGN_SUCCESS)
378     {
379         CPRINTS(ctx, "%s: failed to read hash from flash\n", __FUNCTION__);
380         return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
381     }
382     if (*(uint32_t*)magic_and_digest != HASH_MAGIC)
383     {
384         CPRINTS(ctx, "%s: bad hash magic\n", __FUNCTION__);
385         return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
386     }
387     rv = intf->hash_init(ctx, ctx->descriptor.hash_type);
388     if (rv != LIBCR51SIGN_SUCCESS)
389     {
390         CPRINTS(ctx, "%s: hash_init failed\n", __FUNCTION__);
391         return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
392     }
393     for (i = 0; i < region_count; i++)
394     {
395         uint32_t hash_start, hash_size;
396         region = image_regions->image_regions + i;
397 
398         if (!(region->region_attributes & IMAGE_REGION_STATIC))
399         {
400             continue;
401         }
402         hash_start = region->region_offset;
403         hash_size = region->region_size;
404 
405         // Skip the descriptor.
406         do
407         {
408             if (i == d_region_num)
409             {
410                 hash_size = d_offset - hash_start;
411                 if (!hash_size)
412                 {
413                     hash_start += ctx->descriptor.descriptor_area_size;
414                     hash_size = (region->region_offset + region->region_size -
415                                  hash_start);
416                 }
417             }
418 
419             CPRINTS(ctx, "%s: hashing %s (%x - %x)\n", __FUNCTION__,
420                     (const char*)region->region_name, hash_start,
421                     hash_start + hash_size);
422             // Read the image_region array.
423             rv = read_and_hash_update(ctx, intf, hash_start, hash_size);
424             if (rv != LIBCR51SIGN_SUCCESS)
425             {
426                 return rv;
427             }
428             hash_start += hash_size;
429         } while (hash_start != region->region_offset + region->region_size);
430     }
431     rv = intf->hash_final(ctx, (uint8_t*)dcrypto_digest);
432 
433     if (rv != LIBCR51SIGN_SUCCESS)
434     {
435         return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
436     }
437 
438     if (memcmp(magic_and_digest + MEMBER_SIZE(struct hash_sha256, hash_magic),
439                dcrypto_digest, digest_size) != 0)
440     {
441         CPRINTS(ctx, "%s: invalid hash\n", __FUNCTION__);
442         return LIBCR51SIGN_ERROR_INVALID_HASH;
443     }
444     // Image is valid.
445     return LIBCR51SIGN_SUCCESS;
446 }
447 
448 // Create empty image_regions to pass to validate_payload_regions
449 // Support validate_payload_regions_helper to remove image_regions as a required
450 // input.
451 
allocate_and_validate_payload_regions(struct libcr51sign_ctx * ctx,struct libcr51sign_intf * intf,uint32_t d_offset)452 static failure_reason allocate_and_validate_payload_regions(
453     struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf,
454     uint32_t d_offset)
455 {
456     struct libcr51sign_validated_regions image_regions;
457     return validate_payload_regions(ctx, intf, d_offset, &image_regions);
458 }
459 
460 // Wrapper around validate_payload_regions to allow nullptr for image_regions.
461 // Calls allocate_and_validate_payload_regions when image_regions is nullptr to
462 // create placer holder image_regions.
463 
validate_payload_regions_helper(struct libcr51sign_ctx * ctx,struct libcr51sign_intf * intf,uint32_t d_offset,struct libcr51sign_validated_regions * image_regions)464 static failure_reason validate_payload_regions_helper(
465     struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf,
466     uint32_t d_offset, struct libcr51sign_validated_regions* image_regions)
467 {
468     if (image_regions)
469     {
470         return validate_payload_regions(ctx, intf, d_offset, image_regions);
471     }
472 
473     return allocate_and_validate_payload_regions(ctx, intf, d_offset);
474 }
475 
476 // Check if the given signature_scheme is supported.
477 // Returns nonzero on error, zero on success
478 
is_signature_scheme_supported(enum signature_scheme scheme)479 static failure_reason is_signature_scheme_supported(
480     enum signature_scheme scheme)
481 {
482     switch (scheme)
483     {
484         case SIGNATURE_RSA2048_PKCS15:
485         case SIGNATURE_RSA3072_PKCS15:
486         case SIGNATURE_RSA4096_PKCS15:
487         case SIGNATURE_RSA4096_PKCS15_SHA512:
488             return LIBCR51SIGN_SUCCESS;
489         default:
490             return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME;
491     }
492 }
493 
494 // Returns size of signature struct size in |size|
495 // Returns nonzero on error, zero on success
496 
get_signature_struct_size(enum signature_scheme scheme,uint32_t * size)497 static failure_reason get_signature_struct_size(enum signature_scheme scheme,
498                                                 uint32_t* size)
499 {
500     switch (scheme)
501     {
502         case SIGNATURE_RSA2048_PKCS15:
503             *size = sizeof(struct signature_rsa2048_pkcs15);
504             return LIBCR51SIGN_SUCCESS;
505         case SIGNATURE_RSA3072_PKCS15:
506             *size = sizeof(struct signature_rsa3072_pkcs15);
507             return LIBCR51SIGN_SUCCESS;
508         case SIGNATURE_RSA4096_PKCS15:
509         case SIGNATURE_RSA4096_PKCS15_SHA512:
510             *size = sizeof(struct signature_rsa4096_pkcs15);
511             return LIBCR51SIGN_SUCCESS;
512         default:
513             return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME;
514     }
515 }
516 
get_signature_field_offset(enum signature_scheme scheme,uint32_t * offset)517 static failure_reason get_signature_field_offset(enum signature_scheme scheme,
518                                                  uint32_t* offset)
519 {
520     switch (scheme)
521     {
522         case SIGNATURE_RSA2048_PKCS15:
523             *offset = offsetof(struct signature_rsa2048_pkcs15, signature);
524             return LIBCR51SIGN_SUCCESS;
525         case SIGNATURE_RSA3072_PKCS15:
526             *offset = offsetof(struct signature_rsa3072_pkcs15, signature);
527             return LIBCR51SIGN_SUCCESS;
528         case SIGNATURE_RSA4096_PKCS15:
529         case SIGNATURE_RSA4096_PKCS15_SHA512:
530             *offset = offsetof(struct signature_rsa4096_pkcs15, signature);
531             return LIBCR51SIGN_SUCCESS;
532         default:
533             return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME;
534     }
535 }
536 
is_key_in_signature_struct_trusted(struct libcr51sign_ctx * ctx,const struct libcr51sign_intf * intf,enum signature_scheme scheme,uint32_t raw_signature_offset,void * signature_struct,uint32_t * signature_struct_size)537 __attribute__((nonnull)) static bool is_key_in_signature_struct_trusted(
538     struct libcr51sign_ctx* ctx, const struct libcr51sign_intf* intf,
539     enum signature_scheme scheme, uint32_t raw_signature_offset,
540     void* signature_struct, uint32_t* signature_struct_size)
541 {
542     if (!intf->trust_key_in_signature_structure)
543     {
544         CPRINTS(ctx, "%s: trust_key_in_signature_structure is not supported\n",
545                 __FUNCTION__);
546         return false;
547     }
548 
549     uint32_t signature_field_offset;
550     int rv = get_signature_field_offset(scheme, &signature_field_offset);
551     if (rv != LIBCR51SIGN_SUCCESS)
552     {
553         return false;
554     }
555 
556     if (signature_field_offset > raw_signature_offset)
557     {
558         CPRINTS(ctx,
559                 "%s: signature_field_offset (%d) is larger than "
560                 "raw_signature_offset (%d)\n",
561                 __FUNCTION__, signature_field_offset, raw_signature_offset);
562         return false;
563     }
564     uint32_t signature_offset = raw_signature_offset - signature_field_offset;
565 
566     rv = get_signature_struct_size(scheme, signature_struct_size);
567     if (rv != LIBCR51SIGN_SUCCESS)
568     {
569         return false;
570     }
571 
572     rv = intf->read(ctx, signature_offset, *signature_struct_size,
573                     signature_struct);
574     if (rv != LIBCR51SIGN_SUCCESS)
575     {
576         CPRINTS(ctx, "%s: failed to read signature (status = %d)\n",
577                 __FUNCTION__, rv);
578         return false;
579     }
580 
581     return intf->trust_key_in_signature_structure(ctx, scheme, signature_struct,
582                                                   *signature_struct_size);
583 }
584 // Validates the signature with verification key provided along with the
585 // signature if the key is trusted.
586 
validate_signature_with_key_in_signature_struct(struct libcr51sign_ctx * ctx,const struct libcr51sign_intf * intf,enum signature_scheme scheme,uint32_t raw_signature_offset,const uint8_t * digest,uint32_t digest_size)587 static bool validate_signature_with_key_in_signature_struct(
588     struct libcr51sign_ctx* ctx, const struct libcr51sign_intf* intf,
589     enum signature_scheme scheme, uint32_t raw_signature_offset,
590     const uint8_t* digest, uint32_t digest_size)
591 {
592     // pick the biggest signature struct size.
593     uint8_t signature_struct[sizeof(struct signature_rsa4096_pkcs15)];
594     uint32_t signature_struct_size = sizeof(signature_struct);
595     if (!is_key_in_signature_struct_trusted(
596             ctx, intf, scheme, raw_signature_offset, &signature_struct,
597             &signature_struct_size))
598     {
599         CPRINTS(ctx, "%s: key in signature struct is not trusted\n",
600                 __FUNCTION__);
601         return false;
602     }
603     if (!intf->verify_rsa_signature_with_modulus_and_exponent)
604     {
605         CPRINTS(
606             ctx,
607             "%s: verify_rsa_signature_with_modulus_and_exponent is not supported\n",
608             __FUNCTION__);
609         return false;
610     }
611 
612     switch (scheme)
613     {
614         case SIGNATURE_RSA2048_PKCS15:
615         {
616             struct signature_rsa2048_pkcs15* sig =
617                 (struct signature_rsa2048_pkcs15*)signature_struct;
618             return intf->verify_rsa_signature_with_modulus_and_exponent(
619                 ctx, scheme, sig->modulus, sizeof(sig->modulus), sig->exponent,
620                 sig->signature, sizeof(sig->signature), digest, digest_size);
621         }
622         break;
623         case SIGNATURE_RSA3072_PKCS15:
624         {
625             struct signature_rsa3072_pkcs15* sig =
626                 (struct signature_rsa3072_pkcs15*)signature_struct;
627             return intf->verify_rsa_signature_with_modulus_and_exponent(
628                 ctx, scheme, sig->modulus, sizeof(sig->modulus), sig->exponent,
629                 sig->signature, sizeof(sig->signature), digest, digest_size);
630         }
631         break;
632         case SIGNATURE_RSA4096_PKCS15:
633         case SIGNATURE_RSA4096_PKCS15_SHA512:
634         {
635             struct signature_rsa4096_pkcs15* sig =
636                 (struct signature_rsa4096_pkcs15*)signature_struct;
637             return intf->verify_rsa_signature_with_modulus_and_exponent(
638                 ctx, scheme, sig->modulus, sizeof(sig->modulus), sig->exponent,
639                 sig->signature, sizeof(sig->signature), digest, digest_size);
640         }
641         break;
642         default:
643             CPRINTS(ctx, "%s: unsupported signature scheme %d\n", __FUNCTION__,
644                     scheme);
645             return false;
646     }
647 }
648 
649 // Validates the signature (of type scheme) read from "device" at
650 //"raw_signature_offset" with "public_key" over a SHA256/SHA512 digest of
651 // EEPROM area "data_offset:data_size".
652 
validate_signature(struct libcr51sign_ctx * ctx,const struct libcr51sign_intf * intf,uint32_t data_offset,uint32_t data_size,enum signature_scheme scheme,uint32_t raw_signature_offset)653 static failure_reason validate_signature(
654     struct libcr51sign_ctx* ctx, const struct libcr51sign_intf* intf,
655     uint32_t data_offset, uint32_t data_size, enum signature_scheme scheme,
656     uint32_t raw_signature_offset)
657 {
658     uint8_t signature[LIBCR51SIGN_MAX_SIGNATURE_SIZE];
659     uint16_t key_size;
660     uint32_t digest_size;
661     uint8_t dcrypto_digest[LIBCR51SIGN_SHA512_DIGEST_SIZE];
662     int rv;
663     enum hash_type hash_type;
664 
665     if (!intf->hash_init)
666     {
667         CPRINTS(ctx, "%s: missing hash_init\n", __FUNCTION__);
668         return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
669     }
670     rv = get_hash_type_from_signature(scheme, &hash_type);
671     if (rv != LIBCR51SIGN_SUCCESS)
672     {
673         CPRINTS(ctx, "%s: hash_type from signature failed\n", __FUNCTION__);
674         return rv;
675     }
676     rv = intf->hash_init(ctx, hash_type);
677     if (rv != LIBCR51SIGN_SUCCESS)
678     {
679         CPRINTS(ctx, "%s: hash_init failed\n", __FUNCTION__);
680         return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
681     }
682     rv = read_and_hash_update(ctx, intf, data_offset, data_size);
683     if (rv != LIBCR51SIGN_SUCCESS)
684     {
685         CPRINTS(ctx, "%s: hash_update failed\n", __FUNCTION__);
686         return rv;
687     }
688     if (!intf->hash_final)
689     {
690         CPRINTS(ctx, "%s: missing hash_final\n", __FUNCTION__);
691         return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
692     }
693     rv = intf->hash_final(ctx, dcrypto_digest);
694     if (rv != LIBCR51SIGN_SUCCESS)
695     {
696         CPRINTS(ctx, "%s: hash_final failed (status = %d)\n", __FUNCTION__, rv);
697         return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
698     }
699 
700     rv = get_hash_digest_size(hash_type, &digest_size);
701     if (rv != LIBCR51SIGN_SUCCESS)
702     {
703         return rv;
704     }
705 
706     if (intf->trust_descriptor_hash)
707     {
708         if (intf->trust_descriptor_hash(ctx, dcrypto_digest, digest_size))
709         {
710             CPRINTS(ctx, "%s: descriptor hash trusted\n", __FUNCTION__);
711             return LIBCR51SIGN_SUCCESS;
712         }
713     }
714 
715     rv = get_key_size(scheme, &key_size);
716     if (rv != LIBCR51SIGN_SUCCESS)
717     {
718         return rv;
719     }
720 
721     rv = intf->read(ctx, raw_signature_offset, key_size, signature);
722     if (rv != LIBCR51SIGN_SUCCESS)
723     {
724         CPRINTS(ctx, "%s: failed to read signature (status = %d)\n",
725                 __FUNCTION__, rv);
726         return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
727     }
728 
729     if (validate_signature_with_key_in_signature_struct(
730             ctx, intf, scheme, raw_signature_offset, dcrypto_digest,
731             digest_size))
732     {
733         CPRINTS(ctx, "%s: verification with external key succeeded\n",
734                 __FUNCTION__);
735         return LIBCR51SIGN_SUCCESS;
736     }
737 
738     if (!intf->verify_signature)
739     {
740         CPRINTS(ctx, "%s: missing verify_signature\n", __FUNCTION__);
741         return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
742     }
743 
744     rv = intf->verify_signature(ctx, scheme, signature, key_size,
745                                 dcrypto_digest, digest_size);
746     if (rv != LIBCR51SIGN_SUCCESS)
747     {
748         CPRINTS(ctx, "%s: verification failed (status = %d)\n", __FUNCTION__,
749                 rv);
750         return LIBCR51SIGN_ERROR_INVALID_SIGNATURE;
751     }
752     CPRINTS(ctx, "%s: verification succeeded\n", __FUNCTION__);
753     return LIBCR51SIGN_SUCCESS;
754 }
755 
756 // Sanity checks the image descriptor & validates its signature.
757 // This function does not validate the image_region array or image hash.
758 //
759 //@param[in] ctx  context which describes the image and holds opaque private
760 //                 data for the user of the library
761 //@param[in] intf  function pointers which interface to the current system
762 // and environment
763 //@param offset  Absolute image descriptor flash offset.
764 //@param relative_offset  Image descriptor offset relative to image start.
765 //@param max_size Maximum size of the flash space in bytes.
766 //@param[out] payload_blob_offset  Absolute offset of BLOB data in image
767 //                                 descriptor (if BLOB data is present)
validate_descriptor(struct libcr51sign_ctx * ctx,const struct libcr51sign_intf * intf,uint32_t offset,uint32_t relative_offset,uint32_t max_size,uint32_t * const restrict payload_blob_offset)768 static failure_reason validate_descriptor(
769     struct libcr51sign_ctx* ctx, const struct libcr51sign_intf* intf,
770     uint32_t offset, uint32_t relative_offset, uint32_t max_size,
771     uint32_t* const restrict payload_blob_offset)
772 {
773     uint32_t max_descriptor_size, signed_size, signature_scheme,
774         signature_offset;
775     uint32_t signature_struct_offset, signature_struct_size, hash_struct_size;
776     int rv;
777 
778     max_descriptor_size = max_size - relative_offset;
779     if (max_size < relative_offset ||
780         max_descriptor_size < sizeof(struct image_descriptor))
781     {
782         CPRINTS(ctx, "%s: invalid arguments\n", __FUNCTION__);
783         return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
784     }
785 
786     rv = intf->read(ctx, offset, sizeof(ctx->descriptor),
787                     (uint8_t*)&ctx->descriptor);
788     if (rv != LIBCR51SIGN_SUCCESS)
789     {
790         CPRINTS(ctx, "%s: failed to read descriptor\n", __FUNCTION__);
791         return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
792     }
793     if (ctx->descriptor.descriptor_magic != DESCRIPTOR_MAGIC ||
794         ctx->descriptor.descriptor_offset != relative_offset ||
795         ctx->descriptor.region_count == 0 ||
796         ctx->descriptor.descriptor_area_size > max_descriptor_size ||
797         ctx->descriptor.image_size > max_size)
798     {
799         CPRINTS(ctx, "%s: invalid descriptor\n", __FUNCTION__);
800         return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
801     }
802     if (intf->image_size_valid == NULL)
803     {
804         // Preserve original behavior of requiring exact image_size match if no
805         // operator is provided.
806         if (ctx->descriptor.image_size != max_size)
807         {
808             CPRINTS(ctx, "%s: invalid image size\n", __FUNCTION__);
809             return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
810         }
811     }
812     else if (!intf->image_size_valid(ctx->descriptor.image_size))
813     {
814         CPRINTS(ctx, "%s: invalid image size\n", __FUNCTION__);
815         return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
816     }
817     if (ctx->descriptor.image_type != IMAGE_DEV &&
818         ctx->descriptor.image_type != IMAGE_PROD &&
819         ctx->descriptor.image_type != IMAGE_BREAKOUT &&
820         ctx->descriptor.image_type != IMAGE_TEST &&
821         ctx->descriptor.image_type != IMAGE_UNSIGNED_INTEGRITY)
822     {
823         CPRINTS(ctx, "%s: bad image type\n", __FUNCTION__);
824         return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
825     }
826     // Although the image_descriptor struct supports unauthenticated
827     // images, Haven will not allow it.
828     // Haven only supports SHA256 + RSA2048/RSA3072_PKCS15 currently.
829 
830     signature_scheme = ctx->descriptor.signature_scheme;
831 
832     rv = is_signature_scheme_supported(signature_scheme);
833     if (rv != LIBCR51SIGN_SUCCESS)
834     {
835         return rv;
836     }
837     rv = is_hash_type_supported(ctx->descriptor.hash_type);
838     if (rv != LIBCR51SIGN_SUCCESS)
839     {
840         CPRINTS(ctx, "%s: invalid hash type\n", __FUNCTION__);
841         return rv;
842     }
843     if (ctx->descriptor.descriptor_major > MAX_MAJOR_VERSION ||
844         ctx->descriptor.region_count > LIBCR51SIGN_MAX_REGION_COUNT)
845     {
846         CPRINTS(ctx, "%s: unsupported descriptor\n", __FUNCTION__);
847         return LIBCR51SIGN_ERROR_UNSUPPORTED_DESCRIPTOR;
848     }
849     rv = get_signature_struct_size(signature_scheme, &signature_struct_size);
850     if (rv != LIBCR51SIGN_SUCCESS)
851     {
852         return rv;
853     }
854 
855     // Compute the size of the signed portion of the image descriptor.
856     signed_size = sizeof(struct image_descriptor) +
857                   ctx->descriptor.region_count * sizeof(struct image_region);
858     rv = get_hash_struct_size(ctx->descriptor.hash_type, &hash_struct_size);
859     if (rv != LIBCR51SIGN_SUCCESS)
860     {
861         return rv;
862     }
863     signed_size += hash_struct_size;
864     if (ctx->descriptor.denylist_size)
865     {
866         signed_size += sizeof(struct denylist);
867         signed_size += ctx->descriptor.denylist_size *
868                        sizeof(struct denylist_record);
869     }
870     if (ctx->descriptor.blob_size)
871     {
872         *payload_blob_offset = offset + signed_size;
873         signed_size += sizeof(struct blob);
874         // Previous additions are guaranteed not to overflow.
875         if ((ctx->descriptor.blob_size >
876              ctx->descriptor.descriptor_area_size - signed_size) ||
877             // Sanity check blob size
878             (ctx->descriptor.blob_size < sizeof(struct blob_data)))
879         {
880             CPRINTS(ctx, "%s: invalid blob size (0x%x)\n", __FUNCTION__,
881                     ctx->descriptor.blob_size);
882             return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
883         }
884         signed_size += ctx->descriptor.blob_size;
885     }
886     if (signature_struct_size >
887         ctx->descriptor.descriptor_area_size - signed_size)
888     {
889         CPRINTS(ctx,
890                 "%s: invalid descriptor area size "
891                 "(expected = 0x%x, actual = 0x%x)\n",
892                 __FUNCTION__, ctx->descriptor.descriptor_area_size,
893                 signed_size + signature_struct_size);
894         return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
895     }
896     signature_struct_offset = signed_size;
897     // Omit the actual signature.
898     rv = get_signature_field_offset(signature_scheme, &signature_offset);
899     if (rv != LIBCR51SIGN_SUCCESS)
900     {
901         return rv;
902     }
903     signed_size += signature_offset;
904 
905     // Lookup key & validate transition.
906     rv = validate_transition(ctx, intf, offset + signature_struct_offset);
907 
908     if (rv != LIBCR51SIGN_SUCCESS)
909     {
910         return rv;
911     }
912     return validate_signature(ctx, intf, offset, signed_size, signature_scheme,
913                               offset + signed_size);
914 }
915 
916 // Scans the external EEPROM for a magic value at "alignment" boundaries.
917 //
918 //@param device  Handle to the external EEPROM.
919 //@param magic   8-byte pattern to search for.
920 //@param start_offset  Offset to begin searching at.
921 //@param limit   Exclusive address (e.g. EEPROM size).
922 //@param alignment   Alignment boundaries (POW2) to search on.
923 //@param header_offset   Location to place the new header offset.
924 //@return LIBCR51SIGN_SUCCESS (or non-zero on error).
925 
scan_for_magic_8(struct libcr51sign_ctx * ctx,const struct libcr51sign_intf * intf,uint64_t magic,uint32_t start_offset,uint32_t limit,uint32_t alignment,uint32_t * header_offset)926 static int scan_for_magic_8(struct libcr51sign_ctx* ctx,
927                             const struct libcr51sign_intf* intf, uint64_t magic,
928                             uint32_t start_offset, uint32_t limit,
929                             uint32_t alignment, uint32_t* header_offset)
930 {
931     uint64_t read_data;
932     uint32_t offset;
933     int rv;
934 
935     if (limit <= start_offset || limit > ctx->end_offset ||
936         limit < sizeof(magic) || !POWER_OF_TWO(alignment))
937     {
938         return LIBCR51SIGN_ERROR_INVALID_ARGUMENT;
939     }
940 
941     if (!intf->read)
942     {
943         CPRINTS(ctx, "%s: missing intf->read\n", __FUNCTION__);
944         return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
945     }
946     // Align start_offset to the next valid boundary.
947     start_offset = ((start_offset - 1) & ~(alignment - 1)) + alignment;
948     for (offset = start_offset; offset < limit - sizeof(magic);
949          offset += alignment)
950     {
951         rv = intf->read(ctx, offset, sizeof(read_data), (uint8_t*)&read_data);
952         if (rv != LIBCR51SIGN_SUCCESS)
953         {
954             return rv;
955         }
956         if (read_data == magic)
957         {
958             if (header_offset)
959             {
960                 *header_offset = offset;
961             }
962             return LIBCR51SIGN_SUCCESS;
963         }
964     }
965     // Failed to locate magic.
966     return LIBCR51SIGN_ERROR_FAILED_TO_LOCATE_MAGIC;
967 }
968 
969 // Check whether the signature on the image is valid.
970 // Validates the authenticity of an EEPROM image. Scans for & validates the
971 // signature on the image descriptor. If the descriptor validates, hashes the
972 // rest of the image to verify its integrity.
973 //
974 // @param[in] ctx - context which describes the image and holds opaque private
975 //                 data for the user of the library
976 // @param[in] intf - function pointers which interface to the current system
977 //                  and environment
978 // @param[out] image_regions - image_region pointer to an array for the output
979 //
980 // @return nonzero on error, zero on success
981 
libcr51sign_validate(struct libcr51sign_ctx * ctx,struct libcr51sign_intf * intf,struct libcr51sign_validated_regions * image_regions)982 failure_reason libcr51sign_validate(
983     struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf,
984     struct libcr51sign_validated_regions* image_regions)
985 {
986     int rv, rv_first_desc = LIBCR51SIGN_SUCCESS;
987     uint32_t descriptor_offset;
988     uint32_t payload_blob_offset = 0;
989 
990     if (!ctx)
991     {
992         CPRINTS(ctx, "%s: Missing context\n", __FUNCTION__);
993         return LIBCR51SIGN_ERROR_INVALID_CONTEXT;
994     }
995     if (!intf)
996     {
997         CPRINTS(ctx, "%s: Missing interface\n", __FUNCTION__);
998         return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
999     }
1000 
1001     ctx->validation_state = LIBCR51SIGN_IMAGE_INVALID;
1002 
1003     rv = scan_for_magic_8(ctx, intf, DESCRIPTOR_MAGIC, ctx->start_offset,
1004                           ctx->end_offset, DESCRIPTOR_ALIGNMENT,
1005                           &descriptor_offset);
1006     while (rv == LIBCR51SIGN_SUCCESS)
1007     {
1008         CPRINTS(ctx, "%s: potential image descriptor found @%x\n", __FUNCTION__,
1009                 descriptor_offset);
1010         // Validation is split into 3 functions to minimize stack usage.
1011 
1012         rv = validate_descriptor(
1013             ctx, intf, descriptor_offset, descriptor_offset - ctx->start_offset,
1014             ctx->end_offset - ctx->start_offset, &payload_blob_offset);
1015         if (rv != LIBCR51SIGN_SUCCESS)
1016         {
1017             CPRINTS(ctx, "%s: validate_descriptor() failed ec%d\n",
1018                     __FUNCTION__, rv);
1019         }
1020         else
1021         {
1022             rv = validate_payload_regions_helper(ctx, intf, descriptor_offset,
1023                                                  image_regions);
1024             if (rv != LIBCR51SIGN_SUCCESS)
1025             {
1026                 CPRINTS(ctx, "%s: validate_payload_regions() failed ec%d\n",
1027                         __FUNCTION__, rv);
1028             }
1029             else if (ctx->descriptor.image_type == IMAGE_PROD)
1030             {
1031                 ctx->validation_state = LIBCR51SIGN_IMAGE_VALID;
1032                 // Lookup and validate payload Image MAUV against Image MAUV
1033                 // stored in the system after checking signature to ensure
1034                 // offsets and sizes are not tampered with. Also, do this after
1035                 // hash calculation for payload regions to ensure that stored
1036                 // Image MAUV is updated (if necessary) as close to the end of
1037                 // payload validation as possible
1038                 rv = validate_payload_image_mauv(ctx, intf, payload_blob_offset,
1039                                                  ctx->descriptor.blob_size);
1040                 if (rv == LIBCR51SIGN_SUCCESS)
1041                 {
1042                     CPRINTS(ctx,
1043                             "%s: Payload Image MAUV validation successful\n",
1044                             __FUNCTION__);
1045                     return rv;
1046                 }
1047                 if (rv == LIBCR51SIGN_ERROR_STORING_NEW_IMAGE_MAUV_DATA)
1048                 {
1049                     CPRINTS(
1050                         ctx,
1051                         "%s: Payload validation succeeded, but Image MAUV validation "
1052                         "failed\n",
1053                         __FUNCTION__);
1054                     return LIBCR51SIGN_ERROR_VALID_IMAGE_BUT_NEW_IMAGE_MAUV_DATA_NOT_STORED;
1055                 }
1056                 CPRINTS(ctx, "%s: Payload Image MAUV validation failed\n",
1057                         __FUNCTION__);
1058                 // In practice, we expect only 1 valid image descriptor in
1059                 // payload. If Image MAUV check fails for the payload after
1060                 // validating the image descriptor, do not try validating other
1061                 // image descriptors
1062                 return rv;
1063             }
1064             else
1065             {
1066                 ctx->validation_state = LIBCR51SIGN_IMAGE_VALID;
1067                 return rv;
1068             }
1069         }
1070 
1071         // Store the first desc fail reason if any
1072         if (rv != LIBCR51SIGN_SUCCESS && rv_first_desc == LIBCR51SIGN_SUCCESS)
1073             rv_first_desc = rv;
1074 
1075         // scan_for_magic_8() will round up to the next aligned boundary.
1076         descriptor_offset++;
1077         rv = scan_for_magic_8(ctx, intf, DESCRIPTOR_MAGIC, descriptor_offset,
1078                               ctx->end_offset, DESCRIPTOR_ALIGNMENT,
1079                               &descriptor_offset);
1080     }
1081     CPRINTS(ctx, "%s: failed to validate image ec%d\n", __FUNCTION__, rv);
1082     // If desc validation failed for some reason then return that reason
1083     if (rv_first_desc != LIBCR51SIGN_SUCCESS)
1084         return rv_first_desc;
1085 
1086     return rv;
1087 }
1088 
1089 // @func to returns the libcr51sign error code as a string
1090 // @param[in] ec - Error code
1091 // @return error code in string format
1092 
libcr51sign_errorcode_to_string(failure_reason ec)1093 const char* libcr51sign_errorcode_to_string(failure_reason ec)
1094 {
1095     switch (ec)
1096     {
1097         case LIBCR51SIGN_SUCCESS:
1098             return "Success";
1099         case LIBCR51SIGN_ERROR_RUNTIME_FAILURE:
1100             return "Runtime Error Failure";
1101         case LIBCR51SIGN_ERROR_UNSUPPORTED_DESCRIPTOR:
1102             return "Unsupported descriptor";
1103         case LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR:
1104             return "Invalid descriptor";
1105         case LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY:
1106             return "Invalid image family";
1107         case LIBCR51SIGN_ERROR_IMAGE_TYPE_DISALLOWED:
1108             return "Image type disallowed";
1109         case LIBCR51SIGN_ERROR_DEV_DOWNGRADE_DISALLOWED:
1110             return "Dev downgrade disallowed";
1111         case LIBCR51SIGN_ERROR_UNTRUSTED_KEY:
1112             return "Untrusted key";
1113         case LIBCR51SIGN_ERROR_INVALID_SIGNATURE:
1114             return "Invalid signature";
1115         case LIBCR51SIGN_ERROR_INVALID_HASH:
1116             return "Invalid hash";
1117         case LIBCR51SIGN_ERROR_INVALID_HASH_TYPE:
1118             return "Invalid hash type";
1119         case LIBCR51SIGN_ERROR_INVALID_ARGUMENT:
1120             return "Invalid Argument";
1121         case LIBCR51SIGN_ERROR_FAILED_TO_LOCATE_MAGIC:
1122             return "Failed to locate descriptor";
1123         case LIBCR51SIGN_ERROR_INVALID_CONTEXT:
1124             return "Invalid context";
1125         case LIBCR51SIGN_ERROR_INVALID_INTERFACE:
1126             return "Invalid interface";
1127         case LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME:
1128             return "Invalid signature scheme";
1129         case LIBCR51SIGN_ERROR_INVALID_REGION_INPUT:
1130             return "Invalid image region input";
1131         case LIBCR51SIGN_ERROR_INVALID_REGION_SIZE:
1132             return "Invalid image region size";
1133         case LIBCR51SIGN_ERROR_INVALID_IMAGE_MAUV_DATA:
1134             return "Invalid Image MAUV data";
1135         case LIBCR51SIGN_ERROR_RETRIEVING_STORED_IMAGE_MAUV_DATA:
1136             return "Failed to retrieve Image MAUV data stored in system";
1137         case LIBCR51SIGN_ERROR_STORING_NEW_IMAGE_MAUV_DATA:
1138             return "Failed to store Image MAUV data from payload image into system";
1139         case LIBCR51SIGN_ERROR_STORED_IMAGE_MAUV_DOES_NOT_ALLOW_UPDATE_TO_PAYLOAD:
1140             return "Image MAUV stored in system does not allow payload "
1141                    "update";
1142         case LIBCR51SIGN_ERROR_VALID_IMAGE_BUT_NEW_IMAGE_MAUV_DATA_NOT_STORED:
1143             return "Payload image is valid for update but failed to store new Image "
1144                    "MAUV in system";
1145         case LIBCR51SIGN_ERROR_STORED_IMAGE_MAUV_EXPECTS_PAYLOAD_IMAGE_MAUV:
1146             return "Image MAUV is expected to be present in payload when stored "
1147                    "Image MAUV is present in the system";
1148         case LIBCR51SIGN_NO_STORED_MAUV_FOUND:
1149             return "Client did not find any MAUV data stored in the system";
1150         case LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR_BLOBS:
1151             return "Invalid descriptor blobs";
1152         default:
1153             return "Unknown error";
1154     }
1155 }
1156 
1157 #ifdef __cplusplus
1158 } //  extern "C"
1159 #endif
1160