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 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 class FmpAuthHeaderClass (object):
24 # /// Image Attribute -Authentication Required
28 # /// It is included in the signature of AuthInfo. It is used to ensure freshness/no replay.
29 # /// It is incremented during each firmware image operation.
31 # UINT64 MonotonicCount;
33 # /// Provides the authorization for the firmware image operations. It is a signature across
34 # /// the image data and the Monotonic Count value. Caller uses the private key that is
35 # /// associated with a public key that has been provisioned via the key exchange.
36 # /// Because this is defined as a signature, WIN_CERTIFICATE_UEFI_GUID.CertType must
37 # /// be EFI_CERT_TYPE_PKCS7_GUID.
39 # WIN_CERTIFICATE_UEFI_GUID AuthInfo;
40 # } EFI_FIRMWARE_IMAGE_AUTHENTICATION;
43 # /// Certificate which encapsulates a GUID-specific digital signature
47 # /// This is the standard WIN_CERTIFICATE header, where
48 # /// wCertificateType is set to WIN_CERT_TYPE_EFI_GUID.
50 # WIN_CERTIFICATE Hdr;
52 # /// This is the unique id which determines the
53 # /// format of the CertData. .
57 # /// The following is the certificate data. The format of
58 # /// the data is determined by the CertType.
59 # /// If CertType is EFI_CERT_TYPE_RSA2048_SHA256_GUID,
60 # /// the CertData will be EFI_CERT_BLOCK_RSA_2048_SHA256 structure.
63 # } WIN_CERTIFICATE_UEFI_GUID;
66 # /// The WIN_CERTIFICATE structure is part of the PE/COFF specification.
70 # /// The length of the entire certificate,
71 # /// including the length of the header, in bytes.
75 # /// The revision level of the WIN_CERTIFICATE
76 # /// structure. The current revision level is 0x0200.
80 # /// The certificate type. See WIN_CERT_TYPE_xxx for the UEFI
81 # /// certificate types. The UEFI specification reserves the range of
82 # /// certificate type values from 0x0EF0 to 0x0EFF.
84 # UINT16 wCertificateType;
86 # /// The following is the actual certificate. The format of
87 # /// the certificate depends on wCertificateType.
89 # /// UINT8 bCertificate[ANYSIZE_ARRAY];
93 # #define WIN_CERT_TYPE_EFI_GUID 0x0EF1
96 # /// This identifies a signature containing a DER-encoded PKCS #7 version 1.5 [RFC2315]
97 # /// SignedData value.
99 # #define EFI_CERT_TYPE_PKCS7_GUID \
101 # 0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7} \
104 _StructFormat
= '<QIHH16s'
105 _StructSize
= struct
.calcsize (_StructFormat
)
107 _MonotonicCountFormat
= '<Q'
108 _MonotonicCountSize
= struct
.calcsize (_MonotonicCountFormat
)
110 _StructAuthInfoFormat
= '<IHH16s'
111 _StructAuthInfoSize
= struct
.calcsize (_StructAuthInfoFormat
)
113 _WIN_CERT_REVISION
= 0x0200
114 _WIN_CERT_TYPE_EFI_GUID
= 0x0EF1
115 _EFI_CERT_TYPE_PKCS7_GUID
= uuid
.UUID ('4aafd29d-68df-49ee-8aa9-347d375665a7')
119 self
.MonotonicCount
= 0
120 self
.dwLength
= self
._StructAuthInfoSize
121 self
.wRevision
= self
._WIN
_CERT
_REVISION
122 self
.wCertificateType
= self
._WIN
_CERT
_TYPE
_EFI
_GUID
123 self
.CertType
= self
._EFI
_CERT
_TYPE
_PKCS
7_GUID
129 if self
.wRevision
!= self
._WIN
_CERT
_REVISION
:
131 if self
.wCertificateType
!= self
._WIN
_CERT
_TYPE
_EFI
_GUID
:
133 if self
.CertType
!= self
._EFI
_CERT
_TYPE
_PKCS
7_GUID
:
135 self
.dwLength
= self
._StructAuthInfoSize
+ len (self
.CertData
)
137 FmpAuthHeader
= struct
.pack (
142 self
.wCertificateType
,
143 self
.CertType
.bytes_le
147 return FmpAuthHeader
+ self
.CertData
+ self
.Payload
149 def Decode (self
, Buffer
):
150 if len (Buffer
) < self
._StructSize
:
152 (MonotonicCount
, dwLength
, wRevision
, wCertificateType
, CertType
) = \
155 Buffer
[0:self
._StructSize
]
157 if dwLength
< self
._StructAuthInfoSize
:
159 if wRevision
!= self
._WIN
_CERT
_REVISION
:
161 if wCertificateType
!= self
._WIN
_CERT
_TYPE
_EFI
_GUID
:
163 if CertType
!= self
._EFI
_CERT
_TYPE
_PKCS
7_GUID
.bytes_le
:
165 self
.MonotonicCount
= MonotonicCount
166 self
.dwLength
= dwLength
167 self
.wRevision
= wRevision
168 self
.wCertificateType
= wCertificateType
169 self
.CertType
= uuid
.UUID (bytes_le
= CertType
)
170 self
.CertData
= Buffer
[self
._StructSize
:self
._MonotonicCountSize
+ self
.dwLength
]
171 self
.Payload
= Buffer
[self
._MonotonicCountSize
+ self
.dwLength
:]
178 print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.MonotonicCount = {MonotonicCount:016X}'.format (MonotonicCount
= self
.MonotonicCount
))
179 print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.dwLength = {dwLength:08X}'.format (dwLength
= self
.dwLength
))
180 print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wRevision = {wRevision:04X}'.format (wRevision
= self
.wRevision
))
181 print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wCertificateType = {wCertificateType:04X}'.format (wCertificateType
= self
.wCertificateType
))
182 print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.CertType = {Guid}'.format (Guid
= str(self
.CertType
).upper()))
183 print ('sizeof (EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.CertData) = {Size:08X}'.format (Size
= len (self
.CertData
)))
184 print ('sizeof (Payload) = {Size:08X}'.format (Size
= len (self
.Payload
)))