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