xref: /aosp_15_r20/external/open-dice/generate_test_values.py (revision 60b67249c2e226f42f35cc6cfe66c6048e0bae6b)
1*60b67249SAndroid Build Coastguard Worker# Copyright 2020 Google LLC
2*60b67249SAndroid Build Coastguard Worker#
3*60b67249SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*60b67249SAndroid Build Coastguard Worker# use this file except in compliance with the License. You may obtain a copy of
5*60b67249SAndroid Build Coastguard Worker# the License at
6*60b67249SAndroid Build Coastguard Worker#
7*60b67249SAndroid Build Coastguard Worker#     https://www.apache.org/licenses/LICENSE-2.0
8*60b67249SAndroid Build Coastguard Worker#
9*60b67249SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*60b67249SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*60b67249SAndroid Build Coastguard Worker# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*60b67249SAndroid Build Coastguard Worker# License for the specific language governing permissions and limitations under
13*60b67249SAndroid Build Coastguard Worker# the License.
14*60b67249SAndroid Build Coastguard Worker#
15*60b67249SAndroid Build Coastguard Worker# Lint as: python3
16*60b67249SAndroid Build Coastguard Worker"""Generates known_test_values.h from dumped test values.
17*60b67249SAndroid Build Coastguard Worker
18*60b67249SAndroid Build Coastguard WorkerThis program generates the known_test_values.h file used for unit tests. This is
19*60b67249SAndroid Build Coastguard Workeruseful to correct the baseline test values based on dumps from the tests. Use
20*60b67249SAndroid Build Coastguard Workerthis after fixing a bug in the code, not to 'fix' test breakage not well
21*60b67249SAndroid Build Coastguard Workerunderstood.
22*60b67249SAndroid Build Coastguard Worker
23*60b67249SAndroid Build Coastguard WorkerUsage:
24*60b67249SAndroid Build Coastguard Worker  $ cd out
25*60b67249SAndroid Build Coastguard Worker  $ python ../generate_test_values.py > ../include/dice/known_test_values.h
26*60b67249SAndroid Build Coastguard Worker
27*60b67249SAndroid Build Coastguard WorkerPrerequisites:
28*60b67249SAndroid Build Coastguard Worker  pip install absl-py
29*60b67249SAndroid Build Coastguard Worker"""
30*60b67249SAndroid Build Coastguard Worker
31*60b67249SAndroid Build Coastguard Workerfrom __future__ import print_function
32*60b67249SAndroid Build Coastguard Worker
33*60b67249SAndroid Build Coastguard Workerimport re
34*60b67249SAndroid Build Coastguard Workerimport subprocess
35*60b67249SAndroid Build Coastguard Workerimport textwrap
36*60b67249SAndroid Build Coastguard Worker
37*60b67249SAndroid Build Coastguard Workerfrom absl import app
38*60b67249SAndroid Build Coastguard Workerfrom absl import flags
39*60b67249SAndroid Build Coastguard Worker
40*60b67249SAndroid Build Coastguard WorkerFLAGS = flags.FLAGS
41*60b67249SAndroid Build Coastguard Worker
42*60b67249SAndroid Build Coastguard Worker_FILE_HEADER = textwrap.dedent(
43*60b67249SAndroid Build Coastguard Worker    """\
44*60b67249SAndroid Build Coastguard Worker    // Copyright 2020 Google LLC
45*60b67249SAndroid Build Coastguard Worker    //
46*60b67249SAndroid Build Coastguard Worker    // Licensed under the Apache License, Version 2.0 (the "License"); you may not
47*60b67249SAndroid Build Coastguard Worker    // use this file except in compliance with the License. You may obtain a copy of
48*60b67249SAndroid Build Coastguard Worker    // the License at
49*60b67249SAndroid Build Coastguard Worker    //
50*60b67249SAndroid Build Coastguard Worker    //     https://www.apache.org/licenses/LICENSE-2.0
51*60b67249SAndroid Build Coastguard Worker    //
52*60b67249SAndroid Build Coastguard Worker    // Unless required by applicable law or agreed to in writing, software
53*60b67249SAndroid Build Coastguard Worker    // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
54*60b67249SAndroid Build Coastguard Worker    // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
55*60b67249SAndroid Build Coastguard Worker    // License for the specific language governing permissions and limitations under
56*60b67249SAndroid Build Coastguard Worker    // the License.
57*60b67249SAndroid Build Coastguard Worker
58*60b67249SAndroid Build Coastguard Worker    // !!! GENERATED - DO NOT MODIFY !!!
59*60b67249SAndroid Build Coastguard Worker    // To update this file, use generate_test_values.py.
60*60b67249SAndroid Build Coastguard Worker
61*60b67249SAndroid Build Coastguard Worker    #ifndef DICE_KNOWN_TEST_VALUES_H_
62*60b67249SAndroid Build Coastguard Worker    #define DICE_KNOWN_TEST_VALUES_H_
63*60b67249SAndroid Build Coastguard Worker
64*60b67249SAndroid Build Coastguard Worker    #include <stdint.h>
65*60b67249SAndroid Build Coastguard Worker
66*60b67249SAndroid Build Coastguard Worker    namespace dice {
67*60b67249SAndroid Build Coastguard Worker    namespace test {
68*60b67249SAndroid Build Coastguard Worker
69*60b67249SAndroid Build Coastguard Worker                               """
70*60b67249SAndroid Build Coastguard Worker)
71*60b67249SAndroid Build Coastguard Worker
72*60b67249SAndroid Build Coastguard Worker_FILE_FOOTER = textwrap.dedent(
73*60b67249SAndroid Build Coastguard Worker    """\
74*60b67249SAndroid Build Coastguard Worker    }  // namespace test
75*60b67249SAndroid Build Coastguard Worker    }  // namespace dice
76*60b67249SAndroid Build Coastguard Worker
77*60b67249SAndroid Build Coastguard Worker    #endif  // DICE_KNOWN_TEST_VALUES_H_
78*60b67249SAndroid Build Coastguard Worker                               """
79*60b67249SAndroid Build Coastguard Worker)
80*60b67249SAndroid Build Coastguard Worker
81*60b67249SAndroid Build Coastguard Worker
82*60b67249SAndroid Build Coastguard Workerdef _to_camel_case(s):
83*60b67249SAndroid Build Coastguard Worker    return "".join(tmp.capitalize() for tmp in s.split("_"))
84*60b67249SAndroid Build Coastguard Worker
85*60b67249SAndroid Build Coastguard Worker
86*60b67249SAndroid Build Coastguard Workerdef _read_file(name):
87*60b67249SAndroid Build Coastguard Worker    try:
88*60b67249SAndroid Build Coastguard Worker        with open(name, "rb") as f:
89*60b67249SAndroid Build Coastguard Worker            return f.read()
90*60b67249SAndroid Build Coastguard Worker    except OSError:
91*60b67249SAndroid Build Coastguard Worker        return ""
92*60b67249SAndroid Build Coastguard Worker
93*60b67249SAndroid Build Coastguard Worker
94*60b67249SAndroid Build Coastguard Workerdef _generate_array(name, data):
95*60b67249SAndroid Build Coastguard Worker    return "constexpr uint8_t %s[%d] = {%s};\n\n" % (
96*60b67249SAndroid Build Coastguard Worker        name,
97*60b67249SAndroid Build Coastguard Worker        len(data),
98*60b67249SAndroid Build Coastguard Worker        ", ".join("0x%02x" % tmp for tmp in data),
99*60b67249SAndroid Build Coastguard Worker    )
100*60b67249SAndroid Build Coastguard Worker
101*60b67249SAndroid Build Coastguard Worker
102*60b67249SAndroid Build Coastguard Workerdef _generate_cert_comment(data):
103*60b67249SAndroid Build Coastguard Worker    return re.sub(
104*60b67249SAndroid Build Coastguard Worker        "^",
105*60b67249SAndroid Build Coastguard Worker        "// ",
106*60b67249SAndroid Build Coastguard Worker        subprocess.run(
107*60b67249SAndroid Build Coastguard Worker            [
108*60b67249SAndroid Build Coastguard Worker                "openssl",
109*60b67249SAndroid Build Coastguard Worker                "x509",
110*60b67249SAndroid Build Coastguard Worker                "-inform",
111*60b67249SAndroid Build Coastguard Worker                "DER",
112*60b67249SAndroid Build Coastguard Worker                "-noout",
113*60b67249SAndroid Build Coastguard Worker                "-text",
114*60b67249SAndroid Build Coastguard Worker                "-certopt",
115*60b67249SAndroid Build Coastguard Worker                "ext_parse",
116*60b67249SAndroid Build Coastguard Worker            ],
117*60b67249SAndroid Build Coastguard Worker            input=data,
118*60b67249SAndroid Build Coastguard Worker            capture_output=True,
119*60b67249SAndroid Build Coastguard Worker            check=True,
120*60b67249SAndroid Build Coastguard Worker        ).stdout.decode(),
121*60b67249SAndroid Build Coastguard Worker        flags=re.MULTILINE,
122*60b67249SAndroid Build Coastguard Worker    )[:-3]
123*60b67249SAndroid Build Coastguard Worker
124*60b67249SAndroid Build Coastguard Worker
125*60b67249SAndroid Build Coastguard Workerdef _generate_c(name):
126*60b67249SAndroid Build Coastguard Worker    """Generates C declarations from dumps identified by |name|."""
127*60b67249SAndroid Build Coastguard Worker    content = ""
128*60b67249SAndroid Build Coastguard Worker    attest_cdi_data = _read_file("_attest_cdi_%s.bin" % name)
129*60b67249SAndroid Build Coastguard Worker    content += _generate_array(
130*60b67249SAndroid Build Coastguard Worker        "kExpectedCdiAttest_%s" % _to_camel_case(name), attest_cdi_data
131*60b67249SAndroid Build Coastguard Worker    )
132*60b67249SAndroid Build Coastguard Worker    seal_cdi_data = _read_file("_seal_cdi_%s.bin" % name)
133*60b67249SAndroid Build Coastguard Worker    content += _generate_array(
134*60b67249SAndroid Build Coastguard Worker        "kExpectedCdiSeal_%s" % _to_camel_case(name), seal_cdi_data
135*60b67249SAndroid Build Coastguard Worker    )
136*60b67249SAndroid Build Coastguard Worker    for cert_type in ("X509", "CBOR"):
137*60b67249SAndroid Build Coastguard Worker        for key_type in ("Ed25519", "P256", "P384"):
138*60b67249SAndroid Build Coastguard Worker            var_name = "kExpected%s%sCert_%s" % (
139*60b67249SAndroid Build Coastguard Worker                _to_camel_case(cert_type),
140*60b67249SAndroid Build Coastguard Worker                _to_camel_case(key_type),
141*60b67249SAndroid Build Coastguard Worker                _to_camel_case(name),
142*60b67249SAndroid Build Coastguard Worker            )
143*60b67249SAndroid Build Coastguard Worker            cert_data = _read_file(
144*60b67249SAndroid Build Coastguard Worker                "_%s_%s_cert_%s.cert" % (cert_type, key_type, name)
145*60b67249SAndroid Build Coastguard Worker            )
146*60b67249SAndroid Build Coastguard Worker            if cert_type == "X509" and key_type != "P384":
147*60b67249SAndroid Build Coastguard Worker                content += (
148*60b67249SAndroid Build Coastguard Worker                    "// $ openssl x509 -inform DER -noout -text -certopt "
149*60b67249SAndroid Build Coastguard Worker                    "ext_parse\n"
150*60b67249SAndroid Build Coastguard Worker                )
151*60b67249SAndroid Build Coastguard Worker                content += _generate_cert_comment(cert_data)
152*60b67249SAndroid Build Coastguard Worker            content += _generate_array(var_name, cert_data)
153*60b67249SAndroid Build Coastguard Worker    return content
154*60b67249SAndroid Build Coastguard Worker
155*60b67249SAndroid Build Coastguard Worker
156*60b67249SAndroid Build Coastguard Workerdef main(argv):
157*60b67249SAndroid Build Coastguard Worker    if len(argv) > 1:
158*60b67249SAndroid Build Coastguard Worker        raise app.UsageError("Too many command-line arguments.")
159*60b67249SAndroid Build Coastguard Worker
160*60b67249SAndroid Build Coastguard Worker    content = _FILE_HEADER
161*60b67249SAndroid Build Coastguard Worker    content += _generate_c("zero_input")
162*60b67249SAndroid Build Coastguard Worker    content += _generate_c("hash_only_input")
163*60b67249SAndroid Build Coastguard Worker    content += _generate_c("descriptor_input")
164*60b67249SAndroid Build Coastguard Worker    content += _FILE_FOOTER
165*60b67249SAndroid Build Coastguard Worker    subprocess.run(
166*60b67249SAndroid Build Coastguard Worker        ["clang-format", "--style=file"], input=content.encode(), check=True
167*60b67249SAndroid Build Coastguard Worker    )
168*60b67249SAndroid Build Coastguard Worker
169*60b67249SAndroid Build Coastguard Worker
170*60b67249SAndroid Build Coastguard Workerif __name__ == "__main__":
171*60b67249SAndroid Build Coastguard Worker    app.run(main)
172