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