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