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