]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py
aec52bf772ca5f1bf1d93a3d9bde3e384f0432be
[mirror_edk2.git] / BaseTools / Source / Python / Common / Uefi / Capsule / FmpAuthHeader.py
1 ## @file
2 # Module that encodes and decodes a EFI_FIRMWARE_IMAGE_AUTHENTICATION with
3 # certificate data and payload data.
4 #
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
10 #
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.
13 #
14
15 '''
16 FmpAuthHeader
17 '''
18
19 import struct
20 import uuid
21
22 class FmpAuthHeaderClass (object):
23 # ///
24 # /// Image Attribute -Authentication Required
25 # ///
26 # typedef struct {
27 # ///
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.
30 # ///
31 # UINT64 MonotonicCount;
32 # ///
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.
38 # ///
39 # WIN_CERTIFICATE_UEFI_GUID AuthInfo;
40 # } EFI_FIRMWARE_IMAGE_AUTHENTICATION;
41 #
42 # ///
43 # /// Certificate which encapsulates a GUID-specific digital signature
44 # ///
45 # typedef struct {
46 # ///
47 # /// This is the standard WIN_CERTIFICATE header, where
48 # /// wCertificateType is set to WIN_CERT_TYPE_EFI_GUID.
49 # ///
50 # WIN_CERTIFICATE Hdr;
51 # ///
52 # /// This is the unique id which determines the
53 # /// format of the CertData. .
54 # ///
55 # EFI_GUID CertType;
56 # ///
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.
61 # ///
62 # UINT8 CertData[1];
63 # } WIN_CERTIFICATE_UEFI_GUID;
64 #
65 # ///
66 # /// The WIN_CERTIFICATE structure is part of the PE/COFF specification.
67 # ///
68 # typedef struct {
69 # ///
70 # /// The length of the entire certificate,
71 # /// including the length of the header, in bytes.
72 # ///
73 # UINT32 dwLength;
74 # ///
75 # /// The revision level of the WIN_CERTIFICATE
76 # /// structure. The current revision level is 0x0200.
77 # ///
78 # UINT16 wRevision;
79 # ///
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.
83 # ///
84 # UINT16 wCertificateType;
85 # ///
86 # /// The following is the actual certificate. The format of
87 # /// the certificate depends on wCertificateType.
88 # ///
89 # /// UINT8 bCertificate[ANYSIZE_ARRAY];
90 # ///
91 # } WIN_CERTIFICATE;
92 #
93 # #define WIN_CERT_TYPE_EFI_GUID 0x0EF1
94 #
95 # ///
96 # /// This identifies a signature containing a DER-encoded PKCS #7 version 1.5 [RFC2315]
97 # /// SignedData value.
98 # ///
99 # #define EFI_CERT_TYPE_PKCS7_GUID \
100 # { \
101 # 0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7} \
102 # }
103
104 _StructFormat = '<QIHH16s'
105 _StructSize = struct.calcsize (_StructFormat)
106
107 _MonotonicCountFormat = '<Q'
108 _MonotonicCountSize = struct.calcsize (_MonotonicCountFormat)
109
110 _StructAuthInfoFormat = '<IHH16s'
111 _StructAuthInfoSize = struct.calcsize (_StructAuthInfoFormat)
112
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')
116
117 def __init__ (self):
118 self._Valid = False
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_PKCS7_GUID
124 self.CertData = b''
125 self.Payload = b''
126
127
128 def Encode (self):
129 if self.wRevision != self._WIN_CERT_REVISION:
130 raise ValueError
131 if self.wCertificateType != self._WIN_CERT_TYPE_EFI_GUID:
132 raise ValueError
133 if self.CertType != self._EFI_CERT_TYPE_PKCS7_GUID:
134 raise ValueError
135 self.dwLength = self._StructAuthInfoSize + len (self.CertData)
136
137 FmpAuthHeader = struct.pack (
138 self._StructFormat,
139 self.MonotonicCount,
140 self.dwLength,
141 self.wRevision,
142 self.wCertificateType,
143 self.CertType.bytes_le
144 )
145 self._Valid = True
146
147 return FmpAuthHeader + self.CertData + self.Payload
148
149 def Decode (self, Buffer):
150 if len (Buffer) < self._StructSize:
151 raise ValueError
152 (MonotonicCount, dwLength, wRevision, wCertificateType, CertType) = \
153 struct.unpack (
154 self._StructFormat,
155 Buffer[0:self._StructSize]
156 )
157 if dwLength < self._StructAuthInfoSize:
158 raise ValueError
159 if wRevision != self._WIN_CERT_REVISION:
160 raise ValueError
161 if wCertificateType != self._WIN_CERT_TYPE_EFI_GUID:
162 raise ValueError
163 if CertType != self._EFI_CERT_TYPE_PKCS7_GUID.bytes_le:
164 raise ValueError
165 self.MonotonicCount = MonotonicCount
166 self.dwLength = dwLength
167 self.wRevision = wRevision
168 self.wCertificateType = wCertificateType
169 self.CertType = uuid.UUID (bytes = CertType)
170 self.CertData = Buffer[self._StructSize:self._MonotonicCountSize + self.dwLength]
171 self.Payload = Buffer[self._MonotonicCountSize + self.dwLength:]
172 self._Valid = True
173 return self.Payload
174
175 def DumpInfo (self):
176 if not self._Valid:
177 raise ValueError
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)))