Rouven Czerwinski | bbaeed4 | 2019-08-07 20:07:00 +0200 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Jens Wiklander | cd5cf43 | 2017-11-28 16:59:15 +0100 | [diff] [blame] | 2 | # SPDX-License-Identifier: BSD-2-Clause |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 3 | # |
| 4 | # Copyright (c) 2015, 2017, 2019, Linaro Limited |
| 5 | # |
Jens Wiklander | cd5cf43 | 2017-11-28 16:59:15 +0100 | [diff] [blame] | 6 | |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 7 | import sys |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 8 | import math |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 9 | |
Jerome Forissier | 4a47792 | 2018-11-14 11:02:49 +0100 | [diff] [blame] | 10 | |
Mingyuan Xiang | cf3d6ac | 2020-09-17 19:01:02 +0800 | [diff] [blame] | 11 | algo = {'TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256': 0x70414930, |
| 12 | 'TEE_ALG_RSASSA_PKCS1_V1_5_SHA256': 0x70004830} |
| 13 | |
Donald Chan | c45a84b | 2022-01-01 22:32:45 +0000 | [diff] [blame] | 14 | enc_key_type = {'SHDR_ENC_KEY_DEV_SPECIFIC': 0x0, |
| 15 | 'SHDR_ENC_KEY_CLASS_WIDE': 0x1} |
| 16 | |
Donald Chan | a797f20 | 2022-01-10 19:31:13 +0000 | [diff] [blame^] | 17 | SHDR_BOOTSTRAP_TA = 1 |
| 18 | SHDR_ENCRYPTED_TA = 2 |
| 19 | SHDR_MAGIC = 0x4f545348 |
| 20 | SHDR_SIZE = 20 |
| 21 | |
Mingyuan Xiang | cf3d6ac | 2020-09-17 19:01:02 +0800 | [diff] [blame] | 22 | |
Jens Wiklander | cd5cf43 | 2017-11-28 16:59:15 +0100 | [diff] [blame] | 23 | def uuid_parse(s): |
| 24 | from uuid import UUID |
| 25 | return UUID(s) |
| 26 | |
| 27 | |
| 28 | def int_parse(str): |
| 29 | return int(str, 0) |
| 30 | |
Jens Wiklander | bc42074 | 2015-05-05 14:59:15 +0200 | [diff] [blame] | 31 | |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 32 | def get_args(logger): |
| 33 | from argparse import ArgumentParser, RawDescriptionHelpFormatter |
| 34 | import textwrap |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 35 | command_base = ['sign-enc', 'digest', 'stitch'] |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 36 | command_aliases_digest = ['generate-digest'] |
| 37 | command_aliases_stitch = ['stitch-ta'] |
| 38 | command_aliases = command_aliases_digest + command_aliases_stitch |
| 39 | command_choices = command_base + command_aliases |
Jens Wiklander | bc42074 | 2015-05-05 14:59:15 +0200 | [diff] [blame] | 40 | |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 41 | dat = '[' + ', '.join(command_aliases_digest) + ']' |
| 42 | sat = '[' + ', '.join(command_aliases_stitch) + ']' |
| 43 | |
| 44 | parser = ArgumentParser( |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 45 | description='Sign and encrypt (optional) a Trusted Application for' + |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 46 | ' OP-TEE.', |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 47 | usage='\n %(prog)s command [ arguments ]\n\n' |
| 48 | |
| 49 | ' command:\n' + |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 50 | ' sign-enc Generate signed and optionally encrypted loadable' + |
| 51 | ' TA image file.\n' + |
| 52 | ' Takes arguments --uuid, --ta-version, --in, --out,' + |
Donald Chan | c45a84b | 2022-01-01 22:32:45 +0000 | [diff] [blame] | 53 | ' --key,\n' + |
| 54 | ' --enc-key (optional) and' + |
| 55 | ' --enc-key-type (optional).\n' + |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 56 | ' digest Generate loadable TA binary image digest' + |
| 57 | ' for offline\n' + |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 58 | ' signing. Takes arguments --uuid, --ta-version,' + |
| 59 | ' --in, --key,\n' |
Donald Chan | c45a84b | 2022-01-01 22:32:45 +0000 | [diff] [blame] | 60 | ' --enc-key (optional), --enc-key-type (optional),' + |
| 61 | ' --algo (optional) and --dig.\n' + |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 62 | ' stitch Generate loadable signed and encrypted TA binary' + |
| 63 | ' image file from\n' + |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 64 | ' TA raw image and its signature. Takes' + |
Donald Chan | c45a84b | 2022-01-01 22:32:45 +0000 | [diff] [blame] | 65 | ' arguments --uuid, --in, --key, --out,\n' + |
| 66 | ' --enc-key (optional), --enc-key-type (optional),\n' + |
| 67 | ' --algo (optional) and --sig.\n\n' + |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 68 | ' %(prog)s --help show available commands and arguments\n\n', |
| 69 | formatter_class=RawDescriptionHelpFormatter, |
| 70 | epilog=textwrap.dedent('''\ |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 71 | If no command is given, the script will default to "sign-enc". |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 72 | |
| 73 | command aliases: |
| 74 | The command \'digest\' can be aliased by ''' + dat + ''' |
| 75 | The command \'stitch\' can be aliased by ''' + sat + '\n' + ''' |
Mingyuan Xiang | cf3d6ac | 2020-09-17 19:01:02 +0800 | [diff] [blame] | 76 | example offline signing command using OpenSSL for algorithm |
| 77 | TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 78 | base64 -d <UUID>.dig | \\ |
| 79 | openssl pkeyutl -sign -inkey <KEYFILE>.pem \\ |
Mingyuan Xiang | cf3d6ac | 2020-09-17 19:01:02 +0800 | [diff] [blame] | 80 | -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pss \\ |
| 81 | -pkeyopt rsa_pss_saltlen:digest \\ |
| 82 | -pkeyopt rsa_mgf1_md:sha256 | \\ |
| 83 | base64 > <UUID>.sig\n |
| 84 | example offline signing command using OpenSSL for algorithm |
| 85 | TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: |
| 86 | base64 -d <UUID>.dig | \\ |
| 87 | openssl pkeyutl -sign -inkey <KEYFILE>.pem \\ |
| 88 | -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pkcs1 | \\ |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 89 | base64 > <UUID>.sig |
| 90 | ''')) |
| 91 | |
| 92 | parser.add_argument( |
| 93 | 'command', choices=command_choices, nargs='?', |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 94 | default='sign-enc', |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 95 | help='Command, one of [' + ', '.join(command_base) + ']') |
Jens Wiklander | cd5cf43 | 2017-11-28 16:59:15 +0100 | [diff] [blame] | 96 | parser.add_argument('--uuid', required=True, |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 97 | type=uuid_parse, help='String UUID of the TA') |
| 98 | parser.add_argument('--key', required=True, |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 99 | help='Name of signing key file (PEM format)') |
| 100 | parser.add_argument('--enc-key', required=False, |
| 101 | help='Encryption key string') |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 102 | parser.add_argument( |
Donald Chan | c45a84b | 2022-01-01 22:32:45 +0000 | [diff] [blame] | 103 | '--enc-key-type', required=False, default='SHDR_ENC_KEY_DEV_SPECIFIC', |
| 104 | choices=list(enc_key_type.keys()), |
| 105 | help='Encryption key type.\n' + |
| 106 | '(SHDR_ENC_KEY_DEV_SPECIFIC or SHDR_ENC_KEY_CLASS_WIDE).\n' + |
| 107 | 'Defaults to SHDR_ENC_KEY_DEV_SPECIFIC.') |
| 108 | parser.add_argument( |
Etienne Carriere | 4784462 | 2019-08-12 11:33:24 +0200 | [diff] [blame] | 109 | '--ta-version', required=False, type=int_parse, default=0, |
| 110 | help='TA version stored as a 32-bit unsigned integer and used for\n' + |
| 111 | 'rollback protection of TA install in the secure database.\n' + |
| 112 | 'Defaults to 0.') |
| 113 | parser.add_argument( |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 114 | '--sig', required=False, dest='sigf', |
| 115 | help='Name of signature input file, defaults to <UUID>.sig') |
| 116 | parser.add_argument( |
| 117 | '--dig', required=False, dest='digf', |
| 118 | help='Name of digest output file, defaults to <UUID>.dig') |
| 119 | parser.add_argument( |
Etienne Carriere | 9d8dd73 | 2019-08-12 16:15:42 +0200 | [diff] [blame] | 120 | '--in', required=True, dest='inf', |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 121 | help='Name of application input file, defaults to <UUID>.stripped.elf') |
| 122 | parser.add_argument( |
| 123 | '--out', required=False, dest='outf', |
| 124 | help='Name of application output file, defaults to <UUID>.ta') |
Mingyuan Xiang | cf3d6ac | 2020-09-17 19:01:02 +0800 | [diff] [blame] | 125 | parser.add_argument('--algo', required=False, choices=list(algo.keys()), |
| 126 | default='TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256', |
| 127 | help='The hash and signature algorithm, ' + |
| 128 | 'defaults to TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256. ' + |
| 129 | 'Allowed values are: ' + |
| 130 | ', '.join(list(algo.keys())), metavar='') |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 131 | |
| 132 | parsed = parser.parse_args() |
| 133 | |
| 134 | # Check parameter combinations |
| 135 | |
| 136 | if parsed.digf is None and \ |
| 137 | parsed.outf is not None and \ |
| 138 | parsed.command in ['digest'] + command_aliases_digest: |
| 139 | logger.error('A digest was requested, but argument --out was given.' + |
| 140 | ' Did you mean:\n ' + |
| 141 | parser.prog+' --dig ' + parsed.outf + ' ...') |
| 142 | sys.exit(1) |
| 143 | |
| 144 | if parsed.digf is not None \ |
| 145 | and parsed.outf is not None \ |
| 146 | and parsed.command in ['digest'] + command_aliases_digest: |
| 147 | logger.warn('A digest was requested, but arguments --dig and ' + |
| 148 | '--out were given.\n' + |
| 149 | ' --out will be ignored.') |
| 150 | |
| 151 | # Set defaults for optional arguments. |
| 152 | |
| 153 | if parsed.sigf is None: |
| 154 | parsed.sigf = str(parsed.uuid)+'.sig' |
| 155 | if parsed.digf is None: |
| 156 | parsed.digf = str(parsed.uuid)+'.dig' |
| 157 | if parsed.inf is None: |
| 158 | parsed.inf = str(parsed.uuid)+'.stripped.elf' |
| 159 | if parsed.outf is None: |
| 160 | parsed.outf = str(parsed.uuid)+'.ta' |
| 161 | |
| 162 | return parsed |
Jens Wiklander | cd5cf43 | 2017-11-28 16:59:15 +0100 | [diff] [blame] | 163 | |
Jens Wiklander | bc42074 | 2015-05-05 14:59:15 +0200 | [diff] [blame] | 164 | |
| 165 | def main(): |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 166 | from cryptography import exceptions |
| 167 | from cryptography.hazmat.backends import default_backend |
| 168 | from cryptography.hazmat.primitives import serialization |
| 169 | from cryptography.hazmat.primitives import hashes |
| 170 | from cryptography.hazmat.primitives.asymmetric import padding |
| 171 | from cryptography.hazmat.primitives.asymmetric import rsa |
| 172 | from cryptography.hazmat.primitives.asymmetric import utils |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 173 | import base64 |
| 174 | import logging |
| 175 | import os |
Jens Wiklander | cd5cf43 | 2017-11-28 16:59:15 +0100 | [diff] [blame] | 176 | import struct |
Jens Wiklander | bc42074 | 2015-05-05 14:59:15 +0200 | [diff] [blame] | 177 | |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 178 | logging.basicConfig() |
| 179 | logger = logging.getLogger(os.path.basename(__file__)) |
Jens Wiklander | bc42074 | 2015-05-05 14:59:15 +0200 | [diff] [blame] | 180 | |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 181 | args = get_args(logger) |
Jens Wiklander | bc42074 | 2015-05-05 14:59:15 +0200 | [diff] [blame] | 182 | |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 183 | with open(args.key, 'rb') as f: |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 184 | data = f.read() |
| 185 | |
| 186 | try: |
| 187 | key = serialization.load_pem_private_key(data, password=None, |
| 188 | backend=default_backend()) |
| 189 | except ValueError: |
| 190 | key = serialization.load_pem_public_key(data, |
| 191 | backend=default_backend()) |
Jens Wiklander | bc42074 | 2015-05-05 14:59:15 +0200 | [diff] [blame] | 192 | |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 193 | with open(args.inf, 'rb') as f: |
| 194 | img = f.read() |
| 195 | |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 196 | chosen_hash = hashes.SHA256() |
| 197 | h = hashes.Hash(chosen_hash, default_backend()) |
Jens Wiklander | bc42074 | 2015-05-05 14:59:15 +0200 | [diff] [blame] | 198 | |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 199 | digest_len = chosen_hash.digest_size |
| 200 | sig_len = math.ceil(key.key_size / 8) |
Volodymyr Babchuk | 90ad245 | 2019-08-21 21:00:32 +0300 | [diff] [blame] | 201 | |
Jens Wiklander | cd5cf43 | 2017-11-28 16:59:15 +0100 | [diff] [blame] | 202 | img_size = len(img) |
Jens Wiklander | bc42074 | 2015-05-05 14:59:15 +0200 | [diff] [blame] | 203 | |
Etienne Carriere | 4784462 | 2019-08-12 11:33:24 +0200 | [diff] [blame] | 204 | hdr_version = args.ta_version # struct shdr_bootstrap_ta::ta_version |
| 205 | |
Donald Chan | a797f20 | 2022-01-10 19:31:13 +0000 | [diff] [blame^] | 206 | magic = SHDR_MAGIC |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 207 | if args.enc_key: |
Donald Chan | a797f20 | 2022-01-10 19:31:13 +0000 | [diff] [blame^] | 208 | img_type = SHDR_ENCRYPTED_TA |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 209 | else: |
Donald Chan | a797f20 | 2022-01-10 19:31:13 +0000 | [diff] [blame^] | 210 | img_type = SHDR_BOOTSTRAP_TA |
Etienne Carriere | 4784462 | 2019-08-12 11:33:24 +0200 | [diff] [blame] | 211 | |
Jens Wiklander | cd5cf43 | 2017-11-28 16:59:15 +0100 | [diff] [blame] | 212 | shdr = struct.pack('<IIIIHH', |
Mingyuan Xiang | cf3d6ac | 2020-09-17 19:01:02 +0800 | [diff] [blame] | 213 | magic, img_type, img_size, algo[args.algo], |
| 214 | digest_len, sig_len) |
Jens Wiklander | cd5cf43 | 2017-11-28 16:59:15 +0100 | [diff] [blame] | 215 | shdr_uuid = args.uuid.bytes |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 216 | shdr_version = struct.pack('<I', hdr_version) |
Jens Wiklander | bc42074 | 2015-05-05 14:59:15 +0200 | [diff] [blame] | 217 | |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 218 | if args.enc_key: |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 219 | from cryptography.hazmat.primitives.ciphers.aead import AESGCM |
| 220 | cipher = AESGCM(bytes.fromhex(args.enc_key)) |
| 221 | # Use 12 bytes for nonce per recommendation |
| 222 | nonce = os.urandom(12) |
| 223 | out = cipher.encrypt(nonce, img, None) |
| 224 | ciphertext = out[:-16] |
| 225 | # Authentication Tag is always the last 16 bytes |
| 226 | tag = out[-16:] |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 227 | |
Donald Chan | c45a84b | 2022-01-01 22:32:45 +0000 | [diff] [blame] | 228 | enc_algo = 0x40000810 # TEE_ALG_AES_GCM |
| 229 | flags = enc_key_type[args.enc_key_type] |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 230 | ehdr = struct.pack('<IIHH', |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 231 | enc_algo, flags, len(nonce), len(tag)) |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 232 | |
Jens Wiklander | cd5cf43 | 2017-11-28 16:59:15 +0100 | [diff] [blame] | 233 | h.update(shdr) |
| 234 | h.update(shdr_uuid) |
| 235 | h.update(shdr_version) |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 236 | if args.enc_key: |
| 237 | h.update(ehdr) |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 238 | h.update(nonce) |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 239 | h.update(tag) |
Jens Wiklander | cd5cf43 | 2017-11-28 16:59:15 +0100 | [diff] [blame] | 240 | h.update(img) |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 241 | img_digest = h.finalize() |
Jens Wiklander | bc42074 | 2015-05-05 14:59:15 +0200 | [diff] [blame] | 242 | |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 243 | def write_image_with_signature(sig): |
| 244 | with open(args.outf, 'wb') as f: |
| 245 | f.write(shdr) |
| 246 | f.write(img_digest) |
| 247 | f.write(sig) |
| 248 | f.write(shdr_uuid) |
| 249 | f.write(shdr_version) |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 250 | if args.enc_key: |
| 251 | f.write(ehdr) |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 252 | f.write(nonce) |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 253 | f.write(tag) |
| 254 | f.write(ciphertext) |
| 255 | else: |
| 256 | f.write(img) |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 257 | |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 258 | def sign_encrypt_ta(): |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 259 | if not isinstance(key, rsa.RSAPrivateKey): |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 260 | logger.error('Provided key cannot be used for signing, ' + |
| 261 | 'please use offline-signing mode.') |
Markus S. Wamser | 6ff2e3f | 2019-08-02 14:48:46 +0200 | [diff] [blame] | 262 | sys.exit(1) |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 263 | else: |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 264 | if args.algo == 'TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256': |
| 265 | sig = key.sign( |
| 266 | img_digest, |
| 267 | padding.PSS( |
| 268 | mgf=padding.MGF1(chosen_hash), |
| 269 | salt_length=digest_len |
| 270 | ), |
| 271 | utils.Prehashed(chosen_hash) |
| 272 | ) |
| 273 | elif args.algo == 'TEE_ALG_RSASSA_PKCS1_V1_5_SHA256': |
| 274 | sig = key.sign( |
| 275 | img_digest, |
| 276 | padding.PKCS1v15(), |
| 277 | utils.Prehashed(chosen_hash) |
| 278 | ) |
| 279 | |
Volodymyr Babchuk | 90ad245 | 2019-08-21 21:00:32 +0300 | [diff] [blame] | 280 | if len(sig) != sig_len: |
| 281 | raise Exception(("Actual signature length is not equal to ", |
| 282 | "the computed one: {} != {}"). |
| 283 | format(len(sig), sig_len)) |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 284 | write_image_with_signature(sig) |
| 285 | logger.info('Successfully signed application.') |
| 286 | |
| 287 | def generate_digest(): |
| 288 | with open(args.digf, 'wb+') as digfile: |
| 289 | digfile.write(base64.b64encode(img_digest)) |
| 290 | |
| 291 | def stitch_ta(): |
| 292 | try: |
| 293 | with open(args.sigf, 'r') as sigfile: |
| 294 | sig = base64.b64decode(sigfile.read()) |
| 295 | except IOError: |
Markus S. Wamser | 6ff2e3f | 2019-08-02 14:48:46 +0200 | [diff] [blame] | 296 | if not os.path.exists(args.digf): |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 297 | generate_digest() |
| 298 | logger.error('No signature file found. Please sign\n %s\n' + |
| 299 | 'offline and place the signature at \n %s\n' + |
| 300 | 'or pass a different location ' + |
| 301 | 'using the --sig argument.\n', |
| 302 | args.digf, args.sigf) |
Markus S. Wamser | 6ff2e3f | 2019-08-02 14:48:46 +0200 | [diff] [blame] | 303 | sys.exit(1) |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 304 | else: |
Mingyuan Xiang | cf3d6ac | 2020-09-17 19:01:02 +0800 | [diff] [blame] | 305 | try: |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 306 | if args.algo == 'TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256': |
| 307 | key.verify( |
| 308 | sig, |
| 309 | img_digest, |
| 310 | padding.PSS( |
| 311 | mgf=padding.MGF1(chosen_hash), |
| 312 | salt_length=digest_len |
| 313 | ), |
| 314 | utils.Prehashed(chosen_hash) |
| 315 | ) |
| 316 | elif args.algo == 'TEE_ALG_RSASSA_PKCS1_V1_5_SHA256': |
| 317 | key.verify( |
| 318 | sig, |
| 319 | img_digest, |
| 320 | padding.PKCS1v15(), |
| 321 | utils.Prehashed(chosen_hash) |
| 322 | ) |
| 323 | except exceptions.InvalidSignature: |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 324 | logger.error('Verification failed, ignoring given signature.') |
Markus S. Wamser | 6ff2e3f | 2019-08-02 14:48:46 +0200 | [diff] [blame] | 325 | sys.exit(1) |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 326 | |
Donald Chan | 169eac1 | 2021-10-24 14:22:54 -0700 | [diff] [blame] | 327 | write_image_with_signature(sig) |
| 328 | logger.info('Successfully applied signature.') |
| 329 | |
Markus S. Wamser | 6ff2e3f | 2019-08-02 14:48:46 +0200 | [diff] [blame] | 330 | # dispatch command |
| 331 | { |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 332 | 'sign-enc': sign_encrypt_ta, |
Markus S. Wamser | 1cdd95a | 2019-04-30 12:03:12 +0200 | [diff] [blame] | 333 | 'digest': generate_digest, |
| 334 | 'generate-digest': generate_digest, |
| 335 | 'stitch': stitch_ta, |
| 336 | 'stitch-ta': stitch_ta |
Sumit Garg | 2de17fd | 2019-10-23 12:47:24 +0530 | [diff] [blame] | 337 | }.get(args.command, 'sign_encrypt_ta')() |
Jens Wiklander | cd5cf43 | 2017-11-28 16:59:15 +0100 | [diff] [blame] | 338 | |
Jens Wiklander | bc42074 | 2015-05-05 14:59:15 +0200 | [diff] [blame] | 339 | |
| 340 | if __name__ == "__main__": |
Jens Wiklander | cd5cf43 | 2017-11-28 16:59:15 +0100 | [diff] [blame] | 341 | main() |