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