]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Capsule/GenerateCapsule.py
BaseTools/Capsule: Support capsules without a payload header
[mirror_edk2.git] / BaseTools / Source / Python / Capsule / GenerateCapsule.py
CommitLineData
8b63877a
KM
1## @file\r
2# Generate a capsule.\r
3#\r
d6f079b6
KM
4# This tool generates a UEFI Capsule around an FMP Capsule. The capsule payload\r
5# be signed using signtool or OpenSSL and if it is signed the signed content\r
6# includes an FMP Payload Header.\r
7#\r
8# This tool is intended to be used to generate UEFI Capsules to update the\r
9# system firmware or device firmware for integrated devices. In order to\r
10# keep the tool as simple as possible, it has the following limitations:\r
11# * Do not support multiple payloads in a capsule.\r
12# * Do not support optional drivers in a capsule.\r
13# * Do not support vendor code bytes in a capsule.\r
14#\r
8b63877a
KM
15# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r
16# This program and the accompanying materials\r
17# are licensed and made available under the terms and conditions of the BSD License\r
18# which accompanies this distribution. The full text of the license may be found at\r
19# http://opensource.org/licenses/bsd-license.php\r
20#\r
21# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
22# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
23#\r
24\r
25'''\r
26GenerateCapsule\r
27'''\r
28\r
29import sys\r
30import argparse\r
31import uuid\r
32import struct\r
33import subprocess\r
34import os\r
35import tempfile\r
36import shutil\r
37import platform\r
38from Common.Uefi.Capsule.UefiCapsuleHeader import UefiCapsuleHeaderClass\r
39from Common.Uefi.Capsule.FmpCapsuleHeader import FmpCapsuleHeaderClass\r
40from Common.Uefi.Capsule.FmpAuthHeader import FmpAuthHeaderClass\r
41from Common.Edk2.Capsule.FmpPayloadHeader import FmpPayloadHeaderClass\r
42\r
43#\r
44# Globals for help information\r
45#\r
46__prog__ = 'GenerateCapsule'\r
47__version__ = '0.9'\r
48__copyright__ = 'Copyright (c) 2018, Intel Corporation. All rights reserved.'\r
49__description__ = 'Generate a capsule.\n'\r
50\r
51def SignPayloadSignTool (Payload, ToolPath, PfxFile):\r
52 #\r
53 # Create a temporary directory\r
54 #\r
55 TempDirectoryName = tempfile.mkdtemp()\r
56\r
57 #\r
58 # Generate temp file name for the payload contents\r
59 #\r
60 TempFileName = os.path.join (TempDirectoryName, 'Payload.bin')\r
61\r
62 #\r
63 # Create temporary payload file for signing\r
64 #\r
65 try:\r
66 File = open (TempFileName, mode='wb')\r
67 File.write (Payload)\r
68 File.close ()\r
69 except:\r
70 shutil.rmtree (TempDirectoryName)\r
71 raise ValueError ('GenerateCapsule: error: can not write temporary payload file.')\r
72\r
73 #\r
74 # Build signtool command\r
75 #\r
76 if ToolPath is None:\r
77 ToolPath = ''\r
78 Command = ''\r
79 Command = Command + '"{Path}" '.format (Path = os.path.join (ToolPath, 'signtool.exe'))\r
80 Command = Command + 'sign /fd sha256 /p7ce DetachedSignedData /p7co 1.2.840.113549.1.7.2 '\r
81 Command = Command + '/p7 {TempDir} '.format (TempDir = TempDirectoryName)\r
82 Command = Command + '/f {PfxFile} '.format (PfxFile = PfxFile)\r
83 Command = Command + TempFileName\r
84\r
85 #\r
86 # Sign the input file using the specified private key\r
87 #\r
88 try:\r
89 Process = subprocess.Popen (Command, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True)\r
90 Result = Process.communicate('')\r
91 except:\r
92 shutil.rmtree (TempDirectoryName)\r
93 raise ValueError ('GenerateCapsule: error: can not run signtool.')\r
94\r
95 if Process.returncode != 0:\r
96 shutil.rmtree (TempDirectoryName)\r
97 print (Result[1].decode())\r
98 raise ValueError ('GenerateCapsule: error: signtool failed.')\r
99\r
100 #\r
101 # Read the signature from the generated output file\r
102 #\r
103 try:\r
104 File = open (TempFileName + '.p7', mode='rb')\r
105 Signature = File.read ()\r
106 File.close ()\r
107 except:\r
108 shutil.rmtree (TempDirectoryName)\r
109 raise ValueError ('GenerateCapsule: error: can not read signature file.')\r
110\r
111 shutil.rmtree (TempDirectoryName)\r
112 return Signature\r
113\r
114def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile):\r
115 print ('signtool verify is not supported.')\r
116 raise ValueError ('GenerateCapsule: error: signtool verify is not supported.')\r
117\r
118def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPublicCertFile, TrustedPublicCertFile):\r
119 #\r
120 # Build openssl command\r
121 #\r
122 if ToolPath is None:\r
123 ToolPath = ''\r
124 Command = ''\r
125 Command = Command + '"{Path}" '.format (Path = os.path.join (ToolPath, 'openssl'))\r
126 Command = Command + 'smime -sign -binary -outform DER -md sha256 '\r
127 Command = Command + '-signer "{Private}" -certfile "{Public}"'.format (Private = SignerPrivateCertFile, Public = OtherPublicCertFile)\r
128\r
129 #\r
130 # Sign the input file using the specified private key and capture signature from STDOUT\r
131 #\r
132 try:\r
133 Process = subprocess.Popen (Command, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True)\r
134 Result = Process.communicate(input = Payload)\r
135 Signature = Result[0]\r
136 except:\r
137 raise ValueError ('GenerateCapsule: error: can not run openssl.')\r
138\r
139 if Process.returncode != 0:\r
140 print (Result[1].decode())\r
141 raise ValueError ('GenerateCapsule: error: openssl failed.')\r
142\r
143 return Signature\r
144\r
145def VerifyPayloadOpenSsl (Payload, CertData, ToolPath, SignerPrivateCertFile, OtherPublicCertFile, TrustedPublicCertFile):\r
146 #\r
147 # Create a temporary directory\r
148 #\r
149 TempDirectoryName = tempfile.mkdtemp()\r
150\r
151 #\r
152 # Generate temp file name for the payload contents\r
153 #\r
154 TempFileName = os.path.join (TempDirectoryName, 'Payload.bin')\r
155\r
156 #\r
157 # Create temporary payload file for verification\r
158 #\r
159 try:\r
160 File = open (TempFileName, mode='wb')\r
161 File.write (Payload)\r
162 File.close ()\r
163 except:\r
164 shutil.rmtree (TempDirectoryName)\r
165 raise ValueError ('GenerateCapsule: error: can not write temporary payload file.')\r
166\r
167 #\r
168 # Build openssl command\r
169 #\r
170 if ToolPath is None:\r
171 ToolPath = ''\r
172 Command = ''\r
173 Command = Command + '"{Path}" '.format (Path = os.path.join (ToolPath, 'openssl'))\r
174 Command = Command + 'smime -verify -inform DER '\r
175 Command = Command + '-content {Content} -CAfile "{Public}"'.format (Content = TempFileName, Public = TrustedPublicCertFile)\r
176\r
177 #\r
178 # Verify signature\r
179 #\r
180 try:\r
181 Process = subprocess.Popen (Command, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True)\r
182 Result = Process.communicate(input = CertData)\r
183 except:\r
184 shutil.rmtree (TempDirectoryName)\r
185 raise ValueError ('GenerateCapsule: error: can not run openssl.')\r
186\r
187 if Process.returncode != 0:\r
188 shutil.rmtree (TempDirectoryName)\r
189 print (Result[1].decode())\r
190 raise ValueError ('GenerateCapsule: error: openssl failed.')\r
191\r
192 shutil.rmtree (TempDirectoryName)\r
193 return Payload\r
194\r
195if __name__ == '__main__':\r
196 def convert_arg_line_to_args(arg_line):\r
197 for arg in arg_line.split():\r
198 if not arg.strip():\r
199 continue\r
200 yield arg\r
201\r
202 def ValidateUnsignedInteger (Argument):\r
203 try:\r
204 Value = int (Argument, 0)\r
205 except:\r
206 Message = '{Argument} is not a valid integer value.'.format (Argument = Argument)\r
207 raise argparse.ArgumentTypeError (Message)\r
208 if Value < 0:\r
209 Message = '{Argument} is a negative value.'.format (Argument = Argument)\r
210 raise argparse.ArgumentTypeError (Message)\r
211 return Value\r
212\r
213 def ValidateRegistryFormatGuid (Argument):\r
214 try:\r
215 Value = uuid.UUID (Argument)\r
216 except:\r
217 Message = '{Argument} is not a valid registry format GUID value.'.format (Argument = Argument)\r
218 raise argparse.ArgumentTypeError (Message)\r
219 return Value\r
220\r
221 #\r
222 # Create command line argument parser object\r
223 #\r
224 parser = argparse.ArgumentParser (\r
225 prog = __prog__,\r
226 description = __description__ + __copyright__,\r
227 conflict_handler = 'resolve',\r
228 fromfile_prefix_chars = '@'\r
229 )\r
230 parser.convert_arg_line_to_args = convert_arg_line_to_args\r
231\r
232 #\r
233 # Add input and output file arguments\r
234 #\r
235 parser.add_argument("InputFile", type = argparse.FileType('rb'),\r
236 help = "Input binary payload filename.")\r
237 parser.add_argument("-o", "--output", dest = 'OutputFile', type = argparse.FileType('wb'),\r
238 help = "Output filename.")\r
239 #\r
240 # Add group for -e and -d flags that are mutually exclusive and required\r
241 #\r
242 group = parser.add_mutually_exclusive_group (required = True)\r
243 group.add_argument ("-e", "--encode", dest = 'Encode', action = "store_true",\r
244 help = "Encode file")\r
245 group.add_argument ("-d", "--decode", dest = 'Decode', action = "store_true",\r
246 help = "Decode file")\r
247 group.add_argument ("--dump-info", dest = 'DumpInfo', action = "store_true",\r
248 help = "Display FMP Payload Header information")\r
249 #\r
250 # Add optional arguments for this command\r
251 #\r
252 parser.add_argument ("--capflag", dest = 'CapsuleFlag', action='append', default = [],\r
2779c222
KM
253 choices=['PersistAcrossReset', 'InitiateReset'],\r
254 help = "Capsule flag can be PersistAcrossReset or InitiateReset or not set")\r
8b63877a
KM
255 parser.add_argument ("--capoemflag", dest = 'CapsuleOemFlag', type = ValidateUnsignedInteger, default = 0x0000,\r
256 help = "Capsule OEM Flag is an integer between 0x0000 and 0xffff.")\r
257\r
258 parser.add_argument ("--guid", dest = 'Guid', type = ValidateRegistryFormatGuid,\r
259 help = "The FMP/ESRT GUID in registry format. Required for encode operations.")\r
260 parser.add_argument ("--hardware-instance", dest = 'HardwareInstance', type = ValidateUnsignedInteger, default = 0x0000000000000000,\r
261 help = "The 64-bit hardware instance. The default is 0x0000000000000000")\r
262\r
263\r
264 parser.add_argument ("--monotonic-count", dest = 'MonotonicCount', type = ValidateUnsignedInteger, default = 0x0000000000000000,\r
265 help = "64-bit monotonic count value in header. Default is 0x0000000000000000.")\r
266\r
267 parser.add_argument ("--fw-version", dest = 'FwVersion', type = ValidateUnsignedInteger,\r
ff307fba 268 help = "The 32-bit version of the binary payload (e.g. 0x11223344 or 5678). Required for encode operations that sign a payload.")\r
8b63877a 269 parser.add_argument ("--lsv", dest = 'LowestSupportedVersion', type = ValidateUnsignedInteger,\r
ff307fba 270 help = "The 32-bit lowest supported version of the binary payload (e.g. 0x11223344 or 5678). Required for encode operations that sign a payload.")\r
8b63877a
KM
271\r
272 parser.add_argument ("--pfx-file", dest='SignToolPfxFile', type=argparse.FileType('rb'),\r
273 help="signtool PFX certificate filename.")\r
274\r
275 parser.add_argument ("--signer-private-cert", dest='OpenSslSignerPrivateCertFile', type=argparse.FileType('rb'),\r
276 help="OpenSSL signer private certificate filename.")\r
277 parser.add_argument ("--other-public-cert", dest='OpenSslOtherPublicCertFile', type=argparse.FileType('rb'),\r
278 help="OpenSSL other public certificate filename.")\r
279 parser.add_argument ("--trusted-public-cert", dest='OpenSslTrustedPublicCertFile', type=argparse.FileType('rb'),\r
280 help="OpenSSL trusted public certificate filename.")\r
281\r
282 parser.add_argument ("--signing-tool-path", dest = 'SigningToolPath',\r
283 help = "Path to signtool or OpenSSL tool. Optional if path to tools are already in PATH.")\r
284\r
285 #\r
286 # Add optional arguments common to all operations\r
287 #\r
288 parser.add_argument ('--version', action='version', version='%(prog)s ' + __version__)\r
289 parser.add_argument ("-v", "--verbose", dest = 'Verbose', action = "store_true",\r
290 help = "Turn on verbose output with informational messages printed, including capsule headers and warning messages.")\r
291 parser.add_argument ("-q", "--quiet", dest = 'Quiet', action = "store_true",\r
292 help = "Disable all messages except fatal errors.")\r
293 parser.add_argument ("--debug", dest = 'Debug', type = int, metavar = '[0-9]', choices = range (0, 10), default = 0,\r
294 help = "Set debug level")\r
295\r
296 #\r
297 # Parse command line arguments\r
298 #\r
299 args = parser.parse_args()\r
300\r
301 #\r
302 # Perform additional argument verification\r
303 #\r
304 if args.Encode:\r
305 if args.Guid is None:\r
306 parser.error ('the following option is required: --guid')\r
307 if 'PersistAcrossReset' not in args.CapsuleFlag:\r
8b63877a
KM
308 if 'InitiateReset' in args.CapsuleFlag:\r
309 parser.error ('--capflag InitiateReset also requires --capflag PersistAcrossReset')\r
6ed4651c
KM
310 if args.CapsuleOemFlag > 0xFFFF:\r
311 parser.error ('--capoemflag must be an integer between 0x0000 and 0xffff')\r
312 if args.HardwareInstance > 0xFFFFFFFFFFFFFFFF:\r
313 parser.error ('--hardware-instance must be an integer in range 0x0..0xffffffffffffffff')\r
314 if args.MonotonicCount > 0xFFFFFFFFFFFFFFFF:\r
315 parser.error ('--monotonic-count must be an integer in range 0x0..0xffffffffffffffff')\r
8b63877a
KM
316\r
317 UseSignTool = args.SignToolPfxFile is not None\r
318 UseOpenSsl = (args.OpenSslSignerPrivateCertFile is not None and\r
319 args.OpenSslOtherPublicCertFile is not None and\r
320 args.OpenSslTrustedPublicCertFile is not None)\r
321 AnyOpenSsl = (args.OpenSslSignerPrivateCertFile is not None or\r
322 args.OpenSslOtherPublicCertFile is not None or\r
323 args.OpenSslTrustedPublicCertFile is not None)\r
324 if args.Encode or args.Decode:\r
325 if args.OutputFile is None:\r
326 parser.error ('the following option is required for all encode and decode operations: --output')\r
327\r
328 if UseSignTool and AnyOpenSsl:\r
329 parser.error ('Providing both signtool and OpenSSL options is not supported')\r
330 if not UseSignTool and not UseOpenSsl and AnyOpenSsl:\r
331 parser.error ('all the following options are required for OpenSSL: --signer-private-cert, --other-public-cert, --trusted-public-cert')\r
332 if UseSignTool and platform.system() != 'Windows':\r
333 parser.error ('Use of signtool is not supported on this operating system.')\r
334 if args.Encode and (UseSignTool or UseOpenSsl):\r
335 if args.FwVersion is None or args.LowestSupportedVersion is None:\r
336 parser.error ('the following options are required: --fw-version, --lsv')\r
6ed4651c
KM
337 if args.FwVersion > 0xFFFFFFFF:\r
338 parser.error ('--fw-version must be an integer in range 0x0..0xffffffff')\r
339 if args.LowestSupportedVersion > 0xFFFFFFFF:\r
340 parser.error ('--lsv must be an integer in range 0x0..0xffffffff')\r
8b63877a
KM
341\r
342 if UseSignTool:\r
343 args.SignToolPfxFile.close()\r
344 args.SignToolPfxFile = args.SignToolPfxFile.name\r
345 if UseOpenSsl:\r
346 args.OpenSslSignerPrivateCertFile.close()\r
347 args.OpenSslOtherPublicCertFile.close()\r
348 args.OpenSslTrustedPublicCertFile.close()\r
349 args.OpenSslSignerPrivateCertFile = args.OpenSslSignerPrivateCertFile.name\r
350 args.OpenSslOtherPublicCertFile = args.OpenSslOtherPublicCertFile.name\r
351 args.OpenSslTrustedPublicCertFile = args.OpenSslTrustedPublicCertFile.name\r
352\r
f33d5d68
KM
353 if args.DumpInfo:\r
354 if args.OutputFile is not None:\r
355 parser.error ('the following option is not supported for dumpinfo operations: --output')\r
356\r
8b63877a
KM
357 #\r
358 # Read binary input file\r
359 #\r
360 try:\r
361 if args.Verbose:\r
362 print ('Read binary input file {File}'.format (File = args.InputFile.name))\r
363 Buffer = args.InputFile.read ()\r
364 args.InputFile.close ()\r
365 except:\r
366 print ('GenerateCapsule: error: can not read binary input file {File}'.format (File = args.InputFile.name))\r
367 sys.exit (1)\r
368\r
369 #\r
370 # Create objects\r
371 #\r
372 UefiCapsuleHeader = UefiCapsuleHeaderClass ()\r
373 FmpCapsuleHeader = FmpCapsuleHeaderClass ()\r
374 FmpAuthHeader = FmpAuthHeaderClass ()\r
375 FmpPayloadHeader = FmpPayloadHeaderClass ()\r
376\r
377 if args.Encode:\r
378 Result = Buffer\r
379 if UseSignTool or UseOpenSsl:\r
380 try:\r
381 FmpPayloadHeader.FwVersion = args.FwVersion\r
382 FmpPayloadHeader.LowestSupportedVersion = args.LowestSupportedVersion\r
383 FmpPayloadHeader.Payload = Result\r
384 Result = FmpPayloadHeader.Encode ()\r
385 if args.Verbose:\r
386 FmpPayloadHeader.DumpInfo ()\r
387 except:\r
388 print ('GenerateCapsule: error: can not encode FMP Payload Header')\r
389 sys.exit (1)\r
390\r
391 #\r
392 # Sign image with 64-bit MonotonicCount appended to end of image\r
393 #\r
394 try:\r
395 if UseSignTool:\r
396 CertData = SignPayloadSignTool (\r
397 Result + struct.pack ('<Q', args.MonotonicCount),\r
398 args.SigningToolPath,\r
399 args.SignToolPfxFile\r
400 )\r
401 else:\r
402 CertData = SignPayloadOpenSsl (\r
403 Result + struct.pack ('<Q', args.MonotonicCount),\r
404 args.SigningToolPath,\r
405 args.OpenSslSignerPrivateCertFile,\r
406 args.OpenSslOtherPublicCertFile,\r
407 args.OpenSslTrustedPublicCertFile\r
408 )\r
409 except:\r
410 print ('GenerateCapsule: error: can not sign payload')\r
8b63877a
KM
411 sys.exit (1)\r
412\r
413 try:\r
414 FmpAuthHeader.MonotonicCount = args.MonotonicCount\r
415 FmpAuthHeader.CertData = CertData\r
416 FmpAuthHeader.Payload = Result\r
417 Result = FmpAuthHeader.Encode ()\r
418 if args.Verbose:\r
419 FmpAuthHeader.DumpInfo ()\r
420 except:\r
421 print ('GenerateCapsule: error: can not encode FMP Auth Header')\r
422 sys.exit (1)\r
423\r
424 try:\r
425 FmpCapsuleHeader.AddPayload (args.Guid, Result, HardwareInstance = args.HardwareInstance)\r
426 Result = FmpCapsuleHeader.Encode ()\r
427 if args.Verbose:\r
428 FmpCapsuleHeader.DumpInfo ()\r
429 except:\r
430 print ('GenerateCapsule: error: can not encode FMP Capsule Header')\r
431 sys.exit (1)\r
432\r
433 try:\r
434 UefiCapsuleHeader.OemFlags = args.CapsuleOemFlag\r
435 UefiCapsuleHeader.PersistAcrossReset = 'PersistAcrossReset' in args.CapsuleFlag\r
2779c222 436 UefiCapsuleHeader.PopulateSystemTable = False\r
8b63877a
KM
437 UefiCapsuleHeader.InitiateReset = 'InitiateReset' in args.CapsuleFlag\r
438 UefiCapsuleHeader.Payload = Result\r
439 Result = UefiCapsuleHeader.Encode ()\r
440 if args.Verbose:\r
441 UefiCapsuleHeader.DumpInfo ()\r
442 except:\r
443 print ('GenerateCapsule: error: can not encode UEFI Capsule Header')\r
444 sys.exit (1)\r
445\r
446 elif args.Decode:\r
447 try:\r
448 Result = UefiCapsuleHeader.Decode (Buffer)\r
449 FmpCapsuleHeader.Decode (Result)\r
450 Result = FmpCapsuleHeader.GetFmpCapsuleImageHeader (0).Payload\r
451 if args.Verbose:\r
452 print ('========')\r
453 UefiCapsuleHeader.DumpInfo ()\r
454 print ('--------')\r
455 FmpCapsuleHeader.DumpInfo ()\r
456 if UseSignTool or UseOpenSsl:\r
457 Result = FmpAuthHeader.Decode (Result)\r
de652b14
KM
458 if args.Verbose:\r
459 print ('--------')\r
460 FmpAuthHeader.DumpInfo ()\r
8b63877a
KM
461\r
462 #\r
463 # Verify Image with 64-bit MonotonicCount appended to end of image\r
464 #\r
465 try:\r
466 if UseSignTool:\r
467 CertData = VerifyPayloadSignTool (\r
468 FmpAuthHeader.Payload + struct.pack ('<Q', FmpAuthHeader.MonotonicCount),\r
469 FmpAuthHeader.CertData,\r
470 args.SigningToolPath,\r
471 args.SignToolPfxFile\r
472 )\r
473 else:\r
474 CertData = VerifyPayloadOpenSsl (\r
475 FmpAuthHeader.Payload + struct.pack ('<Q', FmpAuthHeader.MonotonicCount),\r
476 FmpAuthHeader.CertData,\r
477 args.SigningToolPath,\r
478 args.OpenSslSignerPrivateCertFile,\r
479 args.OpenSslOtherPublicCertFile,\r
480 args.OpenSslTrustedPublicCertFile\r
481 )\r
482 except ValueError:\r
483 print ('GenerateCapsule: warning: can not verify payload.')\r
484\r
de652b14
KM
485 try:\r
486 Result = FmpPayloadHeader.Decode (Result)\r
487 if args.Verbose:\r
488 print ('--------')\r
489 FmpPayloadHeader.DumpInfo ()\r
490 print ('========')\r
491 except:\r
492 if args.Verbose:\r
493 print ('--------')\r
494 print ('No FMP_PAYLOAD_HEADER')\r
495 print ('========')\r
496 raise\r
8b63877a
KM
497 else:\r
498 if args.Verbose:\r
499 print ('--------')\r
500 print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION')\r
501 print ('--------')\r
502 print ('No FMP_PAYLOAD_HEADER')\r
de652b14 503 print ('========')\r
8b63877a
KM
504 except:\r
505 print ('GenerateCapsule: error: can not decode capsule')\r
8b63877a
KM
506 sys.exit (1)\r
507\r
508 elif args.DumpInfo:\r
509 try:\r
510 Result = UefiCapsuleHeader.Decode (Buffer)\r
511 FmpCapsuleHeader.Decode (Result)\r
512 Result = FmpCapsuleHeader.GetFmpCapsuleImageHeader (0).Payload\r
513 print ('========')\r
514 UefiCapsuleHeader.DumpInfo ()\r
515 print ('--------')\r
516 FmpCapsuleHeader.DumpInfo ()\r
517 try:\r
518 Result = FmpAuthHeader.Decode (Result)\r
8b63877a
KM
519 print ('--------')\r
520 FmpAuthHeader.DumpInfo ()\r
de652b14
KM
521 try:\r
522 Result = FmpPayloadHeader.Decode (Result)\r
523 print ('--------')\r
524 FmpPayloadHeader.DumpInfo ()\r
525 except:\r
526 print ('--------')\r
527 print ('No FMP_PAYLOAD_HEADER')\r
8b63877a
KM
528 except:\r
529 print ('--------')\r
530 print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION')\r
531 print ('--------')\r
532 print ('No FMP_PAYLOAD_HEADER')\r
533 print ('========')\r
534 except:\r
535 print ('GenerateCapsule: error: can not decode capsule')\r
536 sys.exit (1)\r
537 else:\r
538 print('GenerateCapsule: error: invalid options')\r
539 sys.exit (1)\r
540\r
541 #\r
542 # Write binary output file\r
543 #\r
544 if args.OutputFile is not None:\r
545 try:\r
546 if args.Verbose:\r
547 print ('Write binary output file {File}'.format (File = args.OutputFile.name))\r
548 args.OutputFile.write (Result)\r
549 args.OutputFile.close ()\r
550 except:\r
551 print ('GenerateCapsule: error: can not write binary output file {File}'.format (File = args.OutputFile.name))\r
552 sys.exit (1)\r
553\r
554 if args.Verbose:\r
555 print('Success')\r