1
2
3
4
5
6
7#include "efx.h"
8#include "efx_impl.h"
9
10#include "ef10_firmware_ids.h"
11
12#if EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
13
14#if EFSYS_OPT_IMAGE_LAYOUT
15
16
17
18
19
20
21
22
23#define ASN1_TAG_INTEGER (0x02)
24#define ASN1_TAG_OCTET_STRING (0x04)
25#define ASN1_TAG_OBJ_ID (0x06)
26#define ASN1_TAG_SEQUENCE (0x30)
27#define ASN1_TAG_SET (0x31)
28
29#define ASN1_TAG_IS_PRIM(tag) ((tag & 0x20) == 0)
30
31#define ASN1_TAG_PRIM_CONTEXT(n) (0x80 + (n))
32#define ASN1_TAG_CONS_CONTEXT(n) (0xA0 + (n))
33
34typedef struct efx_asn1_cursor_s {
35 uint8_t *buffer;
36 uint32_t length;
37
38 uint8_t tag;
39 uint32_t hdr_size;
40 uint32_t val_size;
41} efx_asn1_cursor_t;
42
43
44
45static __checkReturn efx_rc_t
46efx_asn1_parse_header_match_tag(
47 __inout efx_asn1_cursor_t *cursor,
48 __in uint8_t tag)
49{
50 efx_rc_t rc;
51
52 if (cursor == NULL || cursor->buffer == NULL || cursor->length < 2) {
53 rc = EINVAL;
54 goto fail1;
55 }
56
57 cursor->tag = cursor->buffer[0];
58 if (cursor->tag != tag) {
59
60 rc = ENOENT;
61 goto fail2;
62 }
63
64 if ((cursor->tag & 0x1F) == 0x1F) {
65
66 rc = EINVAL;
67 goto fail3;
68 }
69
70 if ((cursor->buffer[1] & 0x80) == 0) {
71
72 cursor->hdr_size = 2;
73 cursor->val_size = cursor->buffer[1];
74 } else {
75
76 uint32_t nbytes = cursor->buffer[1] & 0x7F;
77 uint32_t offset;
78
79 if (nbytes == 0) {
80
81 rc = EINVAL;
82 goto fail4;
83 }
84 if (2 + nbytes > cursor->length) {
85
86 rc = EINVAL;
87 goto fail6;
88 }
89 if (nbytes > sizeof (uint32_t)) {
90
91 rc = E2BIG;
92 goto fail5;
93 }
94 cursor->hdr_size = 2 + nbytes;
95 cursor->val_size = 0;
96 for (offset = 2; offset < cursor->hdr_size; offset++) {
97 cursor->val_size =
98 (cursor->val_size << 8) | cursor->buffer[offset];
99 }
100 }
101
102 if ((cursor->hdr_size + cursor->val_size) > cursor->length) {
103
104 rc = E2BIG;
105 goto fail7;
106 }
107
108 return (0);
109
110fail7:
111 EFSYS_PROBE(fail7);
112fail6:
113 EFSYS_PROBE(fail6);
114fail5:
115 EFSYS_PROBE(fail5);
116fail4:
117 EFSYS_PROBE(fail4);
118fail3:
119 EFSYS_PROBE(fail3);
120fail2:
121 EFSYS_PROBE(fail2);
122fail1:
123 EFSYS_PROBE1(fail1, efx_rc_t, rc);
124
125 return (rc);
126}
127
128
129static __checkReturn efx_rc_t
130efx_asn1_enter_tag(
131 __inout efx_asn1_cursor_t *cursor,
132 __in uint8_t tag)
133{
134 efx_rc_t rc;
135
136 if (cursor == NULL) {
137 rc = EINVAL;
138 goto fail1;
139 }
140
141 if (ASN1_TAG_IS_PRIM(tag)) {
142
143 rc = ENOTSUP;
144 goto fail2;
145 }
146 rc = efx_asn1_parse_header_match_tag(cursor, tag);
147 if (rc != 0) {
148
149 goto fail3;
150 }
151
152
153 cursor->buffer += cursor->hdr_size;
154 cursor->length = cursor->val_size;
155
156 return (0);
157
158fail3:
159 EFSYS_PROBE(fail3);
160fail2:
161 EFSYS_PROBE(fail2);
162fail1:
163 EFSYS_PROBE1(fail1, efx_rc_t, rc);
164
165 return (rc);
166}
167
168
169
170
171
172static __checkReturn efx_rc_t
173efx_asn1_match_tag_value(
174 __inout efx_asn1_cursor_t *cursor,
175 __in uint8_t tag,
176 __in const void *valp,
177 __in uint32_t val_size)
178{
179 efx_rc_t rc;
180
181 if (cursor == NULL) {
182 rc = EINVAL;
183 goto fail1;
184 }
185 rc = efx_asn1_parse_header_match_tag(cursor, tag);
186 if (rc != 0) {
187
188 goto fail2;
189 }
190 if (cursor->val_size != val_size) {
191
192 rc = EINVAL;
193 goto fail3;
194 }
195 if (memcmp(cursor->buffer + cursor->hdr_size, valp, val_size) != 0) {
196
197 rc = EINVAL;
198 goto fail4;
199 }
200 cursor->buffer += cursor->hdr_size + cursor->val_size;
201 cursor->length -= cursor->hdr_size + cursor->val_size;
202
203 return (0);
204
205fail4:
206 EFSYS_PROBE(fail4);
207fail3:
208 EFSYS_PROBE(fail3);
209fail2:
210 EFSYS_PROBE(fail2);
211fail1:
212 EFSYS_PROBE1(fail1, efx_rc_t, rc);
213
214 return (rc);
215}
216
217
218static __checkReturn efx_rc_t
219efx_asn1_skip_tag(
220 __inout efx_asn1_cursor_t *cursor,
221 __in uint8_t tag)
222{
223 efx_rc_t rc;
224
225 if (cursor == NULL) {
226 rc = EINVAL;
227 goto fail1;
228 }
229
230 rc = efx_asn1_parse_header_match_tag(cursor, tag);
231 if (rc != 0) {
232
233 goto fail2;
234 }
235 cursor->buffer += cursor->hdr_size + cursor->val_size;
236 cursor->length -= cursor->hdr_size + cursor->val_size;
237
238 return (0);
239
240fail2:
241 EFSYS_PROBE(fail2);
242fail1:
243 EFSYS_PROBE1(fail1, efx_rc_t, rc);
244
245 return (rc);
246}
247
248
249static __checkReturn efx_rc_t
250efx_asn1_get_tag_value(
251 __inout efx_asn1_cursor_t *cursor,
252 __in uint8_t tag,
253 __out uint8_t **valp,
254 __out uint32_t *val_sizep)
255{
256 efx_rc_t rc;
257
258 if (cursor == NULL || valp == NULL || val_sizep == NULL) {
259 rc = EINVAL;
260 goto fail1;
261 }
262
263 rc = efx_asn1_parse_header_match_tag(cursor, tag);
264 if (rc != 0) {
265
266 goto fail2;
267 }
268 *valp = cursor->buffer + cursor->hdr_size;
269 *val_sizep = cursor->val_size;
270
271 return (0);
272
273fail2:
274 EFSYS_PROBE(fail2);
275fail1:
276 EFSYS_PROBE1(fail1, efx_rc_t, rc);
277
278 return (rc);
279}
280
281
282
283
284
285
286
287static const uint8_t PKCS7_SignedData[] =
288{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 };
289
290
291static const uint8_t PKCS7_Data[] =
292{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 };
293
294
295static const uint8_t SignedData_Version[] =
296{ 0x03 };
297
298
299
300
301
302
303
304static __checkReturn efx_rc_t
305efx_check_signed_image_header(
306 __in void *bufferp,
307 __in uint32_t buffer_size,
308 __out uint32_t *content_offsetp,
309 __out uint32_t *content_lengthp)
310{
311 efx_asn1_cursor_t cursor;
312 uint8_t *valp;
313 uint32_t val_size;
314 efx_rc_t rc;
315
316 if (content_offsetp == NULL || content_lengthp == NULL) {
317 rc = EINVAL;
318 goto fail1;
319 }
320 cursor.buffer = (uint8_t *)bufferp;
321 cursor.length = buffer_size;
322
323
324 rc = efx_asn1_enter_tag(&cursor, ASN1_TAG_SEQUENCE);
325 if (rc != 0)
326 goto fail2;
327
328
329 rc = efx_asn1_match_tag_value(&cursor, ASN1_TAG_OBJ_ID,
330 PKCS7_SignedData, sizeof (PKCS7_SignedData));
331 if (rc != 0)
332 goto fail3;
333
334
335 rc = efx_asn1_enter_tag(&cursor, ASN1_TAG_CONS_CONTEXT(0));
336 if (rc != 0)
337 goto fail4;
338
339
340 rc = efx_asn1_enter_tag(&cursor, ASN1_TAG_SEQUENCE);
341 if (rc != 0)
342 goto fail5;
343
344
345 rc = efx_asn1_match_tag_value(&cursor, ASN1_TAG_INTEGER,
346 SignedData_Version, sizeof (SignedData_Version));
347 if (rc != 0)
348 goto fail6;
349
350
351 rc = efx_asn1_skip_tag(&cursor, ASN1_TAG_SET);
352 if (rc != 0)
353 goto fail7;
354
355
356 rc = efx_asn1_enter_tag(&cursor, ASN1_TAG_SEQUENCE);
357 if (rc != 0)
358 goto fail8;
359
360
361 rc = efx_asn1_match_tag_value(&cursor, ASN1_TAG_OBJ_ID,
362 PKCS7_Data, sizeof (PKCS7_Data));
363 if (rc != 0)
364 goto fail9;
365
366
367 rc = efx_asn1_enter_tag(&cursor, ASN1_TAG_CONS_CONTEXT(0));
368 if (rc != 0)
369 goto fail10;
370
371
372
373
374
375 valp = NULL;
376 val_size = 0;
377 rc = efx_asn1_get_tag_value(&cursor, ASN1_TAG_OCTET_STRING,
378 &valp, &val_size);
379 if (rc != 0)
380 goto fail11;
381
382 if ((valp == NULL) || (val_size == 0)) {
383 rc = EINVAL;
384 goto fail12;
385 }
386 if (valp < (uint8_t *)bufferp) {
387 rc = EINVAL;
388 goto fail13;
389 }
390 if ((valp + val_size) > ((uint8_t *)bufferp + buffer_size)) {
391 rc = EINVAL;
392 goto fail14;
393 }
394
395 *content_offsetp = (uint32_t)(valp - (uint8_t *)bufferp);
396 *content_lengthp = val_size;
397
398 return (0);
399
400fail14:
401 EFSYS_PROBE(fail14);
402fail13:
403 EFSYS_PROBE(fail13);
404fail12:
405 EFSYS_PROBE(fail12);
406fail11:
407 EFSYS_PROBE(fail11);
408fail10:
409 EFSYS_PROBE(fail10);
410fail9:
411 EFSYS_PROBE(fail9);
412fail8:
413 EFSYS_PROBE(fail8);
414fail7:
415 EFSYS_PROBE(fail7);
416fail6:
417 EFSYS_PROBE(fail6);
418fail5:
419 EFSYS_PROBE(fail5);
420fail4:
421 EFSYS_PROBE(fail4);
422fail3:
423 EFSYS_PROBE(fail3);
424fail2:
425 EFSYS_PROBE(fail2);
426fail1:
427 EFSYS_PROBE1(fail1, efx_rc_t, rc);
428
429 return (rc);
430}
431
432static __checkReturn efx_rc_t
433efx_check_unsigned_image(
434 __in void *bufferp,
435 __in uint32_t buffer_size,
436 __out efx_image_header_t **headerpp,
437 __out efx_image_trailer_t **trailerpp)
438{
439 efx_image_header_t *headerp;
440 efx_image_trailer_t *trailerp;
441 uint32_t crc;
442 efx_rc_t rc;
443
444 EFX_STATIC_ASSERT(sizeof (*headerp) == EFX_IMAGE_HEADER_SIZE);
445 EFX_STATIC_ASSERT(sizeof (*trailerp) == EFX_IMAGE_TRAILER_SIZE);
446
447
448 if (buffer_size < (EFX_FIELD_OFFSET(efx_image_header_t, eih_size) +
449 sizeof (headerp->eih_size))) {
450 rc = ENOSPC;
451 goto fail1;
452 }
453 headerp = (efx_image_header_t *)bufferp;
454
455
456 if (buffer_size < (headerp->eih_size + headerp->eih_code_size +
457 EFX_IMAGE_TRAILER_SIZE)) {
458 rc = ENOSPC;
459 goto fail2;
460 }
461
462 trailerp = (efx_image_trailer_t *)((uint8_t *)headerp +
463 headerp->eih_size + headerp->eih_code_size);
464
465 *headerpp = headerp;
466 *trailerpp = trailerp;
467
468 if (headerp->eih_magic != EFX_IMAGE_HEADER_MAGIC) {
469 rc = EINVAL;
470 goto fail3;
471 }
472
473
474
475
476
477 if (headerp->eih_version < EFX_IMAGE_HEADER_VERSION) {
478 rc = EINVAL;
479 goto fail4;
480 }
481
482
483 crc = efx_crc32_calculate(0, (uint8_t *)headerp,
484 (headerp->eih_size + headerp->eih_code_size));
485
486 if (trailerp->eit_crc != crc) {
487 rc = EINVAL;
488 goto fail5;
489 }
490
491 return (0);
492
493fail5:
494 EFSYS_PROBE(fail5);
495fail4:
496 EFSYS_PROBE(fail4);
497fail3:
498 EFSYS_PROBE(fail3);
499fail2:
500 EFSYS_PROBE(fail2);
501fail1:
502 EFSYS_PROBE1(fail1, efx_rc_t, rc);
503
504 return (rc);
505}
506
507 __checkReturn efx_rc_t
508efx_check_reflash_image(
509 __in void *bufferp,
510 __in uint32_t buffer_size,
511 __out efx_image_info_t *infop)
512{
513 efx_image_format_t format = EFX_IMAGE_FORMAT_NO_IMAGE;
514 uint32_t image_offset;
515 uint32_t image_size;
516 void *imagep;
517 efx_image_header_t *headerp;
518 efx_image_trailer_t *trailerp;
519 efx_rc_t rc;
520
521 EFSYS_ASSERT(infop != NULL);
522 if (infop == NULL) {
523 rc = EINVAL;
524 goto fail1;
525 }
526 memset(infop, 0, sizeof (*infop));
527
528 if (bufferp == NULL || buffer_size == 0) {
529 rc = EINVAL;
530 goto fail2;
531 }
532
533
534
535
536
537 rc = efx_check_signed_image_header(bufferp, buffer_size,
538 &image_offset, &image_size);
539 if (rc == 0) {
540
541
542
543
544 format = EFX_IMAGE_FORMAT_SIGNED;
545 } else {
546
547 format = EFX_IMAGE_FORMAT_UNSIGNED;
548 image_offset = 0;
549 image_size = buffer_size;
550 }
551 if (image_offset + image_size > buffer_size) {
552 rc = E2BIG;
553 goto fail3;
554 }
555 imagep = (uint8_t *)bufferp + image_offset;
556
557
558 rc = efx_check_unsigned_image(imagep, image_size, &headerp, &trailerp);
559 if (rc != 0)
560 goto fail4;
561
562
563
564
565
566
567 if (format == EFX_IMAGE_FORMAT_SIGNED) {
568 if (headerp->eih_type != FIRMWARE_TYPE_MCFW)
569 format = EFX_IMAGE_FORMAT_SIGNED_PACKAGE;
570 }
571
572
573 infop->eii_format = format;
574 infop->eii_imagep = bufferp;
575 infop->eii_image_size = buffer_size;
576 infop->eii_headerp = (efx_image_header_t *)imagep;
577
578 return (0);
579
580fail4:
581 EFSYS_PROBE(fail4);
582fail3:
583 EFSYS_PROBE(fail3);
584fail2:
585 EFSYS_PROBE(fail2);
586 infop->eii_format = EFX_IMAGE_FORMAT_INVALID;
587 infop->eii_imagep = NULL;
588 infop->eii_image_size = 0;
589
590fail1:
591 EFSYS_PROBE1(fail1, efx_rc_t, rc);
592
593 return (rc);
594}
595
596 __checkReturn efx_rc_t
597efx_build_signed_image_write_buffer(
598 __out_bcount(buffer_size)
599 uint8_t *bufferp,
600 __in uint32_t buffer_size,
601 __in efx_image_info_t *infop,
602 __out efx_image_header_t **headerpp)
603{
604 signed_image_chunk_hdr_t chunk_hdr;
605 uint32_t hdr_offset;
606 struct {
607 uint32_t offset;
608 uint32_t size;
609 } cms_header, image_header, code, image_trailer, signature;
610 efx_rc_t rc;
611
612 EFSYS_ASSERT((infop != NULL) && (headerpp != NULL));
613
614 if ((bufferp == NULL) || (buffer_size == 0) ||
615 (infop == NULL) || (headerpp == NULL)) {
616
617 rc = EINVAL;
618 goto fail1;
619 }
620 if ((infop->eii_format != EFX_IMAGE_FORMAT_SIGNED) ||
621 (infop->eii_imagep == NULL) ||
622 (infop->eii_headerp == NULL) ||
623 ((uint8_t *)infop->eii_headerp < (uint8_t *)infop->eii_imagep) ||
624 (infop->eii_image_size < EFX_IMAGE_HEADER_SIZE) ||
625 ((size_t)((uint8_t *)infop->eii_headerp - infop->eii_imagep) >
626 (infop->eii_image_size - EFX_IMAGE_HEADER_SIZE))) {
627
628 rc = EINVAL;
629 goto fail2;
630 }
631
632
633 cms_header.offset = 0;
634 cms_header.size =
635 (uint32_t)((uint8_t *)infop->eii_headerp - infop->eii_imagep);
636 if ((cms_header.size > buffer_size) ||
637 (cms_header.offset > (buffer_size - cms_header.size))) {
638 rc = EINVAL;
639 goto fail3;
640 }
641
642 image_header.offset = cms_header.offset + cms_header.size;
643 image_header.size = infop->eii_headerp->eih_size;
644 if ((image_header.size > buffer_size) ||
645 (image_header.offset > (buffer_size - image_header.size))) {
646 rc = EINVAL;
647 goto fail4;
648 }
649
650 code.offset = image_header.offset + image_header.size;
651 code.size = infop->eii_headerp->eih_code_size;
652 if ((code.size > buffer_size) ||
653 (code.offset > (buffer_size - code.size))) {
654 rc = EINVAL;
655 goto fail5;
656 }
657
658 image_trailer.offset = code.offset + code.size;
659 image_trailer.size = EFX_IMAGE_TRAILER_SIZE;
660 if ((image_trailer.size > buffer_size) ||
661 (image_trailer.offset > (buffer_size - image_trailer.size))) {
662 rc = EINVAL;
663 goto fail6;
664 }
665
666 signature.offset = image_trailer.offset + image_trailer.size;
667 signature.size = (uint32_t)(infop->eii_image_size - signature.offset);
668 if ((signature.size > buffer_size) ||
669 (signature.offset > (buffer_size - signature.size))) {
670 rc = EINVAL;
671 goto fail7;
672 }
673
674 EFSYS_ASSERT3U(infop->eii_image_size, ==, cms_header.size +
675 image_header.size + code.size + image_trailer.size +
676 signature.size);
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726 memset(bufferp, 0xFF, buffer_size);
727
728 EFX_STATIC_ASSERT(sizeof (chunk_hdr) == SIGNED_IMAGE_CHUNK_HDR_LEN);
729 memset(&chunk_hdr, 0, SIGNED_IMAGE_CHUNK_HDR_LEN);
730
731
732
733
734 if (buffer_size < SIGNED_IMAGE_CHUNK_HDR_LEN) {
735 rc = ENOSPC;
736 goto fail8;
737 }
738 hdr_offset = buffer_size - SIGNED_IMAGE_CHUNK_HDR_LEN;
739
740 chunk_hdr.magic = SIGNED_IMAGE_CHUNK_HDR_MAGIC;
741 chunk_hdr.version = SIGNED_IMAGE_CHUNK_HDR_VERSION;
742 chunk_hdr.id = SIGNED_IMAGE_CHUNK_CMS_HEADER;
743 chunk_hdr.offset = code.size + SIGNED_IMAGE_CHUNK_HDR_LEN;
744 chunk_hdr.len = cms_header.size;
745
746 memcpy(bufferp + hdr_offset, &chunk_hdr, sizeof (chunk_hdr));
747
748 if ((chunk_hdr.len > buffer_size) ||
749 (chunk_hdr.offset > (buffer_size - chunk_hdr.len))) {
750 rc = ENOSPC;
751 goto fail9;
752 }
753 memcpy(bufferp + chunk_hdr.offset,
754 infop->eii_imagep + cms_header.offset,
755 cms_header.size);
756
757
758
759
760 hdr_offset = chunk_hdr.offset + chunk_hdr.len;
761 if (hdr_offset > (buffer_size - SIGNED_IMAGE_CHUNK_HDR_LEN)) {
762 rc = ENOSPC;
763 goto fail10;
764 }
765 chunk_hdr.magic = SIGNED_IMAGE_CHUNK_HDR_MAGIC;
766 chunk_hdr.version = SIGNED_IMAGE_CHUNK_HDR_VERSION;
767 chunk_hdr.id = SIGNED_IMAGE_CHUNK_REFLASH_HEADER;
768 chunk_hdr.offset = hdr_offset + SIGNED_IMAGE_CHUNK_HDR_LEN;
769 chunk_hdr.len = image_header.size;
770
771 memcpy(bufferp + hdr_offset, &chunk_hdr, SIGNED_IMAGE_CHUNK_HDR_LEN);
772
773 if ((chunk_hdr.len > buffer_size) ||
774 (chunk_hdr.offset > (buffer_size - chunk_hdr.len))) {
775 rc = ENOSPC;
776 goto fail11;
777 }
778 memcpy(bufferp + chunk_hdr.offset,
779 infop->eii_imagep + image_header.offset,
780 image_header.size);
781
782 *headerpp = (efx_image_header_t *)(bufferp + chunk_hdr.offset);
783
784
785
786
787 hdr_offset = chunk_hdr.offset + chunk_hdr.len;
788 if (hdr_offset > (buffer_size - SIGNED_IMAGE_CHUNK_HDR_LEN)) {
789 rc = ENOSPC;
790 goto fail12;
791 }
792 chunk_hdr.magic = SIGNED_IMAGE_CHUNK_HDR_MAGIC;
793 chunk_hdr.version = SIGNED_IMAGE_CHUNK_HDR_VERSION;
794 chunk_hdr.id = SIGNED_IMAGE_CHUNK_IMAGE;
795 chunk_hdr.offset = 0;
796 chunk_hdr.len = code.size;
797
798 memcpy(bufferp + hdr_offset, &chunk_hdr, SIGNED_IMAGE_CHUNK_HDR_LEN);
799
800 if ((chunk_hdr.len > buffer_size) ||
801 (chunk_hdr.offset > (buffer_size - chunk_hdr.len))) {
802 rc = ENOSPC;
803 goto fail13;
804 }
805 memcpy(bufferp + chunk_hdr.offset,
806 infop->eii_imagep + code.offset,
807 code.size);
808
809
810
811
812 chunk_hdr.magic = SIGNED_IMAGE_CHUNK_HDR_MAGIC;
813 chunk_hdr.version = SIGNED_IMAGE_CHUNK_HDR_VERSION;
814 chunk_hdr.id = SIGNED_IMAGE_CHUNK_REFLASH_TRAILER;
815 chunk_hdr.offset = hdr_offset + SIGNED_IMAGE_CHUNK_HDR_LEN;
816 chunk_hdr.len = image_trailer.size;
817
818 hdr_offset = code.size;
819 if (hdr_offset > (buffer_size - SIGNED_IMAGE_CHUNK_HDR_LEN)) {
820 rc = ENOSPC;
821 goto fail14;
822 }
823
824 memcpy(bufferp + hdr_offset, &chunk_hdr, SIGNED_IMAGE_CHUNK_HDR_LEN);
825
826 if ((chunk_hdr.len > buffer_size) ||
827 (chunk_hdr.offset > (buffer_size - chunk_hdr.len))) {
828 rc = ENOSPC;
829 goto fail15;
830 }
831 memcpy((uint8_t *)bufferp + chunk_hdr.offset,
832 infop->eii_imagep + image_trailer.offset,
833 image_trailer.size);
834
835
836
837
838 hdr_offset = chunk_hdr.offset + chunk_hdr.len;
839 if (hdr_offset > (buffer_size - SIGNED_IMAGE_CHUNK_HDR_LEN)) {
840 rc = ENOSPC;
841 goto fail16;
842 }
843 chunk_hdr.magic = SIGNED_IMAGE_CHUNK_HDR_MAGIC;
844 chunk_hdr.version = SIGNED_IMAGE_CHUNK_HDR_VERSION;
845 chunk_hdr.id = SIGNED_IMAGE_CHUNK_SIGNATURE;
846 chunk_hdr.offset = chunk_hdr.offset + SIGNED_IMAGE_CHUNK_HDR_LEN;
847 chunk_hdr.len = signature.size;
848
849 memcpy(bufferp + hdr_offset, &chunk_hdr, SIGNED_IMAGE_CHUNK_HDR_LEN);
850
851 if ((chunk_hdr.len > buffer_size) ||
852 (chunk_hdr.offset > (buffer_size - chunk_hdr.len))) {
853 rc = ENOSPC;
854 goto fail17;
855 }
856 memcpy(bufferp + chunk_hdr.offset,
857 infop->eii_imagep + signature.offset,
858 signature.size);
859
860 return (0);
861
862fail17:
863 EFSYS_PROBE(fail17);
864fail16:
865 EFSYS_PROBE(fail16);
866fail15:
867 EFSYS_PROBE(fail15);
868fail14:
869 EFSYS_PROBE(fail14);
870fail13:
871 EFSYS_PROBE(fail13);
872fail12:
873 EFSYS_PROBE(fail12);
874fail11:
875 EFSYS_PROBE(fail11);
876fail10:
877 EFSYS_PROBE(fail10);
878fail9:
879 EFSYS_PROBE(fail9);
880fail8:
881 EFSYS_PROBE(fail8);
882fail7:
883 EFSYS_PROBE(fail7);
884fail6:
885 EFSYS_PROBE(fail6);
886fail5:
887 EFSYS_PROBE(fail5);
888fail4:
889 EFSYS_PROBE(fail4);
890fail3:
891 EFSYS_PROBE(fail3);
892fail2:
893 EFSYS_PROBE(fail2);
894fail1:
895 EFSYS_PROBE1(fail1, efx_rc_t, rc);
896
897 return (rc);
898}
899
900
901
902#endif
903
904#endif
905