]>
Commit | Line | Data |
---|---|---|
8b63877a KM |
1 | ## @file\r |
2 | # Module that encodes and decodes a EFI_FIRMWARE_IMAGE_AUTHENTICATION with\r | |
3 | # certificate data and payload data.\r | |
4 | #\r | |
5 | # Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r | |
6 | # This program and the accompanying materials\r | |
7 | # are licensed and made available under the terms and conditions of the BSD License\r | |
8 | # which accompanies this distribution. The full text of the license may be found at\r | |
9 | # http://opensource.org/licenses/bsd-license.php\r | |
10 | #\r | |
11 | # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
12 | # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
13 | #\r | |
14 | \r | |
15 | '''\r | |
16 | FmpAuthHeader\r | |
17 | '''\r | |
18 | \r | |
19 | import struct\r | |
20 | import uuid\r | |
21 | \r | |
22 | class FmpAuthHeaderClass (object):\r | |
23 | # ///\r | |
24 | # /// Image Attribute -Authentication Required\r | |
25 | # ///\r | |
26 | # typedef struct {\r | |
27 | # ///\r | |
28 | # /// It is included in the signature of AuthInfo. It is used to ensure freshness/no replay.\r | |
29 | # /// It is incremented during each firmware image operation.\r | |
30 | # ///\r | |
31 | # UINT64 MonotonicCount;\r | |
32 | # ///\r | |
33 | # /// Provides the authorization for the firmware image operations. It is a signature across\r | |
34 | # /// the image data and the Monotonic Count value. Caller uses the private key that is\r | |
35 | # /// associated with a public key that has been provisioned via the key exchange.\r | |
36 | # /// Because this is defined as a signature, WIN_CERTIFICATE_UEFI_GUID.CertType must\r | |
37 | # /// be EFI_CERT_TYPE_PKCS7_GUID.\r | |
38 | # ///\r | |
39 | # WIN_CERTIFICATE_UEFI_GUID AuthInfo;\r | |
40 | # } EFI_FIRMWARE_IMAGE_AUTHENTICATION;\r | |
41 | #\r | |
42 | # ///\r | |
43 | # /// Certificate which encapsulates a GUID-specific digital signature\r | |
44 | # ///\r | |
45 | # typedef struct {\r | |
46 | # ///\r | |
47 | # /// This is the standard WIN_CERTIFICATE header, where\r | |
48 | # /// wCertificateType is set to WIN_CERT_TYPE_EFI_GUID.\r | |
49 | # ///\r | |
50 | # WIN_CERTIFICATE Hdr;\r | |
51 | # ///\r | |
52 | # /// This is the unique id which determines the\r | |
53 | # /// format of the CertData. .\r | |
54 | # ///\r | |
55 | # EFI_GUID CertType;\r | |
56 | # ///\r | |
57 | # /// The following is the certificate data. The format of\r | |
58 | # /// the data is determined by the CertType.\r | |
59 | # /// If CertType is EFI_CERT_TYPE_RSA2048_SHA256_GUID,\r | |
60 | # /// the CertData will be EFI_CERT_BLOCK_RSA_2048_SHA256 structure.\r | |
61 | # ///\r | |
62 | # UINT8 CertData[1];\r | |
63 | # } WIN_CERTIFICATE_UEFI_GUID;\r | |
64 | #\r | |
65 | # ///\r | |
66 | # /// The WIN_CERTIFICATE structure is part of the PE/COFF specification.\r | |
67 | # ///\r | |
68 | # typedef struct {\r | |
69 | # ///\r | |
70 | # /// The length of the entire certificate,\r | |
71 | # /// including the length of the header, in bytes.\r | |
72 | # ///\r | |
73 | # UINT32 dwLength;\r | |
74 | # ///\r | |
75 | # /// The revision level of the WIN_CERTIFICATE\r | |
76 | # /// structure. The current revision level is 0x0200.\r | |
77 | # ///\r | |
78 | # UINT16 wRevision;\r | |
79 | # ///\r | |
80 | # /// The certificate type. See WIN_CERT_TYPE_xxx for the UEFI\r | |
81 | # /// certificate types. The UEFI specification reserves the range of\r | |
82 | # /// certificate type values from 0x0EF0 to 0x0EFF.\r | |
83 | # ///\r | |
84 | # UINT16 wCertificateType;\r | |
85 | # ///\r | |
86 | # /// The following is the actual certificate. The format of\r | |
87 | # /// the certificate depends on wCertificateType.\r | |
88 | # ///\r | |
89 | # /// UINT8 bCertificate[ANYSIZE_ARRAY];\r | |
90 | # ///\r | |
91 | # } WIN_CERTIFICATE;\r | |
92 | #\r | |
93 | # #define WIN_CERT_TYPE_EFI_GUID 0x0EF1\r | |
94 | #\r | |
95 | # ///\r | |
96 | # /// This identifies a signature containing a DER-encoded PKCS #7 version 1.5 [RFC2315]\r | |
97 | # /// SignedData value.\r | |
98 | # ///\r | |
99 | # #define EFI_CERT_TYPE_PKCS7_GUID \\r | |
100 | # { \\r | |
101 | # 0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7} \\r | |
102 | # }\r | |
103 | \r | |
104 | _StructFormat = '<QIHH16s'\r | |
105 | _StructSize = struct.calcsize (_StructFormat)\r | |
106 | \r | |
107 | _MonotonicCountFormat = '<Q'\r | |
108 | _MonotonicCountSize = struct.calcsize (_MonotonicCountFormat)\r | |
109 | \r | |
110 | _StructAuthInfoFormat = '<IHH16s'\r | |
111 | _StructAuthInfoSize = struct.calcsize (_StructAuthInfoFormat)\r | |
112 | \r | |
113 | _WIN_CERT_REVISION = 0x0200\r | |
114 | _WIN_CERT_TYPE_EFI_GUID = 0x0EF1\r | |
115 | _EFI_CERT_TYPE_PKCS7_GUID = uuid.UUID ('4aafd29d-68df-49ee-8aa9-347d375665a7')\r | |
116 | \r | |
117 | def __init__ (self):\r | |
118 | self._Valid = False\r | |
119 | self.MonotonicCount = 0\r | |
120 | self.dwLength = self._StructAuthInfoSize\r | |
121 | self.wRevision = self._WIN_CERT_REVISION\r | |
122 | self.wCertificateType = self._WIN_CERT_TYPE_EFI_GUID\r | |
123 | self.CertType = self._EFI_CERT_TYPE_PKCS7_GUID\r | |
124 | self.CertData = b''\r | |
125 | self.Payload = b''\r | |
126 | \r | |
127 | \r | |
128 | def Encode (self):\r | |
129 | if self.wRevision != self._WIN_CERT_REVISION:\r | |
130 | raise ValueError\r | |
131 | if self.wCertificateType != self._WIN_CERT_TYPE_EFI_GUID:\r | |
132 | raise ValueError\r | |
133 | if self.CertType != self._EFI_CERT_TYPE_PKCS7_GUID:\r | |
134 | raise ValueError\r | |
135 | self.dwLength = self._StructAuthInfoSize + len (self.CertData)\r | |
136 | \r | |
137 | FmpAuthHeader = struct.pack (\r | |
138 | self._StructFormat,\r | |
139 | self.MonotonicCount,\r | |
140 | self.dwLength,\r | |
141 | self.wRevision,\r | |
142 | self.wCertificateType,\r | |
143 | self.CertType.bytes_le\r | |
144 | )\r | |
145 | self._Valid = True\r | |
146 | \r | |
147 | return FmpAuthHeader + self.CertData + self.Payload\r | |
148 | \r | |
149 | def Decode (self, Buffer):\r | |
150 | if len (Buffer) < self._StructSize:\r | |
151 | raise ValueError\r | |
152 | (MonotonicCount, dwLength, wRevision, wCertificateType, CertType) = \\r | |
153 | struct.unpack (\r | |
154 | self._StructFormat,\r | |
155 | Buffer[0:self._StructSize]\r | |
156 | )\r | |
157 | if dwLength < self._StructAuthInfoSize:\r | |
158 | raise ValueError\r | |
159 | if wRevision != self._WIN_CERT_REVISION:\r | |
160 | raise ValueError\r | |
161 | if wCertificateType != self._WIN_CERT_TYPE_EFI_GUID:\r | |
162 | raise ValueError\r | |
163 | if CertType != self._EFI_CERT_TYPE_PKCS7_GUID.bytes_le:\r | |
164 | raise ValueError\r | |
165 | self.MonotonicCount = MonotonicCount\r | |
166 | self.dwLength = dwLength\r | |
167 | self.wRevision = wRevision\r | |
168 | self.wCertificateType = wCertificateType\r | |
169 | self.CertType = uuid.UUID (bytes = CertType)\r | |
170 | self.CertData = Buffer[self._StructSize:self._MonotonicCountSize + self.dwLength]\r | |
171 | self.Payload = Buffer[self._MonotonicCountSize + self.dwLength:]\r | |
172 | self._Valid = True\r | |
173 | return self.Payload\r | |
174 | \r | |
175 | def DumpInfo (self):\r | |
176 | if not self._Valid:\r | |
177 | raise ValueError\r | |
178 | print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.MonotonicCount = {MonotonicCount:016X}'.format (MonotonicCount = self.MonotonicCount))\r | |
179 | print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.dwLength = {dwLength:08X}'.format (dwLength = self.dwLength))\r | |
180 | print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wRevision = {wRevision:04X}'.format (wRevision = self.wRevision))\r | |
181 | print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wCertificateType = {wCertificateType:04X}'.format (wCertificateType = self.wCertificateType))\r | |
182 | print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.CertType = {Guid}'.format (Guid = str(self.CertType).upper()))\r | |
183 | print ('sizeof (EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.CertData) = {Size:08X}'.format (Size = len (self.CertData)))\r | |
184 | print ('sizeof (Payload) = {Size:08X}'.format (Size = len (self.Payload)))\r |