diff --git a/ChangeLog.d/Driver_wrapper_codegen_1.0.txt b/ChangeLog.d/Driver_wrapper_codegen_1.0.txt new file mode 100644 index 0000000000..a4d9c54174 --- /dev/null +++ b/ChangeLog.d/Driver_wrapper_codegen_1.0.txt @@ -0,0 +1,5 @@ +Changes + * The file library/psa_crypto_driver_wrappers.c is now generated + from a template. In the future, the generation will support + driver descriptions. For the time being, to customize this file, + see docs/proposed/psa-driver-wrappers-codegen-migration-guide.md diff --git a/docs/proposed/psa-driver-wrappers-codegen-migration-guide.md b/docs/proposed/psa-driver-wrappers-codegen-migration-guide.md new file mode 100644 index 0000000000..4f82bedd54 --- /dev/null +++ b/docs/proposed/psa-driver-wrappers-codegen-migration-guide.md @@ -0,0 +1,32 @@ +Migrating to an auto genrated psa_crypto_driver_wrappers.c file +=============================================================== + +**This is a specification of work in progress. The implementation is not yet merged into Mbed TLS.** + +This document describes how to migrate to the auto generated psa_crypto_driver_wrappers.c file. +It is meant to give the library user migration guidelines while the Mbed TLS project tides over multiple minor revs of version 1.0, after which this will be merged into psa-driver-interface.md. + +## Introduction + +The design of the Driver Wrappers code generation is based on the design proposal https://github.com/ARMmbed/mbedtls/pull/5067 +During the process of implementation there might be minor variations wrt versioning and broader implementation specific ideas, but the design remains the same. + +## Prerequisites + +Python3 and Jinja2 rev 2.10.1 + +## Feature Version + +1.0 + +### What's critical for a migrating user + +The Driver Wrapper auto generation project is designed to use a python templating library ( Jinja2 ) to render templates based on drivers that are defined using a Driver descrioption JSON file(s). + +While that is the larger goal, for version 1.0 here's what's changed + +#### What's changed + +(1) psa_crypto_driver_wrappers.c will from this point on be auto generated. +(2) The auto generation is based on the template file at scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja. +(3) So while all driver wrapper templating support is yet to come in, the library user will need to patch into the template file as needed, this could be read as replacing the template file with the current psa_crypto_driver_wrappers.c file maintained by the library user. diff --git a/library/.gitignore b/library/.gitignore index cf2ddac3a2..18cd305eb8 100644 --- a/library/.gitignore +++ b/library/.gitignore @@ -7,3 +7,4 @@ libmbed* /error.c /version_features.c /ssl_debug_helpers_generated.c +/psa_crypto_driver_wrappers.c diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 1884db9378..ddede03901 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -157,10 +157,25 @@ if(GEN_FILES) ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/generate_ssl_debug_helpers.py ${error_headers} ) + + add_custom_command( + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/psa_crypto_driver_wrappers.c + COMMAND + ${MBEDTLS_PYTHON_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/generate_driver_wrappers.py + ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/generate_driver_wrappers.py + ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja + ) + + else() link_to_source(error.c) link_to_source(version_features.c) link_to_source(ssl_debug_helpers_generated.c) + link_to_source(psa_crypto_driver_wrappers.c) endif() if(CMAKE_COMPILER_IS_GNUCC) diff --git a/library/Makefile b/library/Makefile index 0b5a43a55e..e9c0a11744 100644 --- a/library/Makefile +++ b/library/Makefile @@ -290,7 +290,8 @@ libmbedcrypto.dll: $(OBJS_CRYPTO) .PHONY: generated_files GENERATED_FILES = \ error.c version_features.c \ - ssl_debug_helpers_generated.c + ssl_debug_helpers_generated.c \ + psa_crypto_driver_wrappers.c generated_files: $(GENERATED_FILES) error.c: ../scripts/generate_errors.pl @@ -318,6 +319,12 @@ version_features.c: echo " Gen $@" $(PERL) ../scripts/generate_features.pl +psa_crypto_driver_wrappers.c: ../scripts/generate_driver_wrappers.py +psa_crypto_driver_wrappers.c: ../scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja +psa_crypto_driver_wrappers.c: + echo " Gen $@" + $(PYTHON) ../scripts/generate_driver_wrappers.py + clean: ifndef WINDOWS rm -f *.o libmbed* diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h index e09e4ed70e..b6620a371f 100644 --- a/library/psa_crypto_driver_wrappers.h +++ b/library/psa_crypto_driver_wrappers.h @@ -1,7 +1,6 @@ /* * Function signatures for functionality that can be provided by * cryptographic accelerators. - * Warning: This file will be auto-generated in the future. */ /* Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 diff --git a/library/psa_crypto_driver_wrappers.c b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja similarity index 100% rename from library/psa_crypto_driver_wrappers.c rename to scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja diff --git a/scripts/generate_driver_wrappers.py b/scripts/generate_driver_wrappers.py new file mode 100755 index 0000000000..42331acc81 --- /dev/null +++ b/scripts/generate_driver_wrappers.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +"""Generate library/psa_crypto_driver_wrappers.c + + This module is invoked by the build sripts to auto generate the + psa_crypto_driver_wrappers.c based on template files in + script/data_files/driver_templates/. +""" +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import os +import argparse +import jinja2 +from mbedtls_dev import build_tree + +def render(template_path: str) -> str: + """ + Render template from the input file. + """ + environment = jinja2.Environment( + loader=jinja2.FileSystemLoader(os.path.dirname(template_path)), + keep_trailing_newline=True) + template = environment.get_template(os.path.basename(template_path)) + + return template.render() + +def generate_driver_wrapper_file(mbedtls_root: str, output_dir: str) -> None: + """ + Generate the file psa_crypto_driver_wrapper.c. + """ + driver_wrapper_template_filename = \ + os.path.join(mbedtls_root, \ + "scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja") + + result = render(driver_wrapper_template_filename) + + with open(os.path.join(output_dir, "psa_crypto_driver_wrappers.c"), 'w') as out_file: + out_file.write(result) + +def main() -> int: + """ + Main with command line arguments. + """ + def_arg_mbedtls_root = build_tree.guess_mbedtls_root() + def_arg_output_dir = os.path.join(def_arg_mbedtls_root, 'library') + + parser = argparse.ArgumentParser() + parser.add_argument('--mbedtls-root', nargs='?', default=def_arg_mbedtls_root, + help='root directory of mbedtls source code') + parser.add_argument('output_directory', nargs='?', + default=def_arg_output_dir, help='output file\'s location') + args = parser.parse_args() + + mbedtls_root = os.path.abspath(args.mbedtls_root) + output_directory = args.output_directory + + generate_driver_wrapper_file(mbedtls_root, output_directory) + + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/scripts/make_generated_files.bat b/scripts/make_generated_files.bat index d3a8b36454..662da984c7 100644 --- a/scripts/make_generated_files.bat +++ b/scripts/make_generated_files.bat @@ -1,6 +1,9 @@ @rem Generate automatically-generated configuration-independent source files @rem and build scripts. @rem Perl and Python 3 must be on the PATH. +@rem psa_crypto_driver_wrappers.c needs to be generated prior to +@rem generate_visualc_files.pl being invoked. +python scripts\generate_driver_wrappers.py || exit /b 1 perl scripts\generate_errors.pl || exit /b 1 perl scripts\generate_query_config.pl || exit /b 1 perl scripts\generate_features.pl || exit /b 1 diff --git a/tests/docker/bionic/Dockerfile b/tests/docker/bionic/Dockerfile index 50f5a7fba8..28d33b7553 100644 --- a/tests/docker/bionic/Dockerfile +++ b/tests/docker/bionic/Dockerfile @@ -60,6 +60,10 @@ RUN apt-get update \ pkg-config \ && rm -rf /var/lib/apt/lists/* +# Jinja2 is required for driver dispatch code generation. +RUN python3 -m pip install \ + jinja2==2.10.1 types-jinja2 + # Build a static, legacy openssl from sources with sslv3 enabled # Based on https://gist.github.com/bmaupin/8caca3a1e8c3c5686141 (build-openssl.sh) # Note: openssl-1.0.2 and earlier has known build issues with parallel make. diff --git a/tests/scripts/check-generated-files.sh b/tests/scripts/check-generated-files.sh index 994fd243bb..f42ecd6fb5 100755 --- a/tests/scripts/check-generated-files.sh +++ b/tests/scripts/check-generated-files.sh @@ -117,6 +117,7 @@ check() check scripts/generate_errors.pl library/error.c check scripts/generate_query_config.pl programs/test/query_config.c +check scripts/generate_driver_wrappers.py library/psa_crypto_driver_wrappers.c check scripts/generate_features.pl library/version_features.c check scripts/generate_ssl_debug_helpers.py library/ssl_debug_helpers_generated.c # generate_visualc_files enumerates source files (library/*.c). It doesn't