Enable key ids usage for private keys

This patch enables usage of key id for private keys
in slimboot repo. Key ids are configured in
BuildLoader and platform BoardConfig files.
SLIMBOOT_KEY_DIR is set to default folder outside
sblopen.

Generation of extrenal Keyhash OS key hash to be configured
for QEMU/CGL/APL with appropriate keys.

Signed-off-by: Subash Lakkimsetti <subash.lakkimsetti@intel.com>
This commit is contained in:
Subash Lakkimsetti 2020-06-08 15:58:21 -07:00 committed by Guo Dong
parent 9704eaecec
commit 6328ea56c7
10 changed files with 120 additions and 32 deletions

View File

@ -820,6 +820,7 @@ def print_tool_version_info(cmd, version):
pass
print ('Using %s, Version %s' % (cmd, version))
def check_for_openssl():
'''
Verify OpenSSL executable is available
@ -859,6 +860,10 @@ def check_for_git():
print_tool_version_info(cmd, version)
return version
def check_for_slimbootkeydir():
if not os.path.exists(os.environ.get('SBL_KEY_DIR')):
raise Exception ("SBL_KEY_DIR is not valid. Set correct SBL_KEY_DIR path !!")
def copy_images_to_output (fv_dir, zip_file, img_list, rgn_name_list, out_list):
zip_path_file = os.path.join (os.environ['WORKSPACE'], zip_file)
output_dir = os.path.dirname(zip_path_file)

View File

@ -179,7 +179,7 @@ def main():
dest='key_file',
type=str,
default='',
help='Signing key path')
help='Key Id or Signing key path')
ap.add_argument('-s',
'--script-dir',
dest='script_dir',

View File

@ -920,7 +920,7 @@ def Main():
type=str,
help='Configuration binary file')
SignParser.add_argument('-o', dest='cfg_out_file', type=str, help='Signed configuration output binary file name to be generated', required=True)
SignParser.add_argument('-k', dest='cfg_pri_key', type=str, help='Private key file (PEM format) used to sign configuration data', required=True)
SignParser.add_argument('-k', dest='cfg_pri_key', type=str, help='Key Id or Private key file (PEM format) used to sign configuration data', required=True)
SignParser.add_argument('-a', dest='hash_alg', type=str, choices=['SHA2_256', 'SHA2_384'], help='Hash Type for signing', default = 'SHA2_256')
SignParser.add_argument('-s', dest='sign_scheme', type=str, choices=['RSA_PKCS1', 'RSA_PSS'], help='Signing Scheme', default = 'RSA_PSS')
SignParser.set_defaults(func=CmdSign)

View File

@ -481,7 +481,7 @@ def main():
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('-k', '--priv_key', dest='PrivKey', type=str, required=True, help='Key Id or Private RSA 2048/RSA3072 key in PEM format to sign image')
parser.add_argument('-a', '--alg_hash', dest='HashType', type=str, choices=['SHA2_256', 'SHA2_384'], default='SHA2_256', help='Hash type for signing')
parser.add_argument('-s', '--sign_scheme', dest='SignScheme', type=str, choices=['RSA_PKCS1', 'RSA_PSS'], default='RSA_PSS', help='Signing Scheme types')
parser.add_argument('-o', '--output', dest='NewImage', type=str, required=True, help='Output file for signed image')

View File

@ -578,7 +578,7 @@ class CONTAINER ():
# create header entry
auth_type_str = self.get_auth_type_str (self.header.auth_type)
key_file = 'TestSigningPrivateKey.pem' if auth_type_str.startswith('RSA') else ''
key_file = 'CONTAINER_KEY_ID' if auth_type_str.startswith('RSA') else ''
alignment = self.header.alignment
image_type_str = CONTAINER.get_image_type_str(self.header.image_type)
header = ['%s' % self.header.signature.decode(), file_name, image_type_str, auth_type_str, key_file]
@ -587,7 +587,7 @@ class CONTAINER ():
# create component entry
for component in self.header.comp_entry:
auth_type_str = self.get_auth_type_str (component.auth_type)
key_file = 'TestSigningPrivateKey.pem' if auth_type_str.startswith('RSA') else ''
key_file = 'CONTAINER_COMP_KEY_ID' if auth_type_str.startswith('RSA') else ''
lz_header = LZ_HEADER.from_buffer(component.data)
alg = LZ_HEADER._compress_alg[lz_header.signature]
if component.attribute & COMPONENT_ENTRY._attr['RESERVED']:
@ -798,7 +798,7 @@ def main():
cmd_display.add_argument('-t', dest='img_type', type=str, default='CLASSIC', help='Container Image Type : [NORMAL, CLASSIC, MULTIBOOT]')
cmd_display.add_argument('-o', dest='out_path', type=str, default='.', help='Container output directory/file')
cmd_display.add_argument('-k', dest='key_path', type=str, default='', help='Input key directory/file. Use key directoy path when container layout -l option is used \
Use key file path when component files with -cl option is specified')
Use Key Id or key file path when component files with -cl option is specified')
cmd_display.add_argument('-a', dest='auth', choices=['SHA2_256', 'SHA2_384', 'RSA2048_PKCS1_SHA2_256',
'RSA3072_PKCS1_SHA2_384', 'RSA2048_PSS_SHA2_256', 'RSA3072_PSS_SHA2_384', 'NONE'], default='', help='authentication algorithm')
cmd_display.add_argument('-cd', dest='comp_dir', type=str, default='', help='Componet image input directory')
@ -820,7 +820,7 @@ def main():
cmd_display.add_argument('-n', dest='comp_name', type=str, required=True, help='Component name to replace')
cmd_display.add_argument('-f', dest='comp_file', type=str, required=True, help='Component input file path')
cmd_display.add_argument('-c', dest='compress', choices=['lz4', 'lzma', 'dummy'], default='dummy', help='compression algorithm')
cmd_display.add_argument('-k', dest='key_file', type=str, default='', help='Private key file path to sign component')
cmd_display.add_argument('-k', dest='key_file', type=str, default='', help='Key Id or Private key file path to sign component')
cmd_display.add_argument('-td', dest='tool_dir', type=str, default='', help='Compression tool directory')
cmd_display.set_defaults(func=replace_component)
@ -831,7 +831,7 @@ def main():
cmd_display.add_argument('-c', dest='compress', choices=['lz4', 'lzma', 'dummy'], default='dummy', help='compression algorithm')
cmd_display.add_argument('-a', dest='auth', choices=['SHA2_256', 'SHA2_384', 'RSA2048_PKCS1_SHA2_256',
'RSA3072_PKCS1_SHA2_384', 'RSA2048_PSS_SHA2_256', 'RSA3072_PSS_SHA2_384', 'NONE'], default='NONE', help='authentication algorithm')
cmd_display.add_argument('-k', dest='key_file', type=str, default='', help='Private key file path to sign component')
cmd_display.add_argument('-k', dest='key_file', type=str, default='', help='Key Id or Private key file path to sign component')
cmd_display.add_argument('-td', dest='tool_dir', type=str, default='', help='Compression tool directory')
cmd_display.set_defaults(func=sign_component)

View File

@ -45,14 +45,13 @@ SIGNING_KEY = {
# OS1_PUBLIC_KEY_ID, OS2_PUBLIC_KEY_ID is used for referencing Boot OS public keys
"OS1_PUBLIC_KEY_ID" : "OS1_TestKey_Pub",
"OS2_PUBLIC_KEY_ID" : "OS2_TestKey_Pub",
}
def print_message_slimboot_key_store ():
print ("Pre-requiste: SLIMBOOT_KEY_DIR environment variable has to be set!")
print ("SLIMBOOT_KEY_DIR is path to keys used for the project!")
print ("For Keys generation follow GenerateKey.py availabl in tool directory!")
def print_message_sbl_key_dir ():
print ("Pre-requiste: SBL_KEY_DIR environment variable has to be set!")
print ("SBL_KEY_DIR is path to keys used for the project!")
print ("For Keys generation follow GenerateKeys.py available in tool directory!")
return
@ -111,13 +110,24 @@ def get_key_id (priv_key):
else:
return None
def get_key_dir ():
# Check Key store setting SBL_KEY_DIR path
if 'SBL_KEY_DIR' not in os.environ:
print_message_sbl_key_dir()
raise Exception ("SBL_KEY_DIR is not defined. Set SBL_KEY_DIR !!")
sbl_key_dir = os.environ.get('SBL_KEY_DIR')
if not os.path.exists(sbl_key_dir):
print_message_sbl_key_dir()
raise Exception ("SBL_KEY_DIR is not valid. Set the correct SBL_KEY_DIR path !!")
else:
return sbl_key_dir
def get_key_from_store (in_key):
# Check Key store setting SLIMBOOT_KEY_DIR path
slimboot_key_dir = os.environ.get('SLIMBOOT_KEY_DIR')
if not os.path.exists(slimboot_key_dir):
print_message_slimboot_key_store();
raise Exception ("SLIMBOOT_KEY_DIR is not defined. Set SLIMBOOT_KEY_DIR !!")
print("in_Key %s" % in_key)
# Get Slimboot key dir path
sbl_key_dir = get_key_dir()
# Extract key_id if present
priv_key = get_key_id (in_key)
@ -135,7 +145,7 @@ def get_key_from_store (in_key):
raise Exception('key provided %s is not valid!' % in_key)
try:
priv_key = os.path.join (slimboot_key_dir, priv_key_file)
priv_key = os.path.join (sbl_key_dir, priv_key_file)
except:
raise Exception('priv_key is not found %s!' % priv_key)

View File

@ -88,11 +88,15 @@ def prep_env ():
print("Unsupported operating system !")
sys.exit(1)
if 'SLIMBOOT_KEY_DIR' not in os.environ:
os.environ['SLIMBOOT_KEY_DIR'] = "./../SlimbootKeyDir/"
print_tool_version_info(toolchain, toolchain_ver)
check_for_openssl()
check_for_nasm()
check_for_git()
check_for_slimbootkeydir()
# Update Environment vars
os.environ['SBL_SOURCE'] = sblsource
@ -122,14 +126,14 @@ class BaseBoard(object):
# NOTE: Variables starting with '_' will not be exported to Platform.dsc
# Define default private key (PEM format) used to sign configuration data, firmware capsule and IAS image
key_dir = os.path.join('BootloaderCorePkg', 'Tools', 'Keys')
# Default key dir is set by SLIMBOOT_KEY_DIR. _KEY_DIR is set to NULL.
self._KEY_DIR = ''
# Allow master key to be able to sign everything by default
self._MASTER_KEY_USAGE = HASH_USAGE['PUBKEY_CFG_DATA'] | HASH_USAGE['PUBKEY_FWU'] | HASH_USAGE['PUBKEY_OS'] | \
HASH_USAGE['PUBKEY_CONT_DEF']
self._MASTER_PRIVATE_KEY = os.path.join(key_dir, 'TestSigningPrivateKey.pem')
self._CFGDATA_PRIVATE_KEY = os.path.join(key_dir, 'TestSigningPrivateKey.pem')
self._CONTAINER_PRIVATE_KEY = os.path.join(key_dir, 'TestSigningPrivateKey.pem')
self._MASTER_PRIVATE_KEY = 'MASTER_KEY_ID'
self._CFGDATA_PRIVATE_KEY = 'CFGDATA_KEY_ID'
self._CONTAINER_PRIVATE_KEY = 'CONTAINER_KEY_ID'
self.LOGO_FILE = 'Platform/CommonBoardPkg/Logo/Logo.bmp'
self._RSA_SIGN_TYPE = 'RSA2048'
@ -287,7 +291,7 @@ class Build(object):
self._target = 'RELEASE' if board.RELEASE_MODE else 'NOOPT' if board.NO_OPT_MODE else 'DEBUG'
self._fsp_basename = 'FspDbg' if board.FSPDEBUG_MODE else 'FspRel'
self._fv_dir = os.path.join(self._workspace, 'Build', 'BootloaderCorePkg', '%s_%s' % (self._target, self._toolchain), 'FV')
self._key_dir = os.path.join('BootloaderCorePkg', 'Tools', 'Keys')
self._key_dir = self._board._KEY_DIR
self._img_list = board.GetImageLayout()
self._pld_list = get_payload_list (board._PAYLOAD_NAME.split(';'))
self._comp_list = []

View File

@ -241,6 +241,33 @@ class Board(BaseBoard):
]
return img_list
def GetKeyHashList (self):
# Define a set of new key used for different purposes
# The key is either key id or public key PEM format or private key PEM format
pub_key_list = [
(
# Key for verifying Config data blob
HASH_USAGE['PUBKEY_CFG_DATA'],
'CFGDATA_KEY_ID'
),
(
# Key for verifying firmware update
HASH_USAGE['PUBKEY_FWU'],
'FIRMWAREUPDATE_KEY_ID'
),
(
# Key for verifying container header
HASH_USAGE['PUBKEY_CONT_DEF'],
'CONTAINER_KEY_ID'
),
(
# key for veryfying OS image.
HASH_USAGE['PUBKEY_OS'],
'OS1_PUBLIC_KEY_ID'
),
]
return pub_key_list
def GetImageLayout (self):
ias1_flag = 0 if self.SPI_IAS1_SIZE > 0 else STITCH_OPS.MODE_FILE_IGNOR
fwu_flag = 0 if self.ENABLE_FWU else STITCH_OPS.MODE_FILE_IGNOR

View File

@ -160,6 +160,33 @@ class Board(BaseBoard):
dsc['LibraryClasses.%s' % self.BUILD_ARCH] = common_libs
return dsc
def GetKeyHashList (self):
# Define a set of new key used for different purposes
# The key is either key id or public key PEM format or private key PEM format
pub_key_list = [
(
# Key for verifying Config data blob
HASH_USAGE['PUBKEY_CFG_DATA'],
'CFGDATA_KEY_ID'
),
(
# Key for verifying firmware update
HASH_USAGE['PUBKEY_FWU'],
'FIRMWAREUPDATE_KEY_ID'
),
(
# Key for verifying container header
HASH_USAGE['PUBKEY_CONT_DEF'],
'CONTAINER_KEY_ID'
),
(
# key for veryfying OS image.
HASH_USAGE['PUBKEY_OS'],
'OS1_PUBLIC_KEY_ID'
),
]
return pub_key_list
def GetImageLayout (self):
img_list = []

View File

@ -182,12 +182,27 @@ class Board(BaseBoard):
def GetKeyHashList (self):
# Define a set of new key used for different purposes
# The key is either public key PEM format or private key PEM format
# The key is either key id or public key PEM format or private key PEM format
pub_key_list = [
(
# Use a single test key
HASH_USAGE['PUBKEY_CFG_DATA'] | HASH_USAGE['PUBKEY_FWU'] | HASH_USAGE['PUBKEY_OS'] | HASH_USAGE['PUBKEY_CONT_DEF'],
'TestSigningPrivateKey.pem'
# Key for verifying Config data blob
HASH_USAGE['PUBKEY_CFG_DATA'],
'CFGDATA_KEY_ID'
),
(
# Key for verifying firmware update
HASH_USAGE['PUBKEY_FWU'],
'FIRMWAREUPDATE_KEY_ID'
),
(
# Key for verifying container header
HASH_USAGE['PUBKEY_CONT_DEF'],
'CONTAINER_KEY_ID'
),
(
# key for veryfying OS image.
HASH_USAGE['PUBKEY_OS'],
'OS1_PUBLIC_KEY_ID'
),
]
return pub_key_list
@ -197,12 +212,12 @@ class Board(BaseBoard):
container_list.append ([
# Name | Image File | CompressAlg | AuthType | Key File | Region Align | Region Size
# ============================================================================================================================================
('IPFW', 'SIIPFW.bin', '', 'RSA2048_PSS_SHA2_256', 'TestSigningPrivateKey.pem', 0, 0 ), # Container Header
('IPFW', 'SIIPFW.bin', '', 'RSA2048_PSS_SHA2_256', 'CONTAINER_KEY_ID', 0, 0 ), # Container Header
('TST1', '', 'Dummy', '', '', 0, 0x2000), # Component 1
('TST2', '', 'Lz4', '', '', 0, 0x3000), # Component 2
('TST3', '', 'Lz4', 'RSA2048_PSS_SHA2_256', 'TestSigningPrivateKey.pem', 0, 0x3000), # Component 3
('TST3', '', 'Lz4', 'RSA2048_PSS_SHA2_256', 'CONTAINER_COMP_KEY_ID', 0, 0x3000), # Component 3
('TST4', '', 'Lzma', 'SHA2_256', '', 0, 0x3000), # Component 4
('TST5', '', 'Dummy', 'RSA2048_PSS_SHA2_256', 'TestSigningPrivateKey.pem', 0, 0x3000), # Component 5
('TST5', '', 'Dummy', 'RSA2048_PSS_SHA2_256', 'CONTAINER_COMP_KEY_ID', 0, 0x3000), # Component 5
('TST6', '', '', '', '', 0, 0x1000), # Component 6
])
return container_list