]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py
BaseTools: Replace BSD License with BSD+Patent License
[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
2e351cbe 6# SPDX-License-Identifier: BSD-2-Clause-Patent\r
8b63877a
KM
7#\r
8\r
9'''\r
10FmpAuthHeader\r
11'''\r
12\r
13import struct\r
14import uuid\r
15\r
16class 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