]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py
BaseTools/Capsule: Add Capsule Generation Tools
[mirror_edk2.git] / BaseTools / Source / Python / Common / Uefi / Capsule / FmpAuthHeader.py
CommitLineData
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
16FmpAuthHeader\r
17'''\r
18\r
19import struct\r
20import uuid\r
21\r
22class 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