blob: 06e5d12af7f815bfb64aac74032ecba274763673 [file] [log] [blame]
Rouven Czerwinskibbaeed42019-08-07 20:07:00 +02001#!/usr/bin/env python3
Jens Wiklandercd5cf432017-11-28 16:59:15 +01002# SPDX-License-Identifier: BSD-2-Clause
Sumit Garg2de17fd2019-10-23 12:47:24 +05303#
4# Copyright (c) 2015, 2017, 2019, Linaro Limited
5#
Jens Wiklandercd5cf432017-11-28 16:59:15 +01006
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +02007import sys
Donald Chan169eac12021-10-24 14:22:54 -07008import math
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +02009
Jerome Forissier4a477922018-11-14 11:02:49 +010010
Jens Wiklander49e93632022-10-04 11:25:22 +020011sig_tee_alg = {'TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256': 0x70414930,
12 'TEE_ALG_RSASSA_PKCS1_V1_5_SHA256': 0x70004830}
13
14enc_tee_alg = {'TEE_ALG_AES_GCM': 0x40000810}
Mingyuan Xiangcf3d6ac2020-09-17 19:01:02 +080015
Donald Chanc45a84b2022-01-01 22:32:45 +000016enc_key_type = {'SHDR_ENC_KEY_DEV_SPECIFIC': 0x0,
17 'SHDR_ENC_KEY_CLASS_WIDE': 0x1}
18
Donald Chana797f202022-01-10 19:31:13 +000019SHDR_BOOTSTRAP_TA = 1
20SHDR_ENCRYPTED_TA = 2
21SHDR_MAGIC = 0x4f545348
22SHDR_SIZE = 20
Jens Wiklander49e93632022-10-04 11:25:22 +020023EHDR_SIZE = 12
24UUID_SIZE = 16
25# Use 12 bytes for nonce per recommendation
26NONCE_SIZE = 12
27TAG_SIZE = 16
28
29
30def value_to_key(db, val):
31 for k, v in db.items():
32 if v == val:
33 return k
Donald Chana797f202022-01-10 19:31:13 +000034
Mingyuan Xiangcf3d6ac2020-09-17 19:01:02 +080035
Jens Wiklandercd5cf432017-11-28 16:59:15 +010036def uuid_parse(s):
37 from uuid import UUID
38 return UUID(s)
39
40
41def int_parse(str):
42 return int(str, 0)
43
Jens Wiklanderbc420742015-05-05 14:59:15 +020044
Jens Wiklander5e153002022-10-06 11:43:54 +020045def get_args():
Jens Wiklanderf182afc2022-10-04 10:19:27 +020046 def arg_add_uuid(parser):
47 parser.add_argument(
48 '--uuid', required=True, type=uuid_parse,
49 help='String UUID of the TA')
50
51 def arg_add_key(parser):
52 parser.add_argument(
53 '--key', required=True, help='''
54 Name of signing and verification key file (PEM format) or an
55 Amazon Resource Name (arn:) of an AWS KMS asymmetric key.
56 At least public key for the commands digest, stitch, and
57 verify, else a private key''')
58
59 def arg_add_enc_key(parser):
60 parser.add_argument(
61 '--enc-key', required=False, help='Encryption key string')
62
63 def arg_add_enc_key_type(parser):
64 parser.add_argument(
65 '--enc-key-type', required=False,
66 default='SHDR_ENC_KEY_DEV_SPECIFIC',
67 choices=list(enc_key_type.keys()), help='''
68 Encryption key type,
69 Defaults to SHDR_ENC_KEY_DEV_SPECIFIC.''')
70
71 def arg_add_ta_version(parser):
72 parser.add_argument(
73 '--ta-version', required=False, type=int_parse, default=0, help='''
74 TA version stored as a 32-bit unsigned integer and used for
75 rollback protection of TA install in the secure database.
76 Defaults to 0.''')
77
78 def arg_add_sig(parser):
79 parser.add_argument(
80 '--sig', required=True, dest='sigf',
81 help='Name of signature input file, defaults to <UUID>.sig')
82
83 def arg_add_dig(parser):
84 parser.add_argument(
85 '--dig', required=True, dest='digf',
86 help='Name of digest output file, defaults to <UUID>.dig')
87
88 def arg_add_in(parser):
89 parser.add_argument(
90 '--in', required=False, dest='inf', help='''
91 Name of application input file, defaults to
92 <UUID>.stripped.elf''')
93
94 def arg_add_out(parser):
95 parser.add_argument(
96 '--out', required=True, dest='outf',
97 help='Name of application output file, defaults to <UUID>.ta')
98
99 def arg_add_algo(parser):
100 parser.add_argument(
Jens Wiklander49e93632022-10-04 11:25:22 +0200101 '--algo', required=False, choices=list(sig_tee_alg.keys()),
Jens Wiklanderf182afc2022-10-04 10:19:27 +0200102 default='TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256', help='''
103 The hash and signature algorithm.
104 Defaults to TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256.''')
105
106 def get_outf_default(parsed):
107 return str(parsed.uuid) + '.ta'
108
109 def get_inf_default(parsed):
110 return str(parsed.uuid) + '.stripped.elf'
111
112 def get_sigf_default(parsed):
113 return str(parsed.uuid) + '.sig'
114
115 def get_digf_default(parsed):
116 return str(parsed.uuid) + '.dig'
117
118 def assign_default_value(parsed, attr, func):
119 if hasattr(parsed, attr) and getattr(parsed, attr) is None:
120 setattr(parsed, attr, func(parsed))
121
122 import argparse
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200123 import textwrap
Jens Wiklanderbc420742015-05-05 14:59:15 +0200124
Jens Wiklanderf182afc2022-10-04 10:19:27 +0200125 parser = argparse.ArgumentParser(
126 description='Sign and encrypt (optional) a Trusted Application ' +
127 ' for OP-TEE.',
128 usage='%(prog)s <command> ...',
129 epilog='<command> -h for detailed help')
130 subparsers = parser.add_subparsers(
131 title='valid commands, with possible aliases in ()',
132 dest='command', metavar='')
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200133
Jens Wiklanderf182afc2022-10-04 10:19:27 +0200134 parser_sign_enc = subparsers.add_parser(
135 'sign-enc', prog=parser.prog + ' sign-enc',
136 help='Generate signed and optionally encrypted loadable TA image file')
137 arg_add_uuid(parser_sign_enc)
138 arg_add_ta_version(parser_sign_enc)
139 arg_add_in(parser_sign_enc)
140 arg_add_out(parser_sign_enc)
141 arg_add_key(parser_sign_enc)
142 arg_add_enc_key(parser_sign_enc)
143 arg_add_enc_key_type(parser_sign_enc)
144 arg_add_algo(parser_sign_enc)
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200145
Jens Wiklanderf182afc2022-10-04 10:19:27 +0200146 parser_digest = subparsers.add_parser(
147 'digest', aliases=['generate-digest'], prog=parser.prog + ' digest',
148 formatter_class=argparse.RawDescriptionHelpFormatter,
149 help='Generate loadable TA binary image digest for offline signing',
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200150 epilog=textwrap.dedent('''\
Mingyuan Xiangcf3d6ac2020-09-17 19:01:02 +0800151 example offline signing command using OpenSSL for algorithm
152 TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200153 base64 -d <UUID>.dig | \\
154 openssl pkeyutl -sign -inkey <KEYFILE>.pem \\
Mingyuan Xiangcf3d6ac2020-09-17 19:01:02 +0800155 -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pss \\
156 -pkeyopt rsa_pss_saltlen:digest \\
157 -pkeyopt rsa_mgf1_md:sha256 | \\
Jens Wiklanderf182afc2022-10-04 10:19:27 +0200158 base64 > <UUID>.sig
159
Mingyuan Xiangcf3d6ac2020-09-17 19:01:02 +0800160 example offline signing command using OpenSSL for algorithm
161 TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
162 base64 -d <UUID>.dig | \\
163 openssl pkeyutl -sign -inkey <KEYFILE>.pem \\
164 -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pkcs1 | \\
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200165 base64 > <UUID>.sig
166 '''))
Jens Wiklanderf182afc2022-10-04 10:19:27 +0200167 arg_add_uuid(parser_digest)
168 arg_add_ta_version(parser_digest)
169 arg_add_in(parser_digest)
170 arg_add_key(parser_digest)
171 arg_add_enc_key(parser_digest)
172 arg_add_enc_key_type(parser_digest)
173 arg_add_algo(parser_digest)
174 arg_add_dig(parser_digest)
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200175
Jens Wiklanderf182afc2022-10-04 10:19:27 +0200176 parser_stitch = subparsers.add_parser(
177 'stitch', aliases=['stitch-ta'], prog=parser.prog + ' stich',
178 help='Generate loadable signed and encrypted TA binary image file' +
179 ' from TA raw image and its signature')
180 arg_add_uuid(parser_stitch)
181 arg_add_ta_version(parser_stitch)
182 arg_add_in(parser_stitch)
183 arg_add_key(parser_stitch)
184 arg_add_out(parser_stitch)
185 arg_add_enc_key(parser_stitch)
186 arg_add_enc_key_type(parser_stitch)
187 arg_add_algo(parser_stitch)
188 arg_add_sig(parser_stitch)
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200189
Jens Wiklanderf182afc2022-10-04 10:19:27 +0200190 parser_verify = subparsers.add_parser(
191 'verify', prog=parser.prog + ' verify',
192 help='Verify signed TA binary')
193 arg_add_uuid(parser_verify)
194 arg_add_in(parser_verify)
195 arg_add_key(parser_verify)
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200196
Jens Wiklanderf182afc2022-10-04 10:19:27 +0200197 argv = sys.argv[1:]
198 if (len(argv) > 0 and argv[0][0] == '-' and
199 argv[0] != '-h' and argv[0] != '--help'):
200 # The default sub-command is 'sign-enc' so add it to the parser
201 # if one is missing
202 argv = ['sign-enc'] + argv
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200203
Jens Wiklanderf182afc2022-10-04 10:19:27 +0200204 parsed = parser.parse_args(argv)
205
206 if parsed.command is None:
207 parser.print_help()
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200208 sys.exit(1)
209
Jens Wiklanderf182afc2022-10-04 10:19:27 +0200210 # Set a few defaults if defined for the current command
211 assign_default_value(parsed, 'inf', get_inf_default)
212 assign_default_value(parsed, 'outf', get_outf_default)
213 assign_default_value(parsed, 'sigf', get_sigf_default)
214 assign_default_value(parsed, 'digf', get_digf_default)
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200215
216 return parsed
Jens Wiklandercd5cf432017-11-28 16:59:15 +0100217
Jens Wiklanderbc420742015-05-05 14:59:15 +0200218
Jens Wiklander49e93632022-10-04 11:25:22 +0200219def load_asymmetric_key(arg_key):
220 if arg_key.startswith('arn:'):
Donald Chan05c007f2022-01-05 17:54:00 +0000221 from sign_helper_kms import _RSAPrivateKeyInKMS
Jens Wiklander49e93632022-10-04 11:25:22 +0200222 key = _RSAPrivateKeyInKMS(arg_key)
Donald Chan05c007f2022-01-05 17:54:00 +0000223 else:
Jens Wiklander49e93632022-10-04 11:25:22 +0200224 from cryptography.hazmat.backends import default_backend
225 from cryptography.hazmat.primitives.serialization import (
226 load_pem_private_key, load_pem_public_key)
227
228 with open(arg_key, 'rb') as f:
Donald Chan05c007f2022-01-05 17:54:00 +0000229 data = f.read()
Donald Chan169eac12021-10-24 14:22:54 -0700230
Donald Chan05c007f2022-01-05 17:54:00 +0000231 try:
Jens Wiklander49e93632022-10-04 11:25:22 +0200232 key = load_pem_private_key(data, password=None,
233 backend=default_backend())
Donald Chan05c007f2022-01-05 17:54:00 +0000234 except ValueError:
Jens Wiklander49e93632022-10-04 11:25:22 +0200235 key = load_pem_public_key(data, backend=default_backend())
Jens Wiklanderbc420742015-05-05 14:59:15 +0200236
Jens Wiklander49e93632022-10-04 11:25:22 +0200237 return key
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200238
Jens Wiklanderbc420742015-05-05 14:59:15 +0200239
Jens Wiklander49e93632022-10-04 11:25:22 +0200240class BinaryImage:
241 def __init__(self, arg_inf, arg_key):
242 from cryptography.hazmat.primitives import hashes
Volodymyr Babchuk90ad2452019-08-21 21:00:32 +0300243
Jens Wiklander49e93632022-10-04 11:25:22 +0200244 # Exactly what inf is holding isn't determined a this stage
245 with open(arg_inf, 'rb') as f:
246 self.inf = f.read()
Jens Wiklanderbc420742015-05-05 14:59:15 +0200247
Jens Wiklander49e93632022-10-04 11:25:22 +0200248 self.key = load_asymmetric_key(arg_key)
Etienne Carriere47844622019-08-12 11:33:24 +0200249
Jens Wiklander49e93632022-10-04 11:25:22 +0200250 self.chosen_hash = hashes.SHA256()
251 self.digest_len = self.chosen_hash.digest_size
252 self.sig_len = math.ceil(self.key.key_size / 8)
Etienne Carriere47844622019-08-12 11:33:24 +0200253
Jens Wiklander49e93632022-10-04 11:25:22 +0200254 def __pack_img(self, img_type, sign_algo):
255 import struct
Jens Wiklanderbc420742015-05-05 14:59:15 +0200256
Jens Wiklander49e93632022-10-04 11:25:22 +0200257 self.sig_algo = sign_algo
258 self.img_type = img_type
259 self.shdr = struct.pack('<IIIIHH', SHDR_MAGIC, img_type, len(self.img),
260 sig_tee_alg[sign_algo], self.digest_len,
261 self.sig_len)
262
263 def __calc_digest(self):
264 from cryptography.hazmat.backends import default_backend
265 from cryptography.hazmat.primitives import hashes
266
267 h = hashes.Hash(self.chosen_hash, default_backend())
268 h.update(self.shdr)
269 h.update(self.ta_uuid)
270 h.update(self.ta_version)
271 if hasattr(self, 'ehdr'):
272 h.update(self.ehdr)
273 h.update(self.nonce)
274 h.update(self.tag)
275 h.update(self.img)
276 return h.finalize()
277
278 def encrypt_ta(self, enc_key, key_type, sig_algo, uuid, ta_version):
Donald Chan169eac12021-10-24 14:22:54 -0700279 from cryptography.hazmat.primitives.ciphers.aead import AESGCM
Jens Wiklander49e93632022-10-04 11:25:22 +0200280 import struct
281 import os
Sumit Garg2de17fd2019-10-23 12:47:24 +0530282
Jens Wiklander49e93632022-10-04 11:25:22 +0200283 self.img = self.inf
Sumit Garg2de17fd2019-10-23 12:47:24 +0530284
Jens Wiklander49e93632022-10-04 11:25:22 +0200285 cipher = AESGCM(bytes.fromhex(enc_key))
286 self.nonce = os.urandom(NONCE_SIZE)
287 out = cipher.encrypt(self.nonce, self.img, None)
288 self.ciphertext = out[:-TAG_SIZE]
289 # Authentication Tag is always the last bytes
290 self.tag = out[-TAG_SIZE:]
Jens Wiklanderbc420742015-05-05 14:59:15 +0200291
Jens Wiklander49e93632022-10-04 11:25:22 +0200292 enc_algo = enc_tee_alg['TEE_ALG_AES_GCM']
293 flags = enc_key_type[key_type]
294 self.ehdr = struct.pack('<IIHH', enc_algo, flags, len(self.nonce),
295 len(self.tag))
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200296
Jens Wiklander49e93632022-10-04 11:25:22 +0200297 self.__pack_img(SHDR_ENCRYPTED_TA, sig_algo)
298 self.ta_uuid = uuid.bytes
299 self.ta_version = struct.pack('<I', ta_version)
300 self.img_digest = self.__calc_digest()
Donald Chan169eac12021-10-24 14:22:54 -0700301
Jens Wiklander49e93632022-10-04 11:25:22 +0200302 def set_bootstrap_ta(self, sig_algo, uuid, ta_version):
303 import struct
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200304
Jens Wiklander49e93632022-10-04 11:25:22 +0200305 self.img = self.inf
306 self.__pack_img(SHDR_BOOTSTRAP_TA, sig_algo)
307 self.ta_uuid = uuid.bytes
308 self.ta_version = struct.pack('<I', ta_version)
309 self.img_digest = self.__calc_digest()
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200310
Jens Wiklander49e93632022-10-04 11:25:22 +0200311 def parse(self):
312 import struct
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200313
Jens Wiklander49e93632022-10-04 11:25:22 +0200314 offs = 0
315 self.shdr = self.inf[offs:offs + SHDR_SIZE]
316 [magic, img_type, img_size, algo_value, digest_len,
317 sig_len] = struct.unpack('<IIIIHH', self.shdr)
318 offs += SHDR_SIZE
Donald Chan51eee1e2022-01-11 18:54:25 +0000319
320 if magic != SHDR_MAGIC:
321 raise Exception("Unexpected magic: 0x{:08x}".format(magic))
322
Jens Wiklander49e93632022-10-04 11:25:22 +0200323 if algo_value not in sig_tee_alg.values():
Donald Chan51eee1e2022-01-11 18:54:25 +0000324 raise Exception('Unrecognized algorithm: 0x{:08x}'
325 .format(algo_value))
Jens Wiklander49e93632022-10-04 11:25:22 +0200326 self.sig_algo = value_to_key(sig_tee_alg, algo_value)
Donald Chan51eee1e2022-01-11 18:54:25 +0000327
Jens Wiklander49e93632022-10-04 11:25:22 +0200328 if digest_len != self.digest_len:
329 raise Exception("Unexpected digest len: {}".format(digest_len))
330
331 self.img_digest = self.inf[offs:offs + digest_len]
332 offs += digest_len
333 self.sig = self.inf[offs:offs + sig_len]
334 offs += sig_len
335
336 if img_type == SHDR_BOOTSTRAP_TA or img_type == SHDR_ENCRYPTED_TA:
337 self.ta_uuid = self.inf[offs:offs + UUID_SIZE]
338 offs += UUID_SIZE
339 self.ta_version = self.inf[offs:offs + 4]
340 offs += 4
341 if img_type == SHDR_ENCRYPTED_TA:
342 self.ehdr = self.inf[offs: offs + EHDR_SIZE]
343 offs += EHDR_SIZE
344 [enc_algo, flags, nonce_len,
345 tag_len] = struct.unpack('<IIHH', self.ehdr)
346 if enc_value not in enc_tee_alg.values():
347 raise Exception('Unrecognized encrypt algorithm: 0x{:08x}'
348 .format(enc_value))
349 if nonce_len != 12:
350 raise Exception("Unexpected nonce len: {}"
351 .format(nonce_len))
352 self.nonce = self.inf[offs:offs + nonce_len]
353 offs += nonce_len
354
355 if tag_len != 16:
356 raise Exception("Unexpected tag len: {}".format(tag_len))
357 self.tag = self.inf[-tag_len:]
358 self.ciphertext = self.inf[offs:-tag_len]
359 if len(self.ciphertext) != img_size:
360 raise Exception("Unexpected ciphertext size: ",
361 "got {}, expected {}"
362 .format(len(self.ciphertext), img_size))
363 else:
364 self.img = self.inf[offs:]
365 if len(self.img) != img_size:
366 raise Exception("Unexpected img size: got {}, expected {}"
367 .format(len(self.img), img_size))
Donald Chan51eee1e2022-01-11 18:54:25 +0000368 else:
Jens Wiklander49e93632022-10-04 11:25:22 +0200369 raise Exception("Unsupported image type: {}".format(img_type))
Donald Chan51eee1e2022-01-11 18:54:25 +0000370
Jens Wiklander49e93632022-10-04 11:25:22 +0200371 def decrypt_ta(enc_key):
372 from cryptography.hazmat.primitives.ciphers.aead import AESGCM
Donald Chan51eee1e2022-01-11 18:54:25 +0000373
Jens Wiklander49e93632022-10-04 11:25:22 +0200374 cipher = AESGCM(bytes.fromhex(enc_key))
375 self.img = cipher.decrypt(self.nonce, self.ciphertext, None)
Donald Chan51eee1e2022-01-11 18:54:25 +0000376
Jens Wiklander49e93632022-10-04 11:25:22 +0200377 def __get_padding(self):
378 from cryptography.hazmat.primitives.asymmetric import padding
Donald Chan51eee1e2022-01-11 18:54:25 +0000379
Jens Wiklander49e93632022-10-04 11:25:22 +0200380 if self.sig_algo == 'TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256':
381 pad = padding.PSS(mgf=padding.MGF1(self.chosen_hash),
382 salt_length=self.digest_len)
383 elif self.sig_algo == 'TEE_ALG_RSASSA_PKCS1_V1_5_SHA256':
384 pad = padding.PKCS1v15()
Donald Chan51eee1e2022-01-11 18:54:25 +0000385
Jens Wiklander49e93632022-10-04 11:25:22 +0200386 return pad
387
388 def sign(self):
389 from cryptography.hazmat.primitives.asymmetric import utils
390 from cryptography.hazmat.primitives.asymmetric import rsa
391
392 if not isinstance(self.key, rsa.RSAPrivateKey):
393 logger.error('Provided key cannot be used for signing, ' +
394 'please use offline-signing mode.')
395 sys.exit(1)
396 else:
397 self.sig = self.key.sign(self.img_digest, self.__get_padding(),
398 utils.Prehashed(self.chosen_hash))
399
400 if len(self.sig) != self.sig_len:
401 raise Exception(("Actual signature length is not equal to ",
402 "the computed one: {} != {}").
403 format(len(self.sig), self.sig_len))
404
405 def add_signature(self, sigf):
406 import base64
407
408 with open(sigf, 'r') as f:
409 self.sig = base64.b64decode(f.read())
410
411 if len(self.sig) != self.sig_len:
412 raise Exception(("Actual signature length is not equal to ",
413 "the expected one: {} != {}").
414 format(len(self.sig), self.sig_len))
415
416 def verify_signature(self):
417 from cryptography.hazmat.primitives.asymmetric import utils
418 from cryptography.hazmat.primitives.asymmetric import rsa
419 from cryptography import exceptions
420
421 if isinstance(self.key, rsa.RSAPrivateKey):
422 pkey = self.key.public_key()
423 else:
424 pkey = self.key
425
426 try:
427 pkey.verify(self.sig, self.img_digest, self.__get_padding(),
428 utils.Prehashed(self.chosen_hash))
429 except exceptions.InvalidSignature:
430 logger.error('Verification failed, ignoring given signature.')
431 sys.exit(1)
432
433 def verify_digest(self):
434 if self.img_digest != self.__calc_digest():
Donald Chan51eee1e2022-01-11 18:54:25 +0000435 raise Exception('Hash digest does not match')
436
Jens Wiklander49e93632022-10-04 11:25:22 +0200437 def verify_uuid(self, uuid):
438 if self.ta_uuid != uuid.bytes:
439 raise Exception('UUID does not match')
440
441 def write(self, outf):
442 with open(outf, 'wb') as f:
443 f.write(self.shdr)
444 f.write(self.img_digest)
445 f.write(self.sig)
446 f.write(self.ta_uuid)
447 f.write(self.ta_version)
448 if hasattr(self, 'ehdr'):
449 f.write(self.ehdr)
450 f.write(self.nonce)
451 f.write(self.tag)
452 f.write(self.ciphertext)
453 else:
454 f.write(self.img)
455
456
457def load_ta_image(args):
458 ta_image = BinaryImage(args.inf, args.key)
459
460 if args.enc_key:
461 ta_image.encrypt_ta(args.enc_key, args.enc_key_type,
462 args.algo, args.uuid, args.ta_version)
463 else:
464 ta_image.set_bootstrap_ta(args.algo, args.uuid, args.ta_version)
465
466 return ta_image
467
468
469def main():
470 import logging
471 import os
472
473 global logger
474 logging.basicConfig()
475 logger = logging.getLogger(os.path.basename(__file__))
476
477 args = get_args()
478
479 def sign_encrypt_ta():
480 ta_image = load_ta_image(args)
481 ta_image.sign()
482 ta_image.write(args.outf)
483 logger.info('Successfully signed application.')
484
485 def generate_digest():
486 ta_image = load_ta_image(args)
487 with open(args.digf, 'wb+') as digfile:
488 digfile.write(base64.b64encode(binary_image.img_digest))
489
490 def stitch_ta():
491 ta_image = load_ta_image(args)
492 ta_image.add_signature(args.sigf)
493 ta_image.verify_signature()
494 ta_image.write(args.outf)
495 logger.info('Successfully applied signature.')
496
497 def verify_ta():
498 ta_image = BinaryImage(args.inf, args.key)
499 ta_image.parse()
500 if hasattr(ta_image, 'ciphertext'):
501 if args.enc_key is None:
502 logger.error('--enc_key needed to decrypt TA')
503 sys.exit(1)
504 ta_image.decrypt_ta(args.enc_key)
505 ta_image.verify_signature()
506 ta_image.verify_digest()
507 ta_image.verify_uuid(args.uuid)
Donald Chan51eee1e2022-01-11 18:54:25 +0000508 logger.info('Trusted application is correctly verified.')
509
Markus S. Wamser6ff2e3f2019-08-02 14:48:46 +0200510 # dispatch command
511 {
Sumit Garg2de17fd2019-10-23 12:47:24 +0530512 'sign-enc': sign_encrypt_ta,
Markus S. Wamser1cdd95a2019-04-30 12:03:12 +0200513 'digest': generate_digest,
514 'generate-digest': generate_digest,
515 'stitch': stitch_ta,
Donald Chan51eee1e2022-01-11 18:54:25 +0000516 'stitch-ta': stitch_ta,
517 'verify': verify_ta,
Sumit Garg2de17fd2019-10-23 12:47:24 +0530518 }.get(args.command, 'sign_encrypt_ta')()
Jens Wiklandercd5cf432017-11-28 16:59:15 +0100519
Jens Wiklanderbc420742015-05-05 14:59:15 +0200520
521if __name__ == "__main__":
Jens Wiklandercd5cf432017-11-28 16:59:15 +0100522 main()