1#!/usr/bin/env python3
2# SPDX-License-Identifier: BSD-2-Clause
3#
4# Copyright 2024 NXP
5#
6
7import json
8
9modes = {'encrypt': 0, 'decrypt': 1}
10
11
12def to_compound_str(name, val):
13    assert len(val) % 2 == 0, "Only even sized values supported"
14    if len(val) > 0:
15        import re
16        a = re.findall('..', val)
17        b = name + " = (const uint8_t []){ "
18        for s in a:
19            b += "0x" + s + ", "
20        b += "},\n\t" + name + "_len = " + repr((int)(len(val) / 2)) + ","
21    else:
22        b = name + " = NULL,\n\t" + name + "_len = 0,"
23    return b
24
25
26def generate_case(outf, tv, mode):
27    outf.write('{\n\t.algo = TEE_ALG_AES_GCM, .mode = ' + mode +
28               ', .key_type = TEE_TYPE_AES,\n')
29    outf.write('\t' + to_compound_str('.key', tv['key']) + '\n')
30    outf.write('\t' + to_compound_str('.nonce', tv['iv']) + '\n')
31    outf.write('\t.aad_incr = 0,\n')
32    outf.write('\t' + to_compound_str('.aad', tv['aad']) + '\n')
33    outf.write('\t.in_incr = 0,\n')
34    outf.write('\t' + to_compound_str('.ptx', tv['msg']) + '\n')
35    outf.write('\t' + to_compound_str('.ctx', tv['ct']) + '\n')
36    outf.write('\t' + to_compound_str('.tag', tv['tag']) + '\n')
37    outf.write('\t.line = __LINE__,\n')
38    outf.write('\t.id = ' + repr(tv['tcId']) + '\n},\n')
39
40
41def get_args():
42    import argparse
43
44    parser = argparse.ArgumentParser()
45
46    parser.add_argument('--inf', required=True,
47                        type=argparse.FileType('r'),
48                        help='Name of input json file')
49
50    parser.add_argument('--outf', required=True,
51                        type=argparse.FileType('w'),
52                        help='Name of output C file')
53
54    parser.add_argument('--mode', required=True, choices=modes.keys(),
55                        help='mode: encrypt or decrypt')
56
57    return parser.parse_args()
58
59
60# Convert google/wycheproof AES GCM test vectors to xtest AE test cases
61def main():
62    args = get_args()
63    inf = args.inf
64    outf = args.outf
65
66    outf.write("/* SPDX-License-Identifier: Apache-2.0 */\n")
67    outf.write("/*\n")
68    outf.write(" * Copyright 2024 NXP\n")
69    outf.write(" */\n\n")
70
71    if args.mode == "encrypt":
72        mode = "TEE_MODE_ENCRYPT"
73    else:
74        mode = "TEE_MODE_DECRYPT"
75
76    data = json.load(inf)
77
78    for tg in data['testGroups']:
79        for tv in tg['tests']:
80            if tv['result'] == 'valid' and 'CounterWrap' in tv['flags']:
81                generate_case(outf, tv, mode)
82
83
84if __name__ == "__main__":
85    main()
86