You've already forked slimbootloader
mirror of
https://github.com/Dasharo/slimbootloader.git
synced 2026-03-06 15:26:20 -08:00
ea38da7599
EDK II build has enabled python3 support. Since SBL has its own scripts, it is required to port them accordingly to support python3. This patch added python3 build support for SBL. Signed-off-by: Maurice Ma <maurice.ma@intel.com>
514 lines
19 KiB
Python
514 lines
19 KiB
Python
## @ GenCapsuleFirmware.py
|
|
#
|
|
# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
#
|
|
##
|
|
|
|
import os
|
|
import argparse
|
|
import subprocess
|
|
import sys
|
|
import re
|
|
import struct
|
|
import uuid
|
|
from ctypes import *
|
|
|
|
sys.dont_write_bytecode = True
|
|
from BuildUtility import rsa_sign_file, gen_pub_key
|
|
|
|
|
|
class FmpCapsuleImageHeaderClass(object):
|
|
# typedef struct {
|
|
# UINT32 Version;
|
|
#
|
|
# ///
|
|
# /// Used to identify device firmware targeted by this update. This guid is matched by
|
|
# /// system firmware against ImageTypeId field within a EFI_FIRMWARE_IMAGE_DESCRIPTOR
|
|
# ///
|
|
# EFI_GUID UpdateImageTypeId;
|
|
#
|
|
# ///
|
|
# /// Passed as ImageIndex in call to EFI_FIRMWARE_MANAGEMENT_PROTOCOL.SetImage ()
|
|
# ///
|
|
# UINT8 UpdateImageIndex;
|
|
# UINT8 reserved_bytes[3];
|
|
#
|
|
# ///:
|
|
# /// Size of the binary update image which immediately follows this structure
|
|
# ///
|
|
# UINT32 UpdateImageSize;
|
|
#
|
|
# ///
|
|
# /// Size of the VendorCode bytes which optionally immediately follow binary update image in the capsule
|
|
# ///
|
|
# UINT32 UpdateVendorCodeSize;
|
|
#
|
|
# ///
|
|
# /// The HardwareInstance to target with this update. If value is zero it means match all
|
|
# /// HardwareInstances. This field allows update software to target only a single device in
|
|
# /// cases where there are more than one device with the same ImageTypeId GUID.
|
|
# /// This header is outside the signed data of the Authentication Info structure and
|
|
# /// therefore can be modified without changing the Auth data.
|
|
# ///
|
|
# UINT64 UpdateHardwareInstance;
|
|
# } EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER;
|
|
#
|
|
# #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION 0x00000002
|
|
|
|
_StructFormat = '<I16sB3BIIQ'
|
|
_StructSize = struct.calcsize(_StructFormat)
|
|
|
|
EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION = 0x00000002
|
|
|
|
def __init__(self):
|
|
self._Valid = False
|
|
self.Version = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION
|
|
self.UpdateImageTypeId = uuid.UUID(
|
|
'00000000-0000-0000-0000-000000000000')
|
|
self.UpdateImageIndex = 0
|
|
self.UpdateImageSize = 0
|
|
self.UpdateVendorCodeSize = 0
|
|
self.UpdateHardwareInstance = 0x0000000000000000
|
|
self.Payload = b''
|
|
self.VendorCodeBytes = b''
|
|
|
|
def Encode(self):
|
|
self.UpdateImageSize = len(self.Payload)
|
|
self.UpdateVendorCodeSize = len(self.VendorCodeBytes)
|
|
FmpCapsuleImageHeader = struct.pack(
|
|
self._StructFormat, self.Version, self.UpdateImageTypeId.bytes_le,
|
|
self.UpdateImageIndex, 0, 0, 0, self.UpdateImageSize,
|
|
self.UpdateVendorCodeSize, self.UpdateHardwareInstance)
|
|
self._Valid = True
|
|
return FmpCapsuleImageHeader + self.Payload + self.VendorCodeBytes
|
|
|
|
def Decode(self, Buffer):
|
|
if len(Buffer) < self._StructSize:
|
|
raise ValueError
|
|
(Version, UpdateImageTypeId, UpdateImageIndex, r0, r1, r2,
|
|
UpdateImageSize, UpdateVendorCodeSize,
|
|
UpdateHardwareInstance) = struct.unpack(self._StructFormat,
|
|
Buffer[0:self._StructSize])
|
|
|
|
if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION:
|
|
raise ValueError
|
|
if UpdateImageIndex < 1:
|
|
raise ValueError
|
|
if UpdateImageSize + UpdateVendorCodeSize != len(Buffer[
|
|
self._StructSize:]):
|
|
raise ValueError
|
|
|
|
self.Version = Version
|
|
self.UpdateImageTypeId = uuid.UUID(bytes_le=UpdateImageTypeId)
|
|
self.UpdateImageIndex = UpdateImageIndex
|
|
self.UpdateImageSize = UpdateImageSize
|
|
self.UpdateVendorCodeSize = UpdateVendorCodeSize
|
|
self.UpdateHardwareInstance = UpdateHardwareInstance
|
|
self.Payload = Buffer[self._StructSize:self._StructSize +
|
|
UpdateImageSize]
|
|
self.VendorCodeBytes = Buffer[self._StructSize + UpdateImageSize:]
|
|
self._Valid = True
|
|
return Buffer[self._StructSize:]
|
|
|
|
def DumpInfo(self, padding=''):
|
|
if not self._Valid:
|
|
raise ValueError
|
|
print(
|
|
padding +
|
|
'EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.Version = {Version:08X}'.format(
|
|
Version=self.Version))
|
|
print(
|
|
padding +
|
|
'EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageTypeId = {UpdateImageTypeId}'.format(
|
|
UpdateImageTypeId=str(self.UpdateImageTypeId).upper()))
|
|
print(
|
|
padding +
|
|
'EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageIndex = {UpdateImageIndex:08X}'.format(
|
|
UpdateImageIndex=self.UpdateImageIndex))
|
|
print(
|
|
padding +
|
|
'EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageSize = {UpdateImageSize:08X}'.format(
|
|
UpdateImageSize=self.UpdateImageSize))
|
|
print(
|
|
padding +
|
|
'EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateVendorCodeSize = {UpdateVendorCodeSize:08X}'.format(
|
|
UpdateVendorCodeSize=self.UpdateVendorCodeSize))
|
|
print(
|
|
padding +
|
|
'EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateHardwareInstance = {UpdateHardwareInstance:016X}'.format(
|
|
UpdateHardwareInstance=self.UpdateHardwareInstance))
|
|
print(
|
|
padding +
|
|
'sizeof (Payload) = {Size:08X}'.format(
|
|
Size=len(self.Payload)))
|
|
print(
|
|
padding +
|
|
'sizeof (VendorCodeBytes) = {Size:08X}'.format(
|
|
Size=len(self.VendorCodeBytes)))
|
|
|
|
|
|
class FmpCapsuleHeaderClass(object):
|
|
# typedef struct {
|
|
# UINT32 Version;
|
|
#
|
|
# ///
|
|
# /// The number of drivers included in the capsule and the number of corresponding
|
|
# /// offsets stored in ItemOffsetList array.
|
|
# ///
|
|
# UINT16 EmbeddedDriverCount;
|
|
#
|
|
# ///
|
|
# /// The number of payload items included in the capsule and the number of
|
|
# /// corresponding offsets stored in the ItemOffsetList array.
|
|
# ///
|
|
# UINT16 PayloadItemCount;
|
|
#
|
|
# ///
|
|
# /// Variable length array of dimension [EmbeddedDriverCount + PayloadItemCount]
|
|
# /// containing offsets of each of the drivers and payload items contained within the capsule
|
|
# ///
|
|
# // UINT64 ItemOffsetList[];
|
|
# } EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER;
|
|
#
|
|
# #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION 0x00000001
|
|
_StructFormat = '<IHH'
|
|
_StructSize = struct.calcsize(_StructFormat)
|
|
|
|
_ItemOffsetFormat = '<Q'
|
|
_ItemOffsetSize = struct.calcsize(_ItemOffsetFormat)
|
|
|
|
EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION = 0x00000001
|
|
|
|
def __init__(self):
|
|
self._Valid = False
|
|
self.Version = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION
|
|
self.EmbeddedDriverCount = 0
|
|
self.PayloadItemCount = 0
|
|
self._ItemOffsetList = []
|
|
self._EmbeddedDriverList = []
|
|
self._PayloadList = []
|
|
self._FmpCapsuleImageHeaderList = []
|
|
|
|
def AddEmbeddedDriver(self, EmbeddedDriver):
|
|
self._EmbeddedDriverList.append(EmbeddedDriver)
|
|
|
|
def GetEmbeddedDriver(self, Index):
|
|
if Index > len(self._EmbeddedDriverList):
|
|
raise ValueError
|
|
return self._EmbeddedDriverList[Index]
|
|
|
|
def AddPayload(self,
|
|
UpdateImageTypeId,
|
|
Payload=b'',
|
|
VendorCodeBytes=b'',
|
|
HardwareInstance=0):
|
|
self._PayloadList.append((UpdateImageTypeId, Payload, VendorCodeBytes,
|
|
HardwareInstance))
|
|
|
|
def GetFmpCapsuleImageHeader(self, Index):
|
|
if Index >= len(self._FmpCapsuleImageHeaderList):
|
|
raise ValueError
|
|
return self._FmpCapsuleImageHeaderList[Index]
|
|
|
|
def Encode(self):
|
|
self.EmbeddedDriverCount = len(self._EmbeddedDriverList)
|
|
self.PayloadItemCount = len(self._PayloadList)
|
|
|
|
FmpCapsuleHeader = struct.pack(self._StructFormat, self.Version,
|
|
self.EmbeddedDriverCount,
|
|
self.PayloadItemCount)
|
|
|
|
FmpCapsuleData = b''
|
|
Offset = self._StructSize + (
|
|
self.EmbeddedDriverCount +
|
|
self.PayloadItemCount) * self._ItemOffsetSize
|
|
for EmbeddedDriver in self._EmbeddedDriverList:
|
|
FmpCapsuleData = FmpCapsuleData + EmbeddedDriver
|
|
self._ItemOffsetList.append(Offset)
|
|
Offset = Offset + len(EmbeddedDriver)
|
|
Index = 1
|
|
for (UpdateImageTypeId, Payload, VendorCodeBytes,
|
|
HardwareInstance) in self._PayloadList:
|
|
FmpCapsuleImageHeader = FmpCapsuleImageHeaderClass()
|
|
FmpCapsuleImageHeader.UpdateImageTypeId = UpdateImageTypeId
|
|
FmpCapsuleImageHeader.UpdateImageIndex = Index
|
|
FmpCapsuleImageHeader.Payload = Payload
|
|
FmpCapsuleImageHeader.VendorCodeBytes = VendorCodeBytes
|
|
FmpCapsuleImageHeader.UpdateHardwareInstance = HardwareInstance
|
|
FmpCapsuleImage = FmpCapsuleImageHeader.Encode()
|
|
FmpCapsuleData = FmpCapsuleData + FmpCapsuleImage
|
|
|
|
self._ItemOffsetList.append(Offset)
|
|
self._FmpCapsuleImageHeaderList.append(FmpCapsuleImageHeader)
|
|
|
|
Offset = Offset + len(FmpCapsuleImage)
|
|
Index = Index + 1
|
|
|
|
for Offset in self._ItemOffsetList:
|
|
FmpCapsuleHeader = FmpCapsuleHeader + struct.pack(
|
|
self._ItemOffsetFormat, Offset)
|
|
|
|
self._Valid = True
|
|
return FmpCapsuleHeader + FmpCapsuleData
|
|
|
|
def Decode(self, Buffer):
|
|
if len(Buffer) < self._StructSize:
|
|
raise ValueError
|
|
(Version, EmbeddedDriverCount, PayloadItemCount) = struct.unpack(
|
|
self._StructFormat, Buffer[0:self._StructSize])
|
|
if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION:
|
|
raise ValueError
|
|
|
|
self.Version = Version
|
|
self.EmbeddedDriverCount = EmbeddedDriverCount
|
|
self.PayloadItemCount = PayloadItemCount
|
|
self._ItemOffsetList = []
|
|
self._EmbeddedDriverList = []
|
|
self._PayloadList = []
|
|
self._FmpCapsuleImageHeaderList = []
|
|
|
|
#
|
|
# Parse the ItemOffsetList values
|
|
#
|
|
Offset = self._StructSize
|
|
for Index in range(0, EmbeddedDriverCount + PayloadItemCount):
|
|
ItemOffset = struct.unpack(
|
|
self._ItemOffsetFormat,
|
|
Buffer[Offset:Offset + self._ItemOffsetSize])[0]
|
|
if ItemOffset >= len(Buffer):
|
|
raise ValueError
|
|
self._ItemOffsetList.append(ItemOffset)
|
|
Offset = Offset + self._ItemOffsetSize
|
|
Result = Buffer[Offset:]
|
|
|
|
#
|
|
# Parse the EmbeddedDrivers
|
|
#
|
|
for Index in range(0, EmbeddedDriverCount):
|
|
Offset = self._ItemOffsetList[Index]
|
|
if Index < (len(self._ItemOffsetList) - 1):
|
|
Length = self._ItemOffsetList[Index + 1] - Offset
|
|
else:
|
|
Length = len(Buffer) - Offset
|
|
self.AddEmbeddedDriver(Buffer[Offset:Offset + Length])
|
|
|
|
#
|
|
# Parse the Payloads that are FMP Capsule Images
|
|
#
|
|
for Index in range(EmbeddedDriverCount,
|
|
EmbeddedDriverCount + PayloadItemCount):
|
|
Offset = self._ItemOffsetList[Index]
|
|
if Index < (len(self._ItemOffsetList) - 1):
|
|
Length = self._ItemOffsetList[Index + 1] - Offset
|
|
else:
|
|
Length = len(Buffer) - Offset
|
|
FmpCapsuleImageHeader = FmpCapsuleImageHeaderClass()
|
|
FmpCapsuleImageHeader.Decode(Buffer[Offset:Offset + Length])
|
|
self.AddPayload(FmpCapsuleImageHeader.UpdateImageTypeId,
|
|
FmpCapsuleImageHeader.Payload,
|
|
FmpCapsuleImageHeader.VendorCodeBytes)
|
|
self._FmpCapsuleImageHeaderList.append(FmpCapsuleImageHeader)
|
|
|
|
self._Valid = True
|
|
return Result
|
|
|
|
def DumpInfo(self):
|
|
if not self._Valid:
|
|
raise ValueError
|
|
print(
|
|
'EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version = {Version:08X}'.format(
|
|
Version=self.Version))
|
|
print(
|
|
'EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverCount = {EmbeddedDriverCount:08X}'.format(
|
|
EmbeddedDriverCount=self.EmbeddedDriverCount))
|
|
print(
|
|
'EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCount = {PayloadItemCount:08X}'.format(
|
|
PayloadItemCount=self.PayloadItemCount))
|
|
print('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.ItemOffsetList = ')
|
|
for Offset in self._ItemOffsetList:
|
|
print(' {Offset:016X}'.format(Offset=Offset))
|
|
print('')
|
|
for FmpCapsuleImageHeader in self._FmpCapsuleImageHeaderList:
|
|
FmpCapsuleImageHeader.DumpInfo(' ')
|
|
print('')
|
|
|
|
|
|
def _SIGNATURE_32(A, B, C, D):
|
|
return struct.unpack('=I', bytearray(A + B + C + D, 'ascii'))[0]
|
|
|
|
|
|
def _SIGNATURE_32_TO_STRING(Signature):
|
|
return struct.pack("<I", Signature).decode()
|
|
|
|
|
|
class FmpPayloadHeaderClass(object):
|
|
def __init__(self):
|
|
self._Valid = False
|
|
self.Payload = b''
|
|
|
|
def Encode(self):
|
|
self._Valid = True
|
|
return self.Payload
|
|
|
|
def Decode(self, Buffer):
|
|
self.Payload = Buffer[0:]
|
|
self._Valid = True
|
|
return self.Payload
|
|
|
|
def DumpInfo(self):
|
|
if not self._Valid:
|
|
raise ValueError
|
|
print(
|
|
'FMP_PAYLOAD_HEADER.Signature = {Signature:08X} ({SignatureString})'.format(
|
|
Signature=self.Signature,
|
|
SignatureString=_SIGNATURE_32_TO_STRING(self.Signature)))
|
|
print(
|
|
'FMP_PAYLOAD_HEADER.HeaderSize = {HeaderSize:08X}'.format(
|
|
HeaderSize=self.HeaderSize))
|
|
print(
|
|
'FMP_PAYLOAD_HEADER.FwVersion = {FwVersion:08X}'.format(
|
|
FwVersion=self.FwVersion))
|
|
print(
|
|
'FMP_PAYLOAD_HEADER.LowestSupportedVersion = {LowestSupportedVersion:08X}'.format(
|
|
LowestSupportedVersion=self.LowestSupportedVersion))
|
|
print('sizeof (Payload) = {Size:08X}'.format(
|
|
Size=len(self.Payload)))
|
|
|
|
#
|
|
# GUID for firmware update image file
|
|
#
|
|
FIRMWARE_UPDATE_IMAGE_FILE_GUID = uuid.UUID('{1A3EAE58-B580-4fef-ACA3-A16D9E00DF5F}')
|
|
#0x1a3eae58, 0xb580, 0x4fef, 0xac, 0xa3, 0xa1, 0x6d, 0x9e, 0x0, 0xdf, 0x5f);
|
|
|
|
class Firmware_Update_Header(Structure):
|
|
_fields_ = [
|
|
('FileGuid', ARRAY(c_uint8, 16)),
|
|
('HeaderSize', c_uint32),
|
|
('FirmwreVersion', c_uint32),
|
|
('CapsuleFlags', c_uint32),
|
|
('PubKeyOffset', c_uint32),
|
|
('PubKeySize', c_uint32),
|
|
('ImageOffset', c_uint32),
|
|
('ImageSize', c_uint32),
|
|
('SignatureOffset', c_uint32),
|
|
('SignatureSize', c_uint32),
|
|
('Reserved', ARRAY(c_uint32, 3))
|
|
]
|
|
|
|
|
|
def SignImage(RawData, OutFile, PrivKey):
|
|
|
|
#
|
|
# Generate the new image layout
|
|
# 1. write firmware update header
|
|
#
|
|
unsigned_image = bytearray(sizeof(Firmware_Update_Header))
|
|
header = Firmware_Update_Header.from_buffer(unsigned_image, 0)
|
|
|
|
file_size = len(RawData)
|
|
|
|
header.FileGuid = (c_ubyte *16).from_buffer_copy(FIRMWARE_UPDATE_IMAGE_FILE_GUID.bytes_le)
|
|
header.HeaderSize = sizeof(Firmware_Update_Header)
|
|
header.FirmwreVersion = 1
|
|
header.CapsuleFlags = 0
|
|
header.ImageOffset = header.HeaderSize
|
|
header.ImageSize = file_size
|
|
header.SignatureOffset = header.ImageOffset + header.ImageSize
|
|
header.SignatureSize = 256
|
|
header.PubKeyOffset = header.SignatureOffset + header.SignatureSize
|
|
|
|
pubkey_file = 'fwu_public_key.bin'
|
|
|
|
gen_pub_key(PrivKey, pubkey_file)
|
|
|
|
header.PubKeySize = os.path.getsize(pubkey_file)
|
|
|
|
fwupdate_bin_file = 'fwupdate_unsigned.bin'
|
|
open(fwupdate_bin_file, 'wb').write(unsigned_image + RawData)
|
|
|
|
rsa_sign_file(PrivKey, pubkey_file, fwupdate_bin_file, OutFile, True, True)
|
|
|
|
os.remove(pubkey_file)
|
|
os.remove(fwupdate_bin_file)
|
|
|
|
|
|
def main():
|
|
PredefinedUuidDict = {
|
|
'BIOS': '605C6813-C2C7-4242-9C27-50A4C363DBA4', # SBL BIOS Region
|
|
'CFGD': '66030B7A-47D1-4958-B73D-00B44B9DD4B6', # SBL CFGDATA
|
|
'CSME': '43AEF186-0CA5-4230-B1BD-193FB4627201', # IFWI ME/CSME
|
|
'CSMD': '4A467997-A909-4678-910C-E0FE1C9056EA', # CSME Update driver
|
|
}
|
|
|
|
def ValidateUnsignedInteger(Argument):
|
|
try:
|
|
Value = int(Argument, 0)
|
|
except:
|
|
Message = '{Argument} is not a valid integer value.'.format(
|
|
Argument=Argument)
|
|
raise argparse.ArgumentTypeError(Message)
|
|
if Value < 0:
|
|
Message = '{Argument} is a negative value.'.format(
|
|
Argument=Argument)
|
|
raise argparse.ArgumentTypeError(Message)
|
|
return Value
|
|
|
|
def ValidateRegistryFormatGuid(Argument):
|
|
try:
|
|
Value = uuid.UUID(Argument)
|
|
except:
|
|
Message = '{Argument} is not a valid registry format GUID value.'.format(
|
|
Argument=Argument)
|
|
raise argparse.ArgumentTypeError(Message)
|
|
return Value
|
|
|
|
#
|
|
# Create command line argument parser object
|
|
#
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument('-p', '--payload', nargs=2, action='append', type=str, required=True, help='Specify payload information including GUID, FileName')
|
|
parser.add_argument('-k', '--priv_key', dest='PrivKey', type=str, required=True, help='Private RSA 2048 key in PEM format to sign image')
|
|
parser.add_argument('-o', '--output', dest='NewImage', type=str, required=True, help='Output file for signed image')
|
|
parser.add_argument("-v", "--verbose", dest='Verbose', action="store_true", help= "Turn on verbose output with informational messages printed, including capsule headers and warning messages.")
|
|
|
|
#
|
|
# Parse command line arguments
|
|
#
|
|
args = parser.parse_args()
|
|
|
|
FmpCapsuleHeader = FmpCapsuleHeaderClass()
|
|
for PldUuid, PldFile in args.payload:
|
|
|
|
FmpPayloadHeader = FmpPayloadHeaderClass()
|
|
Buffer = open(PldFile, 'rb').read()
|
|
Result = Buffer
|
|
FmpPayloadHeader.Payload = Result
|
|
Result = FmpPayloadHeader.Encode()
|
|
|
|
if PldUuid in PredefinedUuidDict:
|
|
PldUuid = PredefinedUuidDict[PldUuid]
|
|
Guid = ValidateRegistryFormatGuid(PldUuid)
|
|
FmpCapsuleHeader.AddPayload(Guid, Result, HardwareInstance=0)
|
|
|
|
Result = FmpCapsuleHeader.Encode()
|
|
|
|
#
|
|
# Write binary output file
|
|
#
|
|
if args.Verbose:
|
|
FmpCapsuleHeader.DumpInfo()
|
|
|
|
#
|
|
# Create final capsule
|
|
#
|
|
SignImage(Result, args.NewImage, args.PrivKey)
|
|
|
|
print('Success')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|