blob: fa77a8274f968ea3536a7a68290f8a4b672d30cf [file] [log] [blame]
Raef Coles59cf5d82024-12-09 15:41:13 +00001#!/usr/bin/env python3
2#-------------------------------------------------------------------------------
3# SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
4#
5# SPDX-License-Identifier: BSD-3-Clause
6#
7#-------------------------------------------------------------------------------
8
9import argparse
10
11import logging
Raef Colescfc31242025-04-04 09:38:47 +010012logger = logging.getLogger("TF-M.{}".format(__name__))
Raef Coles59cf5d82024-12-09 15:41:13 +000013
14import arg_utils
15import sign_data
16import encrypt_data
17
18from cryptography.hazmat.primitives.ciphers.aead import AESCCM
19import secrets
20
21def _sign_then_encrypt_aes_ccm(data : bytes,
22 sign_and_encrypt_key : bytes,
23 aad : bytes = bytes(0),
24 iv : bytes = None,
25 tag_length : int = 16,
26 **kwargs,
27 ):
28 if not iv:
29 iv = secrets.token_bytes(12)
30
31 output = AESCCM(sign_and_encrypt_key, tag_length=tag_length).encrypt(nonce=iv,
32 data=data,
33 associated_data=aad)
34 signature = output[-tag_length:]
35 ciphertext = output[:-tag_length]
36 logger.info("Encrypting with IV {}".format(iv.hex()))
37 logger.info("Encrypting with key {}".format(sign_and_encrypt_key.hex()))
38 return iv, ciphertext, signature
39
40combined_algs = {
41 "AES_CCM": _sign_then_encrypt_aes_ccm,
42}
43
44def add_arguments(parser : argparse.ArgumentParser,
45 prefix : str = "",
46 required : bool = True,
47 ) -> None:
48 arg_utils.add_prefixed_argument(parser, "sign_and_encrypt_key", prefix,
49 help="combined sign/encrypt key input file",
50 type=arg_utils.arg_type_bytes, required=False)
51 arg_utils.add_prefixed_argument(parser, "sign_and_encrypt_alg", prefix,
52 help="combined sign/encrypt algorithm",
53 choices=combined_algs.keys(), required=False)
54 encrypt_data.add_arguments(parser, prefix, False)
55 sign_data.add_arguments(parser, prefix, False)
56
57def parse_args(args : argparse.Namespace,
58 prefix : str = "",
59 ) -> dict:
60 out = arg_utils.parse_args_automatically(args, ["sign_and_encrypt_alg",
61 "sign_and_encrypt_key"], prefix)
62
63 out |= sign_data.parse_args(args, prefix)
64 out |= encrypt_data.parse_args(args, prefix)
65
66 arg_utils.incompatible_arg(args, "sign_and_encrypt_alg", "sign_alg")
67 arg_utils.incompatible_arg(args, "sign_and_encrypt_alg", "encrypt_alg")
68
69 return out
70
71def sign_then_encrypt_data(data : bytes,
72 sign_and_encrypt_alg : str = None,
73 aad : bytes = bytes(0),
74 **kwargs,
75 ) -> bytes:
76 if sign_and_encrypt_alg:
77 return combined_algs[sign_and_encrypt_alg](data=data, aad=aad, **kwargs)
78 else:
79 iv, ciphertext = encrypt_data.encrypt_data(data=data, **kwargs)
80 return iv, ciphertext, sign_data.sign_data(data=aad + data, **kwargs)
81
82script_description = """
83"""
84if __name__ == "__main__":
85 import argparse
86
87 parser = argparse.ArgumentParser(allow_abbrev=False,
88 formatter_class=argparse.ArgumentDefaultsHelpFormatter,
89 description=script_description)
90 parser.add_argument("--log_level", help="log level", required=False, default="ERROR", choices=logging._levelToName.values())
91
92 args = parser.parse_args()
Raef Colescfc31242025-04-04 09:38:47 +010093 logging.getLogger("TF-M").setLevel(args.log_level)
94 logger.addHandler(logging.StreamHandler())