OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
DER_Img4Manifest.c
Go to the documentation of this file.
1
14#include "libDER/libDER.h"
15#include "libDER/asn1Types.h"
16#include "libDER/DER_CertCrl.h"
17#include "libDER/DER_Decode.h"
18#include "libDER/DER_Keys.h"
19#include "libDER/oids.h"
20
21#include "libDERImg4.h"
22#include "DER_Img4Manifest.h"
23#include "Img4oids.h"
24
32
33enum {
36};
37
38bool
40 const DERItem *Item1,
41 const DERItem *Item2
42 )
43{
44 assert (Item1 != NULL);
45 assert (Item2 != NULL);
46
47 if (Item1->length != Item2->length) {
48 return false;
49 }
50
51 return DERMemcmp (Item1->data, Item2->data, Item1->length) == 0;
52}
53
54bool
56 const DERItem *Item
57 )
58{
59 assert (Item != NULL);
60
61 if (Item->length == 2 && Item->data[0] == ASN1_NULL && Item->data[1] == 0) {
62 return true;
63 } else if (Item->length == 0) {
64 return true;
65 }
66
67 return false;
68}
69
72 const DERItem *Contents,
73 uint64_t *Result
74 )
75{
76 DERSize Index;
78 uint64_t Value;
79
80 assert (Contents != NULL);
81 assert (Result != NULL);
82
83 Length = Contents->length;
84 if (Length == 0 || (Contents->data[0] & 0x80U) != 0) {
85 return DR_DecodeError;
86 }
87
88 Value = Contents->data[0];
89 if (Length == 1) {
90 *Result = Value;
91 return DR_Success;
92 }
93 //
94 // It is not perfectly clear why the different sizes are allowed in this way.
95 // The original libDER only supports 32-bit integers and I assume bit
96 // strings, which have their first byte signal the number of unused bits,
97 // might have been or are used to implement 64-bit integers. In this case,
98 // the number of unused bits must be 0 and this byte is discarded.
99 //
100 if (Length > 9 || (Value != 0 && Length > 8)) {
101 return DR_BufOverflow;
102 }
103
104 if (Value == 0 && (Contents->data[1] & 0x80U) == 0) {
105 return DR_DecodeError;
106 }
107
108 for (Index = 1; Index < Length; ++Index) {
109 Value <<= 8U;
110 Value += Contents->data[Index];
111 }
112
113 *Result = Value;
114 return DR_Success;
115}
116
119 const DERItem *Contents,
120 uint32_t *Result
121 )
122{
123 DERReturn DerResult;
124 uint64_t Result64;
125
126 assert (Contents != NULL);
127 assert (Result != NULL);
128
129 DerResult = DERImg4ParseInteger64 (Contents, &Result64);
130 if (DerResult != DR_Success) {
131 return DerResult;
132 }
133
134 if ((Result64 & 0xFFFFFFFF80000000U) != 0) {
135 return DR_BufOverflow;
136 }
137
138 *Result = (uint32_t)Result64;
139 return DR_Success;
140}
141
144 const DERItem *PubKeyItem,
145 const DERItem *SigItem,
146 const DERItem *DataItem,
147 const DERItem *algoOid
148 )
149{
150 bool Result;
151 DERReturn DerResult;
152
153 DERRSAPubKeyPKCS1 PkPkcs1;
154
155 DERItem ModulusItem;
156 DERByte NumUnusedBits;
157
158 uint32_t Exponent;
159
160 assert (PubKeyItem != NULL);
161 assert (SigItem != NULL);
162 assert (DataItem != NULL);
163 assert (algoOid != NULL);
164
165 DerResult = DERParseSequence (
166 PubKeyItem,
169 &PkPkcs1,
170 sizeof (PkPkcs1)
171 );
172 if (DerResult != DR_Success) {
173 return DerResult;
174 }
175
176 DerResult = DERParseBitString (
177 &PkPkcs1.modulus,
178 &ModulusItem,
179 &NumUnusedBits
180 );
181 if (DerResult != DR_Success) {
182 return DerResult;
183 }
184
185 if (NumUnusedBits != 0) {
186 return DR_DecodeError;
187 }
188
189 DerResult = DERImg4ParseInteger32 (&PkPkcs1.pubExponent, &Exponent);
190 if (DerResult != DR_Success) {
191 return DerResult;
192 }
193
194 Result = DERImg4VerifySignature (
195 ModulusItem.data,
196 ModulusItem.length,
197 Exponent,
198 SigItem->data,
199 SigItem->length,
200 DataItem->data,
201 DataItem->length,
202 algoOid
203 );
204 if (!Result) {
206 }
207
208 return DR_Success;
209}
210
211static
213DERImg4ManifestVerifyMagic (
214 const DERItem *ManItem
215 )
216{
217 DERReturn DerResult;
218 uint32_t ItemTag;
219
220 assert (ManItem != NULL);
221
222 if (ManItem->length != sizeof (ItemTag)) {
223 return DR_DecodeError;
224 }
225
226 DerResult = DERImg4ParseInteger32 (ManItem, &ItemTag);
227 if (DerResult != DR_Success) {
228 return DerResult;
229 }
230
231 if (ItemTag != DER_IMG4_TAG_MAN_MAGIC) {
232 return DR_UnexpectedTag;
233 }
234
235 return DR_Success;
236}
237
238static
240DERImg4ManifestCollectCertInfo (
241 Image4CertificateInfo *CertInfo
242 )
243{
244 DERReturn DerResult;
245
246 DERTag CertTbsTag;
247 DERSubjPubKeyInfo CertPubKeyInfo;
248 DERAlgorithmId CertSigAlgoId;
249
250 DERSequence CertTbsSeq;
251 DERDecodedInfo CertTbsSeqInfo;
252 DERDecodedInfo CertExtValueInfo;
253 DERExtension TbsCertExt;
254
255 DERByte NumUnusedBits;
256
257 assert (CertInfo != NULL);
258
259 DerResult = DERParseSequence (
260 &CertInfo->certItem,
263 &CertInfo->certCtrl,
264 sizeof (CertInfo->certCtrl)
265 );
266 if (DerResult != DR_Success) {
267 return DerResult;
268 }
269
270 DerResult = DERParseSequence (
271 &CertInfo->certCtrl.tbs,
274 &CertInfo->tbsCert,
275 sizeof (CertInfo->tbsCert)
276 );
277 if (DerResult != DR_Success) {
278 return DerResult;
279 }
280
281 DerResult = DERParseSequenceContent (
282 &CertInfo->tbsCert.subjectPubKey,
285 &CertPubKeyInfo,
286 sizeof (CertPubKeyInfo)
287 );
288 if (DerResult != DR_Success) {
289 return DerResult;
290 }
291
292 DerResult = DERParseSequenceContent (
293 &CertPubKeyInfo.algId,
296 &CertSigAlgoId,
297 sizeof (CertSigAlgoId)
298 );
299 if (DerResult != DR_Success) {
300 return DerResult;
301 }
302
303 if (!DEROidCompare (&CertSigAlgoId.oid, &oidRsa)
304 || !DERItemNull (&CertSigAlgoId.params)) {
306 }
307
308 DerResult = DERParseBitString (
309 &CertPubKeyInfo.pubKey,
310 &CertInfo->pubKeyItem,
311 &NumUnusedBits
312 );
313 if (DerResult != DR_Success) {
314 return DerResult;
315 }
316
317 if (NumUnusedBits != 0) {
318 return DR_DecodeError;
319 }
320 //
321 // The Manifest Certificate Role is only required to be declared by the last
322 // certificate in the Manifest Certificate Chain.
323 //
324 CertInfo->manCertRoleItem.data = NULL;
325 CertInfo->manCertRoleItem.length = 0;
326 if (CertInfo->tbsCert.extensions.length != 0) {
327 DerResult = DERDecodeSeqInit (
328 &CertInfo->tbsCert.extensions,
329 &CertTbsTag,
330 &CertTbsSeq
331 );
332 if (DerResult != DR_Success) {
333 return DerResult;
334 }
335
336 if (CertTbsTag != ASN1_CONSTR_SEQUENCE) {
337 return DR_UnexpectedTag;
338 }
339
340 while (DERDecodeSeqNext (&CertTbsSeq, &CertTbsSeqInfo) == DR_Success) {
341 if (CertTbsSeqInfo.tag != ASN1_CONSTR_SEQUENCE) {
342 return DR_UnexpectedTag;
343 }
344
345 DerResult = DERParseSequenceContent (
346 &CertTbsSeqInfo.content,
349 &TbsCertExt,
350 sizeof (TbsCertExt)
351 );
352 if (DerResult != DR_Success) {
353 return DerResult;
354 }
355
357 DerResult = DERDecodeItem (&TbsCertExt.extnValue, &CertExtValueInfo);
358 if (DerResult != DR_Success) {
359 return DerResult;
360 }
361
362 if (CertExtValueInfo.tag != ASN1_CONSTR_SET) {
363 return DR_UnexpectedTag;
364 }
365
366 CertInfo->manCertRoleItem.data = TbsCertExt.extnValue.data;
367 CertInfo->manCertRoleItem.length = TbsCertExt.extnValue.length;
368 break;
369 }
370 }
371 }
372
373 return DR_Success;
374}
375
378 const Image4CertificateInfo *ChildCertInfo,
379 const Image4CertificateInfo *ParentCertInfo
380 )
381{
382 bool Result;
383 DERReturn DerResult;
384
385 DERAlgorithmId CertSigAlgoId;
386 DERItem CertSigItem;
387
388 DERByte NumUnusedBits;
389
390 assert (ChildCertInfo != NULL);
391 assert (ParentCertInfo != NULL);
392
393 Result = DERItemCompare (
394 &ChildCertInfo->tbsCert.issuer,
395 &ParentCertInfo->tbsCert.subject
396 );
397 if (!Result) {
399 }
400
401 DerResult = DERParseSequenceContent (
402 &ChildCertInfo->certCtrl.sigAlg,
405 &CertSigAlgoId,
406 sizeof (CertSigAlgoId)
407 );
408 if (DerResult != DR_Success) {
409 return DerResult;
410 }
411
412 if (!DERItemNull (&CertSigAlgoId.params)) {
414 }
415
416 DerResult = DERParseBitString (
417 &ChildCertInfo->certCtrl.sig,
418 &CertSigItem,
419 &NumUnusedBits
420 );
421 if (DerResult != DR_Success) {
422 return DerResult;
423 }
424
425 if (NumUnusedBits != 0) {
426 return DR_DecodeError;
427 }
428
429 DerResult = DERVerifySignature (
430 &ParentCertInfo->pubKeyItem,
431 &CertSigItem,
432 &ChildCertInfo->certCtrl.tbs,
433 &CertSigAlgoId.oid
434 );
435 if (DerResult != DR_Success) {
436 return DerResult;
437 }
438
439 return DR_Success;
440}
441
444 DERItem *ManCertRoleItem,
445 const DERImg4Manifest *Manifest
446 )
447{
448 DERReturn DerResult;
449
450 Image4CertificateInfo ParentCertInfo;
451 Image4CertificateInfo CurCertInfo;
452
453 DERItem CertItem;
454 DERDecodedInfo CertInfo;
455 DERByte *NextCert;
456 DERByte *CertWalker;
457 DERSize LeftCertSize;
458 DERSize CertSize;
459 DERSize Index;
460
461 DERAlgorithmId CertSigAlgoId;
462
463 assert (ManCertRoleItem != NULL);
464 assert (Manifest != NULL);
465 //
466 // Verify the Manifest certification chain.
467 //
468 if (Manifest->certificates.length == 0) {
469 return DR_DecodeError;
470 }
471 //
472 // These pointers must be provided by the platform integrator, either by an
473 // external variable declaration or by a macro.
474 //
477
480 DerResult = DERImg4ManifestCollectCertInfo (&CurCertInfo);
481 if (DerResult != DR_Success) {
482 return DerResult;
483 }
484
485 CertWalker = Manifest->certificates.data;
486 for (
487 Index = 1, LeftCertSize = Manifest->certificates.length;
488 Index < DER_IMG4_MAN_CERT_CHAIN_MAX && LeftCertSize > 0;
489 ++Index, LeftCertSize -= CertSize
490 ) {
491 CopyMem (&ParentCertInfo, &CurCertInfo, sizeof (ParentCertInfo));
492
493 CertItem.data = CertWalker;
494 CertItem.length = LeftCertSize;
495 DerResult = DERDecodeItem (&CertItem, &CertInfo);
496 if (DerResult != DR_Success) {
497 return DerResult;
498 }
499
500 NextCert = &CertInfo.content.data[CertInfo.content.length];
501 CertSize = NextCert - CertWalker;
502 //
503 // This is a guarantee libDER is supposed to make.
504 //
505 assert (CertSize <= LeftCertSize);
506 if (CertSize > DER_IMG4_MAX_CERT_SIZE) {
507 return DR_DecodeError;
508 }
509
510 CurCertInfo.certItem.data = CertWalker;
511 CurCertInfo.certItem.length = CertSize;
512
513 CertWalker = NextCert;
514
515 DerResult = DERImg4ManifestCollectCertInfo (&CurCertInfo);
516 if (DerResult != DR_Success) {
517 return DerResult;
518 }
519
521 &CurCertInfo,
522 &ParentCertInfo
523 );
524 if (DerResult != DR_Success) {
525 return DerResult;
526 }
527 }
528
529 if (LeftCertSize != 0) {
530 return DR_DecodeError;
531 }
532
533 if (CurCertInfo.manCertRoleItem.data == NULL
534 || CurCertInfo.manCertRoleItem.length == 0) {
535 return DR_DecodeError;
536 }
537 //
538 // Verify the Manifest body signature.
539 //
540 DerResult = DERParseSequenceContent (
541 &CurCertInfo.tbsCert.tbsSigAlg,
544 &CertSigAlgoId,
545 sizeof (CertSigAlgoId)
546 );
547 if (DerResult != DR_Success) {
548 return DerResult;
549 }
550
551 if (!DERItemNull (&CertSigAlgoId.params)) {
553 }
554
555 DerResult = DERVerifySignature (
556 &CurCertInfo.pubKeyItem,
557 &Manifest->signature,
558 &Manifest->body,
559 &CertSigAlgoId.oid
560 );
561 if (DerResult != DR_Success) {
562 return DerResult;
563 }
564
565 ManCertRoleItem->data = CurCertInfo.manCertRoleItem.data;
566 ManCertRoleItem->length = CurCertInfo.manCertRoleItem.length;
567 return DR_Success;
568}
569
572 const DERItem *PropSetItem,
573 DERTag PropName,
574 DERItem *PropItem
575 )
576{
577 DERReturn DerResult;
578
579 DERSequence PropSetSeq;
580 DERDecodedInfo PropInfo;
581
582 assert (PropSetItem != NULL);
583 assert (PropItem != NULL);
584
585 DerResult = DERDecodeSeqContentInit (PropSetItem, &PropSetSeq);
586 if (DerResult != DR_Success) {
587 return DerResult;
588 }
589
590 while ((DerResult = DERDecodeSeqNext (&PropSetSeq, &PropInfo)) == DR_Success) {
591 if (PropInfo.tag == PropName) {
592 PropItem->length = PropInfo.content.length;
593 PropItem->data = PropInfo.content.data;
594 return DR_Success;
595 }
596 }
597
598 return DerResult;
599}
600
603 const DERItem *PropSetItem,
604 DERTag PropName,
605 DERTag PropValueTag,
606 DERImg4Property *Property
607 )
608{
609 STATIC CONST DERItemSpec PropertyItemSpecTpl[] = DER_IMG4_PROPERTY_SPEC_INIT;
610
611 DERReturn DerResult;
612 DERItem PropItem;
613 uint32_t CurPropTag;
614 DERItemSpec PropertyItemSpec[ARRAY_SIZE (PropertyItemSpecTpl)];
615
616 CopyMem (PropertyItemSpec, PropertyItemSpecTpl, sizeof (PropertyItemSpecTpl));
617
618 PropertyItemSpec[1].tag = PropValueTag;
619
620 assert (PropSetItem != NULL);
621 assert (Property != NULL);
622
623 DerResult = DERImg4FindPropertyItem (
624 PropSetItem,
625 PropName,
626 &PropItem
627 );
628 if (DerResult != DR_Success) {
629 return DerResult;
630 }
631
632 DerResult = DERParseSequence (
633 &PropItem,
634 ARRAY_SIZE (PropertyItemSpec),
635 PropertyItemSpec,
636 Property,
637 0
638 );
639 if (DerResult != DR_Success) {
640 return DerResult;
641 }
642
643 DerResult = DERImg4ParseInteger32 (&Property->nameItem, &CurPropTag);
644 if (DerResult != DR_Success) {
645 return DerResult;
646 }
647
648 if (DER_IMG4_ENCODE_PROPERTY_NAME (CurPropTag) != PropName) {
649 return DR_UnexpectedTag;
650 }
651
652 Property->nameTag = PropName;
653 Property->valueTag = PropValueTag;
654 return DR_Success;
655}
656
659 const DERItem *PropItem,
660 DERTag PropName,
661 DERImg4Property *Property
662 )
663{
664 DERReturn DerResult;
665
666 DERTag PropTag;
667 DERSequence PropSeq;
668
669 DERDecodedInfo PropNameInfo;
670 uint32_t PropNameTag;
671
672 DERDecodedInfo PropValueInfo;
673 DERDecodedInfo PropTailInfo;
674
675 assert (PropItem != NULL);
676 assert (Property != NULL);
677
678 DerResult = DERDecodeSeqInit (PropItem, &PropTag, &PropSeq);
679 if (DerResult != DR_Success) {
680 return DerResult;
681 }
682
683 if (PropTag != ASN1_CONSTR_SEQUENCE) {
684 return DR_UnexpectedTag;
685 }
686
687 DerResult = DERDecodeSeqNext (&PropSeq, &PropNameInfo);
688 if (DerResult != DR_Success) {
689 return DerResult;
690 }
691
692 if (PropNameInfo.tag != ASN1_IA5_STRING) {
693 return DR_UnexpectedTag;
694 }
695
696 DerResult = DERImg4ParseInteger32 (&PropNameInfo.content, &PropNameTag);
697 if (DerResult != DR_Success) {
698 return DerResult;
699 }
700
701 if (DER_IMG4_ENCODE_PROPERTY_NAME (PropNameTag) != PropName) {
702 return DR_UnexpectedTag;
703 }
704
705 DerResult = DERDecodeSeqNext (&PropSeq, &PropValueInfo);
706 if (DerResult != DR_Success) {
707 return DerResult;
708 }
709
710 DerResult = DERDecodeSeqNext (&PropSeq, &PropTailInfo);
711 if (DerResult != DR_EndOfSequence) {
712 return DR_DecodeError;
713 }
714
715 Property->nameTag = PropName;
716 Property->nameItem.data = PropNameInfo.content.data;
717 Property->nameItem.length = PropNameInfo.content.length;
718
719 Property->valueTag = PropValueInfo.tag;
720 Property->valueItem.data = PropValueInfo.content.data;
721 Property->valueItem.length = PropValueInfo.content.length;
722 return DR_Success;
723}
724
727 const DERItem *PropItem,
728 uint32_t PropName,
729 bool *Value
730 )
731{
732 DERReturn DerResult;
733 DERImg4Property Property;
734
735 assert (PropItem != NULL);
736 assert (Value != NULL);
737
738 DerResult = DERImg4DecodeProperty (
739 PropItem,
741 &Property
742 );
743 if (DerResult != DR_Success) {
744 return DerResult;
745 }
746
747 if (Property.valueTag != ASN1_BOOLEAN) {
748 return DR_UnexpectedTag;
749 }
750
751 if (Property.valueItem.length != 1
752 || (*Property.valueItem.data != 0 && *Property.valueItem.data != 0xFF)) {
753 return DR_DecodeError;
754 }
755
756 *Value = *Property.valueItem.data != 0;
757 return DR_Success;
758}
759
762 const DERItem *PropItem,
763 uint32_t PropName,
764 uint32_t *Value
765 )
766{
767 DERReturn DerResult;
768 DERImg4Property Property;
769
770 assert (PropItem != NULL);
771 assert (Value != NULL);
772
773 DerResult = DERImg4DecodeProperty (
774 PropItem,
776 &Property
777 );
778 if (DerResult != DR_Success) {
779 return DerResult;
780 }
781
782 if (Property.valueTag != ASN1_INTEGER) {
783 return DR_UnexpectedTag;
784 }
785
786 return DERImg4ParseInteger32 (&Property.valueItem, Value);
787}
788
791 const DERItem *PropItem,
792 uint32_t PropName,
793 uint64_t *Value
794 )
795{
796 DERReturn DerResult;
797 DERImg4Property Property;
798
799 assert (PropItem != NULL);
800 assert (Value != NULL);
801
802 DerResult = DERImg4DecodeProperty (
803 PropItem,
805 &Property
806 );
807 if (DerResult != DR_Success) {
808 return DerResult;
809 }
810
811 if (Property.valueTag != ASN1_INTEGER) {
812 return DR_UnexpectedTag;
813 }
814
815 return DERImg4ParseInteger64 (&Property.valueItem, Value);
816}
817
820 const DERItem *ManPropSetItem,
821 const DERItem *ObjPropSetItem,
822 const DERItem *ManBodyCertItem
823 )
824{
825 DERReturn DerResult;
826 DERReturn LoopDerResult;
827 DERReturn LoopDerResult2;
828
829 DERTag ManBodyCertTag;
830 DERSequence ManBodyCertSet;
831
832 DERDecodedInfo CertPropSetInfo;
833 DERImg4Property CertPropSet;
834 DERSequence CertPropSetSeq;
835
836 DERDecodedInfo CertPropInfo;
837 DERImg4Property CurCertProp;
838
839 DERItem BodyPropSetItem;
840 DERItem BodyPropItem;
841
842 assert (ManPropSetItem != NULL);
843 assert (ObjPropSetItem != NULL);
844 assert (ManBodyCertItem != NULL);
845
846 DerResult = DERDecodeSeqInit (
847 ManBodyCertItem,
848 &ManBodyCertTag,
849 &ManBodyCertSet
850 );
851 if (DerResult != DR_Success) {
852 return DerResult;
853 }
854
855 if (ManBodyCertTag != ASN1_CONSTR_SET) {
856 return DR_UnexpectedTag;
857 }
858
859 while ((LoopDerResult = DERDecodeSeqNext (&ManBodyCertSet, &CertPropSetInfo)) == DR_Success) {
861 BodyPropSetItem.data = ObjPropSetItem->data;
862 BodyPropSetItem.length = ObjPropSetItem->length;
863 } else if (CertPropSetInfo.tag == DER_IMG4_ENCODE_PROPERTY_NAME (DER_IMG4_TAG_MAN_PROPS)) {
864 BodyPropSetItem.data = ManPropSetItem->data;
865 BodyPropSetItem.length = ManPropSetItem->length;
866 } else {
867 return DR_UnexpectedTag;
868 }
869
870 DerResult = DERImg4DecodeProperty (
871 &CertPropSetInfo.content,
872 CertPropSetInfo.tag,
873 &CertPropSet
874 );
875 if (DerResult != DR_Success) {
876 return DerResult;
877 }
878
879 if (CertPropSet.valueTag != ASN1_CONSTR_SET) {
880 return DR_UnexpectedTag;
881 }
882
883 DerResult = DERDecodeSeqContentInit (
884 &CertPropSet.valueItem,
885 &CertPropSetSeq
886 );
887 if (DerResult != DR_Success) {
888 return DerResult;
889 }
890
891 while ((LoopDerResult2 = DERDecodeSeqNext (&CertPropSetSeq, &CertPropInfo)) == DR_Success) {
892 DerResult = DERImg4DecodeProperty (
893 &CertPropInfo.content,
894 CertPropInfo.tag,
895 &CurCertProp
896 );
897 if (DerResult != DR_Success) {
898 return DerResult;
899 }
900
901 DerResult = DERImg4FindPropertyItem (
902 &BodyPropSetItem,
903 CertPropInfo.tag,
904 &BodyPropItem
905 );
906 if (CurCertProp.valueTag == ASN1_BOOLEAN
907 || CurCertProp.valueTag == ASN1_INTEGER
908 || CurCertProp.valueTag == ASN1_OCTET_STRING) {
909 //
910 // The specified key must be present with the exact role value.
911 //
912 if (DerResult != DR_Success) {
913 return DerResult;
914 }
915
916 if (!DERItemCompare (&CertPropInfo.content, &BodyPropItem)) {
918 }
919 } else if (CurCertProp.valueTag == (ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 0)) {
920 //
921 // The specified key must be present with an arbitrary value.
922 //
923 if (DerResult != DR_Success) {
924 return DerResult;
925 }
926 } else if (CurCertProp.valueTag == (ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 1)) {
927 //
928 // The specified key must not be present.
929 //
930 if (DerResult != DR_EndOfSequence) {
931 return DR_UnexpectedTag;
932 }
933 } else {
934 //
935 // An unexpected tag has been encountered.
936 //
937 return DR_UnexpectedTag;
938 }
939 }
940
941 if (LoopDerResult2 != DR_EndOfSequence) {
942 return DR_DecodeError;
943 }
944 }
945
946 if (LoopDerResult != DR_EndOfSequence) {
947 return LoopDerResult;
948 }
949
950 return DR_Success;
951}
952
955 const DERItem *PropItem,
956 uint32_t PropName,
957 DERImg4ManifestInfo *ManInfo,
958 uint32_t PropSetType
959 )
960{
961 DERReturn DerResult;
962 DERImg4Property Property;
963 uint64_t Ecid;
964
965 assert (PropItem != NULL);
966 assert (ManInfo != NULL);
967
968 if (PropSetType == Img4ManifestPropSetTypeObjp) {
969 switch (PropName) {
971 {
972 ManInfo->hasEffectiveProductionStatus = true;
974 PropItem,
975 PropName,
977 );
978 }
979
981 {
982 ManInfo->hasEffectiveSecurityMode = true;
984 PropItem,
985 PropName,
987 );
988 }
989
991 {
992 DerResult = DERImg4DecodeProperty (
993 PropItem,
995 &Property
996 );
997 if (DerResult != DR_Success) {
998 return DerResult;
999 }
1000
1001 if (Property.valueTag != ASN1_OCTET_STRING) {
1002 return DR_UnexpectedTag;
1003 }
1004
1005 if (Property.valueItem.length > sizeof (ManInfo->imageDigest)) {
1006 return DR_BufOverflow;
1007 }
1008
1009 if (Property.valueItem.length == 0) {
1010 return DR_DecodeError;
1011 }
1012
1013 DERMemmove (
1014 ManInfo->imageDigest,
1015 Property.valueItem.data,
1016 Property.valueItem.length
1017 );
1018 ManInfo->imageDigestSize = Property.valueItem.length;
1019
1020 return DR_Success;
1021 }
1022
1024 {
1026 PropItem,
1027 PropName,
1028 &ManInfo->environment.enableKeys
1029 );
1030 }
1031
1032 default:
1033 {
1034 //
1035 // For forward compatibility, ignore unknown keys.
1036 //
1037 return DR_Success;
1038 }
1039 }
1040 } else {
1041 //
1042 // The conditional branches must be modified when more types are added.
1043 //
1044 assert (PropSetType == Img4ManifestPropSetTypeManp);
1045
1046 switch (PropName) {
1048 {
1050 PropItem,
1051 PropName,
1053 );
1054 }
1055
1057 {
1058 ManInfo->hasEcid = true;
1059 DerResult = DERImg4DecodePropertyInteger64 (PropItem, PropName, &Ecid);
1060 if (DerResult == DR_Success) {
1061 ManInfo->environment.ecid = Ecid;
1062 }
1063
1064 return DerResult;
1065 }
1066
1068 {
1070 PropItem,
1071 PropName,
1072 &ManInfo->environment.chipId
1073 );
1074 }
1075
1077 {
1079 PropItem,
1080 PropName,
1081 &ManInfo->environment.boardId
1082 );
1083 }
1084
1086 {
1088 PropItem,
1089 PropName,
1090 &ManInfo->environment.allowMixNMatch
1091 );
1092 }
1093
1095 {
1097 PropItem,
1098 PropName,
1099 &ManInfo->environment.securityDomain
1100 );
1101 }
1102
1104 {
1106 PropItem,
1107 PropName,
1109 );
1110 }
1111
1113 {
1115 PropItem,
1116 PropName,
1118 );
1119 }
1120
1122 {
1124 PropItem,
1125 PropName,
1126 &ManInfo->environment.securityMode
1127 );
1128 }
1129
1131 {
1132 ManInfo->hasXugs = true;
1134 PropItem,
1135 PropName,
1136 &ManInfo->environment.xugs
1137 );
1138 }
1139
1140 default:
1141 {
1142 //
1143 // For forward compatibility, ignore unknown keys.
1144 //
1145 return DR_Success;
1146 }
1147 }
1148 }
1149}
1150
1153 DERImg4ManifestInfo *ManInfo,
1154 const DERItem *PropSetItem,
1155 uint32_t PropSetType
1156 )
1157{
1158 DERReturn DerResult;
1159 DERReturn LoopDerResult;
1160
1161 DERSequence PropSetSeq;
1162 DERDecodedInfo PropInfo;
1163 DERImg4Property Property;
1164
1165 assert (ManInfo != NULL);
1166 assert (PropSetItem != NULL);
1167
1168 DerResult = DERDecodeSeqContentInit (PropSetItem, &PropSetSeq);
1169 if (DerResult != DR_Success) {
1170 return DerResult;
1171 }
1172
1173 while ((LoopDerResult = DERDecodeSeqNext (&PropSetSeq, &PropInfo)) == DR_Success) {
1174 DerResult = DERImg4DecodeProperty (
1175 &PropInfo.content,
1176 PropInfo.tag,
1177 &Property
1178 );
1179 if (DerResult != DR_Success) {
1180 return DerResult;
1181 }
1182
1183 if (Property.valueTag != ASN1_BOOLEAN
1184 && Property.valueTag != ASN1_INTEGER
1185 && Property.valueTag != ASN1_OCTET_STRING
1186 && Property.valueTag != ASN1_IA5_STRING
1187 ) {
1188 return DR_UnexpectedTag;
1189 }
1190
1191 if ((PropInfo.tag & ASN1_CLASS_MASK) == 0
1192 || (PropInfo.tag & ASN1_CONSTRUCTED) == 0) {
1193 return DR_UnexpectedTag;
1194 }
1195
1196 DerResult = DERImg4ManifestDecodeProperty (
1197 &PropInfo.content,
1198 (uint32_t)PropInfo.tag,
1199 ManInfo,
1200 PropSetType
1201 );
1202 if (DerResult != DR_Success) {
1203 return DerResult;
1204 }
1205 }
1206
1207 if (LoopDerResult != DR_EndOfSequence) {
1208 return LoopDerResult;
1209 }
1210
1211 return DR_Success;
1212}
1213
1231 DERImg4ManifestInfo *ManInfo,
1232 const void *ManBuffer,
1233 size_t ManSize,
1234 uint32_t ObjType
1235 )
1236{
1237 DERReturn DerResult;
1238
1239 DERItem ManifestItem;
1240 DERSize DerManifestSize;
1241
1242 DERDecodedInfo ManifestInfo;
1243 DERImg4Manifest Manifest;
1244 uint32_t ManVersion;
1245
1246 DERDecodedInfo ManBodyInfo;
1247 DERImg4Property ManBodyProp;
1248
1249 DERImg4Property ManPropSetProp;
1250 DERImg4Property ObjPropSetProp;
1251
1252 DERItem ManBodyCertRoleItem;
1253
1254 assert (ManInfo != NULL);
1255 assert (ManBuffer != NULL);
1256 assert (ManSize > 0);
1257 //
1258 // Verify the Manifest header integrity.
1259 //
1260 ManifestItem.data = (DERByte *)ManBuffer;
1261 ManifestItem.length = ManSize;
1262 DerResult = DERDecodeItem (&ManifestItem, &ManifestInfo);
1263 if (DerResult != DR_Success) {
1264 return DerResult;
1265 }
1266
1267 if (ManifestInfo.tag != ASN1_CONSTR_SEQUENCE) {
1268 return DR_UnexpectedTag;
1269 }
1270 //
1271 // This is a guarantee libDER is supposed to make.
1272 //
1273 assert (ManifestInfo.content.data >= (DERByte *)ManBuffer);
1274
1275 DerManifestSize = (DERByte *)ManifestInfo.content.data - (DERByte *)ManBuffer;
1276 DerManifestSize += ManifestInfo.content.length;
1277 if (DerManifestSize != ManSize) {
1278 return DR_DecodeError;
1279 }
1280
1281 DerResult = DERParseSequenceContent (
1282 &ManifestInfo.content,
1283 DERNumImg4ManifestItemSpecs,
1284 DERImg4ManifestItemSpecs,
1285 &Manifest,
1286 0
1287 );
1288 if (DerResult != DR_Success) {
1289 return DerResult;
1290 }
1291
1292 if (Manifest.body.data == NULL) {
1293 return DR_DecodeError;
1294 }
1295
1296 DerResult = DERImg4ManifestVerifyMagic (&Manifest.magic);
1297 if (DerResult != DR_Success) {
1298 return DerResult;
1299 }
1300
1301 DerResult = DERImg4ParseInteger32 (&Manifest.version, &ManVersion);
1302 if (DerResult != DR_Success) {
1303 return DerResult;
1304 }
1305
1306 if (ManVersion != 0) {
1307 return DR_DecodeError;
1308 }
1309 //
1310 // Verify the Manifest body.
1311 //
1312 DerResult = DERImg4ManifestVerifySignature (&ManBodyCertRoleItem, &Manifest);
1313 if (DerResult != DR_Success) {
1314 return DerResult;
1315 }
1316
1317 DerResult = DERDecodeItem (&Manifest.body, &ManBodyInfo);
1318 if (DerResult != DR_Success) {
1319 return DerResult;
1320 }
1321
1322 if (ManBodyInfo.tag != ASN1_CONSTR_SET) {
1323 return DR_UnexpectedTag;
1324 }
1325
1326 DerResult = DERImg4FindDecodeProperty (
1327 &ManBodyInfo.content,
1330 &ManBodyProp
1331 );
1332 if (DerResult != DR_Success) {
1333 return DerResult;
1334 }
1335
1336 DerResult = DERImg4FindDecodeProperty (
1337 &ManBodyProp.valueItem,
1340 &ManPropSetProp
1341 );
1342 if (DerResult != DR_Success) {
1343 return DerResult;
1344 }
1345
1346 DerResult = DERImg4FindDecodeProperty (
1347 &ManBodyProp.valueItem,
1350 &ObjPropSetProp
1351 );
1352 if (DerResult != DR_Success) {
1353 return DerResult;
1354 }
1355
1356 DerResult = DERImg4ValidateCertificateRole (
1357 &ManPropSetProp.valueItem,
1358 &ObjPropSetProp.valueItem,
1359 &ManBodyCertRoleItem
1360 );
1361 if (DerResult != DR_Success) {
1362 return DerResult;
1363 }
1364
1365 DERMemset (ManInfo, 0, sizeof (*ManInfo));
1366 //
1367 // Decode the Manifest body.
1368 //
1370 ManInfo,
1371 &ManPropSetProp.valueItem,
1373 );
1374 if (DerResult != DR_Success) {
1375 return DerResult;
1376 }
1377
1379 ManInfo,
1380 &ObjPropSetProp.valueItem,
1382 );
1383 if (DerResult != DR_Success) {
1384 return DerResult;
1385 }
1386
1387 return DR_Success;
1388}
#define ARRAY_SIZE(Array)
Definition AppleMacEfi.h:34
UINT64 Length
const DERItemSpec DERTBSCertItemSpecs[]
Definition DER_CertCrl.c:35
const DERShort DERNumSignedCertCrlItemSpecs
Definition DER_CertCrl.c:31
const DERShort DERNumTBSCertItemSpecs
Definition DER_CertCrl.c:71
const DERShort DERNumExtensionItemSpecs
const DERItemSpec DERExtensionItemSpecs[]
const DERItemSpec DERSignedCertCrlItemSpecs[]
Definition DER_CertCrl.c:18
DERReturn DERParseSequenceContent(const DERItem *content, DERShort numItems, const DERItemSpec *itemSpecs, void *dest, DERSize sizeToZero)
Definition DER_Decode.c:303
DERReturn DERDecodeSeqInit(const DERItem *der, DERTag *tag, DERSequence *derSeq)
Definition DER_Decode.c:211
DERReturn DERDecodeSeqNext(DERSequence *derSeq, DERDecodedInfo *decoded)
Definition DER_Decode.c:251
DERReturn DERDecodeSeqContentInit(const DERItem *content, DERSequence *derSeq)
Definition DER_Decode.c:241
DERReturn DERDecodeItem(const DERItem *der, DERDecodedInfo *decoded)
Definition DER_Decode.c:63
DERReturn DERParseBitString(const DERItem *contents, DERItem *bitStringBytes, DERByte *numUnusedBits)
Definition DER_Decode.c:150
DERReturn DERParseSequence(const DERItem *der, DERShort numItems, const DERItemSpec *itemSpecs, void *dest, DERSize sizeToZero)
Definition DER_Decode.c:281
DERReturn DERImg4FindPropertyItem(const DERItem *PropSetItem, DERTag PropName, DERItem *PropItem)
bool DERItemNull(const DERItem *Item)
DERReturn DERImg4FindDecodeProperty(const DERItem *PropSetItem, DERTag PropName, DERTag PropValueTag, DERImg4Property *Property)
DERReturn DERImg4DecodePropertyInteger32(const DERItem *PropItem, uint32_t PropName, uint32_t *Value)
DERReturn DERImg4ManifestVerifyCertIssuer(const Image4CertificateInfo *ChildCertInfo, const Image4CertificateInfo *ParentCertInfo)
DERReturn DERImg4ManifestDecodeProperty(const DERItem *PropItem, uint32_t PropName, DERImg4ManifestInfo *ManInfo, uint32_t PropSetType)
DERReturn DERImg4DecodePropertyInteger64(const DERItem *PropItem, uint32_t PropName, uint64_t *Value)
DERReturn DERImg4DecodeProperty(const DERItem *PropItem, DERTag PropName, DERImg4Property *Property)
bool DERItemCompare(const DERItem *Item1, const DERItem *Item2)
DERReturn DERImg4ParseInteger64(const DERItem *Contents, uint64_t *Result)
DERReturn DERImg4ParseInteger32(const DERItem *Contents, uint32_t *Result)
DERReturn DERImg4ManifestDecodeProperties(DERImg4ManifestInfo *ManInfo, const DERItem *PropSetItem, uint32_t PropSetType)
@ Img4ManifestPropSetTypeObjp
@ Img4ManifestPropSetTypeManp
DERReturn DERVerifySignature(const DERItem *PubKeyItem, const DERItem *SigItem, const DERItem *DataItem, const DERItem *algoOid)
DERReturn DERImg4ValidateCertificateRole(const DERItem *ManPropSetItem, const DERItem *ObjPropSetItem, const DERItem *ManBodyCertItem)
DERReturn DERImg4ManifestVerifySignature(DERItem *ManCertRoleItem, const DERImg4Manifest *Manifest)
DERReturn DERImg4ParseManifest(DERImg4ManifestInfo *ManInfo, const void *ManBuffer, size_t ManSize, uint32_t ObjType)
DERReturn DERImg4ManifestDecodePropertyBoolean(const DERItem *PropItem, uint32_t PropName, bool *Value)
#define DER_IMG4_TAG_OBJ_EKEY
#define DER_IMG4_TAG_MAN_IUOB
#define DER_IMG4_TAG_MAN_ECID
#define DER_IMG4_TAG_MAN_CHIP
#define DER_IMG4_TAG_MAN_PROPS
#define DER_IMG4_TAG_MAN_BORD
#define DER_IMG4_ENCODE_PROPERTY_NAME(Name)
#define DER_IMG4_TAG_MAN_XUGS
#define DER_IMG4_TAG_MAN_MPRO
#define DER_IMG4_TAG_OBJ_PROPS
#define DER_IMG4_TAG_OBJ_EPRO
#define DER_IMG4_TAG_MAN_MSEC
#define DER_IMG4_TAG_MAN_SDOM
#define DER_IMG4_TAG_MAN_AMNM
#define DER_IMG4_TAG_MAN_MAGIC
#define DER_IMG4_PROPERTY_SPEC_INIT
#define DER_IMG4_TAG_MAN_CEPO
#define DER_IMG4_TAG_OBJ_ESEC
#define DER_IMG4_TAG_OBJ_DGST
#define DER_IMG4_TAG_MAN_BODY
const DERItemSpec DERRSAPubKeyPKCS1ItemSpecs[]
Definition DER_Keys.c:94
const DERShort DERNumSubjPubKeyInfoItemSpecs
Definition DER_Keys.c:48
const DERItemSpec DERSubjPubKeyInfoItemSpecs[]
Definition DER_Keys.c:38
const DERItemSpec DERAlgorithmIdItemSpecs[]
Definition DER_Keys.c:25
const DERShort DERNumAlgorithmIdItemSpecs
Definition DER_Keys.c:34
const DERShort DERNumRSAPubKeyPKCS1ItemSpecs
Definition DER_Keys.c:103
const DERItem oidAppleImg4ManifestCertSpec
Definition Img4oids.c:32
#define uint32_t
Definition Ubsan.h:59
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define ASN1_INTEGER
Definition asn1Types.h:19
#define ASN1_CONSTR_SET
Definition asn1Types.h:84
#define ASN1_NULL
Definition asn1Types.h:22
#define ASN1_CLASS_MASK
Definition asn1Types.h:74
#define ASN1_IA5_STRING
Definition asn1Types.h:39
#define ASN1_BOOLEAN
Definition asn1Types.h:18
#define ASN1_CONSTRUCTED
Definition asn1Types.h:72
#define ASN1_CONSTR_SEQUENCE
Definition asn1Types.h:83
#define ASN1_CONTEXT_SPECIFIC
Definition asn1Types.h:77
#define ASN1_OCTET_STRING
Definition asn1Types.h:21
DERReturn
Definition libDER.h:20
@ DR_Success
Definition libDER.h:21
@ DR_BufOverflow
Definition libDER.h:28
@ DR_EndOfSequence
Definition libDER.h:22
@ DR_UnexpectedTag
Definition libDER.h:23
@ DR_DecodeError
Definition libDER.h:24
size_t DERSize
#define DERMemmove(dst, src, len)
uint64_t DERTag
uint8_t DERByte
UINT32 uint32_t
#define assert
UINT64 uint64_t
#define DERMemcmp(b1, b2, len)
#define DERMemset(ptr, c, len)
@ DR_SecurityError
Definition libDERImg4.h:25
const UINTN * DERImg4RootCertificateSize
#define DER_IMG4_MAX_CERT_SIZE
const UINT8 * DERImg4RootCertificate
bool DERImg4VerifySignature(DERByte *Modulus, DERSize ModulusSize, uint32_t Exponent, const uint8_t *Signature, size_t SignatureSize, uint8_t *Data, size_t DataSize, const DERItem *AlgoOid)
const DERItem oidRsa
Definition oids.c:264
bool DEROidCompare(const DERItem *oid1, const DERItem *oid2)
Definition oids.c:454
DERItem oid
Definition DER_Keys.h:21
DERItem params
Definition DER_Keys.h:22
DERItem content
Definition DER_Decode.h:44
DERItem extnID
Definition DER_CertCrl.h:76
DERItem extnValue
Definition DER_CertCrl.h:78
bool effectiveProductionStatus
Definition libDERImg4.h:36
uint32_t allowMixNMatch
Definition libDERImg4.h:41
uint32_t securityDomain
Definition libDERImg4.h:33
uint32_t certificateEpoch
Definition libDERImg4.h:32
uint8_t imageDigest[DER_IMG4_MAX_DIGEST_SIZE]
Definition libDERImg4.h:51
bool hasEffectiveSecurityMode
Definition libDERImg4.h:48
DERImg4Environment environment
Definition libDERImg4.h:45
bool hasEffectiveProductionStatus
Definition libDERImg4.h:47
DERByte * data
Definition libDER.h:36
DERSize length
Definition libDER.h:37
DERTag tag
Definition libDER.h:47
DERItem modulus
Definition DER_Keys.h:44
DERItem pubExponent
Definition DER_Keys.h:45
DERItem subjectPubKey
Definition DER_CertCrl.h:41
DERItem subject
Definition DER_CertCrl.h:40
DERItem tbsSigAlg
Definition DER_CertCrl.h:37
DERItem extensions
Definition DER_CertCrl.h:44
DERItem issuer
Definition DER_CertCrl.h:38
DERSignedCertCrl certCtrl