1#!/usr/bin/env python3
2# SPDX-License-Identifier: BSD-2-Clause
3#
4# Copyright (c) 2017, Linaro Limited
5#
6
7modes = {'encrypt': 0, 'decrypt': 1}
8
9limited = False
10
11
12def to_compound_str(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 = "(const uint8_t []){"
18        for s in a:
19            b += "0x" + s + ", "
20        b += "}, " + repr(len(val) / 2) + ","
21    else:
22        b = "NULL, 0,"
23    return b
24
25
26def generate_case(outf, myvars, mode):
27    if 'PT' not in myvars:
28        myvars['PT'] = ''
29    if 'FAIL' in myvars:
30        return
31    if limited and myvars['Count'] != '0':
32        return
33    # Skip cases not supported by GP
34    if len(myvars['Tag']) / 2 < 96 / 8:
35        return
36
37    outf.write('{ TEE_ALG_AES_GCM, ' + mode + ', TEE_TYPE_AES,\n')
38    outf.write('/* Key */ ' + to_compound_str(myvars['Key']) + '\n')
39    outf.write('/* IV  */ ' + to_compound_str(myvars['IV']) + '\n')
40    outf.write('0,\n')
41    outf.write('/* AAD */ ' + to_compound_str(myvars['AAD']) + '\n')
42    outf.write('0,\n')
43    outf.write('/* PT  */ ' + to_compound_str(myvars['PT']) + '\n')
44    outf.write('/* CT  */ ' + to_compound_str(myvars['CT']) + '\n')
45    outf.write('/* Tag */ ' + to_compound_str(myvars['Tag']) + '\n')
46    outf.write(repr(myvars['Line']) + '},\n')
47
48
49def get_args():
50    import argparse
51
52    parser = argparse.ArgumentParser()
53
54    parser.add_argument('--inf', required=True,
55                        type=argparse.FileType('r'),
56                        help='Name of input RSP file')
57
58    parser.add_argument('--outf', required=True,
59                        type=argparse.FileType('w'),
60                        help='Name of output C file')
61
62    parser.add_argument('--mode', required=True, choices=modes.keys(),
63                        help='mode: encrypt or decrypt')
64
65    parser.add_argument('--limited', action="store_true",
66                        help='Only run one test case from each group')
67
68    return parser.parse_args()
69
70
71def main():
72    import re
73    global limited
74    args = get_args()
75    inf = args.inf
76    outf = args.outf
77    myvars = {}
78    line_num = 0
79
80    if args.mode == "encrypt":
81        mode = "TEE_MODE_ENCRYPT"
82    else:
83        mode = "TEE_MODE_DECRYPT"
84
85    limited = args.limited
86
87    for line in inf:
88        line_num += 1
89        myl = line.strip()
90        if len(myl) == 0:
91            continue
92        if re.match('^#', myl):
93            continue
94        if re.match('^\[', myl):
95            continue
96        s = re.split('\W+', myl)
97        if len(s) == 0:
98            continue
99        name = s[0]
100        if name == 'Count':
101            if len(myvars) > 1:
102                generate_case(outf, myvars, mode)
103                myvars = {}
104            myvars['Line'] = line_num
105
106        if len(s) < 2:
107            myvars[s[0]] = ''
108        else:
109            myvars[s[0]] = s[1]
110
111        if len(s) < 2:
112            continue
113        val = s[1]
114
115    if len(myvars) > 1:
116        generate_case(outf, myvars, mode)
117
118
119if __name__ == "__main__":
120    main()
121