2 # Module that encodes and decodes a EFI_FIRMWARE_IMAGE_AUTHENTICATION with
3 # certificate data and payload data.
5 # Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
16 class FmpAuthHeaderClass (object):
18 # /// Image Attribute -Authentication Required
22 # /// It is included in the signature of AuthInfo. It is used to ensure freshness/no replay.
23 # /// It is incremented during each firmware image operation.
25 # UINT64 MonotonicCount;
27 # /// Provides the authorization for the firmware image operations. It is a signature across
28 # /// the image data and the Monotonic Count value. Caller uses the private key that is
29 # /// associated with a public key that has been provisioned via the key exchange.
30 # /// Because this is defined as a signature, WIN_CERTIFICATE_UEFI_GUID.CertType must
31 # /// be EFI_CERT_TYPE_PKCS7_GUID.
33 # WIN_CERTIFICATE_UEFI_GUID AuthInfo;
34 # } EFI_FIRMWARE_IMAGE_AUTHENTICATION;
37 # /// Certificate which encapsulates a GUID-specific digital signature
41 # /// This is the standard WIN_CERTIFICATE header, where
42 # /// wCertificateType is set to WIN_CERT_TYPE_EFI_GUID.
44 # WIN_CERTIFICATE Hdr;
46 # /// This is the unique id which determines the
47 # /// format of the CertData. .
51 # /// The following is the certificate data. The format of
52 # /// the data is determined by the CertType.
53 # /// If CertType is EFI_CERT_TYPE_RSA2048_SHA256_GUID,
54 # /// the CertData will be EFI_CERT_BLOCK_RSA_2048_SHA256 structure.
57 # } WIN_CERTIFICATE_UEFI_GUID;
60 # /// The WIN_CERTIFICATE structure is part of the PE/COFF specification.
64 # /// The length of the entire certificate,
65 # /// including the length of the header, in bytes.
69 # /// The revision level of the WIN_CERTIFICATE
70 # /// structure. The current revision level is 0x0200.
74 # /// The certificate type. See WIN_CERT_TYPE_xxx for the UEFI
75 # /// certificate types. The UEFI specification reserves the range of
76 # /// certificate type values from 0x0EF0 to 0x0EFF.
78 # UINT16 wCertificateType;
80 # /// The following is the actual certificate. The format of
81 # /// the certificate depends on wCertificateType.
83 # /// UINT8 bCertificate[ANYSIZE_ARRAY];
87 # #define WIN_CERT_TYPE_EFI_GUID 0x0EF1
90 # /// This identifies a signature containing a DER-encoded PKCS #7 version 1.5 [RFC2315]
91 # /// SignedData value.
93 # #define EFI_CERT_TYPE_PKCS7_GUID \
95 # 0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7} \
98 _StructFormat
= '<QIHH16s'
99 _StructSize
= struct
.calcsize (_StructFormat
)
101 _MonotonicCountFormat
= '<Q'
102 _MonotonicCountSize
= struct
.calcsize (_MonotonicCountFormat
)
104 _StructAuthInfoFormat
= '<IHH16s'
105 _StructAuthInfoSize
= struct
.calcsize (_StructAuthInfoFormat
)
107 _WIN_CERT_REVISION
= 0x0200
108 _WIN_CERT_TYPE_EFI_GUID
= 0x0EF1
109 _EFI_CERT_TYPE_PKCS7_GUID
= uuid
.UUID ('4aafd29d-68df-49ee-8aa9-347d375665a7')
113 self
.MonotonicCount
= 0
114 self
.dwLength
= self
._StructAuthInfoSize
115 self
.wRevision
= self
._WIN
_CERT
_REVISION
116 self
.wCertificateType
= self
._WIN
_CERT
_TYPE
_EFI
_GUID
117 self
.CertType
= self
._EFI
_CERT
_TYPE
_PKCS
7_GUID
123 if self
.wRevision
!= self
._WIN
_CERT
_REVISION
:
125 if self
.wCertificateType
!= self
._WIN
_CERT
_TYPE
_EFI
_GUID
:
127 if self
.CertType
!= self
._EFI
_CERT
_TYPE
_PKCS
7_GUID
:
129 self
.dwLength
= self
._StructAuthInfoSize
+ len (self
.CertData
)
131 FmpAuthHeader
= struct
.pack (
136 self
.wCertificateType
,
137 self
.CertType
.bytes_le
141 return FmpAuthHeader
+ self
.CertData
+ self
.Payload
143 def Decode (self
, Buffer
):
144 if len (Buffer
) < self
._StructSize
:
146 (MonotonicCount
, dwLength
, wRevision
, wCertificateType
, CertType
) = \
149 Buffer
[0:self
._StructSize
]
151 if dwLength
< self
._StructAuthInfoSize
:
153 if wRevision
!= self
._WIN
_CERT
_REVISION
:
155 if wCertificateType
!= self
._WIN
_CERT
_TYPE
_EFI
_GUID
:
157 if CertType
!= self
._EFI
_CERT
_TYPE
_PKCS
7_GUID
.bytes_le
:
159 self
.MonotonicCount
= MonotonicCount
160 self
.dwLength
= dwLength
161 self
.wRevision
= wRevision
162 self
.wCertificateType
= wCertificateType
163 self
.CertType
= uuid
.UUID (bytes_le
= CertType
)
164 self
.CertData
= Buffer
[self
._StructSize
:self
._MonotonicCountSize
+ self
.dwLength
]
165 self
.Payload
= Buffer
[self
._MonotonicCountSize
+ self
.dwLength
:]
172 print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.MonotonicCount = {MonotonicCount:016X}'.format (MonotonicCount
= self
.MonotonicCount
))
173 print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.dwLength = {dwLength:08X}'.format (dwLength
= self
.dwLength
))
174 print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wRevision = {wRevision:04X}'.format (wRevision
= self
.wRevision
))
175 print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wCertificateType = {wCertificateType:04X}'.format (wCertificateType
= self
.wCertificateType
))
176 print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.CertType = {Guid}'.format (Guid
= str(self
.CertType
).upper()))
177 print ('sizeof (EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.CertData) = {Size:08X}'.format (Size
= len (self
.CertData
)))
178 print ('sizeof (Payload) = {Size:08X}'.format (Size
= len (self
.Payload
)))