From 00ed38c25b2937fb237404beccfff4d9fd07b879 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 22 Nov 2023 19:24:31 +0100 Subject: [PATCH 01/14] Python module to parse function declarations from a header file Signed-off-by: Gilles Peskine --- scripts/mbedtls_dev/c_parsing_helper.py | 127 ++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 scripts/mbedtls_dev/c_parsing_helper.py diff --git a/scripts/mbedtls_dev/c_parsing_helper.py b/scripts/mbedtls_dev/c_parsing_helper.py new file mode 100644 index 000000000..3bb6f0405 --- /dev/null +++ b/scripts/mbedtls_dev/c_parsing_helper.py @@ -0,0 +1,127 @@ +"""Helper functions to parse C code in heavily constrained scenarios. + +Currently supported functionality: + +* read_function_declarations: read function declarations from a header file. +""" + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +import re +from typing import Dict, Iterable, Iterator, List, Optional, Tuple + + +class ArgumentInfo: + """Information about an argument to an API function.""" + #pylint: disable=too-few-public-methods + + _KEYWORDS = [ + 'const', 'register', 'restrict', + 'int', 'long', 'short', 'signed', 'unsigned', + ] + _DECLARATION_RE = re.compile( + r'(?P\w[\w\s*]*?)\s*' + + r'(?!(?:' + r'|'.join(_KEYWORDS) + r'))(?P\b\w+\b)?' + + r'\s*(?P\[[^][]*\])?\Z', + re.A | re.S) + + @classmethod + def normalize_type(cls, typ: str) -> str: + """Normalize whitespace in a type.""" + typ = re.sub(r'\s+', r' ', typ) + typ = re.sub(r'\s*\*', r' *', typ) + return typ + + def __init__(self, decl: str) -> None: + self.decl = decl.strip() + m = self._DECLARATION_RE.match(self.decl) + if not m: + raise ValueError(self.decl) + self.type = self.normalize_type(m.group('type')) #type: str + self.name = m.group('name') #type: Optional[str] + self.suffix = m.group('suffix') if m.group('suffix') else '' #type: str + + +class FunctionInfo: + """Information about an API function.""" + #pylint: disable=too-few-public-methods + + # Regex matching the declaration of a function that returns void. + VOID_RE = re.compile(r'\s*\bvoid\s*\Z', re.A) + + def __init__(self, #pylint: disable=too-many-arguments + filename: str, + line_number: int, + qualifiers: Iterable[str], + return_type: str, + name: str, + arguments: List[str]) -> None: + self.filename = filename + self.line_number = line_number + self.qualifiers = frozenset(qualifiers) + self.return_type = return_type + self.name = name + self.arguments = [ArgumentInfo(arg) for arg in arguments] + + def returns_void(self) -> bool: + """Whether the function returns void.""" + return bool(self.VOID_RE.search(self.return_type)) + + +# Match one C comment. +# Note that we match both comment types, so things like // in a /*...*/ +# comment are handled correctly. +_C_COMMENT_RE = re.compile(r'//[^n]*|/\*.*?\*/', re.S) +_NOT_NEWLINES_RE = re.compile(r'[^\n]+') + +def read_logical_lines(filename: str) -> Iterator[Tuple[int, str]]: + """Read logical lines from a file. + + Logical lines are one or more physical line, with balanced parentheses. + """ + with open(filename, encoding='utf-8') as inp: + content = inp.read() + # Strip comments, but keep newlines for line numbering + content = re.sub(_C_COMMENT_RE, + lambda m: re.sub(_NOT_NEWLINES_RE, "", m.group(0)), + content) + lines = enumerate(content.splitlines(), 1) + for line_number, line in lines: + # Read a logical line, containing balanced parentheses. + # We assume that parentheses are balanced (this should be ok + # since comments have been stripped), otherwise there will be + # a gigantic logical line at the end. + paren_level = line.count('(') - line.count(')') + while paren_level > 0: + _, more = next(lines) #pylint: disable=stop-iteration-return + paren_level += more.count('(') - more.count(')') + line += '\n' + more + yield line_number, line + +_C_FUNCTION_DECLARATION_RE = re.compile( + r'(?P(?:(?:extern|inline|static)\b\s*)*)' + r'(?P\w[\w\s*]*?)\s*' + + r'\b(?P\w+)' + + r'\s*\((?P.*)\)\s*;', + re.A | re.S) + +def read_function_declarations(functions: Dict[str, FunctionInfo], + filename: str) -> None: + """Collect function declarations from a C header file.""" + for line_number, line in read_logical_lines(filename): + m = _C_FUNCTION_DECLARATION_RE.match(line) + if not m: + continue + qualifiers = m.group('qualifiers').split() + return_type = m.group('return_type') + name = m.group('name') + arguments = m.group('arguments').split(',') + if len(arguments) == 1 and re.match(FunctionInfo.VOID_RE, arguments[0]): + arguments = [] + # Note: we replace any existing declaration for the same name. + functions[name] = FunctionInfo(filename, line_number, + qualifiers, + return_type, + name, + arguments) From d022093ea691423339a5a620bedffdcbd95e5b0c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 22 Nov 2023 19:24:59 +0100 Subject: [PATCH 02/14] C function wrapper generator The Base class generates trivial wrappers that just call the underlying function. It is meant as a base class to construct useful wrapper generators. The Logging class generates wrappers that can log the inputs and outputs to a function. Signed-off-by: Gilles Peskine --- scripts/mbedtls_dev/c_wrapper_generator.py | 459 +++++++++++++++++++++ 1 file changed, 459 insertions(+) create mode 100644 scripts/mbedtls_dev/c_wrapper_generator.py diff --git a/scripts/mbedtls_dev/c_wrapper_generator.py b/scripts/mbedtls_dev/c_wrapper_generator.py new file mode 100644 index 000000000..26da9b2f2 --- /dev/null +++ b/scripts/mbedtls_dev/c_wrapper_generator.py @@ -0,0 +1,459 @@ +"""Generate C wrapper functions. +""" + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +import os +import re +import sys +import typing +from typing import Dict, List, Optional, Tuple + +from .c_parsing_helper import ArgumentInfo, FunctionInfo +from . import typing_util + + +def c_declare(prefix: str, name: str, suffix: str) -> str: + """Format a declaration of name with the given type prefix and suffix.""" + if not prefix.endswith('*'): + prefix += ' ' + return prefix + name + suffix + + +WrapperInfo = typing.NamedTuple('WrapperInfo', [ + ('argument_names', List[str]), + ('guard', Optional[str]), + ('wrapper_name', str), +]) + + +class Base: + """Generate a C source file containing wrapper functions.""" + + # This class is designed to have many methods potentially overloaded. + # Tell pylint not to complain about methods that have unused arguments: + # child classes are likely to override those methods and need the + # arguments in question. + #pylint: disable=no-self-use,unused-argument + + # Prefix prepended to the function's name to form the wrapper name. + _WRAPPER_NAME_PREFIX = '' + # Suffix appended to the function's name to form the wrapper name. + _WRAPPER_NAME_SUFFIX = '_wrap' + + # Functions with one of these qualifiers are skipped. + _SKIP_FUNCTION_WITH_QUALIFIERS = frozenset(['inline', 'static']) + + def __init__(self): + """Construct a wrapper generator object. + """ + self.program_name = os.path.basename(sys.argv[0]) + # To be populated in a derived class + self.functions = {} #type: Dict[str, FunctionInfo] + # Preprocessor symbol used as a guard against multiple inclusion in the + # header. Must be set before writing output to a header. + # Not used when writing .c output. + self.header_guard = None #type: Optional[str] + + def _write_prologue(self, out: typing_util.Writable, header: bool) -> None: + """Write the prologue of a C file. + + This includes a description comment and some include directives. + """ + out.write("""/* Automatically generated by {}, do not edit! */ + +/* Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +""" + .format(self.program_name)) + if header: + out.write(""" +#ifndef {guard} +#define {guard} + +#ifdef __cplusplus +extern "C" {{ +#endif +""" + .format(guard=self.header_guard)) + out.write(""" +#include +""") + + def _write_epilogue(self, out: typing_util.Writable, header: bool) -> None: + """Write the epilogue of a C file. + """ + if header: + out.write(""" +#ifdef __cplusplus +}} +#endif + +#endif /* {guard} */ +""" + .format(guard=self.header_guard)) + out.write(""" +/* End of automatically generated file. */ +""") + + def _wrapper_function_name(self, original_name: str) -> str: + """The name of the wrapper function. + + By default, this adds a suffix. + """ + return (self._WRAPPER_NAME_PREFIX + + original_name + + self._WRAPPER_NAME_SUFFIX) + + def _wrapper_declaration_start(self, + function: FunctionInfo, + wrapper_name: str) -> str: + """The beginning of the wrapper function declaration. + + This ends just before the opening parenthesis of the argument list. + + This is a string containing at least the return type and the + function name. It may start with additional qualifiers or attributes + such as `static`, `__attribute__((...))`, etc. + """ + return c_declare(function.return_type, wrapper_name, '') + + def _argument_name(self, + function_name: str, + num: int, + arg: ArgumentInfo) -> str: + """Name to use for the given argument in the wrapper function. + + Argument numbers count from 0. + """ + name = 'arg' + str(num) + if arg.name: + name += '_' + arg.name + return name + + def _wrapper_declaration_argument(self, + function_name: str, + num: int, name: str, + arg: ArgumentInfo) -> str: + """One argument definition in the wrapper function declaration. + + Argument numbers count from 0. + """ + return c_declare(arg.type, name, arg.suffix) + + def _underlying_function_name(self, function: FunctionInfo) -> str: + """The name of the underlying function. + + By default, this is the name of the wrapped function. + """ + return function.name + + def _return_variable_name(self, function: FunctionInfo) -> str: + """The name of the variable that will contain the return value.""" + return 'retval' + + def _write_function_call(self, out: typing_util.Writable, + function: FunctionInfo, + argument_names: List[str]) -> None: + """Write the call to the underlying function. + """ + # Note that the function name is in parentheses, to avoid calling + # a function-like macro with the same name, since in typical usage + # there is a function-like macro with the same name which is the + # wrapper. + call = '({})({})'.format(self._underlying_function_name(function), + ', '.join(argument_names)) + if function.returns_void(): + out.write(' {};\n'.format(call)) + else: + ret_name = self._return_variable_name(function) + ret_decl = c_declare(function.return_type, ret_name, '') + out.write(' {} = {};\n'.format(ret_decl, call)) + + def _write_function_return(self, out: typing_util.Writable, + function: FunctionInfo, + if_void: bool = False) -> None: + """Write a return statement. + + If the function returns void, only write a statement if if_void is true. + """ + if function.returns_void(): + if if_void: + out.write(' return;\n') + else: + ret_name = self._return_variable_name(function) + out.write(' return {};\n'.format(ret_name)) + + def _write_function_body(self, out: typing_util.Writable, + function: FunctionInfo, + argument_names: List[str]) -> None: + """Write the body of the wrapper code for the specified function. + """ + self._write_function_call(out, function, argument_names) + self._write_function_return(out, function) + + def _skip_function(self, function: FunctionInfo) -> bool: + """Whether to skip this function. + + By default, static or inline functions are skipped. + """ + if not self._SKIP_FUNCTION_WITH_QUALIFIERS.isdisjoint(function.qualifiers): + return True + return False + + _FUNCTION_GUARDS = { + } #type: Dict[str, str] + + def _function_guard(self, function: FunctionInfo) -> Optional[str]: + """A preprocessor condition for this function. + + The wrapper will be guarded with `#if` on this condition, if not None. + """ + return self._FUNCTION_GUARDS.get(function.name) + + def _wrapper_info(self, function: FunctionInfo) -> Optional[WrapperInfo]: + """Information about the wrapper for one function. + + Return None if the function should be skipped. + """ + if self._skip_function(function): + return None + argument_names = [self._argument_name(function.name, num, arg) + for num, arg in enumerate(function.arguments)] + return WrapperInfo( + argument_names=argument_names, + guard=self._function_guard(function), + wrapper_name=self._wrapper_function_name(function.name), + ) + + def _write_function_prototype(self, out: typing_util.Writable, + function: FunctionInfo, + wrapper: WrapperInfo, + header: bool) -> None: + """Write the prototype of a wrapper function. + + If header is true, write a function declaration, with a semicolon at + the end. Otherwise just write the prototype, intended to be followed + by the function's body. + """ + declaration_start = self._wrapper_declaration_start(function, + wrapper.wrapper_name) + arg_indent = ' ' + terminator = ';\n' if header else '\n' + if function.arguments: + out.write(declaration_start + '(\n') + for num in range(len(function.arguments)): + arg_def = self._wrapper_declaration_argument( + function.name, + num, wrapper.argument_names[num], function.arguments[num]) + arg_terminator = \ + (')' + terminator if num == len(function.arguments) - 1 else + ',\n') + out.write(arg_indent + arg_def + arg_terminator) + else: + out.write(declaration_start + '(void)' + terminator) + + def _write_c_function(self, out: typing_util.Writable, + function: FunctionInfo) -> None: + """Write wrapper code for one function. + + Do nothing if the function is skipped. + """ + wrapper = self._wrapper_info(function) + if wrapper is None: + return + out.write(""" +/* Wrapper for {} */ +""" + .format(function.name)) + if wrapper.guard is not None: + out.write('#if {}\n'.format(wrapper.guard)) + self._write_function_prototype(out, function, wrapper, False) + out.write('{\n') + self._write_function_body(out, function, wrapper.argument_names) + out.write('}\n') + if wrapper.guard is not None: + out.write('#endif /* {} */\n'.format(wrapper.guard)) + + def _write_h_function(self, out: typing_util.Writable, + function: FunctionInfo, + wrapper: WrapperInfo) -> None: + """Write the declaration of one wrapper function. + """ + out.write('\n') + if wrapper.guard is not None: + out.write('#if {}\n'.format(wrapper.guard)) + self._write_function_prototype(out, function, wrapper, True) + if wrapper.guard is not None: + out.write('#endif /* {} */\n'.format(wrapper.guard)) + + def _write_h_macro(self, out: typing_util.Writable, + function: FunctionInfo, + wrapper: WrapperInfo) -> None: + """Write the macro definition for one wrapper. + """ + arg_list = ', '.join(wrapper.argument_names) + out.write('#define {function_name}({args}) \\\n {wrapper_name}({args})\n' + .format(function_name=function.name, + wrapper_name=wrapper.wrapper_name, + args=arg_list)) + + def write_c_file(self, filename: str) -> None: + """Output a whole C file containing function wrapper definitions.""" + with open(filename, 'w', encoding='utf-8') as out: + self._write_prologue(out, False) + for name in sorted(self.functions): + self._write_c_function(out, self.functions[name]) + self._write_epilogue(out, False) + + def _header_guard_from_file_name(self, filename: str) -> str: + """Preprocessor symbol used as a guard against multiple inclusion.""" + # Heuristic to strip irrelevant leading directories + filename = re.sub(r'.*include[\\/]', r'', filename) + return re.sub(r'[^0-9A-Za-z]', r'_', filename, re.A).upper() + + def write_h_file(self, filename: str) -> None: + """Output a header file with function wrapper declarations and macro definitions.""" + self.header_guard = self._header_guard_from_file_name(filename) + with open(filename, 'w', encoding='utf-8') as out: + self._write_prologue(out, True) + for name in sorted(self.functions.keys()): + function = self.functions[name] + wrapper = self._wrapper_info(function) + if wrapper is None: + continue + self._write_h_function(out, function, wrapper) + self._write_h_macro(out, function, wrapper) + self._write_epilogue(out, True) + + +class UnknownTypeForPrintf(Exception): + """Exception raised when attempting to generate code that logs a value of an unknown type.""" + + def __init__(self, typ: str) -> None: + super().__init__("Unknown type for printf format generation: " + typ) + + +class Logging(Base): + """Generate wrapper functions that log the inputs and outputs.""" + + def __init__(self) -> None: + """Construct a wrapper generator including logging of inputs and outputs. + + Log to stdout by default. Call `set_stream` to change this. + """ + super().__init__() + self.stream = 'stdout' + + def set_stream(self, stream: str) -> None: + """Set the stdio stream to log to. + + Call this method before calling `write_c_output` or `write_h_output`. + """ + self.stream = stream + + def _write_prologue(self, out: typing_util.Writable, header: bool) -> None: + super()._write_prologue(out, header) + if not header: + out.write(""" +#if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_TEST_HOOKS) +#include +#include +#include // for MBEDTLS_PRINTF_SIZET +#include // for mbedtls_fprintf +#endif /* defined(MBEDTLS_FS_IO) && defined(MBEDTLS_TEST_HOOKS) */ +""") + + _PRINTF_SIMPLE_FORMAT = { + 'int': '%d', + 'long': '%ld', + 'long long': '%lld', + 'size_t': '%"MBEDTLS_PRINTF_SIZET"', + 'unsigned': '0x%08x', + 'unsigned int': '0x%08x', + 'unsigned long': '0x%08lx', + 'unsigned long long': '0x%016llx', + } + + def _printf_simple_format(self, typ: str) -> Optional[str]: + """Use this printf format for a value of typ. + + Return None if values of typ need more complex handling. + """ + return self._PRINTF_SIMPLE_FORMAT.get(typ) + + _PRINTF_TYPE_CAST = { + 'int32_t': 'int', + 'uint32_t': 'unsigned', + 'uint64_t': 'unsigned long long', + } #type: Dict[str, str] + + def _printf_type_cast(self, typ: str) -> Optional[str]: + """Cast values of typ to this type before passing them to printf. + + Return None if values of the given type do not need a cast. + """ + return self._PRINTF_TYPE_CAST.get(typ) + + _POINTER_TYPE_RE = re.compile(r'\s*\*\Z') + + def _printf_parameters(self, typ: str, var: str) -> Tuple[str, List[str]]: + """The printf format and arguments for a value of type typ stored in var. + """ + expr = var + base_type = typ + # For outputs via a pointer, get the value that has been written. + # Note: we don't support pointers to pointers here. + pointer_match = self._POINTER_TYPE_RE.search(base_type) + if pointer_match: + base_type = base_type[:pointer_match.start(0)] + expr = '*({})'.format(expr) + # Maybe cast the value to a standard type. + cast_to = self._printf_type_cast(base_type) + if cast_to is not None: + expr = '({}) {}'.format(cast_to, expr) + base_type = cast_to + # Try standard types. + fmt = self._printf_simple_format(base_type) + if fmt is not None: + return '{}={}'.format(var, fmt), [expr] + raise UnknownTypeForPrintf(typ) + + def _write_function_logging(self, out: typing_util.Writable, + function: FunctionInfo, + argument_names: List[str]) -> None: + """Write code to log the function's inputs and outputs.""" + formats, values = '%s', ['"' + function.name + '"'] + for arg_info, arg_name in zip(function.arguments, argument_names): + fmt, vals = self._printf_parameters(arg_info.type, arg_name) + if fmt: + formats += ' ' + fmt + values += vals + if not function.returns_void(): + ret_name = self._return_variable_name(function) + fmt, vals = self._printf_parameters(function.return_type, ret_name) + if fmt: + formats += ' ' + fmt + values += vals + out.write("""\ +#if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_TEST_HOOKS) + if ({stream}) {{ + mbedtls_fprintf({stream}, "{formats}\\n", + {values}); + }} +#endif /* defined(MBEDTLS_FS_IO) && defined(MBEDTLS_TEST_HOOKS) */ +""" + .format(stream=self.stream, + formats=formats, + values=', '.join(values))) + + def _write_function_body(self, out: typing_util.Writable, + function: FunctionInfo, + argument_names: List[str]) -> None: + """Write the body of the wrapper code for the specified function. + """ + self._write_function_call(out, function, argument_names) + self._write_function_logging(out, function, argument_names) + self._write_function_return(out, function) From f838eb2259ac74167508101377e88645534f81f5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 23 Nov 2023 14:12:29 +0100 Subject: [PATCH 03/14] Guard the macro definition It doesn't make sense to define a macro expanding to a non-existent function. Signed-off-by: Gilles Peskine --- scripts/mbedtls_dev/c_wrapper_generator.py | 46 +++++++++++++--------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/scripts/mbedtls_dev/c_wrapper_generator.py b/scripts/mbedtls_dev/c_wrapper_generator.py index 26da9b2f2..de99ddb9a 100644 --- a/scripts/mbedtls_dev/c_wrapper_generator.py +++ b/scripts/mbedtls_dev/c_wrapper_generator.py @@ -277,21 +277,16 @@ extern "C" {{ if wrapper.guard is not None: out.write('#endif /* {} */\n'.format(wrapper.guard)) - def _write_h_function(self, out: typing_util.Writable, - function: FunctionInfo, - wrapper: WrapperInfo) -> None: + def _write_h_function_declaration(self, out: typing_util.Writable, + function: FunctionInfo, + wrapper: WrapperInfo) -> None: """Write the declaration of one wrapper function. """ - out.write('\n') - if wrapper.guard is not None: - out.write('#if {}\n'.format(wrapper.guard)) self._write_function_prototype(out, function, wrapper, True) - if wrapper.guard is not None: - out.write('#endif /* {} */\n'.format(wrapper.guard)) - def _write_h_macro(self, out: typing_util.Writable, - function: FunctionInfo, - wrapper: WrapperInfo) -> None: + def _write_h_macro_definition(self, out: typing_util.Writable, + function: FunctionInfo, + wrapper: WrapperInfo) -> None: """Write the macro definition for one wrapper. """ arg_list = ', '.join(wrapper.argument_names) @@ -300,6 +295,26 @@ extern "C" {{ wrapper_name=wrapper.wrapper_name, args=arg_list)) + def _write_h_function(self, out: typing_util.Writable, + function: FunctionInfo) -> None: + """Write the complete header content for one wrapper. + + This is the declaration of the wrapper function, and the + definition of a function-like macro that calls the wrapper function. + + Do nothing if the function is skipped. + """ + wrapper = self._wrapper_info(function) + if wrapper is None: + return + out.write('\n') + if wrapper.guard is not None: + out.write('#if {}\n'.format(wrapper.guard)) + self._write_h_function_declaration(out, function, wrapper) + self._write_h_macro_definition(out, function, wrapper) + if wrapper.guard is not None: + out.write('#endif /* {} */\n'.format(wrapper.guard)) + def write_c_file(self, filename: str) -> None: """Output a whole C file containing function wrapper definitions.""" with open(filename, 'w', encoding='utf-8') as out: @@ -319,13 +334,8 @@ extern "C" {{ self.header_guard = self._header_guard_from_file_name(filename) with open(filename, 'w', encoding='utf-8') as out: self._write_prologue(out, True) - for name in sorted(self.functions.keys()): - function = self.functions[name] - wrapper = self._wrapper_info(function) - if wrapper is None: - continue - self._write_h_function(out, function, wrapper) - self._write_h_macro(out, function, wrapper) + for name in sorted(self.functions): + self._write_h_function(out, self.functions[name]) self._write_epilogue(out, True) From 5294bb347c84f9c6252fde00f18ab8d2046c4732 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 16:38:17 +0100 Subject: [PATCH 04/14] PSA wrapper generator The new script `tests/scripts/generate_psa_wrappers.py` generates the implementation of wrapper functions for PSA API functions, as well as a header that defines macros that redirect calls to the wrapper functions. By default, the wrapper functions just call the underlying library function. With `--log`, the wrapper functions log the arguments and return values. This commit only introduces the new script. Subsequent commits will integrate the wrappers in the build. Signed-off-by: Gilles Peskine --- tests/scripts/generate_psa_wrappers.py | 159 +++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100755 tests/scripts/generate_psa_wrappers.py diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py new file mode 100755 index 000000000..9bb6eb758 --- /dev/null +++ b/tests/scripts/generate_psa_wrappers.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 +"""Generate wrapper functions for PSA function calls. +""" + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +import argparse +import os +from typing import List, Tuple + +import scripts_path #pylint: disable=unused-import +from mbedtls_dev import build_tree +from mbedtls_dev import c_parsing_helper +from mbedtls_dev import c_wrapper_generator +from mbedtls_dev import typing_util + + +class PSAWrapperGenerator(c_wrapper_generator.Base): + """Generate a C source file containing wrapper functions for PSA Crypto API calls.""" + + _CPP_GUARDS = 'defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS)' + _WRAPPER_NAME_PREFIX = 'mbedtls_test_wrap_' + _WRAPPER_NAME_SUFFIX = '' + + def gather_data(self) -> None: + root_dir = build_tree.guess_mbedtls_root() + for header_name in ['crypto.h', 'crypto_extra.h']: + header_path = os.path.join(root_dir, 'include', 'psa', header_name) + c_parsing_helper.read_function_declarations(self.functions, header_path) + + _SKIP_FUNCTIONS = frozenset([ + 'mbedtls_psa_external_get_random', # not a library function + 'psa_get_key_domain_parameters', # client-side function + 'psa_get_key_slot_number', # client-side function + 'psa_key_derivation_verify_bytes', # not implemented yet + 'psa_key_derivation_verify_key', # not implemented yet + 'psa_set_key_domain_parameters', # client-side function + ]) + + def _skip_function(self, function: c_wrapper_generator.FunctionInfo) -> bool: + if function.return_type != 'psa_status_t': + return True + if function.name in self._SKIP_FUNCTIONS: + return True + return False + + # PAKE stuff: not implemented yet + _PAKE_STUFF = frozenset([ + 'psa_crypto_driver_pake_inputs_t *', + 'psa_pake_cipher_suite_t *', + ]) + + def _return_variable_name(self, + function: c_wrapper_generator.FunctionInfo) -> str: + """The name of the variable that will contain the return value.""" + if function.return_type == 'psa_status_t': + return 'status' + return super()._return_variable_name(function) + + _FUNCTION_GUARDS = c_wrapper_generator.Base._FUNCTION_GUARDS.copy() \ + #pylint: disable=protected-access + _FUNCTION_GUARDS.update({ + 'mbedtls_psa_register_se_key': 'defined(MBEDTLS_PSA_CRYPTO_SE_C)', + 'mbedtls_psa_inject_entropy': 'defined(MBEDTLS_PSA_INJECT_ENTROPY)', + 'mbedtls_psa_external_get_random': 'defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)', + 'mbedtls_psa_platform_get_builtin_key': 'defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)', + }) + + def _write_prologue(self, out: typing_util.Writable, header: bool) -> None: + super()._write_prologue(out, header) + out.write(""" +#if {} + +#include + +#include +#include +""" + .format(self._CPP_GUARDS)) + + def _write_epilogue(self, out: typing_util.Writable, header: bool) -> None: + out.write(""" +#endif /* {} */ +""" + .format(self._CPP_GUARDS)) + super()._write_epilogue(out, header) + + +class PSALoggingWrapperGenerator(PSAWrapperGenerator, c_wrapper_generator.Logging): + """Generate a C source file containing wrapper functions that log PSA Crypto API calls.""" + + def __init__(self, stream: str) -> None: + super().__init__() + self.set_stream(stream) + + _PRINTF_TYPE_CAST = c_wrapper_generator.Logging._PRINTF_TYPE_CAST.copy() + _PRINTF_TYPE_CAST.update({ + 'mbedtls_svc_key_id_t': 'unsigned', + 'psa_algorithm_t': 'unsigned', + 'psa_drv_slot_number_t': 'unsigned long long', + 'psa_key_derivation_step_t': 'int', + 'psa_key_id_t': 'unsigned', + 'psa_key_slot_number_t': 'unsigned long long', + 'psa_key_lifetime_t': 'unsigned', + 'psa_key_type_t': 'unsigned', + 'psa_key_usage_flags_t': 'unsigned', + 'psa_pake_role_t': 'int', + 'psa_pake_step_t': 'int', + 'psa_status_t': 'int', + }) + + def _printf_parameters(self, typ: str, var: str) -> Tuple[str, List[str]]: + if typ.startswith('const '): + typ = typ[6:] + if typ == 'uint8_t *': + # Skip buffers + return '', [] + if typ.endswith('operation_t *'): + return '', [] + if typ in self._PAKE_STUFF: + return '', [] + if typ == 'psa_key_attributes_t *': + return (var + '={id=%u, lifetime=0x%08x, type=0x%08x, bits=%u, alg=%08x, usage=%08x}', + ['(unsigned) psa_get_key_{}({})'.format(field, var) + for field in ['id', 'lifetime', 'type', 'bits', 'algorithm', 'usage_flags']]) + return super()._printf_parameters(typ, var) + + +DEFAULT_C_OUTPUT_FILE_NAME = 'tests/src/psa_test_wrappers.c' +DEFAULT_H_OUTPUT_FILE_NAME = 'tests/include/test/psa_test_wrappers.h' + +def main() -> None: + parser = argparse.ArgumentParser(description=globals()['__doc__']) + parser.add_argument('--log', + help='Stream to log to (default: no logging code)') + parser.add_argument('--output-c', + metavar='FILENAME', + default=DEFAULT_C_OUTPUT_FILE_NAME, + help=('Output .c file path (default: {}; skip .c output if empty)' + .format(DEFAULT_C_OUTPUT_FILE_NAME))) + parser.add_argument('--output-h', + metavar='FILENAME', + default=DEFAULT_H_OUTPUT_FILE_NAME, + help=('Output .h file path (default: {}; skip .h output if empty)' + .format(DEFAULT_H_OUTPUT_FILE_NAME))) + options = parser.parse_args() + if options.log: + generator = PSALoggingWrapperGenerator(options.log) #type: PSAWrapperGenerator + else: + generator = PSAWrapperGenerator() + generator.gather_data() + if options.output_h: + generator.write_h_file(options.output_h) + if options.output_c: + generator.write_c_file(options.output_c) + +if __name__ == '__main__': + main() From 6e4332cc24f18480ac388590fbc57e9e22b1f237 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 16:42:40 +0100 Subject: [PATCH 05/14] Commit generated PSA wrappers Commit files generated by `tests/scripts/generate_psa_wrappers.py`. As of this commit, the new code is neither useful (the wrappers just call the underlying functions) nor used (the wrapper functions are not called from anywhere). This will change in subsequent commits. This is a deviation from our normal practice of generating configuration-independent platform-independent files as part of the build in the development branch. The PSA test wrappers will be committed to the repository for some time for two reasons: * In the short term, we will review the generated code but not fully review the generator script. * The build scripts cannot yet accommodate a generated header file. Signed-off-by: Gilles Peskine --- tests/include/test/psa_test_wrappers.h | 719 ++++++++++++++++++ tests/src/psa_test_wrappers.c | 973 +++++++++++++++++++++++++ 2 files changed, 1692 insertions(+) create mode 100644 tests/include/test/psa_test_wrappers.h create mode 100644 tests/src/psa_test_wrappers.c diff --git a/tests/include/test/psa_test_wrappers.h b/tests/include/test/psa_test_wrappers.h new file mode 100644 index 000000000..18417800c --- /dev/null +++ b/tests/include/test/psa_test_wrappers.h @@ -0,0 +1,719 @@ +/* Automatically generated by generate_psa_wrappers.py, do not edit! */ + +/* Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef TEST_PSA_TEST_WRAPPERS_H +#define TEST_PSA_TEST_WRAPPERS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) + +#include + +#include +#include + +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) +psa_status_t mbedtls_test_wrap_mbedtls_psa_inject_entropy( + const uint8_t *arg0_seed, + size_t arg1_seed_size); +#define mbedtls_psa_inject_entropy(arg0_seed, arg1_seed_size) \ + mbedtls_test_wrap_mbedtls_psa_inject_entropy(arg0_seed, arg1_seed_size) +#endif /* defined(MBEDTLS_PSA_INJECT_ENTROPY) */ + +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) +psa_status_t mbedtls_test_wrap_mbedtls_psa_platform_get_builtin_key( + mbedtls_svc_key_id_t arg0_key_id, + psa_key_lifetime_t *arg1_lifetime, + psa_drv_slot_number_t *arg2_slot_number); +#define mbedtls_psa_platform_get_builtin_key(arg0_key_id, arg1_lifetime, arg2_slot_number) \ + mbedtls_test_wrap_mbedtls_psa_platform_get_builtin_key(arg0_key_id, arg1_lifetime, arg2_slot_number) +#endif /* defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) */ + +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) +psa_status_t mbedtls_test_wrap_mbedtls_psa_register_se_key( + const psa_key_attributes_t *arg0_attributes); +#define mbedtls_psa_register_se_key(arg0_attributes) \ + mbedtls_test_wrap_mbedtls_psa_register_se_key(arg0_attributes) +#endif /* defined(MBEDTLS_PSA_CRYPTO_SE_C) */ + +psa_status_t mbedtls_test_wrap_psa_aead_abort( + psa_aead_operation_t *arg0_operation); +#define psa_aead_abort(arg0_operation) \ + mbedtls_test_wrap_psa_aead_abort(arg0_operation) + +psa_status_t mbedtls_test_wrap_psa_aead_decrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_nonce, + size_t arg3_nonce_length, + const uint8_t *arg4_additional_data, + size_t arg5_additional_data_length, + const uint8_t *arg6_ciphertext, + size_t arg7_ciphertext_length, + uint8_t *arg8_plaintext, + size_t arg9_plaintext_size, + size_t *arg10_plaintext_length); +#define psa_aead_decrypt(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_ciphertext, arg7_ciphertext_length, arg8_plaintext, arg9_plaintext_size, arg10_plaintext_length) \ + mbedtls_test_wrap_psa_aead_decrypt(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_ciphertext, arg7_ciphertext_length, arg8_plaintext, arg9_plaintext_size, arg10_plaintext_length) + +psa_status_t mbedtls_test_wrap_psa_aead_decrypt_setup( + psa_aead_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg); +#define psa_aead_decrypt_setup(arg0_operation, arg1_key, arg2_alg) \ + mbedtls_test_wrap_psa_aead_decrypt_setup(arg0_operation, arg1_key, arg2_alg) + +psa_status_t mbedtls_test_wrap_psa_aead_encrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_nonce, + size_t arg3_nonce_length, + const uint8_t *arg4_additional_data, + size_t arg5_additional_data_length, + const uint8_t *arg6_plaintext, + size_t arg7_plaintext_length, + uint8_t *arg8_ciphertext, + size_t arg9_ciphertext_size, + size_t *arg10_ciphertext_length); +#define psa_aead_encrypt(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_plaintext, arg7_plaintext_length, arg8_ciphertext, arg9_ciphertext_size, arg10_ciphertext_length) \ + mbedtls_test_wrap_psa_aead_encrypt(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_plaintext, arg7_plaintext_length, arg8_ciphertext, arg9_ciphertext_size, arg10_ciphertext_length) + +psa_status_t mbedtls_test_wrap_psa_aead_encrypt_setup( + psa_aead_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg); +#define psa_aead_encrypt_setup(arg0_operation, arg1_key, arg2_alg) \ + mbedtls_test_wrap_psa_aead_encrypt_setup(arg0_operation, arg1_key, arg2_alg) + +psa_status_t mbedtls_test_wrap_psa_aead_finish( + psa_aead_operation_t *arg0_operation, + uint8_t *arg1_ciphertext, + size_t arg2_ciphertext_size, + size_t *arg3_ciphertext_length, + uint8_t *arg4_tag, + size_t arg5_tag_size, + size_t *arg6_tag_length); +#define psa_aead_finish(arg0_operation, arg1_ciphertext, arg2_ciphertext_size, arg3_ciphertext_length, arg4_tag, arg5_tag_size, arg6_tag_length) \ + mbedtls_test_wrap_psa_aead_finish(arg0_operation, arg1_ciphertext, arg2_ciphertext_size, arg3_ciphertext_length, arg4_tag, arg5_tag_size, arg6_tag_length) + +psa_status_t mbedtls_test_wrap_psa_aead_generate_nonce( + psa_aead_operation_t *arg0_operation, + uint8_t *arg1_nonce, + size_t arg2_nonce_size, + size_t *arg3_nonce_length); +#define psa_aead_generate_nonce(arg0_operation, arg1_nonce, arg2_nonce_size, arg3_nonce_length) \ + mbedtls_test_wrap_psa_aead_generate_nonce(arg0_operation, arg1_nonce, arg2_nonce_size, arg3_nonce_length) + +psa_status_t mbedtls_test_wrap_psa_aead_set_lengths( + psa_aead_operation_t *arg0_operation, + size_t arg1_ad_length, + size_t arg2_plaintext_length); +#define psa_aead_set_lengths(arg0_operation, arg1_ad_length, arg2_plaintext_length) \ + mbedtls_test_wrap_psa_aead_set_lengths(arg0_operation, arg1_ad_length, arg2_plaintext_length) + +psa_status_t mbedtls_test_wrap_psa_aead_set_nonce( + psa_aead_operation_t *arg0_operation, + const uint8_t *arg1_nonce, + size_t arg2_nonce_length); +#define psa_aead_set_nonce(arg0_operation, arg1_nonce, arg2_nonce_length) \ + mbedtls_test_wrap_psa_aead_set_nonce(arg0_operation, arg1_nonce, arg2_nonce_length) + +psa_status_t mbedtls_test_wrap_psa_aead_update( + psa_aead_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length, + uint8_t *arg3_output, + size_t arg4_output_size, + size_t *arg5_output_length); +#define psa_aead_update(arg0_operation, arg1_input, arg2_input_length, arg3_output, arg4_output_size, arg5_output_length) \ + mbedtls_test_wrap_psa_aead_update(arg0_operation, arg1_input, arg2_input_length, arg3_output, arg4_output_size, arg5_output_length) + +psa_status_t mbedtls_test_wrap_psa_aead_update_ad( + psa_aead_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length); +#define psa_aead_update_ad(arg0_operation, arg1_input, arg2_input_length) \ + mbedtls_test_wrap_psa_aead_update_ad(arg0_operation, arg1_input, arg2_input_length) + +psa_status_t mbedtls_test_wrap_psa_aead_verify( + psa_aead_operation_t *arg0_operation, + uint8_t *arg1_plaintext, + size_t arg2_plaintext_size, + size_t *arg3_plaintext_length, + const uint8_t *arg4_tag, + size_t arg5_tag_length); +#define psa_aead_verify(arg0_operation, arg1_plaintext, arg2_plaintext_size, arg3_plaintext_length, arg4_tag, arg5_tag_length) \ + mbedtls_test_wrap_psa_aead_verify(arg0_operation, arg1_plaintext, arg2_plaintext_size, arg3_plaintext_length, arg4_tag, arg5_tag_length) + +psa_status_t mbedtls_test_wrap_psa_asymmetric_decrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_salt, + size_t arg5_salt_length, + uint8_t *arg6_output, + size_t arg7_output_size, + size_t *arg8_output_length); +#define psa_asymmetric_decrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length) \ + mbedtls_test_wrap_psa_asymmetric_decrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length) + +psa_status_t mbedtls_test_wrap_psa_asymmetric_encrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_salt, + size_t arg5_salt_length, + uint8_t *arg6_output, + size_t arg7_output_size, + size_t *arg8_output_length); +#define psa_asymmetric_encrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length) \ + mbedtls_test_wrap_psa_asymmetric_encrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length) + +psa_status_t mbedtls_test_wrap_psa_cipher_abort( + psa_cipher_operation_t *arg0_operation); +#define psa_cipher_abort(arg0_operation) \ + mbedtls_test_wrap_psa_cipher_abort(arg0_operation) + +psa_status_t mbedtls_test_wrap_psa_cipher_decrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_output, + size_t arg5_output_size, + size_t *arg6_output_length); +#define psa_cipher_decrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length) \ + mbedtls_test_wrap_psa_cipher_decrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length) + +psa_status_t mbedtls_test_wrap_psa_cipher_decrypt_setup( + psa_cipher_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg); +#define psa_cipher_decrypt_setup(arg0_operation, arg1_key, arg2_alg) \ + mbedtls_test_wrap_psa_cipher_decrypt_setup(arg0_operation, arg1_key, arg2_alg) + +psa_status_t mbedtls_test_wrap_psa_cipher_encrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_output, + size_t arg5_output_size, + size_t *arg6_output_length); +#define psa_cipher_encrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length) \ + mbedtls_test_wrap_psa_cipher_encrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length) + +psa_status_t mbedtls_test_wrap_psa_cipher_encrypt_setup( + psa_cipher_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg); +#define psa_cipher_encrypt_setup(arg0_operation, arg1_key, arg2_alg) \ + mbedtls_test_wrap_psa_cipher_encrypt_setup(arg0_operation, arg1_key, arg2_alg) + +psa_status_t mbedtls_test_wrap_psa_cipher_finish( + psa_cipher_operation_t *arg0_operation, + uint8_t *arg1_output, + size_t arg2_output_size, + size_t *arg3_output_length); +#define psa_cipher_finish(arg0_operation, arg1_output, arg2_output_size, arg3_output_length) \ + mbedtls_test_wrap_psa_cipher_finish(arg0_operation, arg1_output, arg2_output_size, arg3_output_length) + +psa_status_t mbedtls_test_wrap_psa_cipher_generate_iv( + psa_cipher_operation_t *arg0_operation, + uint8_t *arg1_iv, + size_t arg2_iv_size, + size_t *arg3_iv_length); +#define psa_cipher_generate_iv(arg0_operation, arg1_iv, arg2_iv_size, arg3_iv_length) \ + mbedtls_test_wrap_psa_cipher_generate_iv(arg0_operation, arg1_iv, arg2_iv_size, arg3_iv_length) + +psa_status_t mbedtls_test_wrap_psa_cipher_set_iv( + psa_cipher_operation_t *arg0_operation, + const uint8_t *arg1_iv, + size_t arg2_iv_length); +#define psa_cipher_set_iv(arg0_operation, arg1_iv, arg2_iv_length) \ + mbedtls_test_wrap_psa_cipher_set_iv(arg0_operation, arg1_iv, arg2_iv_length) + +psa_status_t mbedtls_test_wrap_psa_cipher_update( + psa_cipher_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length, + uint8_t *arg3_output, + size_t arg4_output_size, + size_t *arg5_output_length); +#define psa_cipher_update(arg0_operation, arg1_input, arg2_input_length, arg3_output, arg4_output_size, arg5_output_length) \ + mbedtls_test_wrap_psa_cipher_update(arg0_operation, arg1_input, arg2_input_length, arg3_output, arg4_output_size, arg5_output_length) + +psa_status_t mbedtls_test_wrap_psa_copy_key( + mbedtls_svc_key_id_t arg0_source_key, + const psa_key_attributes_t *arg1_attributes, + mbedtls_svc_key_id_t *arg2_target_key); +#define psa_copy_key(arg0_source_key, arg1_attributes, arg2_target_key) \ + mbedtls_test_wrap_psa_copy_key(arg0_source_key, arg1_attributes, arg2_target_key) + +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_cipher_suite( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + psa_pake_cipher_suite_t *arg1_cipher_suite); +#define psa_crypto_driver_pake_get_cipher_suite(arg0_inputs, arg1_cipher_suite) \ + mbedtls_test_wrap_psa_crypto_driver_pake_get_cipher_suite(arg0_inputs, arg1_cipher_suite) + +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_password( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + uint8_t *arg1_buffer, + size_t arg2_buffer_size, + size_t *arg3_buffer_length); +#define psa_crypto_driver_pake_get_password(arg0_inputs, arg1_buffer, arg2_buffer_size, arg3_buffer_length) \ + mbedtls_test_wrap_psa_crypto_driver_pake_get_password(arg0_inputs, arg1_buffer, arg2_buffer_size, arg3_buffer_length) + +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_password_len( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + size_t *arg1_password_len); +#define psa_crypto_driver_pake_get_password_len(arg0_inputs, arg1_password_len) \ + mbedtls_test_wrap_psa_crypto_driver_pake_get_password_len(arg0_inputs, arg1_password_len) + +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_peer( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + uint8_t *arg1_peer_id, + size_t arg2_peer_id_size, + size_t *arg3_peer_id_length); +#define psa_crypto_driver_pake_get_peer(arg0_inputs, arg1_peer_id, arg2_peer_id_size, arg3_peer_id_length) \ + mbedtls_test_wrap_psa_crypto_driver_pake_get_peer(arg0_inputs, arg1_peer_id, arg2_peer_id_size, arg3_peer_id_length) + +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_peer_len( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + size_t *arg1_peer_len); +#define psa_crypto_driver_pake_get_peer_len(arg0_inputs, arg1_peer_len) \ + mbedtls_test_wrap_psa_crypto_driver_pake_get_peer_len(arg0_inputs, arg1_peer_len) + +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_user( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + uint8_t *arg1_user_id, + size_t arg2_user_id_size, + size_t *arg3_user_id_len); +#define psa_crypto_driver_pake_get_user(arg0_inputs, arg1_user_id, arg2_user_id_size, arg3_user_id_len) \ + mbedtls_test_wrap_psa_crypto_driver_pake_get_user(arg0_inputs, arg1_user_id, arg2_user_id_size, arg3_user_id_len) + +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_user_len( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + size_t *arg1_user_len); +#define psa_crypto_driver_pake_get_user_len(arg0_inputs, arg1_user_len) \ + mbedtls_test_wrap_psa_crypto_driver_pake_get_user_len(arg0_inputs, arg1_user_len) + +psa_status_t mbedtls_test_wrap_psa_crypto_init(void); +#define psa_crypto_init() \ + mbedtls_test_wrap_psa_crypto_init() + +psa_status_t mbedtls_test_wrap_psa_destroy_key( + mbedtls_svc_key_id_t arg0_key); +#define psa_destroy_key(arg0_key) \ + mbedtls_test_wrap_psa_destroy_key(arg0_key) + +psa_status_t mbedtls_test_wrap_psa_export_key( + mbedtls_svc_key_id_t arg0_key, + uint8_t *arg1_data, + size_t arg2_data_size, + size_t *arg3_data_length); +#define psa_export_key(arg0_key, arg1_data, arg2_data_size, arg3_data_length) \ + mbedtls_test_wrap_psa_export_key(arg0_key, arg1_data, arg2_data_size, arg3_data_length) + +psa_status_t mbedtls_test_wrap_psa_export_public_key( + mbedtls_svc_key_id_t arg0_key, + uint8_t *arg1_data, + size_t arg2_data_size, + size_t *arg3_data_length); +#define psa_export_public_key(arg0_key, arg1_data, arg2_data_size, arg3_data_length) \ + mbedtls_test_wrap_psa_export_public_key(arg0_key, arg1_data, arg2_data_size, arg3_data_length) + +psa_status_t mbedtls_test_wrap_psa_generate_key( + const psa_key_attributes_t *arg0_attributes, + mbedtls_svc_key_id_t *arg1_key); +#define psa_generate_key(arg0_attributes, arg1_key) \ + mbedtls_test_wrap_psa_generate_key(arg0_attributes, arg1_key) + +psa_status_t mbedtls_test_wrap_psa_generate_random( + uint8_t *arg0_output, + size_t arg1_output_size); +#define psa_generate_random(arg0_output, arg1_output_size) \ + mbedtls_test_wrap_psa_generate_random(arg0_output, arg1_output_size) + +psa_status_t mbedtls_test_wrap_psa_get_key_attributes( + mbedtls_svc_key_id_t arg0_key, + psa_key_attributes_t *arg1_attributes); +#define psa_get_key_attributes(arg0_key, arg1_attributes) \ + mbedtls_test_wrap_psa_get_key_attributes(arg0_key, arg1_attributes) + +psa_status_t mbedtls_test_wrap_psa_hash_abort( + psa_hash_operation_t *arg0_operation); +#define psa_hash_abort(arg0_operation) \ + mbedtls_test_wrap_psa_hash_abort(arg0_operation) + +psa_status_t mbedtls_test_wrap_psa_hash_clone( + const psa_hash_operation_t *arg0_source_operation, + psa_hash_operation_t *arg1_target_operation); +#define psa_hash_clone(arg0_source_operation, arg1_target_operation) \ + mbedtls_test_wrap_psa_hash_clone(arg0_source_operation, arg1_target_operation) + +psa_status_t mbedtls_test_wrap_psa_hash_compare( + psa_algorithm_t arg0_alg, + const uint8_t *arg1_input, + size_t arg2_input_length, + const uint8_t *arg3_hash, + size_t arg4_hash_length); +#define psa_hash_compare(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_length) \ + mbedtls_test_wrap_psa_hash_compare(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_length) + +psa_status_t mbedtls_test_wrap_psa_hash_compute( + psa_algorithm_t arg0_alg, + const uint8_t *arg1_input, + size_t arg2_input_length, + uint8_t *arg3_hash, + size_t arg4_hash_size, + size_t *arg5_hash_length); +#define psa_hash_compute(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_size, arg5_hash_length) \ + mbedtls_test_wrap_psa_hash_compute(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_size, arg5_hash_length) + +psa_status_t mbedtls_test_wrap_psa_hash_finish( + psa_hash_operation_t *arg0_operation, + uint8_t *arg1_hash, + size_t arg2_hash_size, + size_t *arg3_hash_length); +#define psa_hash_finish(arg0_operation, arg1_hash, arg2_hash_size, arg3_hash_length) \ + mbedtls_test_wrap_psa_hash_finish(arg0_operation, arg1_hash, arg2_hash_size, arg3_hash_length) + +psa_status_t mbedtls_test_wrap_psa_hash_setup( + psa_hash_operation_t *arg0_operation, + psa_algorithm_t arg1_alg); +#define psa_hash_setup(arg0_operation, arg1_alg) \ + mbedtls_test_wrap_psa_hash_setup(arg0_operation, arg1_alg) + +psa_status_t mbedtls_test_wrap_psa_hash_update( + psa_hash_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length); +#define psa_hash_update(arg0_operation, arg1_input, arg2_input_length) \ + mbedtls_test_wrap_psa_hash_update(arg0_operation, arg1_input, arg2_input_length) + +psa_status_t mbedtls_test_wrap_psa_hash_verify( + psa_hash_operation_t *arg0_operation, + const uint8_t *arg1_hash, + size_t arg2_hash_length); +#define psa_hash_verify(arg0_operation, arg1_hash, arg2_hash_length) \ + mbedtls_test_wrap_psa_hash_verify(arg0_operation, arg1_hash, arg2_hash_length) + +psa_status_t mbedtls_test_wrap_psa_import_key( + const psa_key_attributes_t *arg0_attributes, + const uint8_t *arg1_data, + size_t arg2_data_length, + mbedtls_svc_key_id_t *arg3_key); +#define psa_import_key(arg0_attributes, arg1_data, arg2_data_length, arg3_key) \ + mbedtls_test_wrap_psa_import_key(arg0_attributes, arg1_data, arg2_data_length, arg3_key) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_abort( + psa_key_derivation_operation_t *arg0_operation); +#define psa_key_derivation_abort(arg0_operation) \ + mbedtls_test_wrap_psa_key_derivation_abort(arg0_operation) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_get_capacity( + const psa_key_derivation_operation_t *arg0_operation, + size_t *arg1_capacity); +#define psa_key_derivation_get_capacity(arg0_operation, arg1_capacity) \ + mbedtls_test_wrap_psa_key_derivation_get_capacity(arg0_operation, arg1_capacity) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_input_bytes( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + const uint8_t *arg2_data, + size_t arg3_data_length); +#define psa_key_derivation_input_bytes(arg0_operation, arg1_step, arg2_data, arg3_data_length) \ + mbedtls_test_wrap_psa_key_derivation_input_bytes(arg0_operation, arg1_step, arg2_data, arg3_data_length) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_input_integer( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + uint64_t arg2_value); +#define psa_key_derivation_input_integer(arg0_operation, arg1_step, arg2_value) \ + mbedtls_test_wrap_psa_key_derivation_input_integer(arg0_operation, arg1_step, arg2_value) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_input_key( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + mbedtls_svc_key_id_t arg2_key); +#define psa_key_derivation_input_key(arg0_operation, arg1_step, arg2_key) \ + mbedtls_test_wrap_psa_key_derivation_input_key(arg0_operation, arg1_step, arg2_key) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_key_agreement( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + mbedtls_svc_key_id_t arg2_private_key, + const uint8_t *arg3_peer_key, + size_t arg4_peer_key_length); +#define psa_key_derivation_key_agreement(arg0_operation, arg1_step, arg2_private_key, arg3_peer_key, arg4_peer_key_length) \ + mbedtls_test_wrap_psa_key_derivation_key_agreement(arg0_operation, arg1_step, arg2_private_key, arg3_peer_key, arg4_peer_key_length) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_output_bytes( + psa_key_derivation_operation_t *arg0_operation, + uint8_t *arg1_output, + size_t arg2_output_length); +#define psa_key_derivation_output_bytes(arg0_operation, arg1_output, arg2_output_length) \ + mbedtls_test_wrap_psa_key_derivation_output_bytes(arg0_operation, arg1_output, arg2_output_length) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_output_key( + const psa_key_attributes_t *arg0_attributes, + psa_key_derivation_operation_t *arg1_operation, + mbedtls_svc_key_id_t *arg2_key); +#define psa_key_derivation_output_key(arg0_attributes, arg1_operation, arg2_key) \ + mbedtls_test_wrap_psa_key_derivation_output_key(arg0_attributes, arg1_operation, arg2_key) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_set_capacity( + psa_key_derivation_operation_t *arg0_operation, + size_t arg1_capacity); +#define psa_key_derivation_set_capacity(arg0_operation, arg1_capacity) \ + mbedtls_test_wrap_psa_key_derivation_set_capacity(arg0_operation, arg1_capacity) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_setup( + psa_key_derivation_operation_t *arg0_operation, + psa_algorithm_t arg1_alg); +#define psa_key_derivation_setup(arg0_operation, arg1_alg) \ + mbedtls_test_wrap_psa_key_derivation_setup(arg0_operation, arg1_alg) + +psa_status_t mbedtls_test_wrap_psa_mac_abort( + psa_mac_operation_t *arg0_operation); +#define psa_mac_abort(arg0_operation) \ + mbedtls_test_wrap_psa_mac_abort(arg0_operation) + +psa_status_t mbedtls_test_wrap_psa_mac_compute( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_mac, + size_t arg5_mac_size, + size_t *arg6_mac_length); +#define psa_mac_compute(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_size, arg6_mac_length) \ + mbedtls_test_wrap_psa_mac_compute(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_size, arg6_mac_length) + +psa_status_t mbedtls_test_wrap_psa_mac_sign_finish( + psa_mac_operation_t *arg0_operation, + uint8_t *arg1_mac, + size_t arg2_mac_size, + size_t *arg3_mac_length); +#define psa_mac_sign_finish(arg0_operation, arg1_mac, arg2_mac_size, arg3_mac_length) \ + mbedtls_test_wrap_psa_mac_sign_finish(arg0_operation, arg1_mac, arg2_mac_size, arg3_mac_length) + +psa_status_t mbedtls_test_wrap_psa_mac_sign_setup( + psa_mac_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg); +#define psa_mac_sign_setup(arg0_operation, arg1_key, arg2_alg) \ + mbedtls_test_wrap_psa_mac_sign_setup(arg0_operation, arg1_key, arg2_alg) + +psa_status_t mbedtls_test_wrap_psa_mac_update( + psa_mac_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length); +#define psa_mac_update(arg0_operation, arg1_input, arg2_input_length) \ + mbedtls_test_wrap_psa_mac_update(arg0_operation, arg1_input, arg2_input_length) + +psa_status_t mbedtls_test_wrap_psa_mac_verify( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_mac, + size_t arg5_mac_length); +#define psa_mac_verify(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_length) \ + mbedtls_test_wrap_psa_mac_verify(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_length) + +psa_status_t mbedtls_test_wrap_psa_mac_verify_finish( + psa_mac_operation_t *arg0_operation, + const uint8_t *arg1_mac, + size_t arg2_mac_length); +#define psa_mac_verify_finish(arg0_operation, arg1_mac, arg2_mac_length) \ + mbedtls_test_wrap_psa_mac_verify_finish(arg0_operation, arg1_mac, arg2_mac_length) + +psa_status_t mbedtls_test_wrap_psa_mac_verify_setup( + psa_mac_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg); +#define psa_mac_verify_setup(arg0_operation, arg1_key, arg2_alg) \ + mbedtls_test_wrap_psa_mac_verify_setup(arg0_operation, arg1_key, arg2_alg) + +psa_status_t mbedtls_test_wrap_psa_pake_abort( + psa_pake_operation_t *arg0_operation); +#define psa_pake_abort(arg0_operation) \ + mbedtls_test_wrap_psa_pake_abort(arg0_operation) + +psa_status_t mbedtls_test_wrap_psa_pake_get_implicit_key( + psa_pake_operation_t *arg0_operation, + psa_key_derivation_operation_t *arg1_output); +#define psa_pake_get_implicit_key(arg0_operation, arg1_output) \ + mbedtls_test_wrap_psa_pake_get_implicit_key(arg0_operation, arg1_output) + +psa_status_t mbedtls_test_wrap_psa_pake_input( + psa_pake_operation_t *arg0_operation, + psa_pake_step_t arg1_step, + const uint8_t *arg2_input, + size_t arg3_input_length); +#define psa_pake_input(arg0_operation, arg1_step, arg2_input, arg3_input_length) \ + mbedtls_test_wrap_psa_pake_input(arg0_operation, arg1_step, arg2_input, arg3_input_length) + +psa_status_t mbedtls_test_wrap_psa_pake_output( + psa_pake_operation_t *arg0_operation, + psa_pake_step_t arg1_step, + uint8_t *arg2_output, + size_t arg3_output_size, + size_t *arg4_output_length); +#define psa_pake_output(arg0_operation, arg1_step, arg2_output, arg3_output_size, arg4_output_length) \ + mbedtls_test_wrap_psa_pake_output(arg0_operation, arg1_step, arg2_output, arg3_output_size, arg4_output_length) + +psa_status_t mbedtls_test_wrap_psa_pake_set_password_key( + psa_pake_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_password); +#define psa_pake_set_password_key(arg0_operation, arg1_password) \ + mbedtls_test_wrap_psa_pake_set_password_key(arg0_operation, arg1_password) + +psa_status_t mbedtls_test_wrap_psa_pake_set_peer( + psa_pake_operation_t *arg0_operation, + const uint8_t *arg1_peer_id, + size_t arg2_peer_id_len); +#define psa_pake_set_peer(arg0_operation, arg1_peer_id, arg2_peer_id_len) \ + mbedtls_test_wrap_psa_pake_set_peer(arg0_operation, arg1_peer_id, arg2_peer_id_len) + +psa_status_t mbedtls_test_wrap_psa_pake_set_role( + psa_pake_operation_t *arg0_operation, + psa_pake_role_t arg1_role); +#define psa_pake_set_role(arg0_operation, arg1_role) \ + mbedtls_test_wrap_psa_pake_set_role(arg0_operation, arg1_role) + +psa_status_t mbedtls_test_wrap_psa_pake_set_user( + psa_pake_operation_t *arg0_operation, + const uint8_t *arg1_user_id, + size_t arg2_user_id_len); +#define psa_pake_set_user(arg0_operation, arg1_user_id, arg2_user_id_len) \ + mbedtls_test_wrap_psa_pake_set_user(arg0_operation, arg1_user_id, arg2_user_id_len) + +psa_status_t mbedtls_test_wrap_psa_pake_setup( + psa_pake_operation_t *arg0_operation, + const psa_pake_cipher_suite_t *arg1_cipher_suite); +#define psa_pake_setup(arg0_operation, arg1_cipher_suite) \ + mbedtls_test_wrap_psa_pake_setup(arg0_operation, arg1_cipher_suite) + +psa_status_t mbedtls_test_wrap_psa_purge_key( + mbedtls_svc_key_id_t arg0_key); +#define psa_purge_key(arg0_key) \ + mbedtls_test_wrap_psa_purge_key(arg0_key) + +psa_status_t mbedtls_test_wrap_psa_raw_key_agreement( + psa_algorithm_t arg0_alg, + mbedtls_svc_key_id_t arg1_private_key, + const uint8_t *arg2_peer_key, + size_t arg3_peer_key_length, + uint8_t *arg4_output, + size_t arg5_output_size, + size_t *arg6_output_length); +#define psa_raw_key_agreement(arg0_alg, arg1_private_key, arg2_peer_key, arg3_peer_key_length, arg4_output, arg5_output_size, arg6_output_length) \ + mbedtls_test_wrap_psa_raw_key_agreement(arg0_alg, arg1_private_key, arg2_peer_key, arg3_peer_key_length, arg4_output, arg5_output_size, arg6_output_length) + +psa_status_t mbedtls_test_wrap_psa_sign_hash( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_hash, + size_t arg3_hash_length, + uint8_t *arg4_signature, + size_t arg5_signature_size, + size_t *arg6_signature_length); +#define psa_sign_hash(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_size, arg6_signature_length) \ + mbedtls_test_wrap_psa_sign_hash(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_size, arg6_signature_length) + +psa_status_t mbedtls_test_wrap_psa_sign_hash_abort( + psa_sign_hash_interruptible_operation_t *arg0_operation); +#define psa_sign_hash_abort(arg0_operation) \ + mbedtls_test_wrap_psa_sign_hash_abort(arg0_operation) + +psa_status_t mbedtls_test_wrap_psa_sign_hash_complete( + psa_sign_hash_interruptible_operation_t *arg0_operation, + uint8_t *arg1_signature, + size_t arg2_signature_size, + size_t *arg3_signature_length); +#define psa_sign_hash_complete(arg0_operation, arg1_signature, arg2_signature_size, arg3_signature_length) \ + mbedtls_test_wrap_psa_sign_hash_complete(arg0_operation, arg1_signature, arg2_signature_size, arg3_signature_length) + +psa_status_t mbedtls_test_wrap_psa_sign_hash_start( + psa_sign_hash_interruptible_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg, + const uint8_t *arg3_hash, + size_t arg4_hash_length); +#define psa_sign_hash_start(arg0_operation, arg1_key, arg2_alg, arg3_hash, arg4_hash_length) \ + mbedtls_test_wrap_psa_sign_hash_start(arg0_operation, arg1_key, arg2_alg, arg3_hash, arg4_hash_length) + +psa_status_t mbedtls_test_wrap_psa_sign_message( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_signature, + size_t arg5_signature_size, + size_t *arg6_signature_length); +#define psa_sign_message(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_size, arg6_signature_length) \ + mbedtls_test_wrap_psa_sign_message(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_size, arg6_signature_length) + +psa_status_t mbedtls_test_wrap_psa_verify_hash( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_hash, + size_t arg3_hash_length, + const uint8_t *arg4_signature, + size_t arg5_signature_length); +#define psa_verify_hash(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_length) \ + mbedtls_test_wrap_psa_verify_hash(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_length) + +psa_status_t mbedtls_test_wrap_psa_verify_hash_abort( + psa_verify_hash_interruptible_operation_t *arg0_operation); +#define psa_verify_hash_abort(arg0_operation) \ + mbedtls_test_wrap_psa_verify_hash_abort(arg0_operation) + +psa_status_t mbedtls_test_wrap_psa_verify_hash_complete( + psa_verify_hash_interruptible_operation_t *arg0_operation); +#define psa_verify_hash_complete(arg0_operation) \ + mbedtls_test_wrap_psa_verify_hash_complete(arg0_operation) + +psa_status_t mbedtls_test_wrap_psa_verify_hash_start( + psa_verify_hash_interruptible_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg, + const uint8_t *arg3_hash, + size_t arg4_hash_length, + const uint8_t *arg5_signature, + size_t arg6_signature_length); +#define psa_verify_hash_start(arg0_operation, arg1_key, arg2_alg, arg3_hash, arg4_hash_length, arg5_signature, arg6_signature_length) \ + mbedtls_test_wrap_psa_verify_hash_start(arg0_operation, arg1_key, arg2_alg, arg3_hash, arg4_hash_length, arg5_signature, arg6_signature_length) + +psa_status_t mbedtls_test_wrap_psa_verify_message( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_signature, + size_t arg5_signature_length); +#define psa_verify_message(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_length) \ + mbedtls_test_wrap_psa_verify_message(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_length) + +#endif /* defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) */ + +#ifdef __cplusplus +} +#endif + +#endif /* TEST_PSA_TEST_WRAPPERS_H */ + +/* End of automatically generated file. */ diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c new file mode 100644 index 000000000..f25f1aa9b --- /dev/null +++ b/tests/src/psa_test_wrappers.c @@ -0,0 +1,973 @@ +/* Automatically generated by generate_psa_wrappers.py, do not edit! */ + +/* Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include + +#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) + +#include + +#include +#include + +/* Wrapper for mbedtls_psa_inject_entropy */ +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) +psa_status_t mbedtls_test_wrap_mbedtls_psa_inject_entropy( + const uint8_t *arg0_seed, + size_t arg1_seed_size) +{ + psa_status_t status = (mbedtls_psa_inject_entropy)(arg0_seed, arg1_seed_size); + return status; +} +#endif /* defined(MBEDTLS_PSA_INJECT_ENTROPY) */ + +/* Wrapper for mbedtls_psa_platform_get_builtin_key */ +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) +psa_status_t mbedtls_test_wrap_mbedtls_psa_platform_get_builtin_key( + mbedtls_svc_key_id_t arg0_key_id, + psa_key_lifetime_t *arg1_lifetime, + psa_drv_slot_number_t *arg2_slot_number) +{ + psa_status_t status = (mbedtls_psa_platform_get_builtin_key)(arg0_key_id, arg1_lifetime, arg2_slot_number); + return status; +} +#endif /* defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) */ + +/* Wrapper for mbedtls_psa_register_se_key */ +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) +psa_status_t mbedtls_test_wrap_mbedtls_psa_register_se_key( + const psa_key_attributes_t *arg0_attributes) +{ + psa_status_t status = (mbedtls_psa_register_se_key)(arg0_attributes); + return status; +} +#endif /* defined(MBEDTLS_PSA_CRYPTO_SE_C) */ + +/* Wrapper for psa_aead_abort */ +psa_status_t mbedtls_test_wrap_psa_aead_abort( + psa_aead_operation_t *arg0_operation) +{ + psa_status_t status = (psa_aead_abort)(arg0_operation); + return status; +} + +/* Wrapper for psa_aead_decrypt */ +psa_status_t mbedtls_test_wrap_psa_aead_decrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_nonce, + size_t arg3_nonce_length, + const uint8_t *arg4_additional_data, + size_t arg5_additional_data_length, + const uint8_t *arg6_ciphertext, + size_t arg7_ciphertext_length, + uint8_t *arg8_plaintext, + size_t arg9_plaintext_size, + size_t *arg10_plaintext_length) +{ + psa_status_t status = (psa_aead_decrypt)(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_ciphertext, arg7_ciphertext_length, arg8_plaintext, arg9_plaintext_size, arg10_plaintext_length); + return status; +} + +/* Wrapper for psa_aead_decrypt_setup */ +psa_status_t mbedtls_test_wrap_psa_aead_decrypt_setup( + psa_aead_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg) +{ + psa_status_t status = (psa_aead_decrypt_setup)(arg0_operation, arg1_key, arg2_alg); + return status; +} + +/* Wrapper for psa_aead_encrypt */ +psa_status_t mbedtls_test_wrap_psa_aead_encrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_nonce, + size_t arg3_nonce_length, + const uint8_t *arg4_additional_data, + size_t arg5_additional_data_length, + const uint8_t *arg6_plaintext, + size_t arg7_plaintext_length, + uint8_t *arg8_ciphertext, + size_t arg9_ciphertext_size, + size_t *arg10_ciphertext_length) +{ + psa_status_t status = (psa_aead_encrypt)(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_plaintext, arg7_plaintext_length, arg8_ciphertext, arg9_ciphertext_size, arg10_ciphertext_length); + return status; +} + +/* Wrapper for psa_aead_encrypt_setup */ +psa_status_t mbedtls_test_wrap_psa_aead_encrypt_setup( + psa_aead_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg) +{ + psa_status_t status = (psa_aead_encrypt_setup)(arg0_operation, arg1_key, arg2_alg); + return status; +} + +/* Wrapper for psa_aead_finish */ +psa_status_t mbedtls_test_wrap_psa_aead_finish( + psa_aead_operation_t *arg0_operation, + uint8_t *arg1_ciphertext, + size_t arg2_ciphertext_size, + size_t *arg3_ciphertext_length, + uint8_t *arg4_tag, + size_t arg5_tag_size, + size_t *arg6_tag_length) +{ + psa_status_t status = (psa_aead_finish)(arg0_operation, arg1_ciphertext, arg2_ciphertext_size, arg3_ciphertext_length, arg4_tag, arg5_tag_size, arg6_tag_length); + return status; +} + +/* Wrapper for psa_aead_generate_nonce */ +psa_status_t mbedtls_test_wrap_psa_aead_generate_nonce( + psa_aead_operation_t *arg0_operation, + uint8_t *arg1_nonce, + size_t arg2_nonce_size, + size_t *arg3_nonce_length) +{ + psa_status_t status = (psa_aead_generate_nonce)(arg0_operation, arg1_nonce, arg2_nonce_size, arg3_nonce_length); + return status; +} + +/* Wrapper for psa_aead_set_lengths */ +psa_status_t mbedtls_test_wrap_psa_aead_set_lengths( + psa_aead_operation_t *arg0_operation, + size_t arg1_ad_length, + size_t arg2_plaintext_length) +{ + psa_status_t status = (psa_aead_set_lengths)(arg0_operation, arg1_ad_length, arg2_plaintext_length); + return status; +} + +/* Wrapper for psa_aead_set_nonce */ +psa_status_t mbedtls_test_wrap_psa_aead_set_nonce( + psa_aead_operation_t *arg0_operation, + const uint8_t *arg1_nonce, + size_t arg2_nonce_length) +{ + psa_status_t status = (psa_aead_set_nonce)(arg0_operation, arg1_nonce, arg2_nonce_length); + return status; +} + +/* Wrapper for psa_aead_update */ +psa_status_t mbedtls_test_wrap_psa_aead_update( + psa_aead_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length, + uint8_t *arg3_output, + size_t arg4_output_size, + size_t *arg5_output_length) +{ + psa_status_t status = (psa_aead_update)(arg0_operation, arg1_input, arg2_input_length, arg3_output, arg4_output_size, arg5_output_length); + return status; +} + +/* Wrapper for psa_aead_update_ad */ +psa_status_t mbedtls_test_wrap_psa_aead_update_ad( + psa_aead_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length) +{ + psa_status_t status = (psa_aead_update_ad)(arg0_operation, arg1_input, arg2_input_length); + return status; +} + +/* Wrapper for psa_aead_verify */ +psa_status_t mbedtls_test_wrap_psa_aead_verify( + psa_aead_operation_t *arg0_operation, + uint8_t *arg1_plaintext, + size_t arg2_plaintext_size, + size_t *arg3_plaintext_length, + const uint8_t *arg4_tag, + size_t arg5_tag_length) +{ + psa_status_t status = (psa_aead_verify)(arg0_operation, arg1_plaintext, arg2_plaintext_size, arg3_plaintext_length, arg4_tag, arg5_tag_length); + return status; +} + +/* Wrapper for psa_asymmetric_decrypt */ +psa_status_t mbedtls_test_wrap_psa_asymmetric_decrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_salt, + size_t arg5_salt_length, + uint8_t *arg6_output, + size_t arg7_output_size, + size_t *arg8_output_length) +{ + psa_status_t status = (psa_asymmetric_decrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length); + return status; +} + +/* Wrapper for psa_asymmetric_encrypt */ +psa_status_t mbedtls_test_wrap_psa_asymmetric_encrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_salt, + size_t arg5_salt_length, + uint8_t *arg6_output, + size_t arg7_output_size, + size_t *arg8_output_length) +{ + psa_status_t status = (psa_asymmetric_encrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length); + return status; +} + +/* Wrapper for psa_cipher_abort */ +psa_status_t mbedtls_test_wrap_psa_cipher_abort( + psa_cipher_operation_t *arg0_operation) +{ + psa_status_t status = (psa_cipher_abort)(arg0_operation); + return status; +} + +/* Wrapper for psa_cipher_decrypt */ +psa_status_t mbedtls_test_wrap_psa_cipher_decrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_output, + size_t arg5_output_size, + size_t *arg6_output_length) +{ + psa_status_t status = (psa_cipher_decrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length); + return status; +} + +/* Wrapper for psa_cipher_decrypt_setup */ +psa_status_t mbedtls_test_wrap_psa_cipher_decrypt_setup( + psa_cipher_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg) +{ + psa_status_t status = (psa_cipher_decrypt_setup)(arg0_operation, arg1_key, arg2_alg); + return status; +} + +/* Wrapper for psa_cipher_encrypt */ +psa_status_t mbedtls_test_wrap_psa_cipher_encrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_output, + size_t arg5_output_size, + size_t *arg6_output_length) +{ + psa_status_t status = (psa_cipher_encrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length); + return status; +} + +/* Wrapper for psa_cipher_encrypt_setup */ +psa_status_t mbedtls_test_wrap_psa_cipher_encrypt_setup( + psa_cipher_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg) +{ + psa_status_t status = (psa_cipher_encrypt_setup)(arg0_operation, arg1_key, arg2_alg); + return status; +} + +/* Wrapper for psa_cipher_finish */ +psa_status_t mbedtls_test_wrap_psa_cipher_finish( + psa_cipher_operation_t *arg0_operation, + uint8_t *arg1_output, + size_t arg2_output_size, + size_t *arg3_output_length) +{ + psa_status_t status = (psa_cipher_finish)(arg0_operation, arg1_output, arg2_output_size, arg3_output_length); + return status; +} + +/* Wrapper for psa_cipher_generate_iv */ +psa_status_t mbedtls_test_wrap_psa_cipher_generate_iv( + psa_cipher_operation_t *arg0_operation, + uint8_t *arg1_iv, + size_t arg2_iv_size, + size_t *arg3_iv_length) +{ + psa_status_t status = (psa_cipher_generate_iv)(arg0_operation, arg1_iv, arg2_iv_size, arg3_iv_length); + return status; +} + +/* Wrapper for psa_cipher_set_iv */ +psa_status_t mbedtls_test_wrap_psa_cipher_set_iv( + psa_cipher_operation_t *arg0_operation, + const uint8_t *arg1_iv, + size_t arg2_iv_length) +{ + psa_status_t status = (psa_cipher_set_iv)(arg0_operation, arg1_iv, arg2_iv_length); + return status; +} + +/* Wrapper for psa_cipher_update */ +psa_status_t mbedtls_test_wrap_psa_cipher_update( + psa_cipher_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length, + uint8_t *arg3_output, + size_t arg4_output_size, + size_t *arg5_output_length) +{ + psa_status_t status = (psa_cipher_update)(arg0_operation, arg1_input, arg2_input_length, arg3_output, arg4_output_size, arg5_output_length); + return status; +} + +/* Wrapper for psa_copy_key */ +psa_status_t mbedtls_test_wrap_psa_copy_key( + mbedtls_svc_key_id_t arg0_source_key, + const psa_key_attributes_t *arg1_attributes, + mbedtls_svc_key_id_t *arg2_target_key) +{ + psa_status_t status = (psa_copy_key)(arg0_source_key, arg1_attributes, arg2_target_key); + return status; +} + +/* Wrapper for psa_crypto_driver_pake_get_cipher_suite */ +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_cipher_suite( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + psa_pake_cipher_suite_t *arg1_cipher_suite) +{ + psa_status_t status = (psa_crypto_driver_pake_get_cipher_suite)(arg0_inputs, arg1_cipher_suite); + return status; +} + +/* Wrapper for psa_crypto_driver_pake_get_password */ +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_password( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + uint8_t *arg1_buffer, + size_t arg2_buffer_size, + size_t *arg3_buffer_length) +{ + psa_status_t status = (psa_crypto_driver_pake_get_password)(arg0_inputs, arg1_buffer, arg2_buffer_size, arg3_buffer_length); + return status; +} + +/* Wrapper for psa_crypto_driver_pake_get_password_len */ +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_password_len( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + size_t *arg1_password_len) +{ + psa_status_t status = (psa_crypto_driver_pake_get_password_len)(arg0_inputs, arg1_password_len); + return status; +} + +/* Wrapper for psa_crypto_driver_pake_get_peer */ +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_peer( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + uint8_t *arg1_peer_id, + size_t arg2_peer_id_size, + size_t *arg3_peer_id_length) +{ + psa_status_t status = (psa_crypto_driver_pake_get_peer)(arg0_inputs, arg1_peer_id, arg2_peer_id_size, arg3_peer_id_length); + return status; +} + +/* Wrapper for psa_crypto_driver_pake_get_peer_len */ +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_peer_len( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + size_t *arg1_peer_len) +{ + psa_status_t status = (psa_crypto_driver_pake_get_peer_len)(arg0_inputs, arg1_peer_len); + return status; +} + +/* Wrapper for psa_crypto_driver_pake_get_user */ +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_user( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + uint8_t *arg1_user_id, + size_t arg2_user_id_size, + size_t *arg3_user_id_len) +{ + psa_status_t status = (psa_crypto_driver_pake_get_user)(arg0_inputs, arg1_user_id, arg2_user_id_size, arg3_user_id_len); + return status; +} + +/* Wrapper for psa_crypto_driver_pake_get_user_len */ +psa_status_t mbedtls_test_wrap_psa_crypto_driver_pake_get_user_len( + const psa_crypto_driver_pake_inputs_t *arg0_inputs, + size_t *arg1_user_len) +{ + psa_status_t status = (psa_crypto_driver_pake_get_user_len)(arg0_inputs, arg1_user_len); + return status; +} + +/* Wrapper for psa_crypto_init */ +psa_status_t mbedtls_test_wrap_psa_crypto_init(void) +{ + psa_status_t status = (psa_crypto_init)(); + return status; +} + +/* Wrapper for psa_destroy_key */ +psa_status_t mbedtls_test_wrap_psa_destroy_key( + mbedtls_svc_key_id_t arg0_key) +{ + psa_status_t status = (psa_destroy_key)(arg0_key); + return status; +} + +/* Wrapper for psa_export_key */ +psa_status_t mbedtls_test_wrap_psa_export_key( + mbedtls_svc_key_id_t arg0_key, + uint8_t *arg1_data, + size_t arg2_data_size, + size_t *arg3_data_length) +{ + psa_status_t status = (psa_export_key)(arg0_key, arg1_data, arg2_data_size, arg3_data_length); + return status; +} + +/* Wrapper for psa_export_public_key */ +psa_status_t mbedtls_test_wrap_psa_export_public_key( + mbedtls_svc_key_id_t arg0_key, + uint8_t *arg1_data, + size_t arg2_data_size, + size_t *arg3_data_length) +{ + psa_status_t status = (psa_export_public_key)(arg0_key, arg1_data, arg2_data_size, arg3_data_length); + return status; +} + +/* Wrapper for psa_generate_key */ +psa_status_t mbedtls_test_wrap_psa_generate_key( + const psa_key_attributes_t *arg0_attributes, + mbedtls_svc_key_id_t *arg1_key) +{ + psa_status_t status = (psa_generate_key)(arg0_attributes, arg1_key); + return status; +} + +/* Wrapper for psa_generate_random */ +psa_status_t mbedtls_test_wrap_psa_generate_random( + uint8_t *arg0_output, + size_t arg1_output_size) +{ + psa_status_t status = (psa_generate_random)(arg0_output, arg1_output_size); + return status; +} + +/* Wrapper for psa_get_key_attributes */ +psa_status_t mbedtls_test_wrap_psa_get_key_attributes( + mbedtls_svc_key_id_t arg0_key, + psa_key_attributes_t *arg1_attributes) +{ + psa_status_t status = (psa_get_key_attributes)(arg0_key, arg1_attributes); + return status; +} + +/* Wrapper for psa_hash_abort */ +psa_status_t mbedtls_test_wrap_psa_hash_abort( + psa_hash_operation_t *arg0_operation) +{ + psa_status_t status = (psa_hash_abort)(arg0_operation); + return status; +} + +/* Wrapper for psa_hash_clone */ +psa_status_t mbedtls_test_wrap_psa_hash_clone( + const psa_hash_operation_t *arg0_source_operation, + psa_hash_operation_t *arg1_target_operation) +{ + psa_status_t status = (psa_hash_clone)(arg0_source_operation, arg1_target_operation); + return status; +} + +/* Wrapper for psa_hash_compare */ +psa_status_t mbedtls_test_wrap_psa_hash_compare( + psa_algorithm_t arg0_alg, + const uint8_t *arg1_input, + size_t arg2_input_length, + const uint8_t *arg3_hash, + size_t arg4_hash_length) +{ + psa_status_t status = (psa_hash_compare)(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_length); + return status; +} + +/* Wrapper for psa_hash_compute */ +psa_status_t mbedtls_test_wrap_psa_hash_compute( + psa_algorithm_t arg0_alg, + const uint8_t *arg1_input, + size_t arg2_input_length, + uint8_t *arg3_hash, + size_t arg4_hash_size, + size_t *arg5_hash_length) +{ + psa_status_t status = (psa_hash_compute)(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_size, arg5_hash_length); + return status; +} + +/* Wrapper for psa_hash_finish */ +psa_status_t mbedtls_test_wrap_psa_hash_finish( + psa_hash_operation_t *arg0_operation, + uint8_t *arg1_hash, + size_t arg2_hash_size, + size_t *arg3_hash_length) +{ + psa_status_t status = (psa_hash_finish)(arg0_operation, arg1_hash, arg2_hash_size, arg3_hash_length); + return status; +} + +/* Wrapper for psa_hash_setup */ +psa_status_t mbedtls_test_wrap_psa_hash_setup( + psa_hash_operation_t *arg0_operation, + psa_algorithm_t arg1_alg) +{ + psa_status_t status = (psa_hash_setup)(arg0_operation, arg1_alg); + return status; +} + +/* Wrapper for psa_hash_update */ +psa_status_t mbedtls_test_wrap_psa_hash_update( + psa_hash_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length) +{ + psa_status_t status = (psa_hash_update)(arg0_operation, arg1_input, arg2_input_length); + return status; +} + +/* Wrapper for psa_hash_verify */ +psa_status_t mbedtls_test_wrap_psa_hash_verify( + psa_hash_operation_t *arg0_operation, + const uint8_t *arg1_hash, + size_t arg2_hash_length) +{ + psa_status_t status = (psa_hash_verify)(arg0_operation, arg1_hash, arg2_hash_length); + return status; +} + +/* Wrapper for psa_import_key */ +psa_status_t mbedtls_test_wrap_psa_import_key( + const psa_key_attributes_t *arg0_attributes, + const uint8_t *arg1_data, + size_t arg2_data_length, + mbedtls_svc_key_id_t *arg3_key) +{ + psa_status_t status = (psa_import_key)(arg0_attributes, arg1_data, arg2_data_length, arg3_key); + return status; +} + +/* Wrapper for psa_key_derivation_abort */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_abort( + psa_key_derivation_operation_t *arg0_operation) +{ + psa_status_t status = (psa_key_derivation_abort)(arg0_operation); + return status; +} + +/* Wrapper for psa_key_derivation_get_capacity */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_get_capacity( + const psa_key_derivation_operation_t *arg0_operation, + size_t *arg1_capacity) +{ + psa_status_t status = (psa_key_derivation_get_capacity)(arg0_operation, arg1_capacity); + return status; +} + +/* Wrapper for psa_key_derivation_input_bytes */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_input_bytes( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + const uint8_t *arg2_data, + size_t arg3_data_length) +{ + psa_status_t status = (psa_key_derivation_input_bytes)(arg0_operation, arg1_step, arg2_data, arg3_data_length); + return status; +} + +/* Wrapper for psa_key_derivation_input_integer */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_input_integer( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + uint64_t arg2_value) +{ + psa_status_t status = (psa_key_derivation_input_integer)(arg0_operation, arg1_step, arg2_value); + return status; +} + +/* Wrapper for psa_key_derivation_input_key */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_input_key( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + mbedtls_svc_key_id_t arg2_key) +{ + psa_status_t status = (psa_key_derivation_input_key)(arg0_operation, arg1_step, arg2_key); + return status; +} + +/* Wrapper for psa_key_derivation_key_agreement */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_key_agreement( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + mbedtls_svc_key_id_t arg2_private_key, + const uint8_t *arg3_peer_key, + size_t arg4_peer_key_length) +{ + psa_status_t status = (psa_key_derivation_key_agreement)(arg0_operation, arg1_step, arg2_private_key, arg3_peer_key, arg4_peer_key_length); + return status; +} + +/* Wrapper for psa_key_derivation_output_bytes */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_output_bytes( + psa_key_derivation_operation_t *arg0_operation, + uint8_t *arg1_output, + size_t arg2_output_length) +{ + psa_status_t status = (psa_key_derivation_output_bytes)(arg0_operation, arg1_output, arg2_output_length); + return status; +} + +/* Wrapper for psa_key_derivation_output_key */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_output_key( + const psa_key_attributes_t *arg0_attributes, + psa_key_derivation_operation_t *arg1_operation, + mbedtls_svc_key_id_t *arg2_key) +{ + psa_status_t status = (psa_key_derivation_output_key)(arg0_attributes, arg1_operation, arg2_key); + return status; +} + +/* Wrapper for psa_key_derivation_set_capacity */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_set_capacity( + psa_key_derivation_operation_t *arg0_operation, + size_t arg1_capacity) +{ + psa_status_t status = (psa_key_derivation_set_capacity)(arg0_operation, arg1_capacity); + return status; +} + +/* Wrapper for psa_key_derivation_setup */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_setup( + psa_key_derivation_operation_t *arg0_operation, + psa_algorithm_t arg1_alg) +{ + psa_status_t status = (psa_key_derivation_setup)(arg0_operation, arg1_alg); + return status; +} + +/* Wrapper for psa_mac_abort */ +psa_status_t mbedtls_test_wrap_psa_mac_abort( + psa_mac_operation_t *arg0_operation) +{ + psa_status_t status = (psa_mac_abort)(arg0_operation); + return status; +} + +/* Wrapper for psa_mac_compute */ +psa_status_t mbedtls_test_wrap_psa_mac_compute( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_mac, + size_t arg5_mac_size, + size_t *arg6_mac_length) +{ + psa_status_t status = (psa_mac_compute)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_size, arg6_mac_length); + return status; +} + +/* Wrapper for psa_mac_sign_finish */ +psa_status_t mbedtls_test_wrap_psa_mac_sign_finish( + psa_mac_operation_t *arg0_operation, + uint8_t *arg1_mac, + size_t arg2_mac_size, + size_t *arg3_mac_length) +{ + psa_status_t status = (psa_mac_sign_finish)(arg0_operation, arg1_mac, arg2_mac_size, arg3_mac_length); + return status; +} + +/* Wrapper for psa_mac_sign_setup */ +psa_status_t mbedtls_test_wrap_psa_mac_sign_setup( + psa_mac_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg) +{ + psa_status_t status = (psa_mac_sign_setup)(arg0_operation, arg1_key, arg2_alg); + return status; +} + +/* Wrapper for psa_mac_update */ +psa_status_t mbedtls_test_wrap_psa_mac_update( + psa_mac_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length) +{ + psa_status_t status = (psa_mac_update)(arg0_operation, arg1_input, arg2_input_length); + return status; +} + +/* Wrapper for psa_mac_verify */ +psa_status_t mbedtls_test_wrap_psa_mac_verify( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_mac, + size_t arg5_mac_length) +{ + psa_status_t status = (psa_mac_verify)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_length); + return status; +} + +/* Wrapper for psa_mac_verify_finish */ +psa_status_t mbedtls_test_wrap_psa_mac_verify_finish( + psa_mac_operation_t *arg0_operation, + const uint8_t *arg1_mac, + size_t arg2_mac_length) +{ + psa_status_t status = (psa_mac_verify_finish)(arg0_operation, arg1_mac, arg2_mac_length); + return status; +} + +/* Wrapper for psa_mac_verify_setup */ +psa_status_t mbedtls_test_wrap_psa_mac_verify_setup( + psa_mac_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg) +{ + psa_status_t status = (psa_mac_verify_setup)(arg0_operation, arg1_key, arg2_alg); + return status; +} + +/* Wrapper for psa_pake_abort */ +psa_status_t mbedtls_test_wrap_psa_pake_abort( + psa_pake_operation_t *arg0_operation) +{ + psa_status_t status = (psa_pake_abort)(arg0_operation); + return status; +} + +/* Wrapper for psa_pake_get_implicit_key */ +psa_status_t mbedtls_test_wrap_psa_pake_get_implicit_key( + psa_pake_operation_t *arg0_operation, + psa_key_derivation_operation_t *arg1_output) +{ + psa_status_t status = (psa_pake_get_implicit_key)(arg0_operation, arg1_output); + return status; +} + +/* Wrapper for psa_pake_input */ +psa_status_t mbedtls_test_wrap_psa_pake_input( + psa_pake_operation_t *arg0_operation, + psa_pake_step_t arg1_step, + const uint8_t *arg2_input, + size_t arg3_input_length) +{ + psa_status_t status = (psa_pake_input)(arg0_operation, arg1_step, arg2_input, arg3_input_length); + return status; +} + +/* Wrapper for psa_pake_output */ +psa_status_t mbedtls_test_wrap_psa_pake_output( + psa_pake_operation_t *arg0_operation, + psa_pake_step_t arg1_step, + uint8_t *arg2_output, + size_t arg3_output_size, + size_t *arg4_output_length) +{ + psa_status_t status = (psa_pake_output)(arg0_operation, arg1_step, arg2_output, arg3_output_size, arg4_output_length); + return status; +} + +/* Wrapper for psa_pake_set_password_key */ +psa_status_t mbedtls_test_wrap_psa_pake_set_password_key( + psa_pake_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_password) +{ + psa_status_t status = (psa_pake_set_password_key)(arg0_operation, arg1_password); + return status; +} + +/* Wrapper for psa_pake_set_peer */ +psa_status_t mbedtls_test_wrap_psa_pake_set_peer( + psa_pake_operation_t *arg0_operation, + const uint8_t *arg1_peer_id, + size_t arg2_peer_id_len) +{ + psa_status_t status = (psa_pake_set_peer)(arg0_operation, arg1_peer_id, arg2_peer_id_len); + return status; +} + +/* Wrapper for psa_pake_set_role */ +psa_status_t mbedtls_test_wrap_psa_pake_set_role( + psa_pake_operation_t *arg0_operation, + psa_pake_role_t arg1_role) +{ + psa_status_t status = (psa_pake_set_role)(arg0_operation, arg1_role); + return status; +} + +/* Wrapper for psa_pake_set_user */ +psa_status_t mbedtls_test_wrap_psa_pake_set_user( + psa_pake_operation_t *arg0_operation, + const uint8_t *arg1_user_id, + size_t arg2_user_id_len) +{ + psa_status_t status = (psa_pake_set_user)(arg0_operation, arg1_user_id, arg2_user_id_len); + return status; +} + +/* Wrapper for psa_pake_setup */ +psa_status_t mbedtls_test_wrap_psa_pake_setup( + psa_pake_operation_t *arg0_operation, + const psa_pake_cipher_suite_t *arg1_cipher_suite) +{ + psa_status_t status = (psa_pake_setup)(arg0_operation, arg1_cipher_suite); + return status; +} + +/* Wrapper for psa_purge_key */ +psa_status_t mbedtls_test_wrap_psa_purge_key( + mbedtls_svc_key_id_t arg0_key) +{ + psa_status_t status = (psa_purge_key)(arg0_key); + return status; +} + +/* Wrapper for psa_raw_key_agreement */ +psa_status_t mbedtls_test_wrap_psa_raw_key_agreement( + psa_algorithm_t arg0_alg, + mbedtls_svc_key_id_t arg1_private_key, + const uint8_t *arg2_peer_key, + size_t arg3_peer_key_length, + uint8_t *arg4_output, + size_t arg5_output_size, + size_t *arg6_output_length) +{ + psa_status_t status = (psa_raw_key_agreement)(arg0_alg, arg1_private_key, arg2_peer_key, arg3_peer_key_length, arg4_output, arg5_output_size, arg6_output_length); + return status; +} + +/* Wrapper for psa_sign_hash */ +psa_status_t mbedtls_test_wrap_psa_sign_hash( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_hash, + size_t arg3_hash_length, + uint8_t *arg4_signature, + size_t arg5_signature_size, + size_t *arg6_signature_length) +{ + psa_status_t status = (psa_sign_hash)(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_size, arg6_signature_length); + return status; +} + +/* Wrapper for psa_sign_hash_abort */ +psa_status_t mbedtls_test_wrap_psa_sign_hash_abort( + psa_sign_hash_interruptible_operation_t *arg0_operation) +{ + psa_status_t status = (psa_sign_hash_abort)(arg0_operation); + return status; +} + +/* Wrapper for psa_sign_hash_complete */ +psa_status_t mbedtls_test_wrap_psa_sign_hash_complete( + psa_sign_hash_interruptible_operation_t *arg0_operation, + uint8_t *arg1_signature, + size_t arg2_signature_size, + size_t *arg3_signature_length) +{ + psa_status_t status = (psa_sign_hash_complete)(arg0_operation, arg1_signature, arg2_signature_size, arg3_signature_length); + return status; +} + +/* Wrapper for psa_sign_hash_start */ +psa_status_t mbedtls_test_wrap_psa_sign_hash_start( + psa_sign_hash_interruptible_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg, + const uint8_t *arg3_hash, + size_t arg4_hash_length) +{ + psa_status_t status = (psa_sign_hash_start)(arg0_operation, arg1_key, arg2_alg, arg3_hash, arg4_hash_length); + return status; +} + +/* Wrapper for psa_sign_message */ +psa_status_t mbedtls_test_wrap_psa_sign_message( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_signature, + size_t arg5_signature_size, + size_t *arg6_signature_length) +{ + psa_status_t status = (psa_sign_message)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_size, arg6_signature_length); + return status; +} + +/* Wrapper for psa_verify_hash */ +psa_status_t mbedtls_test_wrap_psa_verify_hash( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_hash, + size_t arg3_hash_length, + const uint8_t *arg4_signature, + size_t arg5_signature_length) +{ + psa_status_t status = (psa_verify_hash)(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_length); + return status; +} + +/* Wrapper for psa_verify_hash_abort */ +psa_status_t mbedtls_test_wrap_psa_verify_hash_abort( + psa_verify_hash_interruptible_operation_t *arg0_operation) +{ + psa_status_t status = (psa_verify_hash_abort)(arg0_operation); + return status; +} + +/* Wrapper for psa_verify_hash_complete */ +psa_status_t mbedtls_test_wrap_psa_verify_hash_complete( + psa_verify_hash_interruptible_operation_t *arg0_operation) +{ + psa_status_t status = (psa_verify_hash_complete)(arg0_operation); + return status; +} + +/* Wrapper for psa_verify_hash_start */ +psa_status_t mbedtls_test_wrap_psa_verify_hash_start( + psa_verify_hash_interruptible_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg, + const uint8_t *arg3_hash, + size_t arg4_hash_length, + const uint8_t *arg5_signature, + size_t arg6_signature_length) +{ + psa_status_t status = (psa_verify_hash_start)(arg0_operation, arg1_key, arg2_alg, arg3_hash, arg4_hash_length, arg5_signature, arg6_signature_length); + return status; +} + +/* Wrapper for psa_verify_message */ +psa_status_t mbedtls_test_wrap_psa_verify_message( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_signature, + size_t arg5_signature_length) +{ + psa_status_t status = (psa_verify_message)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_length); + return status; +} + +#endif /* defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) */ + +/* End of automatically generated file. */ From e00150df4a364ba7243b0842acd35602ef77eb13 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 16:46:00 +0100 Subject: [PATCH 06/14] Declare the outputs from generate_psa_wrappers.py as generated files Signed-off-by: Gilles Peskine --- tests/scripts/check-generated-files.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/scripts/check-generated-files.sh b/tests/scripts/check-generated-files.sh index 67dedeb26..0a1c47748 100755 --- a/tests/scripts/check-generated-files.sh +++ b/tests/scripts/check-generated-files.sh @@ -127,3 +127,8 @@ check scripts/generate_psa_constants.py programs/psa/psa_constant_names_generate check tests/scripts/generate_bignum_tests.py $(tests/scripts/generate_bignum_tests.py --list) check tests/scripts/generate_ecp_tests.py $(tests/scripts/generate_ecp_tests.py --list) check tests/scripts/generate_psa_tests.py $(tests/scripts/generate_psa_tests.py --list) + +# Generated files that are present in the repository even in the development +# branch. (This is intended to be temporary, until the generator scripts are +# fully reviewed and the build scripts support a generated header file.) +check tests/scripts/generate_psa_wrappers.py tests/include/test/psa_test_wrappers.h tests/src/psa_test_wrappers.c From 2b106dec8be1b56db1e06934fc2af6c1d5ea7963 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 16:44:16 +0100 Subject: [PATCH 07/14] Enable generated PSA wrappers Code in unit tests (`tests/suites/*.function`) and in test support code (`tests/src/**.c`) will now go through the wrapper functions when they call a PSA API function and `MBEDTLS_TEST_HOOKS` is enabled. Signed-off-by: Gilles Peskine --- tests/include/test/psa_crypto_helpers.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h index 41b7752be..96a8c1c82 100644 --- a/tests/include/test/psa_crypto_helpers.h +++ b/tests/include/test/psa_crypto_helpers.h @@ -16,6 +16,8 @@ #include #endif +#include "test/psa_test_wrappers.h" + #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \ && defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) #include "test/psa_memory_poisoning_wrappers.h" From 4adacac142e42fb0e418a524e84f1e13f58914d0 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 6 Dec 2023 19:32:52 +0100 Subject: [PATCH 08/14] Generated PSA wrappers: poison/unpoison buffer parameters For now, only instrument the one function for which buffer copying has been implemented, namely `psa_cipher_encrypt`. Signed-off-by: Gilles Peskine --- tests/scripts/generate_psa_wrappers.py | 78 +++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 9bb6eb758..3fa4135cb 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -6,8 +6,9 @@ # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later import argparse +import itertools import os -from typing import List, Tuple +from typing import Iterator, List, Optional, Tuple import scripts_path #pylint: disable=unused-import from mbedtls_dev import build_tree @@ -16,6 +17,27 @@ from mbedtls_dev import c_wrapper_generator from mbedtls_dev import typing_util +class BufferParameter: + """Description of an input or output buffer parameter sequence to a PSA function.""" + #pylint: disable=too-few-public-methods + + def __init__(self, i: int, is_output: bool, + buffer_name: str, size_name: str) -> None: + """Initialize the parameter information. + + i is the index of the function argument that is the pointer to the buffer. + The size is argument i+1. For a variable-size output, the actual length + goes in argument i+2. + + buffer_name and size_names are the names of arguments i and i+1. + This class does not yet help with the output length. + """ + self.index = i + self.buffer_name = buffer_name + self.size_name = size_name + self.is_output = is_output + + class PSAWrapperGenerator(c_wrapper_generator.Base): """Generate a C source file containing wrapper functions for PSA Crypto API calls.""" @@ -67,6 +89,59 @@ class PSAWrapperGenerator(c_wrapper_generator.Base): 'mbedtls_psa_platform_get_builtin_key': 'defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)', }) + @staticmethod + def _detect_buffer_parameters(arguments: List[c_parsing_helper.ArgumentInfo], + argument_names: List[str]) -> Iterator[BufferParameter]: + """Detect function arguments that are buffers (pointer, size [,length]).""" + types = ['' if arg.suffix else arg.type for arg in arguments] + # pairs = list of (type_of_arg_N, type_of_arg_N+1) + # where each type_of_arg_X is the empty string if the type is an array + # or there is no argument X. + pairs = enumerate(itertools.zip_longest(types, types[1:], fillvalue='')) + for i, t01 in pairs: + if (t01[0] == 'const uint8_t *' or t01[0] == 'uint8_t *') and \ + t01[1] == 'size_t': + yield BufferParameter(i, not t01[0].startswith('const '), + argument_names[i], argument_names[i+1]) + + @staticmethod + def _write_poison_buffer_parameter(out: typing_util.Writable, + param: BufferParameter, + poison: bool) -> None: + """Write poisoning or unpoisoning code for a buffer parameter. + + Write poisoning code if poison is true, unpoisoning code otherwise. + """ + out.write(' MBEDTLS_TEST_MEMORY_{}({}, {});\n'.format( + 'POISON' if poison else 'UNPOISON', + param.buffer_name, param.size_name + )) + + @staticmethod + def _parameter_should_be_copied(function_name: str, + _buffer_name: Optional[str]) -> bool: + """Whether the specified buffer argument to a PSA function should be copied. + """ + # Proof-of-concept: just instrument one function for now + if function_name == 'psa_cipher_encrypt': + return True + return False + + def _write_function_call(self, out: typing_util.Writable, + function: c_wrapper_generator.FunctionInfo, + argument_names: List[str]) -> None: + buffer_parameters = list( + param + for param in self._detect_buffer_parameters(function.arguments, + argument_names) + if self._parameter_should_be_copied(function.name, + function.arguments[param.index].name)) + for param in buffer_parameters: + self._write_poison_buffer_parameter(out, param, True) + super()._write_function_call(out, function, argument_names) + for param in buffer_parameters: + self._write_poison_buffer_parameter(out, param, False) + def _write_prologue(self, out: typing_util.Writable, header: bool) -> None: super()._write_prologue(out, header) out.write(""" @@ -74,6 +149,7 @@ class PSAWrapperGenerator(c_wrapper_generator.Base): #include +#include #include #include """ From 90d14d7fc28b939e908148d580514eda84d041fd Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 16:59:28 +0100 Subject: [PATCH 09/14] Update generated PSA wrappers Signed-off-by: Gilles Peskine --- tests/include/test/psa_test_wrappers.h | 1 + tests/src/psa_test_wrappers.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/tests/include/test/psa_test_wrappers.h b/tests/include/test/psa_test_wrappers.h index 18417800c..bd673b80b 100644 --- a/tests/include/test/psa_test_wrappers.h +++ b/tests/include/test/psa_test_wrappers.h @@ -17,6 +17,7 @@ extern "C" { #include +#include #include #include diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index f25f1aa9b..c26835fbf 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -10,6 +10,7 @@ #include +#include #include #include @@ -265,7 +266,11 @@ psa_status_t mbedtls_test_wrap_psa_cipher_encrypt( size_t arg5_output_size, size_t *arg6_output_length) { + MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_output, arg5_output_size); psa_status_t status = (psa_cipher_encrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_output, arg5_output_size); return status; } From 8e7960b685336eba7794f00fd86edd1566263042 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 17:11:54 +0100 Subject: [PATCH 10/14] Remove the manually written poisoning wrapper This fixes the build with ASan + MBEDTLS_TEST_HOOKS. Signed-off-by: Gilles Peskine --- .../test/psa_memory_poisoning_wrappers.h | 17 +++++--------- tests/src/psa_memory_poisoning_wrappers.c | 22 ------------------- 2 files changed, 5 insertions(+), 34 deletions(-) diff --git a/tests/include/test/psa_memory_poisoning_wrappers.h b/tests/include/test/psa_memory_poisoning_wrappers.h index 0052c2fae..3f30b65c0 100644 --- a/tests/include/test/psa_memory_poisoning_wrappers.h +++ b/tests/include/test/psa_memory_poisoning_wrappers.h @@ -1,8 +1,11 @@ -/** Memory poisoning wrappers for PSA functions. +/** Support for memory poisoning wrappers for PSA functions. * - * These wrappers poison the input and output buffers of each function + * The wrappers poison the input and output buffers of each function * before calling it, to ensure that it does not access the buffers * except by calling the approved buffer-copying functions. + * + * This header declares support functions. The wrappers themselves are + * decalred in the automatically generated file `test/psa_test_wrappers.h`. */ /* * Copyright The Mbed TLS Contributors @@ -32,16 +35,6 @@ void mbedtls_poison_test_hooks_setup(void); */ void mbedtls_poison_test_hooks_teardown(void); -psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -#define psa_cipher_encrypt(...) wrap_psa_cipher_encrypt(__VA_ARGS__) - #endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_TEST_MEMORY_CAN_POISON */ #endif /* PSA_MEMORY_POISONING_WRAPPERS_H */ diff --git a/tests/src/psa_memory_poisoning_wrappers.c b/tests/src/psa_memory_poisoning_wrappers.c index a53e875d4..05cba18ee 100644 --- a/tests/src/psa_memory_poisoning_wrappers.c +++ b/tests/src/psa_memory_poisoning_wrappers.c @@ -27,27 +27,5 @@ void mbedtls_poison_test_hooks_teardown(void) psa_output_post_copy_hook = NULL; } -psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length) -{ - MBEDTLS_TEST_MEMORY_POISON(input, input_length); - MBEDTLS_TEST_MEMORY_POISON(output, output_size); - psa_status_t status = psa_cipher_encrypt(key, - alg, - input, - input_length, - output, - output_size, - output_length); - MBEDTLS_TEST_MEMORY_UNPOISON(input, input_length); - MBEDTLS_TEST_MEMORY_UNPOISON(output, output_size); - return status; -} - #endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_PSA_CRYPTO_C && MBEDTLS_TEST_MEMORY_CAN_POISON */ From a1871f318bb4c4a36672f78159dacd0e917344b3 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 17:28:59 +0100 Subject: [PATCH 11/14] Add review exception warning Signed-off-by: Gilles Peskine --- scripts/mbedtls_dev/c_parsing_helper.py | 4 ++++ scripts/mbedtls_dev/c_wrapper_generator.py | 4 ++++ tests/scripts/generate_psa_wrappers.py | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/scripts/mbedtls_dev/c_parsing_helper.py b/scripts/mbedtls_dev/c_parsing_helper.py index 3bb6f0405..72214d51c 100644 --- a/scripts/mbedtls_dev/c_parsing_helper.py +++ b/scripts/mbedtls_dev/c_parsing_helper.py @@ -8,6 +8,10 @@ Currently supported functionality: # Copyright The Mbed TLS Contributors # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +### WARNING: the code in this file has not been extensively reviewed yet. +### We do not think it is harmful, but it may be below our normal standards +### for robustness and maintainability. + import re from typing import Dict, Iterable, Iterator, List, Optional, Tuple diff --git a/scripts/mbedtls_dev/c_wrapper_generator.py b/scripts/mbedtls_dev/c_wrapper_generator.py index de99ddb9a..3cf1e05eb 100644 --- a/scripts/mbedtls_dev/c_wrapper_generator.py +++ b/scripts/mbedtls_dev/c_wrapper_generator.py @@ -4,6 +4,10 @@ # Copyright The Mbed TLS Contributors # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +### WARNING: the code in this file has not been extensively reviewed yet. +### We do not think it is harmful, but it may be below our normal standards +### for robustness and maintainability. + import os import re import sys diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 3fa4135cb..551acbd23 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -5,6 +5,10 @@ # Copyright The Mbed TLS Contributors # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +### WARNING: the code in this file has not been extensively reviewed yet. +### We do not think it is harmful, but it may be below our normal standards +### for robustness and maintainability. + import argparse import itertools import os From 88385c2f74d46c26abb10e5d80ec16d7a257aefa Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 20:33:29 +0100 Subject: [PATCH 12/14] PSA wrappers: don't poison buffers when buffer copying is disabled Signed-off-by: Gilles Peskine --- tests/scripts/generate_psa_wrappers.py | 20 ++++++++++++++++---- tests/src/psa_test_wrappers.c | 4 ++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 551acbd23..85c927855 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -121,6 +121,20 @@ class PSAWrapperGenerator(c_wrapper_generator.Base): param.buffer_name, param.size_name )) + def _write_poison_buffer_parameters(self, out: typing_util.Writable, + buffer_parameters: List[BufferParameter], + poison: bool) -> None: + """Write poisoning or unpoisoning code for the buffer parameters. + + Write poisoning code if poison is true, unpoisoning code otherwise. + """ + if not buffer_parameters: + return + out.write('#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS)\n') + for param in buffer_parameters: + self._write_poison_buffer_parameter(out, param, poison) + out.write('#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */\n') + @staticmethod def _parameter_should_be_copied(function_name: str, _buffer_name: Optional[str]) -> bool: @@ -140,11 +154,9 @@ class PSAWrapperGenerator(c_wrapper_generator.Base): argument_names) if self._parameter_should_be_copied(function.name, function.arguments[param.index].name)) - for param in buffer_parameters: - self._write_poison_buffer_parameter(out, param, True) + self._write_poison_buffer_parameters(out, buffer_parameters, True) super()._write_function_call(out, function, argument_names) - for param in buffer_parameters: - self._write_poison_buffer_parameter(out, param, False) + self._write_poison_buffer_parameters(out, buffer_parameters, False) def _write_prologue(self, out: typing_util.Writable, header: bool) -> None: super()._write_prologue(out, header) diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index c26835fbf..f3fb852e1 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -266,11 +266,15 @@ psa_status_t mbedtls_test_wrap_psa_cipher_encrypt( size_t arg5_output_size, size_t *arg6_output_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_POISON(arg4_output, arg5_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_cipher_encrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_output, arg5_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From 4411c9c1f8d3c0fb5ca7b743c9eb032c3f97370d Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 20:51:38 +0100 Subject: [PATCH 13/14] Disable PSA wrappers psa_collect_statuses builds `psa_collect_statuses.py` runs `make RECORD_PSA_STATUS_COVERAGE_LOG=1`, which builds with `RECORD_PSA_STATUS_COVERAGE_LOG`. In this mode, the build includes wrappers for PSA functions, which conflict with the newly introduced wrappers that are enabled whenever `MBEDTLS_TEST_HOOKS` is enabled. In the future, the collect-statuses mechanism should use the new generic wrapper mechanism. For the time being, keep the old wrappers and avoid the new wrappers when doing the collect-statuses build. Signed-off-by: Gilles Peskine --- programs/Makefile | 4 ++++ tests/include/test/psa_test_wrappers.h | 6 ++++-- tests/scripts/generate_psa_wrappers.py | 4 +++- tests/src/psa_test_wrappers.c | 6 ++++-- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/programs/Makefile b/programs/Makefile index a3fa81679..c16199208 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -26,6 +26,10 @@ endif include ../3rdparty/Makefile.inc LOCAL_CFLAGS+=$(THIRDPARTY_INCLUDES) +ifdef RECORD_PSA_STATUS_COVERAGE_LOG +LOCAL_CFLAGS += -Werror -DRECORD_PSA_STATUS_COVERAGE_LOG +endif + ifndef SHARED MBEDLIBS=../library/libmbedcrypto.a ../library/libmbedx509.a ../library/libmbedtls.a else diff --git a/tests/include/test/psa_test_wrappers.h b/tests/include/test/psa_test_wrappers.h index bd673b80b..86ead0a12 100644 --- a/tests/include/test/psa_test_wrappers.h +++ b/tests/include/test/psa_test_wrappers.h @@ -13,7 +13,8 @@ extern "C" { #include -#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) && \ + !defined(RECORD_PSA_STATUS_COVERAGE_LOG) #include @@ -709,7 +710,8 @@ psa_status_t mbedtls_test_wrap_psa_verify_message( #define psa_verify_message(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_length) \ mbedtls_test_wrap_psa_verify_message(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_length) -#endif /* defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) */ +#endif /* defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) && \ + !defined(RECORD_PSA_STATUS_COVERAGE_LOG) */ #ifdef __cplusplus } diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 85c927855..e5b4256f5 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -45,7 +45,9 @@ class BufferParameter: class PSAWrapperGenerator(c_wrapper_generator.Base): """Generate a C source file containing wrapper functions for PSA Crypto API calls.""" - _CPP_GUARDS = 'defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS)' + _CPP_GUARDS = ('defined(MBEDTLS_PSA_CRYPTO_C) && ' + + 'defined(MBEDTLS_TEST_HOOKS) && \\\n ' + + '!defined(RECORD_PSA_STATUS_COVERAGE_LOG)') _WRAPPER_NAME_PREFIX = 'mbedtls_test_wrap_' _WRAPPER_NAME_SUFFIX = '' diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index f3fb852e1..3a3aaade9 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -6,7 +6,8 @@ #include -#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) && \ + !defined(RECORD_PSA_STATUS_COVERAGE_LOG) #include @@ -977,6 +978,7 @@ psa_status_t mbedtls_test_wrap_psa_verify_message( return status; } -#endif /* defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) */ +#endif /* defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) && \ + !defined(RECORD_PSA_STATUS_COVERAGE_LOG) */ /* End of automatically generated file. */ From 89b50a7cb4b488f8045667b2e64002e89a228621 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 8 Jan 2024 21:05:42 +0100 Subject: [PATCH 14/14] Fix parsing of C line comments Fix // comments stopping on 'n' instead of newlines. Also allow backslash-newline in // comments. Signed-off-by: Gilles Peskine --- scripts/mbedtls_dev/c_parsing_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mbedtls_dev/c_parsing_helper.py b/scripts/mbedtls_dev/c_parsing_helper.py index 72214d51c..2657b7d23 100644 --- a/scripts/mbedtls_dev/c_parsing_helper.py +++ b/scripts/mbedtls_dev/c_parsing_helper.py @@ -76,7 +76,7 @@ class FunctionInfo: # Match one C comment. # Note that we match both comment types, so things like // in a /*...*/ # comment are handled correctly. -_C_COMMENT_RE = re.compile(r'//[^n]*|/\*.*?\*/', re.S) +_C_COMMENT_RE = re.compile(r'//(?:[^\n]|\\\n)*|/\*.*?\*/', re.S) _NOT_NEWLINES_RE = re.compile(r'[^\n]+') def read_logical_lines(filename: str) -> Iterator[Tuple[int, str]]: