Release Mbed Crypto 0.1.0a
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 0000000..3315a6e
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,73 @@
+CFLAGS ?= -O2 -I../include
+WARNING_CFLAGS ?= \
+	-Werror -Wall -Wextra \
+	-Wno-unused-function \
+	-Wno-overlength-strings \
+	-Wdeclaration-after-statement \
+# Don't delete this line.
+
+LDFLAGS ?= -L../library -lmbedcrypto
+
+DEP := ../library/libmbedcrypto.a
+
+# Python executable
+PYTHON ?= python
+
+APPS := \
+	test_suite_psa_crypto \
+# Don't delete this line.
+
+# Look up for associated function files
+func.test_suite_psa_crypto := test_suite_psa_crypto
+
+.SILENT:
+
+.PHONY: all test clean
+
+all: $(APPS)
+
+$(DEP):
+	$(MAKE) -C ../library
+
+C_FILES := $(addsuffix .c,$(APPS))
+
+.SECONDEXPANSION:
+$(C_FILES): %.c: suites/$$(func.$$*).function suites/%.data scripts/generate_test_code.py suites/helpers.function suites/main_test.function suites/host_test.function
+	echo "  Gen   $@"
+	$(PYTHON) scripts/generate_test_code.py -f suites/$(func.$*).function \
+		-d suites/$*.data \
+		-t suites/main_test.function \
+		-p suites/host_test.function \
+		-s suites  \
+		--help-file suites/helpers.function \
+		-o .
+
+
+$(APPS): %: %.c $(DEP)
+	echo "  CC    $<"
+	$(CC) $(CFLAGS) $(WARNING_CFLAGS) $< $(LDFLAGS) -o $@
+
+clean:
+	rm -rf $(APPS) *.c *.data TESTS
+	rm -rf data_files/ctr_drbg_seed data_files/hmac_drbg_seed data_files/mpi_write
+
+test: $(APPS)
+	./test_suite_psa_crypto
+
+# Create separate targets for generating embedded tests.
+EMBEDDED_TESTS := $(addprefix embedded_,$(APPS))
+
+# Generate test code for target.
+
+.SECONDEXPANSION:
+$(EMBEDDED_TESTS): embedded_%: suites/$$(func.$$*).function suites/%.data scripts/generate_test_code.py suites/helpers.function suites/main_test.function suites/target_test.function
+	echo "  Gen  ./TESTS/mbedcrypto/$*/$*.c"
+	$(PYTHON) scripts/generate_test_code.py -f suites/$(func.$*).function \
+		-d suites/$*.data \
+		-t suites/main_test.function \
+		-p suites/target_test.function \
+		-s suites  \
+		--help-file suites/helpers.function \
+		-o ./TESTS/mbedcrypto/$*
+
+gen-embedded-test: $(EMBEDDED_TESTS)
diff --git a/tests/scripts/generate_test_code.py b/tests/scripts/generate_test_code.py
new file mode 100755
index 0000000..345df53
--- /dev/null
+++ b/tests/scripts/generate_test_code.py
@@ -0,0 +1,729 @@
+#!/usr/bin/env python3
+# Test suites code generator.
+#
+# Copyright (C) 2018, ARM Limited, All Rights Reserved
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This file is part of Mbed Crypto (https://tls.mbed.org)
+
+"""
+Test Suite code generator.
+
+Generates a test source file using following input files:
+
+test_suite_xyz.function - Read test functions from test suite functions file.
+test_suite_xyz.data - Read test functions and their dependencies to generate
+                      dispatch and dependency check code.
+main template - Substitute generated test function dispatch code, dependency
+                checking code.
+platform .function - Read host or target platform implementation for
+                     dispatching test cases from .data file.
+helper .function - Read common reusable functions.
+"""
+
+
+import io
+import os
+import re
+import sys
+import argparse
+import shutil
+
+
+BEGIN_HEADER_REGEX = '/\*\s*BEGIN_HEADER\s*\*/'
+END_HEADER_REGEX = '/\*\s*END_HEADER\s*\*/'
+
+BEGIN_SUITE_HELPERS_REGEX = '/\*\s*BEGIN_SUITE_HELPERS\s*\*/'
+END_SUITE_HELPERS_REGEX = '/\*\s*END_SUITE_HELPERS\s*\*/'
+
+BEGIN_DEP_REGEX = 'BEGIN_DEPENDENCIES'
+END_DEP_REGEX = 'END_DEPENDENCIES'
+
+BEGIN_CASE_REGEX = '/\*\s*BEGIN_CASE\s*(.*?)\s*\*/'
+END_CASE_REGEX = '/\*\s*END_CASE\s*\*/'
+
+
+class InvalidFileFormat(Exception):
+    """
+    Exception to indicate invalid file format.
+    """
+    pass
+
+
+class FileWrapper(io.FileIO):
+    """
+    File wrapper class. Provides reading with line no. tracking.
+    """
+
+    def __init__(self, file_name):
+        """
+        Init file handle.
+
+        :param file_name: File path to open.
+        """
+        super(FileWrapper, self).__init__(file_name, 'r')
+        self.line_no = 0
+
+    # Override the generator function in a way that works in both Python 2
+    # and Python 3.
+    def __next__(self):
+        """
+        Iterator return impl.
+        :return: Line read from file.
+        """
+        parent = super(FileWrapper, self)
+        if hasattr(parent, '__next__'):
+            line = parent.__next__() # Python 3
+        else:
+            line = parent.next() # Python 2
+        if line:
+            self.line_no += 1
+            # Convert byte array to string with correct encoding
+            return line.decode(sys.getdefaultencoding())
+        return None
+    next = __next__
+
+
+def split_dep(dep):
+    """
+    Split NOT character '!' from dependency. Used by gen_deps()
+
+    :param dep: Dependency list
+    :return: list of tuples where index 0 has '!' if there was a '!' before the dependency string
+    """
+    return ('!', dep[1:]) if dep[0] == '!' else ('', dep)
+
+
+def gen_deps(deps):
+    """
+    Generates dependency i.e. if def and endif code
+
+    :param deps: List of dependencies.
+    :return: if defined and endif code with macro annotations for readability.
+    """
+    dep_start = ''.join(['#if %sdefined(%s)\n' % split_dep(x) for x in deps])
+    dep_end = ''.join(['#endif /* %s */\n' % x for x in reversed(deps)])
+
+    return dep_start, dep_end
+
+
+def gen_deps_one_line(deps):
+    """
+    Generates dependency checks in one line. Useful for writing code in #else case.
+
+    :param deps: List of dependencies.
+    :return: ifdef code
+    """
+    defines = ('#if ' if len(deps) else '') + ' && '.join(['%sdefined(%s)' % split_dep(x) for x in deps])
+    return defines
+
+
+def gen_function_wrapper(name, locals, args_dispatch):
+    """
+    Creates test function wrapper code. A wrapper has the code to unpack parameters from parameters[] array.
+
+    :param name: Test function name
+    :param locals: Local variables declaration code
+    :param args_dispatch: List of dispatch arguments. Ex: ['(char *)params[0]', '*((int *)params[1])']
+    :return: Test function wrapper.
+    """
+    # Then create the wrapper
+    wrapper = '''
+void {name}_wrapper( void ** params )
+{{
+{unused_params}{locals}
+    {name}( {args} );
+}}
+'''.format(name=name,
+           unused_params='' if args_dispatch else '    (void) params;\n',
+           args=', '.join(args_dispatch),
+           locals=locals)
+    return wrapper
+
+
+def gen_dispatch(name, deps):
+    """
+    Generates dispatch code for the test function table.
+
+    :param name: Test function name
+    :param deps: List of dependencies
+    :return: Dispatch code.
+    """
+    if len(deps):
+        ifdef = gen_deps_one_line(deps)
+        dispatch_code = '''
+{ifdef}
+    {name}_wrapper,
+#else
+    NULL,
+#endif
+'''.format(ifdef=ifdef, name=name)
+    else:
+        dispatch_code = '''
+    {name}_wrapper,
+'''.format(name=name)
+
+    return dispatch_code
+
+
+def parse_until_pattern(funcs_f, end_regex):
+    """
+    Parses function headers or helper code until end pattern.
+
+    :param funcs_f: file object for .functions file
+    :param end_regex: Pattern to stop parsing
+    :return: Test suite headers code
+    """
+    headers = '#line %d "%s"\n' % (funcs_f.line_no + 1, funcs_f.name)
+    for line in funcs_f:
+        if re.search(end_regex, line):
+            break
+        headers += line
+    else:
+        raise InvalidFileFormat("file: %s - end pattern [%s] not found!" % (funcs_f.name, end_regex))
+
+    return headers
+
+
+def parse_suite_deps(funcs_f):
+    """
+    Parses test suite dependencies.
+
+    :param funcs_f: file object for .functions file
+    :return: List of test suite dependencies.
+    """
+    deps = []
+    for line in funcs_f:
+        m = re.search('depends_on\:(.*)', line.strip())
+        if m:
+            deps += [x.strip() for x in m.group(1).split(':')]
+        if re.search(END_DEP_REGEX, line):
+            break
+    else:
+        raise InvalidFileFormat("file: %s - end dependency pattern [%s] not found!" % (funcs_f.name, END_DEP_REGEX))
+
+    return deps
+
+
+def parse_function_deps(line):
+    """
+    Parses function dependencies.
+
+    :param line: Line from .functions file that has dependencies.
+    :return: List of dependencies.
+    """
+    deps = []
+    m = re.search(BEGIN_CASE_REGEX, line)
+    dep_str = m.group(1)
+    if len(dep_str):
+        m = re.search('depends_on:(.*)', dep_str)
+        if m:
+            deps = [x.strip() for x in m.group(1).strip().split(':')]
+    return deps
+
+
+def parse_function_signature(line):
+    """
+    Parsing function signature
+
+    :param line: Line from .functions file that has a function signature.
+    :return: function name, argument list, local variables for wrapper function and argument dispatch code.
+    """
+    args = []
+    locals = ''
+    args_dispatch = []
+    m = re.search('\s*void\s+(\w+)\s*\(', line, re.I)
+    if not m:
+        raise ValueError("Test function should return 'void'\n%s" % line)
+    name = m.group(1)
+    line = line[len(m.group(0)):]
+    arg_idx = 0
+    for arg in line[:line.find(')')].split(','):
+        arg = arg.strip()
+        if arg == '':
+            continue
+        if re.search('int\s+.*', arg.strip()):
+            args.append('int')
+            args_dispatch.append('*( (int *) params[%d] )' % arg_idx)
+        elif re.search('char\s*\*\s*.*', arg.strip()):
+            args.append('char*')
+            args_dispatch.append('(char *) params[%d]' % arg_idx)
+        elif re.search('HexParam_t\s*\*\s*.*', arg.strip()):
+            args.append('hex')
+            # create a structure
+            locals += """    HexParam_t hex%d = {%s, %s};
+""" % (arg_idx, '(uint8_t *) params[%d]' % arg_idx, '*( (uint32_t *) params[%d] )' % (arg_idx + 1))
+
+            args_dispatch.append('&hex%d' % arg_idx)
+            arg_idx += 1
+        else:
+            raise ValueError("Test function arguments can only be 'int', 'char *' or 'HexParam_t'\n%s" % line)
+        arg_idx += 1
+
+    return name, args, locals, args_dispatch
+
+
+def parse_function_code(funcs_f, deps, suite_deps):
+    """
+    Parses out a function from function file object and generates function and dispatch code.
+
+    :param funcs_f: file object of the functions file.
+    :param deps: List of dependencies
+    :param suite_deps: List of test suite dependencies
+    :return: Function name, arguments, function code and dispatch code.
+    """
+    code = '#line %d "%s"\n' % (funcs_f.line_no + 1, funcs_f.name)
+    for line in funcs_f:
+        # Check function signature
+        m = re.match('.*?\s+(\w+)\s*\(', line, re.I)
+        if m:
+            # check if we have full signature i.e. split in more lines
+            if not re.match('.*\)', line):
+                for lin in funcs_f:
+                    line += lin
+                    if re.search('.*?\)', line):
+                        break
+            name, args, locals, args_dispatch = parse_function_signature(line)
+            code += line.replace(name, 'test_' + name)
+            name = 'test_' + name
+            break
+    else:
+        raise InvalidFileFormat("file: %s - Test functions not found!" % funcs_f.name)
+
+    for line in funcs_f:
+        if re.search(END_CASE_REGEX, line):
+            break
+        code += line
+    else:
+        raise InvalidFileFormat("file: %s - end case pattern [%s] not found!" % (funcs_f.name, END_CASE_REGEX))
+
+    # Add exit label if not present
+    if code.find('exit:') == -1:
+        s = code.rsplit('}', 1)
+        if len(s) == 2:
+            code = """exit:
+    ;;
+}""".join(s)
+
+    code += gen_function_wrapper(name, locals, args_dispatch)
+    ifdef, endif = gen_deps(deps)
+    dispatch_code = gen_dispatch(name, suite_deps + deps)
+    return name, args, ifdef + code + endif, dispatch_code
+
+
+def parse_functions(funcs_f):
+    """
+    Returns functions code pieces
+
+    :param funcs_f: file object of the functions file.
+    :return: List of test suite dependencies, test function dispatch code, function code and
+             a dict with function identifiers and arguments info.
+    """
+    suite_headers = ''
+    suite_helpers = ''
+    suite_deps = []
+    suite_functions = ''
+    func_info = {}
+    function_idx = 0
+    dispatch_code = ''
+    for line in funcs_f:
+        if re.search(BEGIN_HEADER_REGEX, line):
+            headers = parse_until_pattern(funcs_f, END_HEADER_REGEX)
+            suite_headers += headers
+        elif re.search(BEGIN_SUITE_HELPERS_REGEX, line):
+            helpers = parse_until_pattern(funcs_f, END_SUITE_HELPERS_REGEX)
+            suite_helpers += helpers
+        elif re.search(BEGIN_DEP_REGEX, line):
+            deps = parse_suite_deps(funcs_f)
+            suite_deps += deps
+        elif re.search(BEGIN_CASE_REGEX, line):
+            deps = parse_function_deps(line)
+            func_name, args, func_code, func_dispatch = parse_function_code(funcs_f, deps, suite_deps)
+            suite_functions += func_code
+            # Generate dispatch code and enumeration info
+            assert func_name not in func_info, "file: %s - function %s re-declared at line %d" % \
+                                               (funcs_f.name, func_name, funcs_f.line_no)
+            func_info[func_name] = (function_idx, args)
+            dispatch_code += '/* Function Id: %d */\n' % function_idx
+            dispatch_code += func_dispatch
+            function_idx += 1
+
+    ifdef, endif = gen_deps(suite_deps)
+    func_code = ifdef + suite_headers + suite_helpers + suite_functions + endif
+    return suite_deps, dispatch_code, func_code, func_info
+
+
+def escaped_split(str, ch):
+    """
+    Split str on character ch but ignore escaped \{ch}
+    Since return value is used to write back to the intermediate data file.
+    Any escape characters in the input are retained in the output.
+
+    :param str: String to split
+    :param ch: split character
+    :return: List of splits
+    """
+    if len(ch) > 1:
+        raise ValueError('Expected split character. Found string!')
+    out = []
+    part = ''
+    escape = False
+    for i in range(len(str)):
+        if not escape and str[i] == ch:
+            out.append(part)
+            part = ''
+        else:
+            part += str[i]
+            escape = not escape and str[i] == '\\'
+    if len(part):
+        out.append(part)
+    return out
+
+
+def parse_test_data(data_f, debug=False):
+    """
+    Parses .data file
+
+    :param data_f: file object of the data file.
+    :return: Generator that yields test name, function name, dependency list and function argument list.
+    """
+    STATE_READ_NAME = 0
+    STATE_READ_ARGS = 1
+    state = STATE_READ_NAME
+    deps = []
+    name = ''
+    for line in data_f:
+        line = line.strip()
+        if len(line) and line[0] == '#': # Skip comments
+            continue
+
+        # Blank line indicates end of test
+        if len(line) == 0:
+            assert state != STATE_READ_ARGS, "Newline before arguments. " \
+                                                 "Test function and arguments missing for %s" % name
+            continue
+
+        if state == STATE_READ_NAME:
+            # Read test name
+            name = line
+            state = STATE_READ_ARGS
+        elif state == STATE_READ_ARGS:
+            # Check dependencies
+            m = re.search('depends_on\:(.*)', line)
+            if m:
+                deps = [x.strip() for x in m.group(1).split(':') if len(x.strip())]
+            else:
+                # Read test vectors
+                parts = escaped_split(line, ':')
+                function = parts[0]
+                args = parts[1:]
+                yield name, function, deps, args
+                deps = []
+                state = STATE_READ_NAME
+    assert state != STATE_READ_ARGS, "Newline before arguments. " \
+                                     "Test function and arguments missing for %s" % name
+
+
+def gen_dep_check(dep_id, dep):
+    """
+    Generate code for the dependency.
+
+    :param dep_id: Dependency identifier
+    :param dep: Dependency macro
+    :return: Dependency check code
+    """
+    assert dep_id > -1, "Dependency Id should be a positive integer."
+    noT, dep = ('!', dep[1:]) if dep[0] == '!' else ('', dep)
+    assert len(dep) > 0, "Dependency should not be an empty string."
+    dep_check = '''
+        case {id}:
+            {{
+#if {noT}defined({macro})
+                ret = DEPENDENCY_SUPPORTED;
+#else
+                ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+            }}
+            break;'''.format(noT=noT, macro=dep, id=dep_id)
+    return dep_check
+
+
+def gen_expression_check(exp_id, exp):
+    """
+    Generates code for expression check
+
+    :param exp_id: Expression Identifier
+    :param exp: Expression/Macro
+    :return: Expression check code
+    """
+    assert exp_id > -1, "Expression Id should be a positive integer."
+    assert len(exp) > 0, "Expression should not be an empty string."
+    exp_code = '''
+        case {exp_id}:
+            {{
+                *out_value = {expression};
+            }}
+            break;'''.format(exp_id=exp_id, expression=exp)
+    return exp_code
+
+
+def write_deps(out_data_f, test_deps, unique_deps):
+    """
+    Write dependencies to intermediate test data file.
+    It also returns dependency check code.
+
+    :param out_data_f: Output intermediate data file
+    :param test_deps: Dependencies
+    :param unique_deps: Mutable list to track unique dependencies that are global to this re-entrant function.
+    :return: returns dependency check code.
+    """
+    dep_check_code = ''
+    if len(test_deps):
+        out_data_f.write('depends_on')
+        for dep in test_deps:
+            if dep not in unique_deps:
+                unique_deps.append(dep)
+                dep_id = unique_deps.index(dep)
+                dep_check_code += gen_dep_check(dep_id, dep)
+            else:
+                dep_id = unique_deps.index(dep)
+            out_data_f.write(':' + str(dep_id))
+        out_data_f.write('\n')
+    return dep_check_code
+
+
+def write_parameters(out_data_f, test_args, func_args, unique_expressions):
+    """
+    Writes test parameters to the intermediate data file.
+    Also generates expression code.
+
+    :param out_data_f: Output intermediate data file
+    :param test_args: Test parameters
+    :param func_args: Function arguments
+    :param unique_expressions: Mutable list to track unique expressions that are global to this re-entrant function.
+    :return: Returns expression check code.
+    """
+    expression_code = ''
+    for i in range(len(test_args)):
+        typ = func_args[i]
+        val = test_args[i]
+
+        # check if val is a non literal int val
+        if typ == 'int' and not re.match('(\d+$)|((0x)?[0-9a-fA-F]+$)', val):  # its an expression
+            typ = 'exp'
+            if val not in unique_expressions:
+                unique_expressions.append(val)
+                # exp_id can be derived from len(). But for readability and consistency with case of existing let's
+                # use index().
+                exp_id = unique_expressions.index(val)
+                expression_code += gen_expression_check(exp_id, val)
+                val = exp_id
+            else:
+                val = unique_expressions.index(val)
+        out_data_f.write(':' + typ + ':' + str(val))
+    out_data_f.write('\n')
+    return expression_code
+
+
+def gen_suite_deps_checks(suite_deps, dep_check_code, expression_code):
+    """
+    Adds preprocessor checks for test suite dependencies.
+
+    :param suite_deps: Test suite dependencies read from the .functions file.
+    :param dep_check_code: Dependency check code
+    :param expression_code: Expression check code
+    :return: Dependency and expression code guarded by test suite dependencies.
+    """
+    if len(suite_deps):
+        ifdef = gen_deps_one_line(suite_deps)
+        dep_check_code = '''
+{ifdef}
+{code}
+#endif
+'''.format(ifdef=ifdef, code=dep_check_code)
+        expression_code = '''
+{ifdef}
+{code}
+#endif
+'''.format(ifdef=ifdef, code=expression_code)
+    return dep_check_code, expression_code
+
+
+def gen_from_test_data(data_f, out_data_f, func_info, suite_deps):
+    """
+    Generates dependency checks, expression code and intermediate data file from test data file.
+
+    :param data_f: Data file object
+    :param out_data_f:Output intermediate data file
+    :param func_info: Dict keyed by function and with function id and arguments info
+    :param suite_deps: Test suite deps
+    :return: Returns dependency and expression check code
+    """
+    unique_deps = []
+    unique_expressions = []
+    dep_check_code = ''
+    expression_code = ''
+    for test_name, function_name, test_deps, test_args in parse_test_data(data_f):
+        out_data_f.write(test_name + '\n')
+
+        # Write deps
+        dep_check_code += write_deps(out_data_f, test_deps, unique_deps)
+
+        # Write test function name
+        test_function_name = 'test_' + function_name
+        assert test_function_name in func_info, "Function %s not found!" % test_function_name
+        func_id, func_args = func_info[test_function_name]
+        out_data_f.write(str(func_id))
+
+        # Write parameters
+        assert len(test_args) == len(func_args), \
+            "Invalid number of arguments in test %s. See function %s signature." % (test_name, function_name)
+        expression_code += write_parameters(out_data_f, test_args, func_args, unique_expressions)
+
+        # Write a newline as test case separator
+        out_data_f.write('\n')
+
+    dep_check_code, expression_code = gen_suite_deps_checks(suite_deps, dep_check_code, expression_code)
+    return dep_check_code, expression_code
+
+
+def generate_code(funcs_file, data_file, template_file, platform_file, help_file, suites_dir, c_file, out_data_file):
+    """
+    Generate mbed-os test code.
+
+    :param funcs_file: Functions file object
+    :param data_file: Data file object
+    :param template_file: Template file object
+    :param platform_file: Platform file object
+    :param help_file: Helper functions file object
+    :param suites_dir: Test suites dir
+    :param c_file: Output C file object
+    :param out_data_file: Output intermediate data file object
+    :return:
+    """
+    for name, path in [('Functions file', funcs_file),
+                       ('Data file', data_file),
+                       ('Template file', template_file),
+                       ('Platform file', platform_file),
+                       ('Help code file', help_file),
+                       ('Suites dir', suites_dir)]:
+        if not os.path.exists(path):
+            raise IOError("ERROR: %s [%s] not found!" % (name, path))
+
+    snippets = {'generator_script' : os.path.basename(__file__)}
+
+    # Read helpers
+    with open(help_file, 'r') as help_f, open(platform_file, 'r') as platform_f:
+        snippets['test_common_helper_file'] = help_file
+        snippets['test_common_helpers'] = help_f.read()
+        snippets['test_platform_file'] = platform_file
+        snippets['platform_code'] = platform_f.read().replace('DATA_FILE',
+                                                              out_data_file.replace('\\', '\\\\')) # escape '\'
+
+    # Function code
+    with FileWrapper(funcs_file) as funcs_f, open(data_file, 'r') as data_f, open(out_data_file, 'w') as out_data_f:
+        suite_deps, dispatch_code, func_code, func_info = parse_functions(funcs_f)
+        snippets['functions_code'] = func_code
+        snippets['dispatch_code'] = dispatch_code
+        dep_check_code, expression_code = gen_from_test_data(data_f, out_data_f, func_info, suite_deps)
+        snippets['dep_check_code'] = dep_check_code
+        snippets['expression_code'] = expression_code
+
+    snippets['test_file'] = c_file
+    snippets['test_main_file'] = template_file
+    snippets['test_case_file'] = funcs_file
+    snippets['test_case_data_file'] = data_file
+    # Read Template
+    # Add functions
+    #
+    with open(template_file, 'r') as template_f, open(c_file, 'w') as c_f:
+        line_no = 1
+        for line in template_f.readlines():
+            snippets['line_no'] = line_no + 1 # Increment as it sets next line number
+            code = line.format(**snippets)
+            c_f.write(code)
+            line_no += 1
+
+
+def check_cmd():
+    """
+    Command line parser.
+
+    :return:
+    """
+    parser = argparse.ArgumentParser(description='Generate code for mbed-os tests.')
+
+    parser.add_argument("-f", "--functions-file",
+                        dest="funcs_file",
+                        help="Functions file",
+                        metavar="FUNCTIONS",
+                        required=True)
+
+    parser.add_argument("-d", "--data-file",
+                        dest="data_file",
+                        help="Data file",
+                        metavar="DATA",
+                        required=True)
+
+    parser.add_argument("-t", "--template-file",
+                        dest="template_file",
+                        help="Template file",
+                        metavar="TEMPLATE",
+                        required=True)
+
+    parser.add_argument("-s", "--suites-dir",
+                        dest="suites_dir",
+                        help="Suites dir",
+                        metavar="SUITES",
+                        required=True)
+
+    parser.add_argument("--help-file",
+                        dest="help_file",
+                        help="Help file",
+                        metavar="HELPER",
+                        required=True)
+
+    parser.add_argument("-p", "--platform-file",
+                        dest="platform_file",
+                        help="Platform code file",
+                        metavar="PLATFORM_FILE",
+                        required=True)
+
+    parser.add_argument("-o", "--out-dir",
+                        dest="out_dir",
+                        help="Dir where generated code and scripts are copied",
+                        metavar="OUT_DIR",
+                        required=True)
+
+    args = parser.parse_args()
+
+    data_file_name = os.path.basename(args.data_file)
+    data_name = os.path.splitext(data_file_name)[0]
+
+    out_c_file = os.path.join(args.out_dir, data_name + '.c')
+    out_data_file = os.path.join(args.out_dir, data_file_name)
+
+    out_c_file_dir = os.path.dirname(out_c_file)
+    out_data_file_dir = os.path.dirname(out_data_file)
+    for d in [out_c_file_dir, out_data_file_dir]:
+        if not os.path.exists(d):
+            os.makedirs(d)
+
+    generate_code(args.funcs_file, args.data_file, args.template_file, args.platform_file,
+                  args.help_file, args.suites_dir, out_c_file, out_data_file)
+
+
+if __name__ == "__main__":
+    check_cmd()
diff --git a/tests/scripts/mbedtls_test.py b/tests/scripts/mbedtls_test.py
new file mode 100755
index 0000000..cdd7524
--- /dev/null
+++ b/tests/scripts/mbedtls_test.py
@@ -0,0 +1,342 @@
+# Greentea host test script for on-target tests.
+#
+# Copyright (C) 2018, ARM Limited, All Rights Reserved
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This file is part of Mbed Crypto (https://tls.mbed.org)
+
+
+"""
+Greentea host test script for on-target tests.
+
+Host test script for testing Mbed Crypto test suites on target. Implements
+BaseHostTest to handle key,value pairs (events) coming from Mbed Crypto
+tests. Reads data file corresponding to the executing binary and dispatches
+test cases.
+"""
+
+
+import re
+import os
+import binascii
+from mbed_host_tests import BaseHostTest, event_callback
+
+
+class TestDataParser(object):
+    """
+    parser for mbedcrypto test data files.
+    """
+
+    def __init__(self):
+        """
+        Constructor
+        """
+        self.tests = []
+
+    def parse(self, data_file):
+        """
+        Data file parser.
+
+        :param data_file: Data file path
+        """
+        with open(data_file, 'r') as f:
+            self.__parse(f)
+
+    @staticmethod
+    def __escaped_split(str, ch):
+        """
+        Splits str on ch except when escaped.
+
+        :param str: String to split
+        :param ch: Split character
+        :return: List of splits
+        """
+        if len(ch) > 1:
+            raise ValueError('Expected split character. Found string!')
+        out = []
+        part = ''
+        escape = False
+        for i in range(len(str)):
+            if not escape and str[i] == ch:
+                out.append(part)
+                part = ''
+            else:
+                part += str[i]
+                escape = not escape and str[i] == '\\'
+        if len(part):
+            out.append(part)
+        return out
+
+    def __parse(self, file):
+        """
+        Parses data file using supplied file object.
+
+        :param file: Data file object
+        :return:
+        """
+        for line in file:
+            line = line.strip()
+            if len(line) == 0:
+                continue
+            # Read test name
+            name = line
+
+            # Check dependencies
+            deps = []
+            line = file.next().strip()
+            m = re.search('depends_on\:(.*)', line)
+            if m:
+                deps = [int(x) for x in m.group(1).split(':')]
+                line = file.next().strip()
+
+            # Read test vectors
+            line = line.replace('\\n', '\n')
+            parts = self.__escaped_split(line, ':')
+            function = int(parts[0])
+            x = parts[1:]
+            l = len(x)
+            assert l % 2 == 0, "Number of test arguments should be even: %s" % line
+            args = [(x[i * 2], x[(i * 2) + 1]) for i in range(len(x)/2)]
+            self.tests.append((name, function, deps, args))
+
+    def get_test_data(self):
+        """
+        Returns test data.
+        """
+        return self.tests
+
+
+class MbedCryptoTest(BaseHostTest):
+    """
+    Event handler for mbedcrypto unit tests. This script is loaded at run time
+    by htrun while executing mbedcrypto unit tests.
+    """
+    # From suites/helpers.function
+    DEPENDENCY_SUPPORTED = 0
+    KEY_VALUE_MAPPING_FOUND = DEPENDENCY_SUPPORTED
+    DISPATCH_TEST_SUCCESS = DEPENDENCY_SUPPORTED
+
+    KEY_VALUE_MAPPING_NOT_FOUND = -1
+    DEPENDENCY_NOT_SUPPORTED = -2
+    DISPATCH_TEST_FN_NOT_FOUND = -3
+    DISPATCH_INVALID_TEST_DATA = -4
+    DISPATCH_UNSUPPORTED_SUITE = -5
+
+    def __init__(self):
+        """
+        Constructor initialises test index to 0.
+        """
+        super(MbedCryptoTest, self).__init__()
+        self.tests = []
+        self.test_index = -1
+        self.dep_index = 0
+        self.error_str = dict()
+        self.error_str[self.DEPENDENCY_SUPPORTED] = 'DEPENDENCY_SUPPORTED'
+        self.error_str[self.KEY_VALUE_MAPPING_NOT_FOUND] = 'KEY_VALUE_MAPPING_NOT_FOUND'
+        self.error_str[self.DEPENDENCY_NOT_SUPPORTED] = 'DEPENDENCY_NOT_SUPPORTED'
+        self.error_str[self.DISPATCH_TEST_FN_NOT_FOUND] = 'DISPATCH_TEST_FN_NOT_FOUND'
+        self.error_str[self.DISPATCH_INVALID_TEST_DATA] = 'DISPATCH_INVALID_TEST_DATA'
+        self.error_str[self.DISPATCH_UNSUPPORTED_SUITE] = 'DISPATCH_UNSUPPORTED_SUITE'
+
+    def setup(self):
+        """
+        Setup hook implementation. Reads test suite data file and parses out tests.
+        """
+        binary_path = self.get_config_item('image_path')
+        script_dir = os.path.split(os.path.abspath(__file__))[0]
+        suite_name = os.path.splitext(os.path.basename(binary_path))[0]
+        data_file = ".".join((suite_name, 'data'))
+        data_file = os.path.join(script_dir, '..', 'mbedcrypto', suite_name, data_file)
+        if os.path.exists(data_file):
+            self.log("Running tests from %s" % data_file)
+            parser = TestDataParser()
+            parser.parse(data_file)
+            self.tests = parser.get_test_data()
+            self.print_test_info()
+        else:
+            self.log("Data file not found: %s" % data_file)
+            self.notify_complete(False)
+
+    def print_test_info(self):
+        """
+        Prints test summary read by Greentea to detect test cases.
+        """
+        self.log('{{__testcase_count;%d}}' % len(self.tests))
+        for name, _, _, _ in self.tests:
+            self.log('{{__testcase_name;%s}}' % name)
+
+    @staticmethod
+    def align_32bit(b):
+        """
+        4 byte aligns input byte array.
+
+        :return:
+        """
+        b += bytearray((4 - (len(b))) % 4)
+
+    @staticmethod
+    def hex_str_bytes(hex_str):
+        """
+        Converts Hex string representation to byte array
+
+        :param hex_str: Hex in string format.
+        :return: Output Byte array
+        """
+        assert hex_str[0] == '"' and hex_str[len(hex_str) - 1] == '"', \
+            "HEX test parameter missing '\"': %s" % hex_str
+        hex_str = hex_str.strip('"')
+        assert len(hex_str) % 2 == 0, "HEX parameter len should be mod of 2: %s" % hex_str
+
+        b = binascii.unhexlify(hex_str)
+        return b
+
+    @staticmethod
+    def int32_to_bigendian_bytes(i):
+        """
+        Coverts i to bytearray in big endian format.
+
+        :param i: Input integer
+        :return: Output bytes array in big endian or network order
+        """
+        b = bytearray([((i >> x) & 0xff) for x in [24, 16, 8, 0]])
+        return b
+
+    def test_vector_to_bytes(self, function_id, deps, parameters):
+        """
+        Converts test vector into a byte array that can be sent to the target.
+
+        :param function_id: Test Function Identifier
+        :param deps: Dependency list
+        :param parameters: Test function input parameters
+        :return: Byte array and its length
+        """
+        b = bytearray([len(deps)])
+        if len(deps):
+            b += bytearray(deps)
+        b += bytearray([function_id, len(parameters)])
+        for typ, param in parameters:
+            if typ == 'int' or typ == 'exp':
+                i = int(param)
+                b += 'I' if typ == 'int' else 'E'
+                self.align_32bit(b)
+                b += self.int32_to_bigendian_bytes(i)
+            elif typ == 'char*':
+                param = param.strip('"')
+                i = len(param) + 1  # + 1 for null termination
+                b += 'S'
+                self.align_32bit(b)
+                b += self.int32_to_bigendian_bytes(i)
+                b += bytearray(list(param))
+                b += '\0'   # Null terminate
+            elif typ == 'hex':
+                hb = self.hex_str_bytes(param)
+                b += 'H'
+                self.align_32bit(b)
+                i = len(hb)
+                b += self.int32_to_bigendian_bytes(i)
+                b += hb
+        length = self.int32_to_bigendian_bytes(len(b))
+        return b, length
+
+    def run_next_test(self):
+        """
+        Send next test function to the target.
+
+        """
+        self.test_index += 1
+        self.dep_index = 0
+        if self.test_index < len(self.tests):
+            name, function_id, deps, args = self.tests[self.test_index]
+            self.run_test(name, function_id, deps, args)
+        else:
+            self.notify_complete(True)
+
+    def run_test(self, name, function_id, deps, args):
+        """
+        Runs the test.
+
+        :param name: Test name
+        :param function_id: function identifier
+        :param deps: Dependencies list
+        :param args: test parameters
+        :return:
+        """
+        self.log("Running: %s" % name)
+
+        bytes, length = self.test_vector_to_bytes(function_id, deps, args)
+        self.send_kv(length, bytes)
+
+    @staticmethod
+    def get_result(value):
+        """
+        Converts result from string type to integer
+        :param value: Result code in string
+        :return: Integer result code
+        """
+        try:
+            return int(value)
+        except ValueError:
+            ValueError("Result should return error number. Instead received %s" % value)
+        return 0
+
+    @event_callback('GO')
+    def on_go(self, key, value, timestamp):
+        """
+        Called on key "GO". Kicks off test execution.
+
+        :param key: Event key
+        :param value: Value. ignored
+        :param timestamp: Timestamp ignored.
+        :return:
+        """
+        self.run_next_test()
+
+    @event_callback("R")
+    def on_result(self, key, value, timestamp):
+        """
+        Handle result. Prints test start, finish prints required by Greentea to detect test execution.
+
+        :param key: Event key
+        :param value: Value. ignored
+        :param timestamp: Timestamp ignored.
+        :return:
+        """
+        int_val = self.get_result(value)
+        name, function, deps, args = self.tests[self.test_index]
+        self.log('{{__testcase_start;%s}}' % name)
+        self.log('{{__testcase_finish;%s;%d;%d}}' % (name, int_val == 0,
+                                                     int_val != 0))
+        self.run_next_test()
+
+    @event_callback("F")
+    def on_failure(self, key, value, timestamp):
+        """
+        Handles test execution failure. That means dependency not supported or
+        Test function not supported. Hence marking test as skipped.
+
+        :param key: Event key
+        :param value: Value. ignored
+        :param timestamp: Timestamp ignored.
+        :return:
+        """
+        int_val = self.get_result(value)
+        name, function, deps, args = self.tests[self.test_index]
+        if int_val in self.error_str:
+            err = self.error_str[int_val]
+        else:
+            err = 'Unknown error'
+        # For skip status, do not write {{__testcase_finish;...}}
+        self.log("Error: %s" % err)
+        self.run_next_test()
diff --git a/tests/scripts/run-test-suites.pl b/tests/scripts/run-test-suites.pl
new file mode 100755
index 0000000..5de20f8
--- /dev/null
+++ b/tests/scripts/run-test-suites.pl
@@ -0,0 +1,101 @@
+#!/usr/bin/perl
+
+# run-test-suites.pl
+#
+# This file is part of Mbed Crypto (https://tls.mbed.org)
+#
+# Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# Executes all the available test suites, and provides a basic summary of the
+# results.
+#
+# Usage: run-test-suites.pl [-v]
+#
+# Options :
+#   -v|--verbose    - Provide a pass/fail/skip breakdown per test suite and
+#                     in total
+#
+
+use warnings;
+use strict;
+
+use utf8;
+use open qw(:std utf8);
+
+use constant FALSE => 0;
+use constant TRUE => 1;
+
+my $verbose;
+my $switch = shift;
+if ( defined($switch) && ( $switch eq "-v" || $switch eq "--verbose" ) ) {
+    $verbose = TRUE;
+}
+
+# All test suites = executable files, excluding source files, debug
+# and profiling information, etc. We can't just grep {! /\./} because
+#some of our test cases' base names contain a dot.
+my @suites = grep { -x $_ || /\.exe$/ } glob 'test_suite_*';
+die "$0: no test suite found\n" unless @suites;
+
+# in case test suites are linked dynamically
+$ENV{'LD_LIBRARY_PATH'} = '../library';
+$ENV{'DYLD_LIBRARY_PATH'} = '../library';
+
+my $prefix = $^O eq "MSWin32" ? '' : './';
+
+my ($failed_suites, $total_tests_run, $failed, $suite_cases_passed,
+    $suite_cases_failed, $suite_cases_skipped, $total_cases_passed,
+    $total_cases_failed, $total_cases_skipped );
+
+for my $suite (@suites)
+{
+    print "$suite ", "." x ( 72 - length($suite) - 2 - 4 ), " ";
+    my $result = `$prefix$suite`;
+
+    $suite_cases_passed = () = $result =~ /.. PASS/g;
+    $suite_cases_failed = () = $result =~ /.. FAILED/g;
+    $suite_cases_skipped = () = $result =~ /.. ----/g;
+
+    if( $result =~ /PASSED/ ) {
+        print "PASS\n";
+    } else {
+        $failed_suites++;
+        print "FAIL\n";
+    }
+
+    my ($passed, $tests, $skipped) = $result =~ /([0-9]*) \/ ([0-9]*) tests.*?([0-9]*) skipped/;
+    $total_tests_run += $tests - $skipped;
+
+    if ( $verbose ) {
+        print "(test cases passed:", $suite_cases_passed,
+                " failed:", $suite_cases_failed,
+                " skipped:", $suite_cases_skipped,
+                " of total:", ($suite_cases_passed + $suite_cases_failed +
+                               $suite_cases_skipped),
+                ")\n"
+    }
+
+    $total_cases_passed += $suite_cases_passed;
+    $total_cases_failed += $suite_cases_failed;
+    $total_cases_skipped += $suite_cases_skipped;
+}
+
+print "-" x 72, "\n";
+print $failed_suites ? "FAILED" : "PASSED";
+printf " (%d suites, %d tests run)\n", scalar @suites, $total_tests_run;
+
+if ( $verbose ) {
+    print "  test cases passed :", $total_cases_passed, "\n";
+    print "             failed :", $total_cases_failed, "\n";
+    print "            skipped :", $total_cases_skipped, "\n";
+    print "  of tests executed :", ( $total_cases_passed + $total_cases_failed ),
+            "\n";
+    print " of available tests :",
+            ( $total_cases_passed + $total_cases_failed + $total_cases_skipped ),
+            "\n"
+    }
+
+exit( $failed_suites ? 1 : 0 );
+
diff --git a/tests/scripts/test_generate_test_code.py b/tests/scripts/test_generate_test_code.py
new file mode 100755
index 0000000..9adb441
--- /dev/null
+++ b/tests/scripts/test_generate_test_code.py
@@ -0,0 +1,1524 @@
+# Unit test for generate_test_code.py
+#
+# Copyright (C) 2018, ARM Limited, All Rights Reserved
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This file is part of Mbed Crypto (https://tls.mbed.org)
+
+from StringIO import StringIO
+from unittest import TestCase, main as unittest_main
+from mock import patch
+from generate_test_code import *
+
+
+"""
+Unit tests for generate_test_code.py
+"""
+
+
+class GenDep(TestCase):
+    """
+    Test suite for function gen_dep()
+    """
+
+    def test_deps_list(self):
+        """
+        Test that gen_dep() correctly creates deps for given dependency list.
+        :return:
+        """
+        deps = ['DEP1', 'DEP2']
+        dep_start, dep_end = gen_deps(deps)
+        ifdef1, ifdef2 = dep_start.splitlines()
+        endif1, endif2 = dep_end.splitlines()
+        self.assertEqual(ifdef1, '#if defined(DEP1)', 'ifdef generated incorrectly')
+        self.assertEqual(ifdef2, '#if defined(DEP2)', 'ifdef generated incorrectly')
+        self.assertEqual(endif1, '#endif /* DEP2 */', 'endif generated incorrectly')
+        self.assertEqual(endif2, '#endif /* DEP1 */', 'endif generated incorrectly')
+
+    def test_disabled_deps_list(self):
+        """
+        Test that gen_dep() correctly creates deps for given dependency list.
+        :return:
+        """
+        deps = ['!DEP1', '!DEP2']
+        dep_start, dep_end = gen_deps(deps)
+        ifdef1, ifdef2 = dep_start.splitlines()
+        endif1, endif2 = dep_end.splitlines()
+        self.assertEqual(ifdef1, '#if !defined(DEP1)', 'ifdef generated incorrectly')
+        self.assertEqual(ifdef2, '#if !defined(DEP2)', 'ifdef generated incorrectly')
+        self.assertEqual(endif1, '#endif /* !DEP2 */', 'endif generated incorrectly')
+        self.assertEqual(endif2, '#endif /* !DEP1 */', 'endif generated incorrectly')
+
+    def test_mixed_deps_list(self):
+        """
+        Test that gen_dep() correctly creates deps for given dependency list.
+        :return:
+        """
+        deps = ['!DEP1', 'DEP2']
+        dep_start, dep_end = gen_deps(deps)
+        ifdef1, ifdef2 = dep_start.splitlines()
+        endif1, endif2 = dep_end.splitlines()
+        self.assertEqual(ifdef1, '#if !defined(DEP1)', 'ifdef generated incorrectly')
+        self.assertEqual(ifdef2, '#if defined(DEP2)', 'ifdef generated incorrectly')
+        self.assertEqual(endif1, '#endif /* DEP2 */', 'endif generated incorrectly')
+        self.assertEqual(endif2, '#endif /* !DEP1 */', 'endif generated incorrectly')
+
+    def test_empty_deps_list(self):
+        """
+        Test that gen_dep() correctly creates deps for given dependency list.
+        :return:
+        """
+        deps = []
+        dep_start, dep_end = gen_deps(deps)
+        self.assertEqual(dep_start, '', 'ifdef generated incorrectly')
+        self.assertEqual(dep_end, '', 'ifdef generated incorrectly')
+
+    def test_large_deps_list(self):
+        """
+        Test that gen_dep() correctly creates deps for given dependency list.
+        :return:
+        """
+        deps = []
+        count = 10
+        for i in range(count):
+            deps.append('DEP%d' % i)
+        dep_start, dep_end = gen_deps(deps)
+        self.assertEqual(len(dep_start.splitlines()), count, 'ifdef generated incorrectly')
+        self.assertEqual(len(dep_end.splitlines()), count, 'ifdef generated incorrectly')
+
+
+class GenDepOneLine(TestCase):
+    """
+    Test Suite for testing gen_deps_one_line()
+    """
+
+    def test_deps_list(self):
+        """
+        Test that gen_dep() correctly creates deps for given dependency list.
+        :return:
+        """
+        deps = ['DEP1', 'DEP2']
+        dep_str = gen_deps_one_line(deps)
+        self.assertEqual(dep_str, '#if defined(DEP1) && defined(DEP2)', 'ifdef generated incorrectly')
+
+    def test_disabled_deps_list(self):
+        """
+        Test that gen_dep() correctly creates deps for given dependency list.
+        :return:
+        """
+        deps = ['!DEP1', '!DEP2']
+        dep_str = gen_deps_one_line(deps)
+        self.assertEqual(dep_str, '#if !defined(DEP1) && !defined(DEP2)', 'ifdef generated incorrectly')
+
+    def test_mixed_deps_list(self):
+        """
+        Test that gen_dep() correctly creates deps for given dependency list.
+        :return:
+        """
+        deps = ['!DEP1', 'DEP2']
+        dep_str = gen_deps_one_line(deps)
+        self.assertEqual(dep_str, '#if !defined(DEP1) && defined(DEP2)', 'ifdef generated incorrectly')
+
+    def test_empty_deps_list(self):
+        """
+        Test that gen_dep() correctly creates deps for given dependency list.
+        :return:
+        """
+        deps = []
+        dep_str = gen_deps_one_line(deps)
+        self.assertEqual(dep_str, '', 'ifdef generated incorrectly')
+
+    def test_large_deps_list(self):
+        """
+        Test that gen_dep() correctly creates deps for given dependency list.
+        :return:
+        """
+        deps = []
+        count = 10
+        for i in range(count):
+            deps.append('DEP%d' % i)
+        dep_str = gen_deps_one_line(deps)
+        expected = '#if ' + ' && '.join(['defined(%s)' % x for x in deps])
+        self.assertEqual(dep_str, expected, 'ifdef generated incorrectly')
+
+
+class GenFunctionWrapper(TestCase):
+    """
+    Test Suite for testing gen_function_wrapper()
+    """
+
+    def test_params_unpack(self):
+        """
+        Test that params are properly unpacked in the function call.
+
+        :return:
+        """
+        code = gen_function_wrapper('test_a', '', ('a', 'b', 'c', 'd'))
+        expected = '''
+void test_a_wrapper( void ** params )
+{
+
+
+    test_a( a, b, c, d );
+}
+'''
+        self.assertEqual(code, expected)
+
+    def test_local(self):
+        """
+        Test that params are properly unpacked in the function call.
+
+        :return:
+        """
+        code = gen_function_wrapper('test_a', 'int x = 1;', ('x', 'b', 'c', 'd'))
+        expected = '''
+void test_a_wrapper( void ** params )
+{
+
+int x = 1;
+    test_a( x, b, c, d );
+}
+'''
+        self.assertEqual(code, expected)
+
+    def test_empty_params(self):
+        """
+        Test that params are properly unpacked in the function call.
+
+        :return:
+        """
+        code = gen_function_wrapper('test_a', '', ())
+        expected = '''
+void test_a_wrapper( void ** params )
+{
+    (void)params;
+
+    test_a(  );
+}
+'''
+        self.assertEqual(code, expected)
+
+
+class GenDispatch(TestCase):
+    """
+    Test suite for testing gen_dispatch()
+    """
+
+    def test_dispatch(self):
+        """
+        Test that dispatch table entry is generated correctly.
+        :return:
+        """
+        code = gen_dispatch('test_a', ['DEP1', 'DEP2'])
+        expected = '''
+#if defined(DEP1) && defined(DEP2)
+    test_a_wrapper,
+#else
+    NULL,
+#endif
+'''
+        self.assertEqual(code, expected)
+
+    def test_empty_deps(self):
+        """
+        Test empty dependency list.
+        :return:
+        """
+        code = gen_dispatch('test_a', [])
+        expected = '''
+    test_a_wrapper,
+'''
+        self.assertEqual(code, expected)
+
+
+class StringIOWrapper(StringIO, object):
+    """
+    file like class to mock file object in tests.
+    """
+    def __init__(self, file_name, data, line_no = 1):
+        """
+        Init file handle.
+
+        :param file_name:
+        :param data:
+        :param line_no:
+        """
+        super(StringIOWrapper, self).__init__(data)
+        self.line_no = line_no
+        self.name = file_name
+
+    def next(self):
+        """
+        Iterator return impl.
+        :return:
+        """
+        line = super(StringIOWrapper, self).next()
+        return line
+
+    def readline(self, limit=0):
+        """
+        Wrap the base class readline.
+
+        :param limit:
+        :return:
+        """
+        line = super(StringIOWrapper, self).readline()
+        if line:
+            self.line_no += 1
+        return line
+
+
+class ParseUntilPattern(TestCase):
+    """
+    Test Suite for testing parse_until_pattern().
+    """
+
+    def test_suite_headers(self):
+        """
+        Test that suite headers are parsed correctly.
+
+        :return:
+        """
+        data = '''#include "mbedcrypto/ecp.h"
+
+#define ECP_PF_UNKNOWN     -1
+/* END_HEADER */
+'''
+        expected = '''#line 1 "test_suite_ut.function"
+#include "mbedcrypto/ecp.h"
+
+#define ECP_PF_UNKNOWN     -1
+'''
+        s = StringIOWrapper('test_suite_ut.function', data, line_no=0)
+        headers = parse_until_pattern(s, END_HEADER_REGEX)
+        self.assertEqual(headers, expected)
+
+    def test_line_no(self):
+        """
+        Test that #line is set to correct line no. in source .function file.
+
+        :return:
+        """
+        data = '''#include "mbedcrypto/ecp.h"
+
+#define ECP_PF_UNKNOWN     -1
+/* END_HEADER */
+'''
+        offset_line_no = 5
+        expected = '''#line %d "test_suite_ut.function"
+#include "mbedcrypto/ecp.h"
+
+#define ECP_PF_UNKNOWN     -1
+''' % (offset_line_no + 1)
+        s = StringIOWrapper('test_suite_ut.function', data, offset_line_no)
+        headers = parse_until_pattern(s, END_HEADER_REGEX)
+        self.assertEqual(headers, expected)
+
+    def test_no_end_header_comment(self):
+        """
+        Test that InvalidFileFormat is raised when end header comment is missing.
+        :return:
+        """
+        data = '''#include "mbedcrypto/ecp.h"
+
+#define ECP_PF_UNKNOWN     -1
+
+'''
+        s = StringIOWrapper('test_suite_ut.function', data)
+        self.assertRaises(InvalidFileFormat, parse_until_pattern, s, END_HEADER_REGEX)
+
+
+class ParseSuiteDeps(TestCase):
+    """
+    Test Suite for testing parse_suite_deps().
+    """
+
+    def test_suite_deps(self):
+        """
+
+        :return:
+        """
+        data = '''
+ * depends_on:MBEDCRYPTO_ECP_C
+ * END_DEPENDENCIES
+ */
+'''
+        expected = ['MBEDCRYPTO_ECP_C']
+        s = StringIOWrapper('test_suite_ut.function', data)
+        deps = parse_suite_deps(s)
+        self.assertEqual(deps, expected)
+
+    def test_no_end_dep_comment(self):
+        """
+        Test that InvalidFileFormat is raised when end dep comment is missing.
+        :return:
+        """
+        data = '''
+* depends_on:MBEDCRYPTO_ECP_C
+'''
+        s = StringIOWrapper('test_suite_ut.function', data)
+        self.assertRaises(InvalidFileFormat, parse_suite_deps, s)
+
+    def test_deps_split(self):
+        """
+        Test that InvalidFileFormat is raised when end dep comment is missing.
+        :return:
+        """
+        data = '''
+ * depends_on:MBEDCRYPTO_ECP_C:A:B:   C  : D :F : G: !H
+ * END_DEPENDENCIES
+ */
+'''
+        expected = ['MBEDCRYPTO_ECP_C', 'A', 'B', 'C', 'D', 'F', 'G', '!H']
+        s = StringIOWrapper('test_suite_ut.function', data)
+        deps = parse_suite_deps(s)
+        self.assertEqual(deps, expected)
+
+
+class ParseFuncDeps(TestCase):
+    """
+    Test Suite for testing parse_function_deps()
+    """
+
+    def test_function_deps(self):
+        """
+        Test that parse_function_deps() correctly parses function dependencies.
+        :return:
+        """
+        line = '/* BEGIN_CASE depends_on:MBEDCRYPTO_ENTROPY_NV_SEED:MBEDCRYPTO_FS_IO */'
+        expected = ['MBEDCRYPTO_ENTROPY_NV_SEED', 'MBEDCRYPTO_FS_IO']
+        deps = parse_function_deps(line)
+        self.assertEqual(deps, expected)
+
+    def test_no_deps(self):
+        """
+        Test that parse_function_deps() correctly parses function dependencies.
+        :return:
+        """
+        line = '/* BEGIN_CASE */'
+        deps = parse_function_deps(line)
+        self.assertEqual(deps, [])
+
+    def test_poorly_defined_deps(self):
+        """
+        Test that parse_function_deps() correctly parses function dependencies.
+        :return:
+        """
+        line = '/* BEGIN_CASE depends_on:MBEDCRYPTO_FS_IO: A : !B:C : F*/'
+        deps = parse_function_deps(line)
+        self.assertEqual(deps, ['MBEDCRYPTO_FS_IO', 'A', '!B', 'C', 'F'])
+
+
+class ParseFuncSignature(TestCase):
+    """
+    Test Suite for parse_function_signature().
+    """
+
+    def test_int_and_char_params(self):
+        """
+        Test int and char parameters parsing
+        :return:
+        """
+        line = 'void entropy_threshold( char * a, int b, int result )'
+        name, args, local, arg_dispatch = parse_function_signature(line)
+        self.assertEqual(name, 'entropy_threshold')
+        self.assertEqual(args, ['char*', 'int', 'int'])
+        self.assertEqual(local, '')
+        self.assertEqual(arg_dispatch, ['(char *) params[0]', '*( (int *) params[1] )', '*( (int *) params[2] )'])
+
+    def test_hex_params(self):
+        """
+        Test hex parameters parsing
+        :return:
+        """
+        line = 'void entropy_threshold( char * a, HexParam_t * h, int result )'
+        name, args, local, arg_dispatch = parse_function_signature(line)
+        self.assertEqual(name, 'entropy_threshold')
+        self.assertEqual(args, ['char*', 'hex', 'int'])
+        self.assertEqual(local, '    HexParam_t hex1 = {(uint8_t *) params[1], *( (uint32_t *) params[2] )};\n')
+        self.assertEqual(arg_dispatch, ['(char *) params[0]', '&hex1', '*( (int *) params[3] )'])
+
+    def test_non_void_function(self):
+        """
+        Test invalid signature (non void).
+        :return:
+        """
+        line = 'int entropy_threshold( char * a, HexParam_t * h, int result )'
+        self.assertRaises(ValueError, parse_function_signature, line)
+
+    def test_unsupported_arg(self):
+        """
+        Test unsupported arguments (not among int, char * and HexParam_t)
+        :return:
+        """
+        line = 'int entropy_threshold( char * a, HexParam_t * h, int * result )'
+        self.assertRaises(ValueError, parse_function_signature, line)
+
+    def test_no_params(self):
+        """
+        Test no parameters.
+        :return:
+        """
+        line = 'void entropy_threshold()'
+        name, args, local, arg_dispatch = parse_function_signature(line)
+        self.assertEqual(name, 'entropy_threshold')
+        self.assertEqual(args, [])
+        self.assertEqual(local, '')
+        self.assertEqual(arg_dispatch, [])
+
+
+class ParseFunctionCode(TestCase):
+    """
+    Test suite for testing parse_function_code()
+    """
+
+    def test_no_function(self):
+        """
+        Test no test function found.
+        :return:
+        """
+        data = '''
+No
+test
+function
+'''
+        s = StringIOWrapper('test_suite_ut.function', data)
+        self.assertRaises(InvalidFileFormat, parse_function_code, s, [], [])
+
+    def test_no_end_case_comment(self):
+        """
+        Test missing end case.
+        :return:
+        """
+        data = '''
+void test_func()
+{
+}
+'''
+        s = StringIOWrapper('test_suite_ut.function', data)
+        self.assertRaises(InvalidFileFormat, parse_function_code, s, [], [])
+
+    @patch("generate_test_code.parse_function_signature")
+    def test_parse_function_signature_called(self, parse_function_signature_mock):
+        """
+        Test parse_function_code()
+        :return:
+        """
+        parse_function_signature_mock.return_value = ('test_func', [], '', [])
+        data = '''
+void test_func()
+{
+}
+'''
+        s = StringIOWrapper('test_suite_ut.function', data)
+        self.assertRaises(InvalidFileFormat, parse_function_code, s, [], [])
+        self.assertTrue(parse_function_signature_mock.called)
+        parse_function_signature_mock.assert_called_with('void test_func()\n')
+
+    @patch("generate_test_code.gen_dispatch")
+    @patch("generate_test_code.gen_deps")
+    @patch("generate_test_code.gen_function_wrapper")
+    @patch("generate_test_code.parse_function_signature")
+    def test_return(self, parse_function_signature_mock,
+                                             gen_function_wrapper_mock,
+                                             gen_deps_mock,
+                                             gen_dispatch_mock):
+        """
+        Test generated code.
+        :return:
+        """
+        parse_function_signature_mock.return_value = ('func', [], '', [])
+        gen_function_wrapper_mock.return_value = ''
+        gen_deps_mock.side_effect = gen_deps
+        gen_dispatch_mock.side_effect = gen_dispatch
+        data = '''
+void func()
+{
+    ba ba black sheep
+    have you any wool
+}
+/* END_CASE */
+'''
+        s = StringIOWrapper('test_suite_ut.function', data)
+        name, arg, code, dispatch_code = parse_function_code(s, [], [])
+
+        #self.assertRaises(InvalidFileFormat, parse_function_code, s, [], [])
+        self.assertTrue(parse_function_signature_mock.called)
+        parse_function_signature_mock.assert_called_with('void func()\n')
+        gen_function_wrapper_mock.assert_called_with('test_func', '', [])
+        self.assertEqual(name, 'test_func')
+        self.assertEqual(arg, [])
+        expected = '''#line 2 "test_suite_ut.function"
+void test_func()
+{
+    ba ba black sheep
+    have you any wool
+exit:
+    ;;
+}
+'''
+        self.assertEqual(code, expected)
+        self.assertEqual(dispatch_code, "\n    test_func_wrapper,\n")
+
+    @patch("generate_test_code.gen_dispatch")
+    @patch("generate_test_code.gen_deps")
+    @patch("generate_test_code.gen_function_wrapper")
+    @patch("generate_test_code.parse_function_signature")
+    def test_with_exit_label(self, parse_function_signature_mock,
+                           gen_function_wrapper_mock,
+                           gen_deps_mock,
+                           gen_dispatch_mock):
+        """
+        Test when exit label is present.
+        :return:
+        """
+        parse_function_signature_mock.return_value = ('func', [], '', [])
+        gen_function_wrapper_mock.return_value = ''
+        gen_deps_mock.side_effect = gen_deps
+        gen_dispatch_mock.side_effect = gen_dispatch
+        data = '''
+void func()
+{
+    ba ba black sheep
+    have you any wool
+exit:
+    yes sir yes sir
+    3 bags full
+}
+/* END_CASE */
+'''
+        s = StringIOWrapper('test_suite_ut.function', data)
+        name, arg, code, dispatch_code = parse_function_code(s, [], [])
+
+        expected = '''#line 2 "test_suite_ut.function"
+void test_func()
+{
+    ba ba black sheep
+    have you any wool
+exit:
+    yes sir yes sir
+    3 bags full
+}
+'''
+        self.assertEqual(code, expected)
+
+
+class ParseFunction(TestCase):
+    """
+    Test Suite for testing parse_functions()
+    """
+
+    @patch("generate_test_code.parse_until_pattern")
+    def test_begin_header(self, parse_until_pattern_mock):
+        """
+        Test that begin header is checked and parse_until_pattern() is called.
+        :return:
+        """
+        def stop(this):
+            raise Exception
+        parse_until_pattern_mock.side_effect = stop
+        data = '''/* BEGIN_HEADER */
+#include "mbedcrypto/ecp.h"
+
+#define ECP_PF_UNKNOWN     -1
+/* END_HEADER */
+'''
+        s = StringIOWrapper('test_suite_ut.function', data)
+        self.assertRaises(Exception, parse_functions, s)
+        parse_until_pattern_mock.assert_called_with(s, END_HEADER_REGEX)
+        self.assertEqual(s.line_no, 2)
+
+    @patch("generate_test_code.parse_until_pattern")
+    def test_begin_helper(self, parse_until_pattern_mock):
+        """
+        Test that begin helper is checked and parse_until_pattern() is called.
+        :return:
+        """
+        def stop(this):
+            raise Exception
+        parse_until_pattern_mock.side_effect = stop
+        data = '''/* BEGIN_SUITE_HELPERS */
+void print_helloworld()
+{
+    printf ("Hello World!\n");
+}
+/* END_SUITE_HELPERS */
+'''
+        s = StringIOWrapper('test_suite_ut.function', data)
+        self.assertRaises(Exception, parse_functions, s)
+        parse_until_pattern_mock.assert_called_with(s, END_SUITE_HELPERS_REGEX)
+        self.assertEqual(s.line_no, 2)
+
+    @patch("generate_test_code.parse_suite_deps")
+    def test_begin_dep(self, parse_suite_deps_mock):
+        """
+        Test that begin dep is checked and parse_suite_deps() is called.
+        :return:
+        """
+        def stop(this):
+            raise Exception
+        parse_suite_deps_mock.side_effect = stop
+        data = '''/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDCRYPTO_ECP_C
+ * END_DEPENDENCIES
+ */
+'''
+        s = StringIOWrapper('test_suite_ut.function', data)
+        self.assertRaises(Exception, parse_functions, s)
+        parse_suite_deps_mock.assert_called_with(s)
+        self.assertEqual(s.line_no, 2)
+
+    @patch("generate_test_code.parse_function_deps")
+    def test_begin_function_dep(self, parse_function_deps_mock):
+        """
+        Test that begin dep is checked and parse_function_deps() is called.
+        :return:
+        """
+        def stop(this):
+            raise Exception
+        parse_function_deps_mock.side_effect = stop
+
+        deps_str = '/* BEGIN_CASE depends_on:MBEDCRYPTO_ENTROPY_NV_SEED:MBEDCRYPTO_FS_IO */\n'
+        data = '''%svoid test_func()
+{
+}
+''' % deps_str
+        s = StringIOWrapper('test_suite_ut.function', data)
+        self.assertRaises(Exception, parse_functions, s)
+        parse_function_deps_mock.assert_called_with(deps_str)
+        self.assertEqual(s.line_no, 2)
+
+    @patch("generate_test_code.parse_function_code")
+    @patch("generate_test_code.parse_function_deps")
+    def test_return(self, parse_function_deps_mock, parse_function_code_mock):
+        """
+        Test that begin case is checked and parse_function_code() is called.
+        :return:
+        """
+        def stop(this):
+            raise Exception
+        parse_function_deps_mock.return_value = []
+        in_func_code= '''void test_func()
+{
+}
+'''
+        func_dispatch = '''
+    test_func_wrapper,
+'''
+        parse_function_code_mock.return_value = 'test_func', [], in_func_code, func_dispatch
+        deps_str = '/* BEGIN_CASE depends_on:MBEDCRYPTO_ENTROPY_NV_SEED:MBEDCRYPTO_FS_IO */\n'
+        data = '''%svoid test_func()
+{
+}
+''' % deps_str
+        s = StringIOWrapper('test_suite_ut.function', data)
+        suite_deps, dispatch_code, func_code, func_info = parse_functions(s)
+        parse_function_deps_mock.assert_called_with(deps_str)
+        parse_function_code_mock.assert_called_with(s, [], [])
+        self.assertEqual(s.line_no, 5)
+        self.assertEqual(suite_deps, [])
+        expected_dispatch_code = '''/* Function Id: 0 */
+
+    test_func_wrapper,
+'''
+        self.assertEqual(dispatch_code, expected_dispatch_code)
+        self.assertEqual(func_code, in_func_code)
+        self.assertEqual(func_info, {'test_func': (0, [])})
+
+    def test_parsing(self):
+        """
+        Test case parsing.
+        :return:
+        """
+        data = '''/* BEGIN_HEADER */
+#include "mbedcrypto/ecp.h"
+
+#define ECP_PF_UNKNOWN     -1
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDCRYPTO_ECP_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE depends_on:MBEDCRYPTO_ENTROPY_NV_SEED:MBEDCRYPTO_FS_IO */
+void func1()
+{
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDCRYPTO_ENTROPY_NV_SEED:MBEDCRYPTO_FS_IO */
+void func2()
+{
+}
+/* END_CASE */
+'''
+        s = StringIOWrapper('test_suite_ut.function', data)
+        suite_deps, dispatch_code, func_code, func_info = parse_functions(s)
+        self.assertEqual(s.line_no, 23)
+        self.assertEqual(suite_deps, ['MBEDCRYPTO_ECP_C'])
+
+        expected_dispatch_code = '''/* Function Id: 0 */
+
+#if defined(MBEDCRYPTO_ECP_C) && defined(MBEDCRYPTO_ENTROPY_NV_SEED) && defined(MBEDCRYPTO_FS_IO)
+    test_func1_wrapper,
+#else
+    NULL,
+#endif
+/* Function Id: 1 */
+
+#if defined(MBEDCRYPTO_ECP_C) && defined(MBEDCRYPTO_ENTROPY_NV_SEED) && defined(MBEDCRYPTO_FS_IO)
+    test_func2_wrapper,
+#else
+    NULL,
+#endif
+'''
+        self.assertEqual(dispatch_code, expected_dispatch_code)
+        expected_func_code = '''#if defined(MBEDCRYPTO_ECP_C)
+#line 3 "test_suite_ut.function"
+#include "mbedcrypto/ecp.h"
+
+#define ECP_PF_UNKNOWN     -1
+#if defined(MBEDCRYPTO_ENTROPY_NV_SEED)
+#if defined(MBEDCRYPTO_FS_IO)
+#line 14 "test_suite_ut.function"
+void test_func1()
+{
+exit:
+    ;;
+}
+
+void test_func1_wrapper( void ** params )
+{
+    (void)params;
+
+    test_func1(  );
+}
+#endif /* MBEDCRYPTO_FS_IO */
+#endif /* MBEDCRYPTO_ENTROPY_NV_SEED */
+#if defined(MBEDCRYPTO_ENTROPY_NV_SEED)
+#if defined(MBEDCRYPTO_FS_IO)
+#line 20 "test_suite_ut.function"
+void test_func2()
+{
+exit:
+    ;;
+}
+
+void test_func2_wrapper( void ** params )
+{
+    (void)params;
+
+    test_func2(  );
+}
+#endif /* MBEDCRYPTO_FS_IO */
+#endif /* MBEDCRYPTO_ENTROPY_NV_SEED */
+#endif /* MBEDCRYPTO_ECP_C */
+'''
+        self.assertEqual(func_code, expected_func_code)
+        self.assertEqual(func_info, {'test_func1': (0, []), 'test_func2': (1, [])})
+
+    def test_same_function_name(self):
+        """
+        Test name conflict.
+        :return:
+        """
+        data = '''/* BEGIN_HEADER */
+#include "mbedcrypto/ecp.h"
+
+#define ECP_PF_UNKNOWN     -1
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDCRYPTO_ECP_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE depends_on:MBEDCRYPTO_ENTROPY_NV_SEED:MBEDCRYPTO_FS_IO */
+void func()
+{
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDCRYPTO_ENTROPY_NV_SEED:MBEDCRYPTO_FS_IO */
+void func()
+{
+}
+/* END_CASE */
+'''
+        s = StringIOWrapper('test_suite_ut.function', data)
+        self.assertRaises(AssertionError, parse_functions, s)
+
+
+class ExcapedSplit(TestCase):
+    """
+    Test suite for testing escaped_split().
+    Note: Since escaped_split() output is used to write back to the intermediate data file. Any escape characters
+     in the input are retained in the output.
+    """
+
+    def test_invalid_input(self):
+        """
+        Test when input split character is not a character.
+        :return:
+        """
+        self.assertRaises(ValueError, escaped_split, '', 'string')
+
+    def test_empty_string(self):
+        """
+        Test empty strig input.
+        :return:
+        """
+        splits = escaped_split('', ':')
+        self.assertEqual(splits, [])
+
+    def test_no_escape(self):
+        """
+        Test with no escape character. The behaviour should be same as str.split()
+        :return:
+        """
+        s = 'yahoo:google'
+        splits = escaped_split(s, ':')
+        self.assertEqual(splits, s.split(':'))
+
+    def test_escaped_input(self):
+        """
+        Test imput that has escaped delimiter.
+        :return:
+        """
+        s = 'yahoo\:google:facebook'
+        splits = escaped_split(s, ':')
+        self.assertEqual(splits, ['yahoo\:google', 'facebook'])
+
+    def test_escaped_escape(self):
+        """
+        Test imput that has escaped delimiter.
+        :return:
+        """
+        s = 'yahoo\\\:google:facebook'
+        splits = escaped_split(s, ':')
+        self.assertEqual(splits, ['yahoo\\\\', 'google', 'facebook'])
+
+    def test_all_at_once(self):
+        """
+        Test imput that has escaped delimiter.
+        :return:
+        """
+        s = 'yahoo\\\:google:facebook\:instagram\\\:bbc\\\\:wikipedia'
+        splits = escaped_split(s, ':')
+        self.assertEqual(splits, ['yahoo\\\\', 'google', 'facebook\:instagram\\\\', 'bbc\\\\', 'wikipedia'])
+
+
+class ParseTestData(TestCase):
+    """
+    Test suite for parse test data.
+    """
+
+    def test_parser(self):
+        """
+        Test that tests are parsed correctly from data file.
+        :return:
+        """
+        data = """
+Diffie-Hellman full exchange #1
+dhm_do_dhm:10:"23":10:"5"
+
+Diffie-Hellman full exchange #2
+dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
+
+Diffie-Hellman full exchange #3
+dhm_do_dhm:10:"9345098382739712938719287391879381271":10:"9345098792137312973297123912791271"
+
+Diffie-Hellman selftest
+dhm_selftest:
+"""
+        s = StringIOWrapper('test_suite_ut.function', data)
+        tests = [(name, function, deps, args) for name, function, deps, args in parse_test_data(s)]
+        t1, t2, t3, t4 = tests
+        self.assertEqual(t1[0], 'Diffie-Hellman full exchange #1')
+        self.assertEqual(t1[1], 'dhm_do_dhm')
+        self.assertEqual(t1[2], [])
+        self.assertEqual(t1[3], ['10', '"23"', '10', '"5"'])
+
+        self.assertEqual(t2[0], 'Diffie-Hellman full exchange #2')
+        self.assertEqual(t2[1], 'dhm_do_dhm')
+        self.assertEqual(t2[2], [])
+        self.assertEqual(t2[3], ['10', '"93450983094850938450983409623"', '10', '"9345098304850938450983409622"'])
+
+        self.assertEqual(t3[0], 'Diffie-Hellman full exchange #3')
+        self.assertEqual(t3[1], 'dhm_do_dhm')
+        self.assertEqual(t3[2], [])
+        self.assertEqual(t3[3], ['10', '"9345098382739712938719287391879381271"', '10', '"9345098792137312973297123912791271"'])
+
+        self.assertEqual(t4[0], 'Diffie-Hellman selftest')
+        self.assertEqual(t4[1], 'dhm_selftest')
+        self.assertEqual(t4[2], [])
+        self.assertEqual(t4[3], [])
+
+    def test_with_dependencies(self):
+        """
+        Test that tests with dependencies are parsed.
+        :return:
+        """
+        data = """
+Diffie-Hellman full exchange #1
+depends_on:YAHOO
+dhm_do_dhm:10:"23":10:"5"
+
+Diffie-Hellman full exchange #2
+dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
+
+"""
+        s = StringIOWrapper('test_suite_ut.function', data)
+        tests = [(name, function, deps, args) for name, function, deps, args in parse_test_data(s)]
+        t1, t2 = tests
+        self.assertEqual(t1[0], 'Diffie-Hellman full exchange #1')
+        self.assertEqual(t1[1], 'dhm_do_dhm')
+        self.assertEqual(t1[2], ['YAHOO'])
+        self.assertEqual(t1[3], ['10', '"23"', '10', '"5"'])
+
+        self.assertEqual(t2[0], 'Diffie-Hellman full exchange #2')
+        self.assertEqual(t2[1], 'dhm_do_dhm')
+        self.assertEqual(t2[2], [])
+        self.assertEqual(t2[3], ['10', '"93450983094850938450983409623"', '10', '"9345098304850938450983409622"'])
+
+    def test_no_args(self):
+        """
+        Test AssertionError is raised when test function name and args line is missing.
+        :return:
+        """
+        data = """
+Diffie-Hellman full exchange #1
+depends_on:YAHOO
+
+
+Diffie-Hellman full exchange #2
+dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
+
+"""
+        s = StringIOWrapper('test_suite_ut.function', data)
+        e = None
+        try:
+            for x, y, z, a in parse_test_data(s):
+                pass
+        except AssertionError, e:
+            pass
+        self.assertEqual(type(e), AssertionError)
+
+    def test_incomplete_data(self):
+        """
+        Test AssertionError is raised when test function name and args line is missing.
+        :return:
+        """
+        data = """
+Diffie-Hellman full exchange #1
+depends_on:YAHOO
+"""
+        s = StringIOWrapper('test_suite_ut.function', data)
+        e = None
+        try:
+            for x, y, z, a in parse_test_data(s):
+                pass
+        except AssertionError, e:
+            pass
+        self.assertEqual(type(e), AssertionError)
+
+
+class GenDepCheck(TestCase):
+    """
+    Test suite for gen_dep_check(). It is assumed this function is called with valid inputs.
+    """
+
+    def test_gen_dep_check(self):
+        """
+        Test that dependency check code generated correctly.
+        :return:
+        """
+        expected = """
+        case 5:
+            {
+#if defined(YAHOO)
+                ret = DEPENDENCY_SUPPORTED;
+#else
+                ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+            }
+            break;"""
+        out = gen_dep_check(5, 'YAHOO')
+        self.assertEqual(out, expected)
+
+    def test_noT(self):
+        """
+        Test dependency with !.
+        :return:
+        """
+        expected = """
+        case 5:
+            {
+#if !defined(YAHOO)
+                ret = DEPENDENCY_SUPPORTED;
+#else
+                ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+            }
+            break;"""
+        out = gen_dep_check(5, '!YAHOO')
+        self.assertEqual(out, expected)
+
+    def test_empty_dependency(self):
+        """
+        Test invalid dependency input.
+        :return:
+        """
+        self.assertRaises(AssertionError, gen_dep_check, 5, '!')
+
+    def test_negative_dep_id(self):
+        """
+        Test invalid dependency input.
+        :return:
+        """
+        self.assertRaises(AssertionError, gen_dep_check, -1, 'YAHOO')
+
+
+class GenExpCheck(TestCase):
+    """
+    Test suite for gen_expression_check(). It is assumed this function is called with valid inputs.
+    """
+
+    def test_gen_exp_check(self):
+        """
+        Test that expression check code generated correctly.
+        :return:
+        """
+        expected = """
+        case 5:
+            {
+                *out_value = YAHOO;
+            }
+            break;"""
+        out = gen_expression_check(5, 'YAHOO')
+        self.assertEqual(out, expected)
+
+    def test_invalid_expression(self):
+        """
+        Test invalid expression input.
+        :return:
+        """
+        self.assertRaises(AssertionError, gen_expression_check, 5, '')
+
+    def test_negative_exp_id(self):
+        """
+        Test invalid expression id.
+        :return:
+        """
+        self.assertRaises(AssertionError, gen_expression_check, -1, 'YAHOO')
+
+
+class WriteDeps(TestCase):
+    """
+    Test suite for testing write_deps.
+    """
+
+    def test_no_test_deps(self):
+        """
+        Test when test_deps is empty.
+        :return:
+        """
+        s = StringIOWrapper('test_suite_ut.data', '')
+        unique_deps = []
+        dep_check_code = write_deps(s, [], unique_deps)
+        self.assertEqual(dep_check_code, '')
+        self.assertEqual(len(unique_deps), 0)
+        self.assertEqual(s.getvalue(), '')
+
+    def test_unique_dep_ids(self):
+        """
+
+        :return:
+        """
+        s = StringIOWrapper('test_suite_ut.data', '')
+        unique_deps = []
+        dep_check_code = write_deps(s, ['DEP3', 'DEP2', 'DEP1'], unique_deps)
+        expect_dep_check_code = '''
+        case 0:
+            {
+#if defined(DEP3)
+                ret = DEPENDENCY_SUPPORTED;
+#else
+                ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+            }
+            break;
+        case 1:
+            {
+#if defined(DEP2)
+                ret = DEPENDENCY_SUPPORTED;
+#else
+                ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+            }
+            break;
+        case 2:
+            {
+#if defined(DEP1)
+                ret = DEPENDENCY_SUPPORTED;
+#else
+                ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+            }
+            break;'''
+        self.assertEqual(dep_check_code, expect_dep_check_code)
+        self.assertEqual(len(unique_deps), 3)
+        self.assertEqual(s.getvalue(), 'depends_on:0:1:2\n')
+
+    def test_dep_id_repeat(self):
+        """
+
+        :return:
+        """
+        s = StringIOWrapper('test_suite_ut.data', '')
+        unique_deps = []
+        dep_check_code = ''
+        dep_check_code += write_deps(s, ['DEP3', 'DEP2'], unique_deps)
+        dep_check_code += write_deps(s, ['DEP2', 'DEP1'], unique_deps)
+        dep_check_code += write_deps(s, ['DEP1', 'DEP3'], unique_deps)
+        expect_dep_check_code = '''
+        case 0:
+            {
+#if defined(DEP3)
+                ret = DEPENDENCY_SUPPORTED;
+#else
+                ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+            }
+            break;
+        case 1:
+            {
+#if defined(DEP2)
+                ret = DEPENDENCY_SUPPORTED;
+#else
+                ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+            }
+            break;
+        case 2:
+            {
+#if defined(DEP1)
+                ret = DEPENDENCY_SUPPORTED;
+#else
+                ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+            }
+            break;'''
+        self.assertEqual(dep_check_code, expect_dep_check_code)
+        self.assertEqual(len(unique_deps), 3)
+        self.assertEqual(s.getvalue(), 'depends_on:0:1\ndepends_on:1:2\ndepends_on:2:0\n')
+
+
+class WriteParams(TestCase):
+    """
+    Test Suite for testing write_parameters().
+    """
+
+    def test_no_params(self):
+        """
+        Test with empty test_args
+        :return:
+        """
+        s = StringIOWrapper('test_suite_ut.data', '')
+        unique_expressions = []
+        expression_code = write_parameters(s, [], [], unique_expressions)
+        self.assertEqual(len(unique_expressions), 0)
+        self.assertEqual(expression_code, '')
+        self.assertEqual(s.getvalue(), '\n')
+
+    def test_no_exp_param(self):
+        """
+        Test when there is no macro or expression in the params.
+        :return:
+        """
+        s = StringIOWrapper('test_suite_ut.data', '')
+        unique_expressions = []
+        expression_code = write_parameters(s, ['"Yahoo"', '"abcdef00"', '0'], ['char*', 'hex', 'int'],
+                                           unique_expressions)
+        self.assertEqual(len(unique_expressions), 0)
+        self.assertEqual(expression_code, '')
+        self.assertEqual(s.getvalue(), ':char*:"Yahoo":hex:"abcdef00":int:0\n')
+
+    def test_hex_format_int_param(self):
+        """
+        Test int parameter in hex format.
+        :return:
+        """
+        s = StringIOWrapper('test_suite_ut.data', '')
+        unique_expressions = []
+        expression_code = write_parameters(s, ['"Yahoo"', '"abcdef00"', '0xAA'], ['char*', 'hex', 'int'],
+                                           unique_expressions)
+        self.assertEqual(len(unique_expressions), 0)
+        self.assertEqual(expression_code, '')
+        self.assertEqual(s.getvalue(), ':char*:"Yahoo":hex:"abcdef00":int:0xAA\n')
+
+    def test_with_exp_param(self):
+        """
+        Test when there is macro or expression in the params.
+        :return:
+        """
+        s = StringIOWrapper('test_suite_ut.data', '')
+        unique_expressions = []
+        expression_code = write_parameters(s, ['"Yahoo"', '"abcdef00"', '0', 'MACRO1', 'MACRO2', 'MACRO3'],
+                                           ['char*', 'hex', 'int', 'int', 'int', 'int'],
+                                           unique_expressions)
+        self.assertEqual(len(unique_expressions), 3)
+        self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
+        expected_expression_code = '''
+        case 0:
+            {
+                *out_value = MACRO1;
+            }
+            break;
+        case 1:
+            {
+                *out_value = MACRO2;
+            }
+            break;
+        case 2:
+            {
+                *out_value = MACRO3;
+            }
+            break;'''
+        self.assertEqual(expression_code, expected_expression_code)
+        self.assertEqual(s.getvalue(), ':char*:"Yahoo":hex:"abcdef00":int:0:exp:0:exp:1:exp:2\n')
+
+    def test_with_repeate_calls(self):
+        """
+        Test when write_parameter() is called with same macro or expression.
+        :return:
+        """
+        s = StringIOWrapper('test_suite_ut.data', '')
+        unique_expressions = []
+        expression_code = ''
+        expression_code += write_parameters(s, ['"Yahoo"', 'MACRO1', 'MACRO2'], ['char*', 'int', 'int'],
+                                            unique_expressions)
+        expression_code += write_parameters(s, ['"abcdef00"', 'MACRO2', 'MACRO3'], ['hex', 'int', 'int'],
+                                            unique_expressions)
+        expression_code += write_parameters(s, ['0', 'MACRO3', 'MACRO1'], ['int', 'int', 'int'],
+                                            unique_expressions)
+        self.assertEqual(len(unique_expressions), 3)
+        self.assertEqual(unique_expressions, ['MACRO1', 'MACRO2', 'MACRO3'])
+        expected_expression_code = '''
+        case 0:
+            {
+                *out_value = MACRO1;
+            }
+            break;
+        case 1:
+            {
+                *out_value = MACRO2;
+            }
+            break;
+        case 2:
+            {
+                *out_value = MACRO3;
+            }
+            break;'''
+        self.assertEqual(expression_code, expected_expression_code)
+        expected_data_file = ''':char*:"Yahoo":exp:0:exp:1
+:hex:"abcdef00":exp:1:exp:2
+:int:0:exp:2:exp:0
+'''
+        self.assertEqual(s.getvalue(), expected_data_file)
+
+
+class GenTestSuiteDepsChecks(TestCase):
+    """
+
+    """
+    def test_empty_suite_deps(self):
+        """
+        Test with empty suite_deps list.
+
+        :return:
+        """
+        dep_check_code, expression_code = gen_suite_deps_checks([], 'DEP_CHECK_CODE', 'EXPRESSION_CODE')
+        self.assertEqual(dep_check_code, 'DEP_CHECK_CODE')
+        self.assertEqual(expression_code, 'EXPRESSION_CODE')
+
+    def test_suite_deps(self):
+        """
+        Test with suite_deps list.
+
+        :return:
+        """
+        dep_check_code, expression_code = gen_suite_deps_checks(['SUITE_DEP'], 'DEP_CHECK_CODE', 'EXPRESSION_CODE')
+        exprectd_dep_check_code = '''
+#if defined(SUITE_DEP)
+DEP_CHECK_CODE
+#endif
+'''
+        expected_expression_code = '''
+#if defined(SUITE_DEP)
+EXPRESSION_CODE
+#endif
+'''
+        self.assertEqual(dep_check_code, exprectd_dep_check_code)
+        self.assertEqual(expression_code, expected_expression_code)
+
+    def test_no_dep_no_exp(self):
+        """
+        Test when there are no dependency and expression code.
+        :return:
+        """
+        dep_check_code, expression_code = gen_suite_deps_checks([], '', '')
+        self.assertEqual(dep_check_code, '')
+        self.assertEqual(expression_code, '')
+
+
+class GenFromTestData(TestCase):
+    """
+    Test suite for gen_from_test_data()
+    """
+
+    @patch("generate_test_code.write_deps")
+    @patch("generate_test_code.write_parameters")
+    @patch("generate_test_code.gen_suite_deps_checks")
+    def test_intermediate_data_file(self, gen_suite_deps_checks_mock, write_parameters_mock, write_deps_mock):
+        """
+        Test that intermediate data file is written with expected data.
+        :return:
+        """
+        data = '''
+My test
+depends_on:DEP1
+func1:0
+'''
+        data_f = StringIOWrapper('test_suite_ut.data', data)
+        out_data_f = StringIOWrapper('test_suite_ut.datax', '')
+        func_info = {'test_func1': (1, ('int',))}
+        suite_deps = []
+        write_parameters_mock.side_effect = write_parameters
+        write_deps_mock.side_effect = write_deps
+        gen_suite_deps_checks_mock.side_effect = gen_suite_deps_checks
+        gen_from_test_data(data_f, out_data_f, func_info, suite_deps)
+        write_deps_mock.assert_called_with(out_data_f, ['DEP1'], ['DEP1'])
+        write_parameters_mock.assert_called_with(out_data_f, ['0'], ('int',), [])
+        expected_dep_check_code = '''
+        case 0:
+            {
+#if defined(DEP1)
+                ret = DEPENDENCY_SUPPORTED;
+#else
+                ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+            }
+            break;'''
+        gen_suite_deps_checks_mock.assert_called_with(suite_deps, expected_dep_check_code, '')
+
+    def test_function_not_found(self):
+        """
+        Test that AssertError is raised when function info in not found.
+        :return:
+        """
+        data = '''
+My test
+depends_on:DEP1
+func1:0
+'''
+        data_f = StringIOWrapper('test_suite_ut.data', data)
+        out_data_f = StringIOWrapper('test_suite_ut.datax', '')
+        func_info = {'test_func2': (1, ('int',))}
+        suite_deps = []
+        self.assertRaises(AssertionError, gen_from_test_data, data_f, out_data_f, func_info, suite_deps)
+
+    def test_different_func_args(self):
+        """
+        Test that AssertError is raised when no. of parameters and function args differ.
+        :return:
+        """
+        data = '''
+My test
+depends_on:DEP1
+func1:0
+'''
+        data_f = StringIOWrapper('test_suite_ut.data', data)
+        out_data_f = StringIOWrapper('test_suite_ut.datax', '')
+        func_info = {'test_func2': (1, ('int','hex'))}
+        suite_deps = []
+        self.assertRaises(AssertionError, gen_from_test_data, data_f, out_data_f, func_info, suite_deps)
+
+    def test_output(self):
+        """
+        Test that intermediate data file is written with expected data.
+        :return:
+        """
+        data = '''
+My test 1
+depends_on:DEP1
+func1:0:0xfa:MACRO1:MACRO2
+
+My test 2
+depends_on:DEP1:DEP2
+func2:"yahoo":88:MACRO1
+'''
+        data_f = StringIOWrapper('test_suite_ut.data', data)
+        out_data_f = StringIOWrapper('test_suite_ut.datax', '')
+        func_info = {'test_func1': (0, ('int', 'int', 'int', 'int')), 'test_func2': (1, ('char*', 'int', 'int'))}
+        suite_deps = []
+        dep_check_code, expression_code = gen_from_test_data(data_f, out_data_f, func_info, suite_deps)
+        expected_dep_check_code = '''
+        case 0:
+            {
+#if defined(DEP1)
+                ret = DEPENDENCY_SUPPORTED;
+#else
+                ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+            }
+            break;
+        case 1:
+            {
+#if defined(DEP2)
+                ret = DEPENDENCY_SUPPORTED;
+#else
+                ret = DEPENDENCY_NOT_SUPPORTED;
+#endif
+            }
+            break;'''
+        expecrted_data = '''My test 1
+depends_on:0
+0:int:0:int:0xfa:exp:0:exp:1
+
+My test 2
+depends_on:0:1
+1:char*:"yahoo":int:88:exp:0
+
+'''
+        expected_expression_code = '''
+        case 0:
+            {
+                *out_value = MACRO1;
+            }
+            break;
+        case 1:
+            {
+                *out_value = MACRO2;
+            }
+            break;'''
+        self.assertEqual(dep_check_code, expected_dep_check_code)
+        self.assertEqual(out_data_f.getvalue(), expecrted_data)
+        self.assertEqual(expression_code, expected_expression_code)
+
+
+if __name__=='__main__':
+    unittest_main()
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
new file mode 100644
index 0000000..6f79701
--- /dev/null
+++ b/tests/suites/helpers.function
@@ -0,0 +1,469 @@
+#line 2 "suites/helpers.function"
+/*----------------------------------------------------------------------------*/
+/* Headers */
+
+#include <stdlib.h>
+
+#if defined(MBEDCRYPTO_PLATFORM_C)
+#include "mbedcrypto/platform.h"
+#else
+#include <stdio.h>
+#define mbedcrypto_fprintf    fprintf
+#define mbedcrypto_snprintf   snprintf
+#define mbedcrypto_calloc     calloc
+#define mbedcrypto_free       free
+#define mbedcrypto_exit       exit
+#define mbedcrypto_time       time
+#define mbedcrypto_time_t     time_t
+#define MBEDCRYPTO_EXIT_SUCCESS EXIT_SUCCESS
+#define MBEDCRYPTO_EXIT_FAILURE EXIT_FAILURE
+#endif
+
+#if defined(MBEDCRYPTO_MEMORY_BUFFER_ALLOC_C)
+#include "mbedcrypto/memory_buffer_alloc.h"
+#endif
+
+#ifdef _MSC_VER
+#include <basetsd.h>
+typedef UINT32 uint32_t;
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
+#else
+#include <stdint.h>
+#endif
+
+#include <string.h>
+
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+#include <unistd.h>
+#endif
+
+/* Type for Hex parameters */
+typedef struct HexParam_tag
+{
+    uint8_t *   x;
+    uint32_t    len;
+} HexParam_t;
+
+/*----------------------------------------------------------------------------*/
+/* Constants */
+
+#define DEPENDENCY_SUPPORTED            0
+#define KEY_VALUE_MAPPING_FOUND         0
+#define DISPATCH_TEST_SUCCESS           0
+
+#define KEY_VALUE_MAPPING_NOT_FOUND     -1
+#define DEPENDENCY_NOT_SUPPORTED        -2
+#define DISPATCH_TEST_FN_NOT_FOUND      -3
+#define DISPATCH_INVALID_TEST_DATA      -4
+#define DISPATCH_UNSUPPORTED_SUITE      -5
+
+
+/*----------------------------------------------------------------------------*/
+/* Macros */
+
+#define TEST_ASSERT( TEST )                         \
+    do {                                            \
+        if( ! (TEST) )                              \
+        {                                           \
+            test_fail( #TEST, __LINE__, __FILE__ ); \
+            goto exit;                              \
+        }                                           \
+    } while( 0 )
+
+#define assert(a) if( !( a ) )                                      \
+{                                                                   \
+    mbedcrypto_fprintf( stderr, "Assertion Failed at %s:%d - %s\n",   \
+                             __FILE__, __LINE__, #a );              \
+    mbedcrypto_exit( 1 );                                             \
+}
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
+}
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
+}
+#endif
+
+
+/*----------------------------------------------------------------------------*/
+/* Global variables */
+
+
+static struct
+{
+    int failed;
+    const char *test;
+    const char *filename;
+    int line_no;
+}
+test_info;
+
+#if defined(MBEDCRYPTO_PLATFORM_C)
+mbedcrypto_platform_context platform_ctx;
+#endif
+
+/*----------------------------------------------------------------------------*/
+/* Helper flags for complex dependencies */
+
+/* Indicates whether we expect mbedcrypto_entropy_init
+ * to initialize some strong entropy source. */
+#if defined(MBEDCRYPTO_TEST_NULL_ENTROPY) ||             \
+    ( !defined(MBEDCRYPTO_NO_DEFAULT_ENTROPY_SOURCES) && \
+      ( !defined(MBEDCRYPTO_NO_PLATFORM_ENTROPY)  ||     \
+         defined(MBEDCRYPTO_HAVEGE_C)             ||     \
+         defined(MBEDCRYPTO_ENTROPY_HARDWARE_ALT) ||     \
+         defined(ENTROPY_NV_SEED) ) )
+#define ENTROPY_HAVE_STRONG
+#endif
+
+
+/*----------------------------------------------------------------------------*/
+/* Helper Functions */
+static int platform_setup()
+{
+    int ret = 0;
+#if defined(MBEDCRYPTO_PLATFORM_C)
+    ret = mbedcrypto_platform_setup( &platform_ctx );
+#endif /* MBEDCRYPTO_PLATFORM_C */
+    return( ret );
+}
+
+static void platform_teardown()
+{
+#if defined(MBEDCRYPTO_PLATFORM_C)
+    mbedcrypto_platform_teardown( &platform_ctx );
+#endif /* MBEDCRYPTO_PLATFORM_C */
+}
+
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+static int redirect_output( FILE** out_stream, const char* path )
+{
+    int stdout_fd = dup( fileno( *out_stream ) );
+
+    if( stdout_fd == -1 )
+    {
+        return -1;
+    }
+
+    fflush( *out_stream );
+    fclose( *out_stream );
+    *out_stream = fopen( path, "w" );
+
+    if( *out_stream == NULL )
+    {
+        return -1;
+    }
+
+    return stdout_fd;
+}
+
+static int restore_output( FILE** out_stream, int old_fd )
+{
+    fflush( *out_stream );
+    fclose( *out_stream );
+
+    *out_stream = fdopen( old_fd, "w" );
+    if( *out_stream == NULL )
+    {
+        return -1;
+    }
+
+    return 0;
+}
+
+static void close_output( FILE* out_stream )
+{
+    fclose( out_stream );
+}
+#endif /* __unix__ || __APPLE__ __MACH__ */
+
+static int unhexify( unsigned char *obuf, const char *ibuf )
+{
+    unsigned char c, c2;
+    int len = strlen( ibuf ) / 2;
+    assert( strlen( ibuf ) % 2 == 0 ); /* must be even number of bytes */
+
+    while( *ibuf != 0 )
+    {
+        c = *ibuf++;
+        if( c >= '0' && c <= '9' )
+            c -= '0';
+        else if( c >= 'a' && c <= 'f' )
+            c -= 'a' - 10;
+        else if( c >= 'A' && c <= 'F' )
+            c -= 'A' - 10;
+        else
+            assert( 0 );
+
+        c2 = *ibuf++;
+        if( c2 >= '0' && c2 <= '9' )
+            c2 -= '0';
+        else if( c2 >= 'a' && c2 <= 'f' )
+            c2 -= 'a' - 10;
+        else if( c2 >= 'A' && c2 <= 'F' )
+            c2 -= 'A' - 10;
+        else
+            assert( 0 );
+
+        *obuf++ = ( c << 4 ) | c2;
+    }
+
+    return len;
+}
+
+static void hexify( unsigned char *obuf, const unsigned char *ibuf, int len )
+{
+    unsigned char l, h;
+
+    while( len != 0 )
+    {
+        h = *ibuf / 16;
+        l = *ibuf % 16;
+
+        if( h < 10 )
+            *obuf++ = '0' + h;
+        else
+            *obuf++ = 'a' + h - 10;
+
+        if( l < 10 )
+            *obuf++ = '0' + l;
+        else
+            *obuf++ = 'a' + l - 10;
+
+        ++ibuf;
+        len--;
+    }
+}
+
+/**
+ * Allocate and zeroize a buffer.
+ *
+ * If the size if zero, a pointer to a zeroized 1-byte buffer is returned.
+ *
+ * For convenience, dies if allocation fails.
+ */
+static unsigned char *zero_alloc( size_t len )
+{
+    void *p;
+    size_t actual_len = ( len != 0 ) ? len : 1;
+
+    p = mbedcrypto_calloc( 1, actual_len );
+    assert( p != NULL );
+
+    memset( p, 0x00, actual_len );
+
+    return( p );
+}
+
+/**
+ * Allocate and fill a buffer from hex data.
+ *
+ * The buffer is sized exactly as needed. This allows to detect buffer
+ * overruns (including overreads) when running the test suite under valgrind.
+ *
+ * If the size if zero, a pointer to a zeroized 1-byte buffer is returned.
+ *
+ * For convenience, dies if allocation fails.
+ */
+static unsigned char *unhexify_alloc( const char *ibuf, size_t *olen )
+{
+    unsigned char *obuf;
+
+    *olen = strlen( ibuf ) / 2;
+
+    if( *olen == 0 )
+        return( zero_alloc( *olen ) );
+
+    obuf = mbedcrypto_calloc( 1, *olen );
+    assert( obuf != NULL );
+
+    (void) unhexify( obuf, ibuf );
+
+    return( obuf );
+}
+
+/**
+ * This function just returns data from rand().
+ * Although predictable and often similar on multiple
+ * runs, this does not result in identical random on
+ * each run. So do not use this if the results of a
+ * test depend on the random data that is generated.
+ *
+ * rng_state shall be NULL.
+ */
+static int rnd_std_rand( void *rng_state, unsigned char *output, size_t len )
+{
+#if !defined(__OpenBSD__)
+    size_t i;
+
+    if( rng_state != NULL )
+        rng_state  = NULL;
+
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+#else
+    if( rng_state != NULL )
+        rng_state = NULL;
+
+    arc4random_buf( output, len );
+#endif /* !OpenBSD */
+
+    return( 0 );
+}
+
+/**
+ * This function only returns zeros
+ *
+ * rng_state shall be NULL.
+ */
+static int rnd_zero_rand( void *rng_state, unsigned char *output, size_t len )
+{
+    if( rng_state != NULL )
+        rng_state  = NULL;
+
+    memset( output, 0, len );
+
+    return( 0 );
+}
+
+typedef struct
+{
+    unsigned char *buf;
+    size_t length;
+} rnd_buf_info;
+
+/**
+ * This function returns random based on a buffer it receives.
+ *
+ * rng_state shall be a pointer to a rnd_buf_info structure.
+ *
+ * The number of bytes released from the buffer on each call to
+ * the random function is specified by per_call. (Can be between
+ * 1 and 4)
+ *
+ * After the buffer is empty it will return rand();
+ */
+static int rnd_buffer_rand( void *rng_state, unsigned char *output, size_t len )
+{
+    rnd_buf_info *info = (rnd_buf_info *) rng_state;
+    size_t use_len;
+
+    if( rng_state == NULL )
+        return( rnd_std_rand( NULL, output, len ) );
+
+    use_len = len;
+    if( len > info->length )
+        use_len = info->length;
+
+    if( use_len )
+    {
+        memcpy( output, info->buf, use_len );
+        info->buf += use_len;
+        info->length -= use_len;
+    }
+
+    if( len - use_len > 0 )
+        return( rnd_std_rand( NULL, output + use_len, len - use_len ) );
+
+    return( 0 );
+}
+
+/**
+ * Info structure for the pseudo random function
+ *
+ * Key should be set at the start to a test-unique value.
+ * Do not forget endianness!
+ * State( v0, v1 ) should be set to zero.
+ */
+typedef struct
+{
+    uint32_t key[16];
+    uint32_t v0, v1;
+} rnd_pseudo_info;
+
+/**
+ * This function returns random based on a pseudo random function.
+ * This means the results should be identical on all systems.
+ * Pseudo random is based on the XTEA encryption algorithm to
+ * generate pseudorandom.
+ *
+ * rng_state shall be a pointer to a rnd_pseudo_info structure.
+ */
+static int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len )
+{
+    rnd_pseudo_info *info = (rnd_pseudo_info *) rng_state;
+    uint32_t i, *k, sum, delta=0x9E3779B9;
+    unsigned char result[4], *out = output;
+
+    if( rng_state == NULL )
+        return( rnd_std_rand( NULL, output, len ) );
+
+    k = info->key;
+
+    while( len > 0 )
+    {
+        size_t use_len = ( len > 4 ) ? 4 : len;
+        sum = 0;
+
+        for( i = 0; i < 32; i++ )
+        {
+            info->v0 += ( ( ( info->v1 << 4 ) ^ ( info->v1 >> 5 ) )
+                            + info->v1 ) ^ ( sum + k[sum & 3] );
+            sum += delta;
+            info->v1 += ( ( ( info->v0 << 4 ) ^ ( info->v0 >> 5 ) )
+                            + info->v0 ) ^ ( sum + k[( sum>>11 ) & 3] );
+        }
+
+        PUT_UINT32_BE( info->v0, result, 0 );
+        memcpy( out, result, use_len );
+        len -= use_len;
+        out += 4;
+    }
+
+    return( 0 );
+}
+
+static void test_fail( const char *test, int line_no, const char* filename )
+{
+    test_info.failed = 1;
+    test_info.test = test;
+    test_info.line_no = line_no;
+    test_info.filename = filename;
+}
+
+int hexcmp( uint8_t * a, uint8_t * b, uint32_t a_len, uint32_t b_len)
+{
+    int ret = 0;
+    uint32_t i = 0;
+
+    if ( a_len != b_len )
+        return( a_len - b_len );
+
+    for( i = 0; i < a_len; i++ )
+    {
+        if ( a[i] != b[i] )
+        {
+            ret = -1;
+            break;
+        }
+    }
+    return ret;
+}
+
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
new file mode 100644
index 0000000..31f93c6
--- /dev/null
+++ b/tests/suites/host_test.function
@@ -0,0 +1,672 @@
+#line 2 "suites/host_test.function"
+
+/**
+ * \brief       Varifies that string is in string parameter format i.e. "<str>"
+ *              It also strips enclosing '"' from the input string.
+ *
+ * \param str   String parameter.
+ *
+ * \return      0 if success else 1
+ */
+int verify_string( char **str )
+{
+    if( (*str)[0] != '"' ||
+        (*str)[strlen( *str ) - 1] != '"' )
+    {
+        mbedcrypto_fprintf( stderr,
+            "Expected string (with \"\") for parameter and got: %s\n", *str );
+        return( -1 );
+    }
+
+    (*str)++;
+    (*str)[strlen( *str ) - 1] = '\0';
+
+    return( 0 );
+}
+
+/**
+ * \brief       Varifies that string is an integer. Also gives the converted
+ *              integer value.
+ *
+ * \param str   Input string.
+ * \param value Pointer to int for output value.
+ *
+ * \return      0 if success else 1
+ */
+int verify_int( char *str, int *value )
+{
+    size_t i;
+    int minus = 0;
+    int digits = 1;
+    int hex = 0;
+
+    for( i = 0; i < strlen( str ); i++ )
+    {
+        if( i == 0 && str[i] == '-' )
+        {
+            minus = 1;
+            continue;
+        }
+
+        if( ( ( minus && i == 2 ) || ( !minus && i == 1 ) ) &&
+            str[i - 1] == '0' && str[i] == 'x' )
+        {
+            hex = 1;
+            continue;
+        }
+
+        if( ! ( ( str[i] >= '0' && str[i] <= '9' ) ||
+                ( hex && ( ( str[i] >= 'a' && str[i] <= 'f' ) ||
+                           ( str[i] >= 'A' && str[i] <= 'F' ) ) ) ) )
+        {
+            digits = 0;
+            break;
+        }
+    }
+
+    if( digits )
+    {
+        if( hex )
+            *value = strtol( str, NULL, 16 );
+        else
+            *value = strtol( str, NULL, 10 );
+
+        return( 0 );
+    }
+
+    mbedcrypto_fprintf( stderr,
+                    "Expected integer for parameter and got: %s\n", str );
+    return( KEY_VALUE_MAPPING_NOT_FOUND );
+}
+
+
+/**
+ * \brief       Usage string.
+ *
+ */
+#define USAGE \
+    "Usage: %s [OPTIONS] files...\n\n" \
+    "   Command line arguments:\n" \
+    "     files...          One or more test data file. If no file is specified\n" \
+    "                       the followimg default test case is used:\n" \
+    "                           %s\n\n" \
+    "   Options:\n" \
+    "     -v | --verbose    Display full information about each test\n" \
+    "     -h | --help       Display this information\n\n", \
+    argv[0], \
+    "TESTCASE_FILENAME"
+
+
+/**
+ * \brief       Read a line from the passed file pointer.
+ *
+ * \param f     FILE pointer
+ * \param buf   Pointer to memory to hold read line.
+ * \param len   Length of the buf.
+ *
+ * \return      0 if success else -1
+ */
+int get_line( FILE *f, char *buf, size_t len )
+{
+    char *ret;
+    int i = 0, str_len = 0, has_string = 0;
+
+    /* Read until we get a valid line */
+    do
+    {
+        ret = fgets( buf, len, f );
+        if( ret == NULL )
+            return( -1 );
+
+        str_len = strlen( buf );
+
+        /* Skip empty line and comment */
+        if ( str_len == 0 || buf[0] == '#' )
+            continue;
+        has_string = 0;
+        for ( i = 0; i < str_len; i++ )
+        {
+            char c = buf[i];
+            if ( c != ' ' && c != '\t' && c != '\n' &&
+                 c != '\v' && c != '\f' && c != '\r' )
+            {
+                has_string = 1;
+                break;
+            }
+        }
+    } while( !has_string );
+
+    /* Strip new line and carriage return */
+    ret = buf + strlen( buf );
+    if( ret-- > buf && *ret == '\n' )
+        *ret = '\0';
+    if( ret-- > buf && *ret == '\r' )
+        *ret = '\0';
+
+    return( 0 );
+}
+
+/**
+ * \brief       Splits string delimited by ':'. Ignores '\:'.
+ *
+ * \param buf           Input string
+ * \param len           Input string length
+ * \param params        Out params found
+ * \param params_len    Out params array len
+ *
+ * \return      Count of strings found.
+ */
+static int parse_arguments( char *buf, size_t len, char **params,
+                            size_t params_len )
+{
+    size_t cnt = 0, i;
+    char *cur = buf;
+    char *p = buf, *q;
+
+    params[cnt++] = cur;
+
+    while( *p != '\0' && p < buf + len )
+    {
+        if( *p == '\\' )
+        {
+            p++;
+            p++;
+            continue;
+        }
+        if( *p == ':' )
+        {
+            if( p + 1 < buf + len )
+            {
+                cur = p + 1;
+                assert( cnt < params_len );
+                params[cnt++] = cur;
+            }
+            *p = '\0';
+        }
+
+        p++;
+    }
+
+    /* Replace newlines, question marks and colons in strings */
+    for( i = 0; i < cnt; i++ )
+    {
+        p = params[i];
+        q = params[i];
+
+        while( *p != '\0' )
+        {
+            if( *p == '\\' && *(p + 1) == 'n' )
+            {
+                p += 2;
+                *(q++) = '\n';
+            }
+            else if( *p == '\\' && *(p + 1) == ':' )
+            {
+                p += 2;
+                *(q++) = ':';
+            }
+            else if( *p == '\\' && *(p + 1) == '?' )
+            {
+                p += 2;
+                *(q++) = '?';
+            }
+            else
+                *(q++) = *(p++);
+        }
+        *q = '\0';
+    }
+
+    return( cnt );
+}
+
+/**
+ * \brief       Converts parameters into test function consumable parameters.
+ *              Example: Input:  {"int", "0", "char*", "Hello",
+ *                                "hex", "abef", "exp", "1"}
+ *                      Output:  {
+ *                                0,                // Verified int
+ *                                "Hello",          // Verified string
+ *                                2, { 0xab, 0xef },// Converted len,hex pair
+ *                                9600              // Evaluated expression
+ *                               }
+ *
+ *
+ * \param cnt               Input string.
+ * \param params            Out array of found strings.
+ * \param int_params_store  Memory for storing processed integer parameters.
+ *
+ * \return      0 for success else 1
+ */
+static int convert_params( size_t cnt , char ** params , int * int_params_store )
+{
+    char ** cur = params;
+    char ** out = params;
+    int ret = ( DISPATCH_TEST_SUCCESS );
+
+    while ( cur - params < (int) cnt )
+    {
+        char * type = *cur++;
+        char * val = *cur++;
+
+        if ( strcmp( type, "char*" ) == 0 )
+        {
+            if ( verify_string( &val ) == 0 )
+            {
+              *out++ = val;
+            }
+            else
+            {
+                ret = ( DISPATCH_INVALID_TEST_DATA );
+                break;
+            }
+        }
+        else if ( strcmp( type, "int" ) == 0 )
+        {
+            if ( verify_int ( val, int_params_store ) == 0 )
+            {
+              *out++ = (char *) int_params_store++;
+            }
+            else
+            {
+                ret = ( DISPATCH_INVALID_TEST_DATA );
+                break;
+            }
+        }
+        else if ( strcmp( type, "hex" ) == 0 )
+        {
+            if ( verify_string( &val ) == 0 )
+            {
+                int j;
+                *int_params_store = unhexify( (unsigned char *) val, val );
+                printf ("\n");
+                for (j = 0; j < *int_params_store; j++)
+                    printf ("%02x ", (uint8_t)val[j]);
+                printf ("\n len %d\n", *int_params_store);
+                *out++ = val;
+                *out++ = (char *)(int_params_store++);
+            }
+            else
+            {
+                ret = ( DISPATCH_INVALID_TEST_DATA );
+                break;
+            }
+        }
+        else if ( strcmp( type, "exp" ) == 0 )
+        {
+            int exp_id = strtol( val, NULL, 10 );
+            if ( get_expression ( exp_id, int_params_store ) == 0 )
+            {
+              *out++ = (char *)int_params_store++;
+            }
+            else
+            {
+              ret = ( DISPATCH_INVALID_TEST_DATA );
+              break;
+            }
+        }
+        else
+        {
+          ret = ( DISPATCH_INVALID_TEST_DATA );
+          break;
+        }
+    }
+    return( ret );
+}
+
+/**
+ * \brief       Tests snprintf implementation with test input.
+ *
+ * \param n         Buffer test length.
+ * \param ref_buf   Expected buffer.
+ * \param ref_ret   Expected snprintf return value.
+ *
+ * \return      0 for success else 1
+ */
+#if defined(__GNUC__)
+/* At high optimization levels (e.g. gcc -O3), this function may be
+ * inlined in run_test_snprintf. This can trigger a spurious warning about
+ * potential misuse of snprintf from gcc -Wformat-truncation (observed with
+ * gcc 7.2). This warning makes tests in run_test_snprintf redundant on gcc
+ * only. They are still valid for other compilers. Avoid this warning by
+ * forbidding inlining of this function by gcc. */
+__attribute__((__noinline__))
+#endif
+static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret )
+{
+    int ret;
+    char buf[10] = "xxxxxxxxx";
+    const char ref[10] = "xxxxxxxxx";
+
+    if( n >= sizeof( buf ) )
+        return( -1 );
+    ret = mbedcrypto_snprintf( buf, n, "%s", "123" );
+    if( ret < 0 || (size_t) ret >= n )
+        ret = -1;
+
+    if( strncmp( ref_buf, buf, sizeof( buf ) ) != 0 ||
+        ref_ret != ret ||
+        memcmp( buf + n, ref + n, sizeof( buf ) - n ) != 0 )
+    {
+        return( 1 );
+    }
+
+    return( 0 );
+}
+
+/**
+ * \brief       Tests snprintf implementation.
+ *
+ * \param none
+ *
+ * \return      0 for success else 1
+ */
+static int run_test_snprintf( void )
+{
+    return( test_snprintf( 0, "xxxxxxxxx",  -1 ) != 0 ||
+            test_snprintf( 1, "",           -1 ) != 0 ||
+            test_snprintf( 2, "1",          -1 ) != 0 ||
+            test_snprintf( 3, "12",         -1 ) != 0 ||
+            test_snprintf( 4, "123",         3 ) != 0 ||
+            test_snprintf( 5, "123",         3 ) != 0 );
+}
+
+
+/**
+ * \brief       Desktop implementation of execute_tests().
+ *              Parses command line and executes tests from
+ *              supplied or default data file.
+ *
+ * \param argc  Command line argument count.
+ * \param argv  Argument array.
+ *
+ * \return      Program exit status.
+ */
+int execute_tests( int argc , const char ** argv )
+{
+    /* Local Configurations and options */
+    const char *default_filename = "DATA_FILE";
+    const char *test_filename = NULL;
+    const char **test_files = NULL;
+    int testfile_count = 0;
+    int option_verbose = 0;
+    int function_id = 0;
+
+    /* Other Local variables */
+    int arg_index = 1;
+    const char *next_arg;
+    int testfile_index, ret, i, cnt;
+    int total_errors = 0, total_tests = 0, total_skipped = 0;
+    FILE *file;
+    char buf[5000];
+    char *params[50];
+    int int_params[50]; // Store for proccessed integer params.
+    void *pointer;
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+    int stdout_fd = -1;
+#endif /* __unix__ || __APPLE__ __MACH__ */
+
+#if defined(MBEDCRYPTO_MEMORY_BUFFER_ALLOC_C) && \
+    !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
+    unsigned char alloc_buf[1000000];
+    mbedcrypto_memory_buffer_alloc_init( alloc_buf, sizeof( alloc_buf ) );
+#endif
+
+    /*
+     * The C standard doesn't guarantee that all-bits-0 is the representation
+     * of a NULL pointer. We do however use that in our code for initializing
+     * structures, which should work on every modern platform. Let's be sure.
+     */
+    memset( &pointer, 0, sizeof( void * ) );
+    if( pointer != NULL )
+    {
+        mbedcrypto_fprintf( stderr, "all-bits-zero is not a NULL pointer\n" );
+        return( 1 );
+    }
+
+    /*
+     * Make sure we have a snprintf that correctly zero-terminates
+     */
+    if( run_test_snprintf() != 0 )
+    {
+        mbedcrypto_fprintf( stderr, "the snprintf implementation is broken\n" );
+        return( 1 );
+    }
+
+    while( arg_index < argc )
+    {
+        next_arg = argv[ arg_index ];
+
+        if( strcmp(next_arg, "--verbose" ) == 0 ||
+                 strcmp(next_arg, "-v" ) == 0 )
+        {
+            option_verbose = 1;
+        }
+        else if( strcmp(next_arg, "--help" ) == 0 ||
+                 strcmp(next_arg, "-h" ) == 0 )
+        {
+            mbedcrypto_fprintf( stdout, USAGE );
+            mbedcrypto_exit( EXIT_SUCCESS );
+        }
+        else
+        {
+            /* Not an option, therefore treat all further arguments as the file
+             * list.
+             */
+            test_files = &argv[ arg_index ];
+            testfile_count = argc - arg_index;
+        }
+
+        arg_index++;
+    }
+
+    /* If no files were specified, assume a default */
+    if ( test_files == NULL || testfile_count == 0 )
+    {
+        test_files = &default_filename;
+        testfile_count = 1;
+    }
+
+    /* Initialize the struct that holds information about the last test */
+    memset( &test_info, 0, sizeof( test_info ) );
+
+    /* Now begin to execute the tests in the testfiles */
+    for ( testfile_index = 0;
+          testfile_index < testfile_count;
+          testfile_index++ )
+    {
+        int unmet_dep_count = 0;
+        char *unmet_dependencies[20];
+
+        test_filename = test_files[ testfile_index ];
+
+        file = fopen( test_filename, "r" );
+        if( file == NULL )
+        {
+            mbedcrypto_fprintf( stderr, "Failed to open test file: %s\n",
+                             test_filename );
+            return( 1 );
+        }
+
+        while( !feof( file ) )
+        {
+            if( unmet_dep_count > 0 )
+            {
+                mbedcrypto_fprintf( stderr,
+                    "FATAL: Dep count larger than zero at start of loop\n" );
+                mbedcrypto_exit( MBEDCRYPTO_EXIT_FAILURE );
+            }
+            unmet_dep_count = 0;
+
+            if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
+                break;
+            mbedcrypto_fprintf( stdout, "%s%.66s", test_info.failed ? "\n" : "", buf );
+            mbedcrypto_fprintf( stdout, " " );
+            for( i = strlen( buf ) + 1; i < 67; i++ )
+                mbedcrypto_fprintf( stdout, "." );
+            mbedcrypto_fprintf( stdout, " " );
+            fflush( stdout );
+
+            total_tests++;
+
+            if( ( ret = get_line( file, buf, sizeof( buf ) ) ) != 0 )
+                break;
+            cnt = parse_arguments( buf, strlen( buf ), params,
+                                   sizeof( params ) / sizeof( params[0] ) );
+
+            if( strcmp( params[0], "depends_on" ) == 0 )
+            {
+                for( i = 1; i < cnt; i++ )
+                {
+                    int dep_id = strtol( params[i], NULL, 10 );
+                    if( dep_check( dep_id ) != DEPENDENCY_SUPPORTED )
+                    {
+                        if( 0 == option_verbose )
+                        {
+                            /* Only one count is needed if not verbose */
+                            unmet_dep_count++;
+                            break;
+                        }
+
+                        unmet_dependencies[ unmet_dep_count ] = strdup( params[i] );
+                        if(  unmet_dependencies[ unmet_dep_count ] == NULL )
+                        {
+                            mbedcrypto_fprintf( stderr, "FATAL: Out of memory\n" );
+                            mbedcrypto_exit( MBEDCRYPTO_EXIT_FAILURE );
+                        }
+                        unmet_dep_count++;
+                    }
+                }
+
+                if( ( ret = get_line( file, buf, sizeof( buf ) ) ) != 0 )
+                    break;
+                cnt = parse_arguments( buf, strlen( buf ), params,
+                                       sizeof( params ) / sizeof( params[0] ) );
+            }
+
+            // If there are no unmet dependencies execute the test
+            if( unmet_dep_count == 0 )
+            {
+                test_info.failed = 0;
+
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+                /* Suppress all output from the library unless we're verbose
+                 * mode
+                 */
+                if( !option_verbose )
+                {
+                    stdout_fd = redirect_output( &stdout, "/dev/null" );
+                    if( stdout_fd == -1 )
+                    {
+                        /* Redirection has failed with no stdout so exit */
+                        exit( 1 );
+                    }
+                }
+#endif /* __unix__ || __APPLE__ __MACH__ */
+
+                function_id = strtol( params[0], NULL, 10 );
+                if ( (ret = check_test( function_id )) == DISPATCH_TEST_SUCCESS )
+                {
+                    ret = convert_params( cnt - 1, params + 1, int_params );
+                    if ( DISPATCH_TEST_SUCCESS == ret )
+                    {
+                        ret = dispatch_test( function_id, (void **)( params + 1 ) );
+                    }
+                }
+
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+                if( !option_verbose && restore_output( &stdout, stdout_fd ) )
+                {
+                        /* Redirection has failed with no stdout so exit */
+                        exit( 1 );
+                }
+#endif /* __unix__ || __APPLE__ __MACH__ */
+
+            }
+
+            if( unmet_dep_count > 0 || ret == DISPATCH_UNSUPPORTED_SUITE )
+            {
+                total_skipped++;
+                mbedcrypto_fprintf( stdout, "----" );
+
+                if( 1 == option_verbose && ret == DISPATCH_UNSUPPORTED_SUITE )
+                {
+                    mbedcrypto_fprintf( stdout, "\n   Test Suite not enabled" );
+                }
+
+                if( 1 == option_verbose && unmet_dep_count > 0 )
+                {
+                    mbedcrypto_fprintf( stdout, "\n   Unmet dependencies: " );
+                    for( i = 0; i < unmet_dep_count; i++ )
+                    {
+                        mbedcrypto_fprintf( stdout, "%s  ",
+                                        unmet_dependencies[i] );
+                        free( unmet_dependencies[i] );
+                    }
+                }
+                mbedcrypto_fprintf( stdout, "\n" );
+                fflush( stdout );
+
+                unmet_dep_count = 0;
+            }
+            else if( ret == DISPATCH_TEST_SUCCESS )
+            {
+                if( test_info.failed == 0 )
+                {
+                    mbedcrypto_fprintf( stdout, "PASS\n" );
+                }
+                else
+                {
+                    total_errors++;
+                    mbedcrypto_fprintf( stdout, "FAILED\n" );
+                    mbedcrypto_fprintf( stdout, "  %s\n  at line %d, %s\n",
+                                     test_info.test, test_info.line_no,
+                                     test_info.filename );
+                }
+                fflush( stdout );
+            }
+            else if( ret == DISPATCH_INVALID_TEST_DATA )
+            {
+                mbedcrypto_fprintf( stderr, "FAILED: FATAL PARSE ERROR\n" );
+                fclose( file );
+                mbedcrypto_exit( 2 );
+            }
+            else if( ret == DISPATCH_TEST_FN_NOT_FOUND )
+            {
+                mbedcrypto_fprintf( stderr, "FAILED: FATAL TEST FUNCTION NOT FUND\n" );
+                fclose( file );
+                mbedcrypto_exit( 2 );
+            }
+            else
+                total_errors++;
+        }
+        fclose( file );
+
+        /* In case we encounter early end of file */
+        for( i = 0; i < unmet_dep_count; i++ )
+            free( unmet_dependencies[i] );
+    }
+
+    mbedcrypto_fprintf( stdout, "\n----------------------------------------------------------------------------\n\n");
+    if( total_errors == 0 )
+        mbedcrypto_fprintf( stdout, "PASSED" );
+    else
+        mbedcrypto_fprintf( stdout, "FAILED" );
+
+    mbedcrypto_fprintf( stdout, " (%d / %d tests (%d skipped))\n",
+             total_tests - total_errors, total_tests, total_skipped );
+
+#if defined(MBEDCRYPTO_MEMORY_BUFFER_ALLOC_C) && \
+    !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
+#if defined(MBEDCRYPTO_MEMORY_DEBUG)
+    mbedcrypto_memory_buffer_alloc_status();
+#endif
+    mbedcrypto_memory_buffer_alloc_free();
+#endif
+
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+    if( stdout_fd != -1 )
+        close_output( stdout );
+#endif /* __unix__ || __APPLE__ __MACH__ */
+
+    return( total_errors != 0 );
+}
diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function
new file mode 100644
index 0000000..1a070ff
--- /dev/null
+++ b/tests/suites/main_test.function
@@ -0,0 +1,228 @@
+#line 2 "suites/main_test.function"
+/*
+ * *** THIS FILE HAS BEEN MACHINE GENERATED ***
+ *
+ * This file has been machine generated using the script:
+ * {generator_script}
+ *
+ * Test file      : {test_file}
+ *
+ * The following files were used to create this file.
+ *
+ *      Main code file      : {test_main_file}
+ *      Platform code file  : {test_platform_file}
+ *      Helper file         : {test_common_helper_file}
+ *      Test suite file     : {test_case_file}
+ *      Test suite data     : {test_case_data_file}
+ *
+ *
+ *  This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include <mbedcrypto/config.h>
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+
+/*----------------------------------------------------------------------------*/
+/* Common helper code */
+
+{test_common_helpers}
+
+#line {line_no} "suites/main_test.function"
+
+
+/*----------------------------------------------------------------------------*/
+/* Test Suite Code */
+
+
+#define TEST_SUITE_ACTIVE
+
+{functions_code}
+
+#line {line_no} "suites/main_test.function"
+
+
+/*----------------------------------------------------------------------------*/
+/* Test dispatch code */
+
+
+/**
+ * \brief       Evaluates an expression/macro into its literal integer value.
+ *              For optimizing space for embedded targets each expression/macro
+ *              is identified by a unique identifier instead of string literals.
+ *              Identifiers and evaluation code is generated by script:
+ *              {generator_script}
+ *
+ * \param exp_id    Expression identifier.
+ * \param out_value Pointer to int to hold the integer.
+ *
+ * \return       0 if exp_id is found. 1 otherwise.
+ */
+int get_expression( int32_t exp_id, int32_t * out_value )
+{{
+    int ret = KEY_VALUE_MAPPING_FOUND;
+
+    (void) exp_id;
+    (void) out_value;
+
+    switch( exp_id )
+    {{
+{expression_code}
+#line {line_no} "suites/main_test.function"
+        default:
+           {{
+                ret = KEY_VALUE_MAPPING_NOT_FOUND;
+           }}
+           break;
+    }}
+    return( ret );
+}}
+
+
+/**
+ * \brief       Checks if the dependency i.e. the compile flag is set.
+ *              For optimizing space for embedded targets each dependency
+ *              is identified by a unique identifier instead of string literals.
+ *              Identifiers and check code is generated by script:
+ *              {generator_script}
+ *
+ * \param exp_id    Dependency identifier.
+ *
+ * \return       DEPENDENCY_SUPPORTED if set else DEPENDENCY_NOT_SUPPORTED
+ */
+int dep_check( int dep_id )
+{{
+    int ret = DEPENDENCY_NOT_SUPPORTED;
+
+    (void) dep_id;
+
+    switch( dep_id )
+    {{
+{dep_check_code}
+#line {line_no} "suites/main_test.function"
+        default:
+            break;
+    }}
+    return( ret );
+}}
+
+
+/**
+ * \brief       Function pointer type for test function wrappers.
+ *
+ *
+ * \param void **   Pointer to void pointers. Represents an array of test
+ *                  function parameters.
+ *
+ * \return       void
+ */
+typedef void (*TestWrapper_t)( void ** );
+
+
+/**
+ * \brief       Table of test function wrappers. Used by dispatch_test().
+ *              This table is populated by script:
+ *              {generator_script}
+ *
+ */
+TestWrapper_t test_funcs[] =
+{{
+{dispatch_code}
+#line {line_no} "suites/main_test.function"
+}};
+
+
+/**
+ * \brief       Dispatches test functions based on function index.
+ *
+ * \param exp_id    Test function index.
+ *
+ * \return       DISPATCH_TEST_SUCCESS if found
+ *               DISPATCH_TEST_FN_NOT_FOUND if not found
+ *               DISPATCH_UNSUPPORTED_SUITE if not compile time enabled.
+ */
+int dispatch_test( int func_idx, void ** params )
+{{
+    int ret = DISPATCH_TEST_SUCCESS;
+    TestWrapper_t fp = NULL;
+
+    if ( func_idx < (int)( sizeof(test_funcs)/sizeof( TestWrapper_t ) ) )
+    {{
+        fp = test_funcs[func_idx];
+        if ( fp )
+            fp( params );
+        else
+            ret = ( DISPATCH_UNSUPPORTED_SUITE );
+    }}
+    else
+    {{
+        ret = ( DISPATCH_TEST_FN_NOT_FOUND );
+    }}
+
+    return( ret );
+}}
+
+
+/**
+ * \brief       Checks if test function is supported
+ *
+ * \param exp_id    Test function index.
+ *
+ * \return       DISPATCH_TEST_SUCCESS if found
+ *               DISPATCH_TEST_FN_NOT_FOUND if not found
+ *               DISPATCH_UNSUPPORTED_SUITE if not compile time enabled.
+ */
+int check_test( int func_idx )
+{{
+    int ret = DISPATCH_TEST_SUCCESS;
+    TestWrapper_t fp = NULL;
+
+    if ( func_idx < (int)( sizeof(test_funcs)/sizeof( TestWrapper_t ) ) )
+    {{
+        fp = test_funcs[func_idx];
+        if ( fp == NULL )
+            ret = ( DISPATCH_UNSUPPORTED_SUITE );
+    }}
+    else
+    {{
+        ret = ( DISPATCH_TEST_FN_NOT_FOUND );
+    }}
+
+    return( ret );
+}}
+
+
+{platform_code}
+
+#line {line_no} "suites/main_test.function"
+
+/*----------------------------------------------------------------------------*/
+/* Main Test code */
+
+
+/**
+ * \brief       Program main. Invokes platform specific execute_tests().
+ *
+ * \param argc      Command line arguments count.
+ * \param argv      Array of command line arguments.
+ *
+ * \return       Exit code.
+ */
+int main( int argc, const char *argv[] )
+{{
+    int ret = platform_setup();
+    if( ret != 0 )
+    {{
+        mbedcrypto_fprintf( stderr,
+                         "FATAL: Failed to initialize platform - error %d\n",
+                         ret );
+        return( -1 );
+    }}
+    ret = execute_tests( argc, argv );
+    platform_teardown();
+    return( ret );
+}}
+
diff --git a/tests/suites/target_test.function b/tests/suites/target_test.function
new file mode 100644
index 0000000..d5cded0
--- /dev/null
+++ b/tests/suites/target_test.function
@@ -0,0 +1,413 @@
+#line 2 "suites/target_test.function"
+
+#include "greentea-client/test_env.h"
+
+/**
+ * \brief       Increments pointer and asserts that it does not overflow.
+ *
+ * \param p     Pointer to byte array
+ * \param start Pointer to start of byte array
+ * \param len   Length of byte array
+ * \param step  Increment size
+ *
+ */
+#define INCR_ASSERT(p, start, len, step) do                     \
+{                                                               \
+    assert( ( p ) >= ( start ) );                               \
+    assert( sizeof( *( p ) ) == sizeof( *( start ) ) );         \
+    /* <= is checked to support use inside a loop where         \
+       pointer is incremented after reading data.       */      \
+    assert( (uint32_t)( ( ( p ) - ( start ) ) + ( step ) ) <= ( len ) );\
+    ( p ) += ( step );                                          \
+}                                                               \
+while( 0 )
+
+
+/**
+ * \brief       4 byte align unsigned char pointer
+ *
+ * \param p     Pointer to byte array
+ * \param start Pointer to start of byte array
+ * \param len   Length of byte array
+ *
+ */
+#define ALIGN_32BIT(p, start, len) do           \
+{                                               \
+    uint32_t align = ( - (uintptr_t)( p ) ) % 4;\
+    INCR_ASSERT( ( p ), ( start ), ( len ), align);\
+}                                               \
+while( 0 )
+
+
+/**
+ * \brief       Verify dependencies. Dependency identifiers are
+ *              encoded in the buffer as 8 bit unsigned integers.
+ *
+ * \param count     Number of dependencies.
+ * \param dep_p     Pointer to buffer.
+ *
+ * \return          DEPENDENCY_SUPPORTED if success else DEPENDENCY_NOT_SUPPORTED.
+ */
+int verify_dependencies( uint8_t count, uint8_t * dep_p )
+{
+    uint8_t i;
+    for ( i = 0; i < count; i++ )
+    {
+        if ( dep_check( (int)(dep_p[i]) ) != DEPENDENCY_SUPPORTED )
+            return( DEPENDENCY_NOT_SUPPORTED );
+    }
+    return( DEPENDENCY_SUPPORTED );
+}
+
+
+/**
+ * \brief       Receives unsigned integer on serial interface.
+ *              Integers are encoded in network order.
+ *
+ * \param none
+ *
+ * \return      unsigned int
+ */
+uint32_t receive_uint32()
+{
+    uint32_t value;
+    value =  (uint8_t)greentea_getc() << 24;
+    value |= (uint8_t)greentea_getc() << 16;
+    value |= (uint8_t)greentea_getc() << 8;
+    value |= (uint8_t)greentea_getc();
+    return( (uint32_t)value );
+}
+
+/**
+ * \brief       Parses out an unsigned 32 int value from the byte array.
+ *              Integers are encoded in network order.
+ *
+ * \param p     Pointer to byte array
+ *
+ * \return      unsigned int
+ */
+uint32_t parse_uint32( uint8_t * p )
+{
+    uint32_t value;
+    value =  *p++ << 24;
+    value |= *p++ << 16;
+    value |= *p++ << 8;
+    value |= *p;
+    return( value );
+}
+
+
+/**
+ * \brief       Receives test data on serial as greentea key,value pair:
+ *              {{<length>;<byte array>}}
+ *
+ * \param data_len  Out pointer to hold received data length.
+ *
+ * \return      Byte array.
+ */
+uint8_t * receive_data( uint32_t * data_len )
+{
+    uint32_t i = 0, errors = 0;
+    char c;
+    uint8_t * data = NULL;
+
+    /* Read opening braces */
+    i = 0;
+    while ( i < 2 )
+    {
+        c = greentea_getc();
+        /* Ignore any prevous CR LF characters */
+        if ( c == '\n' || c == '\r' )
+            continue;
+        i++;
+        if ( c != '{' )
+            return( NULL );
+    }
+
+    /* Read data length */
+    *data_len = receive_uint32();
+    data = (uint8_t *)malloc( *data_len );
+    assert( data != NULL );
+
+    greentea_getc(); // read ';' received after key i.e. *data_len
+
+    for( i = 0; i < *data_len; i++ )
+        data[i] = greentea_getc();
+
+    /* Read closing braces */
+    for( i = 0; i < 2; i++ )
+    {
+        c = greentea_getc();
+        if ( c != '}' )
+        {
+            errors++;
+            break;
+        }
+    }
+
+    if ( errors )
+    {
+        free( data );
+        data = NULL;
+        *data_len = 0;
+    }
+
+    return( data );
+}
+
+/**
+ * \brief       Parse the received byte array and count the number of arguments
+ *              to the test function passed as type hex.
+ *
+ * \param count     Parameter count
+ * \param data      Received Byte array
+ * \param data_len  Byte array length
+ *
+ * \return      count of hex params
+ */
+uint32_t find_hex_count( uint8_t count, uint8_t * data, uint32_t data_len )
+{
+    uint32_t i = 0, sz = 0;
+    char c;
+    uint8_t * p = NULL;
+    uint32_t hex_count = 0;
+
+    p = data;
+
+    for( i = 0; i < count; i++ )
+    {
+        c = (char)*p;
+        INCR_ASSERT( p, data, data_len, 1 );
+
+        /* Align p to 4 bytes for int, expression, string len or hex length */
+        ALIGN_32BIT( p, data, data_len );
+
+        /* Network to host conversion */
+        sz = (int32_t)parse_uint32( p );
+
+        INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
+
+        if ( c == 'H' || c == 'S' )
+        {
+            INCR_ASSERT( p, data, data_len, sz );
+            hex_count += ( c == 'H' )?1:0;
+        }
+    }
+
+    return( hex_count );
+}
+
+/**
+ * \brief       Parses received byte array for test parameters.
+ *
+ * \param count     Parameter count
+ * \param data      Received Byte array
+ * \param data_len  Byte array length
+ * \param error     Parsing error out variable.
+ *
+ * \return      Array of parsed parameters allocated on heap.
+ *              Note: Caller has the responsibility to delete
+ *                    the memory after use.
+ */
+void ** parse_parameters( uint8_t count, uint8_t * data, uint32_t data_len,
+                            int * error )
+{
+    uint32_t i = 0, hex_count = 0;
+    char c;
+    void ** params = NULL;
+    void ** cur = NULL;
+    uint8_t * p = NULL;
+
+    hex_count = find_hex_count(count, data, data_len);
+
+    params = (void **)malloc( sizeof( void *) * ( count + hex_count ) );
+    assert( params != NULL );
+    cur = params;
+
+    p = data;
+
+    /* Parameters */
+    for( i = 0; i < count; i++ )
+    {
+        c = (char)*p;
+        INCR_ASSERT( p, data, data_len, 1 );
+
+        /* Align p to 4 bytes for int, expression, string len or hex length */
+        ALIGN_32BIT( p, data, data_len );
+
+        /* Network to host conversion */
+        *( (int32_t *)p ) = (int32_t)parse_uint32( p );
+
+        switch( c )
+        {
+            case 'E':
+                {
+                    if ( get_expression( *( (int32_t *)p ), (int32_t *)p ) )
+                    {
+                        *error = KEY_VALUE_MAPPING_NOT_FOUND;
+                        goto exit;
+                    }
+                } /* Intentional fall through */
+            case 'I':
+                {
+                    *cur++ = (void *)p;
+                    INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
+                }
+                break;
+            case 'H': /* Intentional fall through */
+            case 'S':
+                {
+                    uint32_t * sz = (uint32_t *)p;
+                    INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
+                    *cur++ = (void *)p;
+                    if ( c == 'H' )
+                        *cur++ = (void *)sz;
+                    INCR_ASSERT( p, data, data_len, ( *sz ) );
+                }
+                break;
+            default:
+                    {
+                        *error = DISPATCH_INVALID_TEST_DATA;
+                        goto exit;
+                    }
+                break;
+        }
+    }
+
+exit:
+    if ( *error )
+    {
+        free( params );
+        params = NULL;
+    }
+
+    return( params );
+}
+
+/**
+ * \brief       Sends greentea key and int value pair to host.
+ *
+ * \param key   key string
+ * \param value integer value
+ *
+ * \return      void
+ */
+void send_key_integer( char * key, int value )
+{
+    char str[50];
+    snprintf( str, sizeof( str ), "%d", value );
+    greentea_send_kv( key, str );
+}
+
+/**
+ * \brief       Sends test setup failure to the host.
+ *
+ * \param failure   Test set failure
+ *
+ * \return      void
+ */
+void send_failure( int failure )
+{
+    send_key_integer( "F", failure );
+}
+
+/**
+ * \brief       Sends test status to the host.
+ *
+ * \param status    Test status (PASS=0/FAIL=!0)
+ *
+ * \return      void
+ */
+void send_status( int status )
+{
+    send_key_integer( "R", status );
+}
+
+
+/**
+ * \brief       Embedded implementation of execute_tests().
+ *              Ignores command line and received test data
+ *              on serial.
+ *
+ * \param argc  not used
+ * \param argv  not used
+ *
+ * \return      Program exit status.
+ */
+int execute_tests( int args, const char ** argv )
+{
+    int ret = 0;
+    uint32_t data_len = 0;
+    uint8_t count = 0, function_id;
+    void ** params = NULL;
+    uint8_t * data = NULL, * p = NULL;
+
+    GREENTEA_SETUP( 180, "mbedcrypto_test" );
+    greentea_send_kv( "GO", " " );
+
+    while ( 1 )
+    {
+        ret = 0;
+        test_info.failed = 0;
+        data_len = 0;
+
+        data = receive_data( &data_len );
+        if ( data == NULL )
+            continue;
+        p = data;
+
+        do
+        {
+            /* Read dependency count */
+            count = *p;
+            assert( count < data_len );
+            INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
+            ret = verify_dependencies( count, p );
+            if ( ret != DEPENDENCY_SUPPORTED )
+                break;
+
+            if ( count )
+                INCR_ASSERT( p, data, data_len, count );
+
+            /* Read function id */
+            function_id = *p;
+            INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
+            if ( ( ret = check_test( function_id ) ) != DISPATCH_TEST_SUCCESS )
+                break;
+
+            /* Read number of parameters */
+            count = *p;
+            INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
+
+            /* Parse parameters if present */
+            if ( count )
+            {
+                params = parse_parameters( count, p, data_len - ( p - data ), &ret );
+                if ( ret )
+                    break;
+            }
+
+            ret = dispatch_test( function_id, params );
+        }
+        while ( 0 );
+
+        if ( data )
+        {
+            free(data);
+            data = NULL;
+        }
+
+        if ( params )
+        {
+            free( params );
+            params = NULL;
+        }
+
+        if ( ret )
+            send_failure( ret );
+        else
+            send_status( test_info.failed );
+    }
+    return( 0 );
+}
+
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
new file mode 100644
index 0000000..4a3dd17
--- /dev/null
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -0,0 +1,1170 @@
+PSA init/deinit
+init_deinit:
+
+PSA fill 250 slots
+fill_slots:250
+
+PSA import/export raw: 0 bytes
+import_export:"":PSA_KEY_TYPE_RAW_DATA:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_USAGE_EXPORT:0:0:PSA_SUCCESS:1
+
+PSA import/export raw: 1 bytes
+import_export:"2a":PSA_KEY_TYPE_RAW_DATA:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_USAGE_EXPORT:8:0:PSA_SUCCESS:1
+
+PSA import/export raw: 1 bytes, larger buffer
+import_export:"2a":PSA_KEY_TYPE_RAW_DATA:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_USAGE_EXPORT:8:1:PSA_SUCCESS:1
+
+PSA import/export raw: 2 bytes, buffer too small
+import_export:"2a2b":PSA_KEY_TYPE_RAW_DATA:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_USAGE_EXPORT:16:-1:PSA_ERROR_BUFFER_TOO_SMALL:1
+
+PSA import/export AES-128
+depends_on:MBEDCRYPTO_AES_C
+import_export:"0123456789abcdef0123456789abcdef":PSA_KEY_TYPE_AES:PSA_ALG_CTR:PSA_KEY_USAGE_EXPORT:128:0:PSA_SUCCESS:1
+
+PSA import/export AES-192
+depends_on:MBEDCRYPTO_AES_C
+import_export:"0123456789abcdef0123456789abcdef0123456789abcdef":PSA_KEY_TYPE_AES:PSA_ALG_CTR:PSA_KEY_USAGE_EXPORT:192:0:PSA_SUCCESS:1
+
+PSA import/export AES-256
+depends_on:MBEDCRYPTO_AES_C
+import_export:"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef":PSA_KEY_TYPE_AES:PSA_ALG_CTR:PSA_KEY_USAGE_EXPORT:256:0:PSA_SUCCESS:1
+
+PSA import AES: bad key size
+depends_on:MBEDCRYPTO_AES_C
+import:"0123456789abcdef":PSA_KEY_TYPE_AES:PSA_ERROR_INVALID_ARGUMENT
+
+PSA import/export RSA public key: good, 1024-bit
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:0:PSA_SUCCESS:1
+
+PSA import/export RSA public key: good, larger buffer (+1 byte)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:1:PSA_SUCCESS:1
+
+PSA import/export RSA public key: good, larger buffer (*2-1)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:161:PSA_SUCCESS:1
+
+PSA import/export RSA public key: good, larger buffer (*2)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:162:PSA_SUCCESS:1
+
+PSA import/export RSA public key: good, larger buffer (*2+1)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:163:PSA_SUCCESS:1
+
+PSA import/export RSA public key: export buffer too small
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:-1:PSA_ERROR_BUFFER_TOO_SMALL:1
+
+PSA import/export RSA keypair: good, 1024-bit
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:0:PSA_SUCCESS:1
+
+PSA import/export RSA keypair: good, larger buffer (+1 byte)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:1:PSA_SUCCESS:1
+
+PSA import/export RSA keypair: good, larger buffer (*2-1)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:609:PSA_SUCCESS:1
+
+PSA import/export RSA keypair: good, larger buffer (*2)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:610:PSA_SUCCESS:1
+
+PSA import/export RSA keypair: good, larger buffer (*2+1)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:611:PSA_SUCCESS:1
+
+PSA import/export RSA keypair: export buffer too small
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:-1:PSA_ERROR_BUFFER_TOO_SMALL:1
+
+PSA import/export RSA keypair: trailing garbage ignored
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b2400":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:-1:PSA_SUCCESS:0
+
+PSA import RSA keypair: truncated
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C
+import:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ERROR_INVALID_ARGUMENT
+
+PSA import RSA keypair: public key
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C
+import:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ERROR_INVALID_ARGUMENT
+
+PSA import RSA public key: key pair
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C
+import:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ERROR_INVALID_ARGUMENT
+
+PSA import RSA keypair: valid key but EC
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C
+import:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ERROR_INVALID_ARGUMENT
+
+PSA import/export RSA keypair: good, 1023-bit
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export:"3082025a0201000281806c49704e91f3df44fc99e9b3c0fee5025cc04d09529a1dd05754f2da2751d7a9aa5a79f7070132f2c47b31963e37cd74675f9c93ee7c85a143fefe303e94d1ee0e4d30898d17ab3a229e8457ef21fd179039f748305babe7f134f6d58ce5d721a1a5da98f63503d2466c6a515e53494a41180a91e535bd5b55d4dce2c17419870203010001028180491b277413fb35efe82dace68b544a9dd6aa8917d329731955ec66ec3b0178fcf5a29196e1a6c093bf6c8064b36a8f0d9840a78003d11392754a70a77788975515a1442a6c806cafa2f07fe99cac78a86fa868888d654cec4baf205352cf8255acaa47e2455f23b58c0e5ae43fa297bbffe5b970caa80f71e82084fd35425479024100ef27f3fb2df90ac4910ed95fdde4877d09b0dc4e95079f12a7e2041300a8884a39372a1c79691338cd5c3965bcf3a24f2ce9e10de19d4cb87c7546d60ca0aa0d024073e9e1283475e9ab3075da0b005ca7c7b05e76325f8deb648238831c8353041d594307f784cd527cfee9187b997713d71c0ff98f01beac4d1a85583be52e90e302402f0c801e311c2677274671933f96fee4a56c6adaf6ccaa09c4875d5fd3a8542fadf3e14ffabea62e6d90302688b6b17ebc0a42e1353a79e66d6db102d9371e5d02406731ef3c8607fbf266806590a9cfd3a79a435ee355e2d9906fc6b4236c5f3a288ed178844a7d295512f49ed15b3d82325e4f729478af3262aa9bd083f273d49502410090a32c0e8ca3bcd4c66f092cdc369cd1abb4a05b9a6f0e65e5a51da1d96d5aca8c1525b3f11322c0588062fc8592ebf25b7950f918d39018e82b8acccc8f7e7a":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1023:0:PSA_SUCCESS:1
+
+PSA import/export-public RSA public key: good, 1024-bit
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export_public_key:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:1024:162:PSA_SUCCESS
+
+PSA import/export-public RSA keypair: good, 1024-bit
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export_public_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:1024:162:PSA_SUCCESS
+
+PSA import/export-public: cannot export-public a symmetric key
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_RSA_C
+import_export_public_key:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:128:0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA import/export EC secp256r1: good
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED
+import_export:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):PSA_ALG_ECDSA_ANY:PSA_KEY_USAGE_EXPORT:256:0:PSA_SUCCESS:1
+
+PSA import/export EC secp384r1: good
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_PK_WRITE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP384R1_ENABLED
+import_export:"3081a402010104303f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76aa00706052b81040022a16403620004d9c662b50ba29ca47990450e043aeaf4f0c69b15676d112f622a71c93059af999691c5680d2b44d111579db12f4a413a2ed5c45fcfb67b5b63e00b91ebe59d09a6b1ac2c0c4282aa12317ed5914f999bc488bb132e8342cc36f2ca5e3379c747":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP384R1):PSA_ALG_ECDSA_ANY:PSA_KEY_USAGE_EXPORT:384:0:PSA_SUCCESS:1
+
+PSA import/export AES key: policy forbids export
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CTR
+import_export:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:128:0:PSA_ERROR_NOT_PERMITTED:1
+
+PSA import/export HMAC key: policy forbids export
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+import_export:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_HMAC:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:256:0:PSA_ERROR_NOT_PERMITTED:1
+
+PSA import/export RSA keypair: policy forbids export (crypt)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:1024:0:PSA_ERROR_NOT_PERMITTED:1
+
+PSA import/export RSA keypair: policy forbids export (sign)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:1024:0:PSA_ERROR_NOT_PERMITTED:1
+
+PSA import EC keypair secp384r1: valid key but wrong curve (secp256r1)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_ECP_DP_SECP384R1_ENABLED
+import:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP384R1):PSA_ERROR_INVALID_ARGUMENT
+
+PSA import EC keypair brainpool384r1: valid key but wrong curve (secp384r1)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_BP384R1_ENABLED:MBEDCRYPTO_ECP_DP_SECP384R1_ENABLED
+import:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_BRAINPOOL_P384R1):PSA_ERROR_INVALID_ARGUMENT
+
+PSA import EC keypair: public key
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED
+import:"3059301306072a8648ce3d020106082a8648ce3d03010703420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):PSA_ERROR_INVALID_ARGUMENT
+
+PSA import EC public key: key pair
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED
+# For consistency with ECpub as ECpair, RSApub as RSApair and RSApair as RSApub,
+# one would expect the status to be PSA_ERROR_INVALID_ARGUMENT. But the
+# Mbed Crypto pkparse module returns MBEDCRYPTO_ERR_PK_INVALID_ALG, I think because
+# it's looking for an OID where there is no OID.
+import:"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):PSA_ERROR_NOT_SUPPORTED
+
+PSA import EC keypair: valid key but RSA
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_BP512R1_ENABLED:MBEDCRYPTO_RSA_C
+import:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_BRAINPOOL_P512R1):PSA_ERROR_INVALID_ARGUMENT
+
+PSA import RSA key pair: maximum size exceeded
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C
+import_rsa_made_up:PSA_VENDOR_RSA_MAX_KEY_BITS+8:1:PSA_ERROR_NOT_SUPPORTED
+
+PSA import RSA public key: maximum size exceeded
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C
+import_rsa_made_up:PSA_VENDOR_RSA_MAX_KEY_BITS+8:0:PSA_ERROR_NOT_SUPPORTED
+
+PSA key policy set and get
+key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE
+
+PSA key policy: MAC, sign | verify
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256)
+
+PSA key policy: MAC, wrong algorithm
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_224)
+
+PSA key policy: MAC, sign but not verify
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_key_policy:PSA_KEY_USAGE_SIGN:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256)
+
+PSA key policy: MAC, verify but not sign
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_key_policy:PSA_KEY_USAGE_VERIFY:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256)
+
+PSA key policy: MAC, neither sign nor verify
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_key_policy:0:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256)
+
+PSA key policy: cipher, encrypt | decrypt
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CTR
+cipher_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CTR
+
+PSA key policy: cipher, wrong algorithm
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CTR:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE
+
+PSA key policy: cipher, encrypt but not decrypt
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CTR
+cipher_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CTR
+
+PSA key policy: cipher, decrypt but not encrypt
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CTR
+cipher_key_policy:PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CTR
+
+PSA key policy: cipher, neither encrypt nor decrypt
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CTR
+cipher_key_policy:0:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CTR
+
+PSA key policy: AEAD, encrypt | decrypt
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CCM_C
+aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM
+
+PSA key policy: AEAD, wrong algorithm
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CCM_C:MBEDCRYPTO_GCM_C
+aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":16:16:PSA_ALG_GCM
+
+PSA key policy: AEAD, encrypt but not decrypt
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CCM_C
+aead_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM
+
+PSA key policy: AEAD, decrypt but not encrypt
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CCM_C
+aead_key_policy:PSA_KEY_USAGE_DECRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM
+
+PSA key policy: AEAD, neither encrypt nor decrypt
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CCM_C
+aead_key_policy:0:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM
+
+PSA key policy: asymmetric encryption, encrypt | decrypt
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT
+
+PSA key policy: asymmetric encryption, wrong algorithm
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256)
+
+PSA key policy: asymmetric encryption, encrypt but not decrypt
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT
+
+PSA key policy: asymmetric encryption, decrypt but not encrypt
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_encryption_key_policy:PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT
+
+PSA key policy: asymmetric encryption, neither encrypt nor decrypt
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_encryption_key_policy:0:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT
+
+PSA key policy: asymmetric signature, sign | verify
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW
+
+PSA key policy: asymmetric signature, wrong algorithm
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_SHA256_C
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_224)
+
+PSA key policy: asymmetric signature, sign but not verify
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW
+
+PSA key policy: asymmetric signature, verify but not sign
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_signature_key_policy:PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW
+
+PSA key policy: asymmetric signature, neither sign nor verify
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_signature_key_policy:0:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW
+
+PSA key policy: derive, permitted
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HKDF(PSA_ALG_SHA_256)
+
+PSA key policy: derive, not permitted
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_key_policy:0:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HKDF(PSA_ALG_SHA_256)
+
+PSA key policy: derive, wrong algorithm
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HKDF(PSA_ALG_SHA_224)
+
+PSA key lifetime: set and get volatile
+key_lifetime:PSA_KEY_LIFETIME_VOLATILE
+
+PSA key lifetime set: invalid key slot
+key_lifetime_set_fail:0:PSA_KEY_LIFETIME_VOLATILE:PSA_ERROR_INVALID_ARGUMENT
+
+PSA key lifetime set: cannot change write_once lifetime
+key_lifetime_set_fail:1:PSA_KEY_LIFETIME_WRITE_ONCE:PSA_ERROR_NOT_SUPPORTED
+
+PSA key lifetime set: invalid key lifetime value
+key_lifetime_set_fail:1:PSA_KEY_LIFETIME_PERSISTENT+1:PSA_ERROR_INVALID_ARGUMENT
+
+PSA hash setup: good, SHA-256
+depends_on:MBEDCRYPTO_SHA256_C
+hash_setup:PSA_ALG_SHA_256:PSA_SUCCESS
+
+PSA hash setup: bad (unknown hash algorithm)
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+hash_setup:PSA_ALG_CATEGORY_HASH:PSA_ERROR_NOT_SUPPORTED
+
+PSA hash setup: bad (not a hash algorithm)
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+hash_setup:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_INVALID_ARGUMENT
+
+PSA hash finish: SHA-256
+depends_on:MBEDCRYPTO_SHA256_C
+hash_finish:PSA_ALG_SHA_256:"bd":"68325720aabd7c82f30f554b313d0570c95accbb7dc4b5aae11204c08ffe732b"
+
+PSA hash verify: SHA-256
+depends_on:MBEDCRYPTO_SHA256_C
+hash_verify:PSA_ALG_SHA_256:"bd":"68325720aabd7c82f30f554b313d0570c95accbb7dc4b5aae11204c08ffe732b"
+
+PSA MAC setup: good, HMAC-SHA-256
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+
+PSA MAC setup: good, AES-CMAC
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CMAC_C
+mac_setup:PSA_KEY_TYPE_AES:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CMAC:PSA_SUCCESS
+
+PSA MAC setup: bad algorithm (unknown MAC algorithm)
+depends_on:MBEDCRYPTO_MD_C
+mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(0):PSA_ERROR_NOT_SUPPORTED
+
+PSA MAC setup: bad algorithm (not a MAC algorithm)
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+mac_setup:PSA_KEY_TYPE_AES:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_ERROR_INVALID_ARGUMENT
+
+PSA MAC setup: invalid key type, HMAC-SHA-256
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_setup:PSA_KEY_TYPE_RAW_DATA:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_INVALID_ARGUMENT
+
+PSA MAC setup: incompatible key HMAC for CMAC
+depends_on:MBEDCRYPTO_CMAC_C
+# Either INVALID_ARGUMENT or NOT_SUPPORTED would be reasonable here
+mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CMAC:PSA_ERROR_NOT_SUPPORTED
+
+PSA MAC verify: HMAC-SHA-256
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(PSA_ALG_SHA_256):"53616d706c65206d65737361676520666f72206b65796c656e3d626c6f636b6c656e":"8bb9a1db9806f20df7f77b82138c7914d174d59e13dc4d0169c9057b133e1d62"
+
+PSA MAC verify: RFC4231 Test case 1 - HMAC-SHA-224
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22"
+
+PSA MAC verify: RFC4231 Test case 1 - HMAC-SHA-256
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_256):"4869205468657265":"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"
+
+PSA MAC verify: RFC4231 Test case 1 - HMAC-SHA-384
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_384):"4869205468657265":"afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6"
+
+PSA MAC verify: RFC4231 Test case 1 - HMAC-SHA-512
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_512):"4869205468657265":"87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854"
+
+PSA MAC verify: RFC4231 Test case 2 - HMAC-SHA-224
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"4a656665":PSA_ALG_HMAC(PSA_ALG_SHA_224):"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44"
+
+PSA MAC verify: RFC4231 Test case 2 - HMAC-SHA-256
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"4a656665":PSA_ALG_HMAC(PSA_ALG_SHA_256):"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"
+
+PSA MAC verify: RFC4231 Test case 2 - HMAC-SHA-384
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"4a656665":PSA_ALG_HMAC(PSA_ALG_SHA_384):"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649"
+
+PSA MAC verify: RFC4231 Test case 2 - HMAC-SHA-512
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"4a656665":PSA_ALG_HMAC(PSA_ALG_SHA_512):"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737"
+
+PSA MAC verify: RFC4231 Test case 3 - HMAC-SHA-224
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_224):"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea"
+
+PSA MAC verify: RFC4231 Test case 3 - HMAC-SHA-256
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe"
+
+PSA MAC verify: RFC4231 Test case 3 - HMAC-SHA-384
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_384):"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b2a5ab39dc13814b94e3ab6e101a34f27"
+
+PSA MAC verify: RFC4231 Test case 3 - HMAC-SHA-512
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_512):"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb"
+
+PSA MAC verify: RFC4231 Test case 4 - HMAC-SHA-224
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0102030405060708090a0b0c0d0e0f10111213141516171819":PSA_ALG_HMAC(PSA_ALG_SHA_224):"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a"
+
+PSA MAC verify: RFC4231 Test case 4 - HMAC-SHA-256
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0102030405060708090a0b0c0d0e0f10111213141516171819":PSA_ALG_HMAC(PSA_ALG_SHA_256):"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"
+
+PSA MAC verify: RFC4231 Test case 4 - HMAC-SHA-384
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0102030405060708090a0b0c0d0e0f10111213141516171819":PSA_ALG_HMAC(PSA_ALG_SHA_384):"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e6801dd23c4a7d679ccf8a386c674cffb"
+
+PSA MAC verify: RFC4231 Test case 4 - HMAC-SHA-512
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0102030405060708090a0b0c0d0e0f10111213141516171819":PSA_ALG_HMAC(PSA_ALG_SHA_512):"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd"
+
+PSA MAC verify: RFC4231 Test case 6 - HMAC-SHA-224
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_224):"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374":"95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e"
+
+PSA MAC verify: RFC4231 Test case 6 - HMAC-SHA-256
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374":"60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54"
+
+PSA MAC verify: RFC4231 Test case 6 - HMAC-SHA-384
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_384):"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374":"4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c60c2ef6ab4030fe8296248df163f44952"
+
+PSA MAC verify: RFC4231 Test case 6 - HMAC-SHA-512
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_512):"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374":"80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598"
+
+PSA MAC verify: RFC4231 Test case 7 - HMAC-SHA-224
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_224):"5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e":"3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1"
+
+PSA MAC verify: RFC4231 Test case 7 - HMAC-SHA-256
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):"5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e":"9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2"
+
+PSA MAC verify: RFC4231 Test case 7 - HMAC-SHA-384
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_384):"5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e":"6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5a678cc31e799176d3860e6110c46523e"
+
+PSA MAC verify: RFC4231 Test case 7 - HMAC-SHA-512
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_512):"5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e":"e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58"
+
+PSA MAC verify: CMAC-AES-128
+depends_on:MBEDCRYPTO_CMAC_C:MBEDCRYPTO_AES_C
+mac_verify:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827"
+
+PSA cipher setup: good, AES-CTR
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CTR
+cipher_setup:PSA_KEY_TYPE_AES:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CTR:PSA_SUCCESS
+
+PSA cipher setup: bad algorithm (unknown cipher algorithm)
+depends_on:MBEDCRYPTO_AES_C
+cipher_setup:PSA_KEY_TYPE_AES:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CATEGORY_CIPHER:PSA_ERROR_NOT_SUPPORTED
+
+PSA cipher setup: bad algorithm (not a cipher algorithm)
+depends_on:MBEDCRYPTO_AES_C
+cipher_setup:PSA_KEY_TYPE_AES:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CMAC:PSA_ERROR_INVALID_ARGUMENT
+
+PSA cipher setup: invalid key type, CTR
+depends_on:MBEDCRYPTO_CIPHER_MODE_CTR
+# Either INVALID_ARGUMENT or NOT_SUPPORTED would be reasonable here
+cipher_setup:PSA_KEY_TYPE_RAW_DATA:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CTR:PSA_ERROR_NOT_SUPPORTED
+
+PSA cipher setup: incompatible key ARC4 for CTR
+depends_on:MBEDCRYPTO_ARC4_C:MBEDCRYPTO_CIPHER_MODE_CTR
+# Either INVALID_ARGUMENT or NOT_SUPPORTED would be reasonable here
+cipher_setup:PSA_KEY_TYPE_ARC4:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CTR:PSA_ERROR_NOT_SUPPORTED
+
+PSA symmetric encrypt: AES-CBC-nopad, 16 bytes, good
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_encrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":"a076ec9dfbe47d52afc357336f20743b":PSA_SUCCESS
+
+PSA symmetric encrypt: AES-CBC-PKCS#7, 16 bytes, good
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_encrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":"a076ec9dfbe47d52afc357336f20743bca7e8a15dc3c776436314293031cd4f3":PSA_SUCCESS
+
+PSA symmetric encrypt: AES-CBC-PKCS#7, 15 bytes, good
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_encrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e11739317":"6279b49d7f7a8dd87b685175d4276e24":PSA_SUCCESS
+
+PSA symmetric encrypt: AES-CBC-nopad, input too short
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_encrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee223":"6bc1bee223":PSA_ERROR_INVALID_ARGUMENT
+
+PSA symmetric encrypt: AES-CTR, 16 bytes, good
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC:MBEDCRYPTO_CIPHER_MODE_CTR
+cipher_encrypt:PSA_ALG_CTR | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":"8f9408fe80a81d3e813da3c7b0b2bd32":PSA_SUCCESS
+
+PSA symmetric encrypt: AES-CTR, 15 bytes, good
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC:MBEDCRYPTO_CIPHER_MODE_CTR
+cipher_encrypt:PSA_ALG_CTR | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e11739317":"8f9408fe80a81d3e813da3c7b0b2bd":PSA_SUCCESS
+
+PSA symmetric encrypt: DES-CBC-nopad, 8 bytes, good
+depends_on:MBEDCRYPTO_DES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_encrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_DES:"01020407080b0d0e":"eda4011239bc3ac9":"64f917b0152f8f05":PSA_SUCCESS
+
+PSA symmetric encrypt: 2-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:MBEDCRYPTO_DES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_encrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"eda4011239bc3ac9":"5d0652429c5b0ac7":PSA_SUCCESS
+
+PSA symmetric encrypt: 3-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:MBEDCRYPTO_DES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_encrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"eda4011239bc3ac9":"817ca7d69b80d86a":PSA_SUCCESS
+
+PSA symmetric decrypt: AES-CBC-nopad, 16 bytes, good
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_decrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"396ee84fb75fdbb5c2b13c7fe5a654aa":"49e4e66c89a86b67758df89db9ad6955":PSA_SUCCESS
+
+PSA symmetric decrypt: AES-CBC-PKCS#7, 16 bytes, good
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_decrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"a076ec9dfbe47d52afc357336f20743bca7e8a15dc3c776436314293031cd4f3":"6bc1bee22e409f96e93d7e117393172a":PSA_SUCCESS
+
+PSA symmetric decrypt: AES-CBC-PKCS#7, 15 bytes, good
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_decrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6279b49d7f7a8dd87b685175d4276e24":"6bc1bee22e409f96e93d7e11739317":PSA_SUCCESS
+
+PSA symmetric decrypt: AES-CBC-PKCS#7, input too short (15 bytes)
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_decrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e11739317":"49e4e66c89a86b67758df89db9ad6955":PSA_ERROR_BAD_STATE
+
+PSA symmetric decrypt: AES-CTR, 16 bytes, good
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC:MBEDCRYPTO_CIPHER_MODE_CTR
+cipher_decrypt:PSA_ALG_CTR | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"396ee84fb75fdbb5c2b13c7fe5a654aa":"dd3b5e5319b7591daab1e1a92687feb2":PSA_SUCCESS
+
+PSA symmetric decrypt: AES-CBC-nopad, input too short (5 bytes)
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_decrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee223":"6bc1bee223":PSA_ERROR_BAD_STATE
+
+PSA symmetric decrypt: DES-CBC-nopad, 8 bytes, good
+depends_on:MBEDCRYPTO_DES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_decrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_DES:"01020407080b0d0e":"64f917b0152f8f05":"eda4011239bc3ac9":PSA_SUCCESS
+
+PSA symmetric decrypt: 2-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:MBEDCRYPTO_DES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_decrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"5d0652429c5b0ac7":"eda4011239bc3ac9":PSA_SUCCESS
+
+PSA symmetric decrypt: 3-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:MBEDCRYPTO_DES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_decrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"817ca7d69b80d86a":"eda4011239bc3ac9":PSA_SUCCESS
+
+PSA symmetric encrypt/decrypt: AES-CBC-nopad, 16 bytes, good
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_verify_output:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a"
+
+PSA symmetric encrypt/decrypt: AES-CBC-PKCS#7, 16 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC:MBEDCRYPTO_CIPHER_PADDING_PKCS7
+cipher_verify_output:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a"
+
+PSA symmetric encrypt/decrypt: AES-CBC-PKCS#7, 15 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC:MBEDCRYPTO_CIPHER_PADDING_PKCS7
+cipher_verify_output:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e11739317"
+
+PSA symmetric encrypt/decrypt: AES-CTR
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CTR
+cipher_verify_output:PSA_ALG_CTR | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a"
+
+PSA symmetric encryption multipart: AES-CBC-nopad, 7+9 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_encrypt_multipart:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":7:"a076ec9dfbe47d52afc357336f20743b"
+
+PSA symmetric encryption multipart: AES-CBC-nopad, 3+13 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_encrypt_multipart:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":3:"a076ec9dfbe47d52afc357336f20743b"
+
+PSA symmetric encryption multipart: AES-CBC-nopad, 4+12 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_encrypt_multipart:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":4:"a076ec9dfbe47d52afc357336f20743b"
+
+PSA symmetric encryption multipart: AES-CBC-nopad, 11+5 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_encrypt_multipart:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":11:"a076ec9dfbe47d52afc357336f20743b"
+
+PSA symmetric decryption multipart: AES-CBC-nopad, 7+9 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_decrypt_multipart:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"a076ec9dfbe47d52afc357336f20743b":7:"6bc1bee22e409f96e93d7e117393172a"
+
+PSA symmetric decryption multipart: AES-CBC-nopad, 3+13 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_decrypt_multipart:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"a076ec9dfbe47d52afc357336f20743b":3:"6bc1bee22e409f96e93d7e117393172a"
+
+PSA symmetric decryption multipart: AES-CBC-nopad, 11+5 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_decrypt_multipart:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"a076ec9dfbe47d52afc357336f20743b":11:"6bc1bee22e409f96e93d7e117393172a"
+
+PSA symmetric encrypt/decrypt multipart: AES-CBC-nopad, 11+5 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+cipher_verify_output_multipart:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"a076ec9dfbe47d52afc357336f20743b":11
+
+PSA symmetric encrypt/decrypt multipart: AES-CBC-PKCS#7 padding, 4+12 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CBC:MBEDCRYPTO_CIPHER_PADDING_PKCS7
+cipher_verify_output_multipart:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"a076ec9dfbe47d52afc357336f20743b":4
+
+PSA AEAD encrypt/decrypt: AES-CCM, 19 bytes #1
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CCM_C
+aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":PSA_ALG_CCM:"0C0D0E0F101112131415161718191A1B1C1D1E":"000102030405060708090A0B":"000102030405060708090A0B":PSA_SUCCESS
+
+PSA AEAD encrypt/decrypt: AES-CCM, 19 bytes #2
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CCM_C
+aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"B96B49E21D621741632875DB7F6C9243D2D7C2":"000102030405060708090A0B":"EC46BB63B02520C33C49FD70":PSA_SUCCESS
+
+PSA AEAD encrypt/decrypt: DES-CCM not supported
+depends_on:MBEDCRYPTO_DES_C:MBEDCRYPTO_CCM_C
+aead_encrypt_decrypt:PSA_KEY_TYPE_DES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"B96B49E21D621741632875DB7F6C9243D2D7C2":"000102030405060708090A0B":"EC46BB63B02520C33C49FD70":PSA_ERROR_NOT_SUPPORTED
+
+PSA AEAD encrypt: AES-CCM, 23 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"08E8CF97D820EA258460E96AD9CF5289054D895CEAC47C":"0BE1A88BACE018B1":"00412B4EA9CDBE3C9696766CFA":"4CB97F86A2A4689A877947AB8091EF5386A6FFBDD080F8120333D1FCB691F3406CBF531F83A4D8"
+
+PSA AEAD encrypt: AES-CCM, 24 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"48c0906930561e0ab0ef4cd972":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9"
+
+PSA AEAD decrypt: AES-CCM, 39 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"4CB97F86A2A4689A877947AB8091EF5386A6FFBDD080F8120333D1FCB691F3406CBF531F83A4D8":"0BE1A88BACE018B1":"00412B4EA9CDBE3C9696766CFA":"08E8CF97D820EA258460E96AD9CF5289054D895CEAC47C":PSA_SUCCESS
+
+PSA AEAD decrypt, AES-CCM, 40 bytes
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"48c0906930561e0ab0ef4cd972":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_SUCCESS
+
+PSA AEAD decrypt: AES-CCM, invalid signature
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"26d56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"48c0906930561e0ab0ef4cd972":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_SIGNATURE
+
+PSA AEAD encrypt/decrypt, AES-GCM, 19 bytes #1
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_GCM_C
+aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":PSA_ALG_GCM:"0C0D0E0F101112131415161718191A1B1C1D1E":"000102030405060708090A0B0C0D0E0F":"000102030405060708090A0B":PSA_SUCCESS
+
+PSA AEAD encrypt/decrypt, AES GCM, 19 bytes #2
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_GCM_C
+aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_GCM:"B96B49E21D621741632875DB7F6C9243D2D7C2":"000102030405060708090A0B0C0D0E0F":"EC46BB63B02520C33C49FD70":PSA_SUCCESS
+
+PSA AEAD encrypt, AES-GCM, 128 bytes #1
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_GCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"00e440846db73a490573deaf3728c94f":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96"
+
+PSA AEAD encrypt, AES-GCM, 128 bytes #2
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_GCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"194c8bbbfae4a671386b8cd38f390f46f9df6b8661b470c310921a1c858a938045834bb10380037fbf5f5e00688554537be0fcafe8270b9b59068fa056ab1268fc166c2d729243a06650a171c929c7845c85330c04568d62977eedf3b1ba9dca13bdb8f9522817c8cb99e635e37465ec1c9f6f148d51437aa9f994a62e1bd013":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"97ce3f848276783599c6875de324361e":"12495120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f6bac793bdc2190a195122c98544ccf56"
+
+PSA AEAD decrypt, AES-GCM, 144 bytes #1
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_GCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"00e440846db73a490573deaf3728c94f":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_SUCCESS
+
+PSA AEAD decrypt, AES-GCM, 144 bytes #2
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_GCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"12495120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f6bac793bdc2190a195122c98544ccf56":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"97ce3f848276783599c6875de324361e":"194c8bbbfae4a671386b8cd38f390f46f9df6b8661b470c310921a1c858a938045834bb10380037fbf5f5e00688554537be0fcafe8270b9b59068fa056ab1268fc166c2d729243a06650a171c929c7845c85330c04568d62977eedf3b1ba9dca13bdb8f9522817c8cb99e635e37465ec1c9f6f148d51437aa9f994a62e1bd013":PSA_SUCCESS
+
+PSA AEAD decrypt, AES-GCM, invalid signature
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_GCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"12195120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f6bac793bdc2190a195122c98544ccf56":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"97ce3f848276783599c6875de324361e":"194c8bbbfae4a671386b8cd38f390f46f9df6b8661b470c310921a1c858a938045834bb10380037fbf5f5e00688554537be0fcafe8270b9b59068fa056ab1268fc166c2d729243a06650a171c929c7845c85330c04568d62977eedf3b1ba9dca13bdb8f9522817c8cb99e635e37465ec1c9f6f148d51437aa9f994a62e1bd013":PSA_ERROR_INVALID_SIGNATURE
+
+PSA AEAD encrypt/decrypt: invalid algorithm (CTR)
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_GCM_C
+aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CTR:"B96B49E21D621741632875DB7F6C9243D2D7C2":"000102030405060708090A0B0C0D0E0F":"EC46BB63B02520C33C49FD70":PSA_ERROR_NOT_SUPPORTED
+
+PSA signature size: RSA keypair, 1024 bits, PKCS#1 v1.5 raw
+signature_size:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:128
+
+PSA signature size: RSA public key, 1024 bits, PKCS#1 v1.5 raw
+signature_size:PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:128
+
+PSA signature size: RSA keypair, 1024 bits, PKCS#1 v1.5 SHA-256
+signature_size:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):128
+
+PSA signature size: RSA keypair, 1024 bits, PSS
+signature_size:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_ALG_RSA_PSS( PSA_ALG_SHA_256 ):128
+
+PSA signature size: RSA keypair, 1023 bits, PKCS#1 v1.5 raw
+signature_size:PSA_KEY_TYPE_RSA_KEYPAIR:1023:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:128
+
+PSA signature size: RSA keypair, 1025 bits, PKCS#1 v1.5 raw
+signature_size:PSA_KEY_TYPE_RSA_KEYPAIR:1025:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:129
+
+PSA import/exercise RSA keypair, PKCS#1 v1.5 raw
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+import_and_exercise_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW
+
+PSA import/exercise: ECP SECP256R1 keypair, ECDSA
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_ECDSA_C
+import_and_exercise_key:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):256:PSA_ALG_ECDSA_ANY
+
+PSA import/exercise: ECP SECP256R1 keypair, deterministic ECDSA
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_ECDSA_C:MBEDCRYPTO_ECDSA_DETERMINISTIC:MBEDCRYPTO_SHA256_C
+import_and_exercise_key:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):256:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 )
+
+PSA sign: RSA PKCS#1 v1.5, raw
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+sign_deterministic:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"616263":"2c7744983f023ac7bb1c55529d83ed11a76a7898a1bb5ce191375a4aa7495a633d27879ff58eba5a57371c34feb1180e8b850d552476ebb5634df620261992f12ebee9097041dbbea85a42d45b344be5073ceb772ffc604954b9158ba81ec3dc4d9d65e3ab7aa318165f38c36f841f1c69cb1cfa494aa5cbb4d6c0efbafb043a"
+
+PSA sign: RSA PKCS#1 v1.5 SHA-256
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15:MBEDCRYPTO_SHA256_C
+sign_deterministic:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311"
+
+PSA sign: deterministic ECDSA SECP256R1 SHA-256
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_ECDSA_DETERMINISTIC:MBEDCRYPTO_SHA256_C:MBEDCRYPTO_ECDSA_C
+sign_deterministic:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f"
+
+PSA sign: RSA PKCS#1 v1.5 SHA-256, wrong hash size
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15:MBEDCRYPTO_SHA256_C
+sign_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015":128:PSA_ERROR_INVALID_ARGUMENT
+
+PSA sign: RSA PKCS#1 v1.5 raw, input too large
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+sign_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":128:PSA_ERROR_INVALID_ARGUMENT
+
+PSA sign: RSA PKCS#1 v1.5 SHA-256, output buffer too small
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15:MBEDCRYPTO_SHA256_C
+sign_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":127:PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA sign: deterministic ECDSA SECP256R1 SHA-256, output buffer too small
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_SHA256_C:MBEDCRYPTO_ECDSA_C
+sign_fail:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":63:PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA sign: deterministic ECDSA SECP256R1, invalid hash
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_ECDSA_DETERMINISTIC:MBEDCRYPTO_SHA256_C
+sign_fail:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_DETERMINISTIC_ECDSA( 0 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":72:PSA_ERROR_INVALID_ARGUMENT
+
+PSA sign/verify: RSA PKCS#1 v1.5, raw
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+sign_verify:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"616263"
+
+PSA sign/verify: RSA PKCS#1 v1.5 SHA-256
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15:MBEDCRYPTO_SHA256_C
+sign_verify:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
+
+PSA sign/verify: RSA PSS SHA-256, 0 bytes
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+sign_verify:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):""
+
+PSA sign/verify: RSA PSS SHA-256, 32 bytes (hash size)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+sign_verify:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
+
+PSA sign/verify: RSA PSS SHA-256, 129 bytes
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+sign_verify:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+
+PSA sign/verify: randomized ECDSA SECP256R1 SHA-256
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_ECDSA_C
+sign_verify:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b"
+
+PSA sign/verify: deterministic ECDSA SECP256R1 SHA-256
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_ECDSA_DETERMINISTIC:MBEDCRYPTO_SHA256_C:MBEDCRYPTO_ECDSA_C
+sign_verify:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b"
+
+PSA verify: RSA PKCS#1 v1.5 SHA-256, good signature
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15:MBEDCRYPTO_SHA256_C
+asymmetric_verify:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311"
+
+PSA verify with keypair: RSA PKCS#1 v1.5 SHA-256, good signature
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15:MBEDCRYPTO_SHA256_C
+asymmetric_verify:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311"
+
+PSA verify: RSA PKCS#1 v1.5 SHA-256, wrong hash
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15:MBEDCRYPTO_SHA1_C
+asymmetric_verify_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_1):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311":PSA_ERROR_INVALID_ARGUMENT
+
+PSA verify: RSA PKCS#1 v1.5 SHA-256, wrong signature
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15:MBEDCRYPTO_SHA256_C
+asymmetric_verify_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"111164d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify: RSA PSS SHA-256, good signature, 0 bytes
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_verify:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"":"34c011b625c32d992f4ab8fcfa52b616ea66270b5b75a4fc71af712f9b8806bcdd374ce50eafcbb489562b93347885f93c2de1d404c45cacccefceb112ff6ffdfe4264f91d66320bbbe09304b851b8ad6280bbccc571eebcd49c7db5dfa399a6289e1978407904598751613d9870770cdd8507e3dc7b46851dbf05ae1df2988d"
+
+PSA verify: RSA PSS SHA-256, good signature, 32 bytes (hash size)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_verify:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"1967ae568cc071dfebeeca76b11d40bd1ec5af241c50b3dcceff21f4536c0693a7179a8d5d163a7625fefd37c161127800edeebc24fa73ca772096827bd3f75e8ccf2c64f07b7171b5c99022a4d73b760f34a385ccff0bd5ed7997d2a29d2847acb0767f93a2a404bc046c97de66d95dc9f7646fdb216b627b2ea0de8afcefb7"
+
+PSA verify: RSA PSS SHA-256, good signature, 129 bytes
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_verify:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"1491cead330b4ad5b092f8351518141ac11d0888591572669c1e79d6e932c488acd62d44479b0e14cd91a048778bc02398a772ad6bdb4f7764780cf0afe70293d0cac86f2695a1dcb54568bb37d7086f9e86f95a6802d2ee5a4facaa762beff5261bb2816b62cb5af86404974c3f6b67985ac1fbfdf46d6de54f6e29d9274308"
+
+PSA verify: ECDSA SECP256R1, good
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_SHA256_C:MBEDCRYPTO_ECDSA_C
+asymmetric_verify:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):"3059301306072a8648ce3d020106082a8648ce3d03010703420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f"
+
+PSA verify with keypair: ECDSA SECP256R1, good
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_ECDSA_C
+asymmetric_verify:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f"
+
+PSA verify: ECDSA SECP256R1, wrong signature size (correct but ASN1-encoded)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_ECDSA_C
+asymmetric_verify_fail:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):"3059301306072a8648ce3d020106082a8648ce3d03010703420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"304502206a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151022100ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify: ECDSA SECP256R1, wrong signature of correct size
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_ECDSA_C
+asymmetric_verify_fail:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):"3059301306072a8648ce3d020106082a8648ce3d03010703420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50e":PSA_ERROR_INVALID_SIGNATURE
+
+PSA encrypt: RSA PKCS#1 v1.5, good
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"":128:PSA_SUCCESS
+
+PSA encrypt: RSA OAEP-SHA-256, good
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"":128:PSA_SUCCESS
+
+PSA encrypt: RSA OAEP-SHA-256, good, with label
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"746869730069730061006c6162656c00":128:PSA_SUCCESS
+
+PSA encrypt: RSA OAEP-SHA-384, good
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA512_C
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_384):"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e":"":128:PSA_SUCCESS
+
+PSA encrypt: RSA OAEP-SHA-384, good
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA512_C
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_384):"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e":"":128:PSA_SUCCESS
+
+PSA encrypt: RSA PKCS#1 v1.5, key pair
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"":128:PSA_SUCCESS
+
+PSA encrypt: RSA OAEP-SHA-256, key pair
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"":128:PSA_SUCCESS
+
+PSA encrypt: RSA PKCS#1 v1.5, input too large
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_CRYPT:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":"":0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA encrypt: RSA PKCS#1 v1.5: salt not allowed
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA encrypt: RSA OAEP-SHA-384, input too large
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA512_C
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_384):"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"":0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA encrypt: invalid algorithm
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_encrypt:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_SHA_256:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"":0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA encrypt: RSA PKCS#1 v1.5: invalid key type
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_encrypt:PSA_KEY_TYPE_AES:"3082025e02010002818100af057d396e":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"":0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA encrypt-decrypt: RSA PKCS#1 v1.5 vector #1
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_encrypt_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":""
+
+PSA encrypt-decrypt: RSA PKCS#1 v1.5 vector #2
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_encrypt_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"99e8a6144bcb9a29660303bdc4305bb5eca8c64b96788cad062be9967bdab2f7ffff":""
+
+PSA encrypt-decrypt: RSA OAEP-SHA-256
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_encrypt_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":""
+
+PSA encrypt-decrypt: RSA OAEP-SHA-256, with label
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_encrypt_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"746869730069730061006c6162656c00"
+
+PSA encrypt-decrypt: RSA OAEP-SHA-384
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA512_C
+asymmetric_encrypt_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_384):"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e":""
+
+PSA decrypt: RSA PKCS#1 v1.5: good #1
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"99ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"":"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
+
+PSA decrypt: RSA PKCS#1 v1.5: good #2
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"adeecba2db7f867a733853f0136c554e5e01c7a2015721a9bfe30c3ad163b93a9c7589170311209f91420ad8a1a8280c7e890a6d7bca3c500b4da4f53a17bd84a21d58f979a9b4b8f2246b482d930804f12b3aeb2ac8b5ac7938d452ca13be8eb8e973c4e2b19fd454058cbae037bcef7ef68a5fbabf050de5f283cf1998c695":"":"99e8a6144bcb9a29660303bdc4305bb5eca8c64b96788cad062be9967bdab2f7ffff"
+
+PSA decrypt: RSA OAEP-SHA-256, 0 bytes
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"3d3146b1c982004273a9ebb9b063e6ae53b1a85bfc802324bcdd04faa0f7211fb2bdeea40358095554df9c250866c7361e738f0d270eaa27738e87928c5e31815506346727900ff03cef0be6f9dd6bba63ce89074e8194fe68b5a5739422d4f138bbbb61f49b76cf1f18def2c993e3113b08c191ea1da0feb94f8fd9b30109a1":"":""
+
+PSA decrypt: RSA OAEP-SHA-256, 0 bytes, with label
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"14e57648fbbd3c2c195d71fcb9b6c332e2ad9e3402aa701e7270b05775e9ddd025e2330d7b84e67866524c67f9c38b11e4679e28a38574b47f8d218a1a04a7466754d6ea7f959ab1f5b85d066d3f90076e8219f66653f7b78a9789d76213505b4e75ec28081608ed2f1ea1238e3eeab011ce4ec147327cd0ca029c2818133cb6":"746869730069730061006c6162656c00":""
+
+PSA decrypt: RSA OAEP-SHA-256, 30 bytes
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"3fd3c81e3919a19014400d91098090f273312e0150e09eff7f66fb9624d2ec9764fc80befcb592e9d102493c882b8bc0334a257e73aba23a0ee13f826cbc64f8200b9150784d004ccb2955c877c95ab888e3917f423dd52f3c8a49cb61c1966ec04f336068729ae0bce7d7fb3e680f9d15d658db9b906efcbf2c2fae45e75429":"":"74686973206973206e6f2073717565616d697368206f7373696672616765"
+
+PSA decrypt: RSA OAEP-SHA-256, 30 bytes, with label
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"46edc9984a6d4b7c7fd88fda9ea91ddbd30b28a0793cc75a9fcdd94d867c69090a697d46a6f336a3e48a122dd3ee3b51566b445ff78adb613d09b7d8c59c25a27d8cf7f5e36455f2e71ff6c6ee98d5740e66b23794acc72906561951c2be5064f6a250646ab627ecbfa48c02f82c29fe9b8c8e6be8eb752432124974373b542c":"746869730069730061006c6162656c00":"74686973206973206e6f2073717565616d697368206f7373696672616765"
+
+PSA decrypt: RSA OAEP-SHA-384, 30 bytes
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA512_C
+asymmetric_decrypt:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_384):"0df6750b8fed749359c016887d2cf097cc512c065526a91a7ee9b345a1bfff833737e7326e54d03f6bb65971962885a7661a16858d53ea55821052f4c7798d395b5c5495332fd4174451a1a437f36c27f446b96f309ff1cb6837274aa8ae2b51a8a479d736d25b8d2ca8ab96fe589553a3e52818b7df75544eb5469977b29aa4":"":"74686973206973206e6f2073717565616d697368206f7373696672616765"
+
+PSA decrypt: RSA OAEP-SHA-256, 30 bytes, wrong label (should be empty)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"3fd3c81e3919a19014400d91098090f273312e0150e09eff7f66fb9624d2ec9764fc80befcb592e9d102493c882b8bc0334a257e73aba23a0ee13f826cbc64f8200b9150784d004ccb2955c877c95ab888e3917f423dd52f3c8a49cb61c1966ec04f336068729ae0bce7d7fb3e680f9d15d658db9b906efcbf2c2fae45e75429":"00":PSA_ERROR_INVALID_PADDING
+
+PSA decrypt: RSA OAEP-SHA-256, 30 bytes, wrong label (empty)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"46edc9984a6d4b7c7fd88fda9ea91ddbd30b28a0793cc75a9fcdd94d867c69090a697d46a6f336a3e48a122dd3ee3b51566b445ff78adb613d09b7d8c59c25a27d8cf7f5e36455f2e71ff6c6ee98d5740e66b23794acc72906561951c2be5064f6a250646ab627ecbfa48c02f82c29fe9b8c8e6be8eb752432124974373b542c":"":PSA_ERROR_INVALID_PADDING
+
+PSA decrypt: RSA OAEP-SHA-256, 30 bytes, wrong label (same length)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"46edc9984a6d4b7c7fd88fda9ea91ddbd30b28a0793cc75a9fcdd94d867c69090a697d46a6f336a3e48a122dd3ee3b51566b445ff78adb613d09b7d8c59c25a27d8cf7f5e36455f2e71ff6c6ee98d5740e66b23794acc72906561951c2be5064f6a250646ab627ecbfa48c02f82c29fe9b8c8e6be8eb752432124974373b542c":"746869730069730061006c6162656c01":PSA_ERROR_INVALID_PADDING
+
+PSA decrypt: RSA PKCS#1 v1.5, invalid padding
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"99ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46873":"":PSA_ERROR_INVALID_PADDING
+
+PSA decrypt: RSA PKCS#1 v1.5: salt not allowed
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"99ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":PSA_ERROR_INVALID_ARGUMENT
+
+PSA decrypt: RSA OAEP-SHA-256, invalid padding
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"3fd3c81e3919a19014400d91098090f273312e0150e09eff7f66fb9624d2ec9764fc80befcb592e9d102493c882b8bc0334a257e73aba23a0ee13f826cbc64f8200b9150784d004ccb2955c877c95ab888e3917f423dd52f3c8a49cb61c1966ec04f336068729ae0bce7d7fb3e680f9d15d658db9b906efcbf2c2fae45e75428":"":PSA_ERROR_INVALID_PADDING
+
+PSA decrypt: invalid algorithm
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_SHA_256:"adeecba2db7f867a733853f0136c554e5e01c7a2015721a9bfe30c3ad163b93a9c7589170311209f91420ad8a1a8280c7e890a6d7bca3c500b4da4f53a17bd84a21d58f979a9b4b8f2246b482d930804f12b3aeb2ac8b5ac7938d452ca13be8eb8e973c4e2b19fd454058cbae037bcef7ef68a5fbabf050de5f283cf1998c695":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA decrypt: RSA PKCS#1 v1.5, invalid key type (RSA public key)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_CRYPT:"adeecba2db7f867a733853f0136c554e5e01c7a2015721a9bfe30c3ad163b93a9c7589170311209f91420ad8a1a8280c7e890a6d7bca3c500b4da4f53a17bd84a21d58f979a9b4b8f2246b482d930804f12b3aeb2ac8b5ac7938d452ca13be8eb8e973c4e2b19fd454058cbae037bcef7ef68a5fbabf050de5f283cf1998c695":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA decrypt: RSA OAEP, invalid key type (RSA public key)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"adeecba2db7f867a733853f0136c554e5e01c7a2015721a9bfe30c3ad163b93a9c7589170311209f91420ad8a1a8280c7e890a6d7bca3c500b4da4f53a17bd84a21d58f979a9b4b8f2246b482d930804f12b3aeb2ac8b5ac7938d452ca13be8eb8e973c4e2b19fd454058cbae037bcef7ef68a5fbabf050de5f283cf1998c695":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA decrypt: RSA PKCS#1 v1.5: invalid key type (AES)
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_decrypt_fail:PSA_KEY_TYPE_AES:"3082025e02010002818100af057d396e":PSA_ALG_RSA_PKCS1V15_CRYPT:"3082025e02010002818100af057d396e":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA decrypt: RSA PKCS#1 v1.5, input too small
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA decrypt: RSA PKCS#1 v1.5, input too large
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V15
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"0099ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA decrypt: RSA OAEP-SHA-256, input too small
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA decrypt: RSA OAEP-SHA-256, input too large
+depends_on:MBEDCRYPTO_PK_PARSE_C:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"0099ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: HKDF-SHA-256, good case
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HKDF(PSA_ALG_SHA_256):"":"":42:PSA_SUCCESS
+
+PSA key derivation: bad key type
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_setup:PSA_KEY_TYPE_RAW_DATA:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HKDF(PSA_ALG_SHA_256):"":"":42:PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: not a key derivation algorithm
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_256):"":"":42:PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: unsupported key derivation algorithm
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HKDF(PSA_ALG_CATEGORY_HASH):"":"":42:PSA_ERROR_NOT_SUPPORTED
+
+PSA key derivation: HKDF SHA-256, RFC5869 #1, output 42+0
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865":""
+
+PSA key derivation: HKDF SHA-256, RFC5869 #1, output 32+10
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf":"34007208d5b887185865"
+
+PSA key derivation: HKDF SHA-256, RFC5869 #1, output 0+42
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"":"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
+
+PSA key derivation: HKDF SHA-256, RFC5869 #1, output 1+41
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3c":"b25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
+
+PSA key derivation: HKDF SHA-256, RFC5869 #1, output 41+0
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b8871858":""
+
+PSA key derivation: HKDF SHA-256, RFC5869 #1, output 1+40
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3c":"b25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b8871858"
+
+PSA key derivation: HKDF SHA-256, RFC5869 #2, output 82+0
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":82:"b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87":""
+
+PSA key derivation: HKDF SHA-256, RFC5869 #3, output 42+0
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"":42:"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8":""
+
+PSA key derivation: HKDF SHA-1, RFC5869 #4, output 42+0
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA1_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):"0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896":""
+
+PSA key derivation: HKDF SHA-1, RFC5869 #5, output 82+0
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA1_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":82:"0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4":""
+
+PSA key derivation: HKDF SHA-1, RFC5869 #6, output 42+0
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA1_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"":42:"0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918":""
+
+PSA key derivation: HKDF SHA-1, RFC5869 #7, output 42+0
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA1_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"":"":42:"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48":""
+
+PSA key derivation: HKDF SHA-256, request maximum capacity
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865":""
+
+PSA key derivation: HKDF SHA-1, request maximum capacity
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA1_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_1):"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"":"":255 * 20:"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48":""
+
+PSA key derivation: HKDF SHA-256, request too much capacity
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HKDF(PSA_ALG_SHA_256):"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32 + 1:PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: HKDF SHA-1, request too much capacity
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA1_C
+derive_setup:PSA_KEY_TYPE_DERIVE:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":PSA_ALG_HKDF(PSA_ALG_SHA_1):"":"":255 * 20 + 1:PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: over capacity 42: output 42+1
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865":"ff"
+
+PSA key derivation: over capacity 42: output 41+2
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b8871858":"65ff"
+
+PSA key derivation: over capacity 42: output 43+0
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865ff":""
+
+PSA key derivation: over capacity 42: output 43+1
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865ff":"ff"
+
+PSA key derivation: HKDF SHA-256, read maximum capacity minus 1
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_full:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32 - 1
+
+PSA key derivation: HKDF SHA-256, read maximum capacity
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_full:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32
+
+PSA key derivation: HKDF SHA-256, exercise AES128-CTR
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CTR
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR
+
+PSA key derivation: HKDF SHA-256, exercise AES256-CTR
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CTR
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:256:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR
+
+PSA key derivation: HKDF SHA-256, exercise DES-CBC
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C:MBEDCRYPTO_DES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_DES:64:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7
+
+PSA key derivation: HKDF SHA-256, exercise 2-key 3DES-CBC
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C:MBEDCRYPTO_DES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_DES:128:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7
+
+PSA key derivation: HKDF SHA-256, exercise 3-key 3DES-CBC
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C:MBEDCRYPTO_DES_C:MBEDCRYPTO_CIPHER_MODE_CBC
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_DES:192:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_PKCS7
+
+PSA key derivation: HKDF SHA-256, exercise HMAC-SHA-256
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_HMAC:256:PSA_KEY_USAGE_SIGN:PSA_ALG_HMAC(PSA_ALG_SHA_256)
+
+PSA key derivation: HKDF SHA-256, exercise HKDF-SHA-256
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_key_exercise:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_DERIVE:400:PSA_KEY_USAGE_DERIVE:PSA_ALG_HKDF(PSA_ALG_SHA_256)
+
+PSA key derivation: HKDF SHA-256, derive key, 16+32
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_key_export:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":16:32
+
+PSA key derivation: HKDF SHA-256, derive key, 1+41
+depends_on:MBEDCRYPTO_MD_C:MBEDCRYPTO_SHA256_C
+derive_key_export:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":1:41
+
+PSA generate random: 0 bytes
+generate_random:0
+
+PSA generate random: 1 byte
+generate_random:1
+
+PSA generate random: 4 bytes
+generate_random:4
+
+PSA generate random: 16 bytes
+generate_random:16
+
+PSA generate random: 19 bytes
+generate_random:19
+
+PSA generate random: 260 bytes
+generate_random:260
+
+PSA generate key: bad type (PSA_KEY_TYPE_CATEGORY_MASK)
+generate_key:PSA_KEY_TYPE_CATEGORY_MASK:128:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED
+
+PSA generate key: bad type (RSA public key)
+generate_key:PSA_KEY_TYPE_RSA_PUBLIC_KEY:512:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED
+
+PSA generate key: raw data, 0 bits
+generate_key:PSA_KEY_TYPE_RAW_DATA:128:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS
+
+PSA generate key: raw data, 7 bits: invalid argument
+generate_key:PSA_KEY_TYPE_RAW_DATA:7:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA generate key: raw data, 8 bits
+generate_key:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS
+
+PSA generate key: AES, 128 bits, CTR
+depends_on:MBEDCRYPTO_AES_C:MBEDCRYPTO_CIPHER_MODE_CTR
+generate_key:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_SUCCESS
+
+PSA generate key: AES, 128 bits, GCM
+depends_on:MBEDCRYPTO_AES_C
+generate_key:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_GCM:PSA_SUCCESS
+
+PSA generate key: DES, 64 bits, CBC-nopad
+depends_on:MBEDCRYPTO_DES_C
+generate_key:PSA_KEY_TYPE_DES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_SUCCESS
+
+PSA generate key: DES, 128 bits, CBC-nopad
+depends_on:MBEDCRYPTO_DES_C
+generate_key:PSA_KEY_TYPE_DES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_SUCCESS
+
+PSA generate key: DES, 192 bits, CBC-nopad
+depends_on:MBEDCRYPTO_DES_C
+generate_key:PSA_KEY_TYPE_DES:192:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_SUCCESS
+
+PSA generate key: invalid key size: AES, 64 bits
+depends_on:MBEDCRYPTO_AES_C
+generate_key:PSA_KEY_TYPE_AES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_ERROR_INVALID_ARGUMENT
+
+PSA generate key: RSA, 512 bits, good, sign (PKCS#1 v1.5)
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_GENPRIME:MBEDCRYPTO_PKCS1_V15
+generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:512:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_SUCCESS
+
+PSA generate key: RSA, 1024 bits, good, sign (PSS SHA-256)
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_GENPRIME:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_SUCCESS
+
+PSA generate key: RSA, 512 bits, good, encrypt (PKCS#1 v1.5)
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_GENPRIME:MBEDCRYPTO_PKCS1_V15
+generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:512:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_SUCCESS
+
+PSA generate key: RSA, 1024 bits, good, encrypt (OAEP SHA-256)
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_PKCS1_V21:MBEDCRYPTO_SHA256_C
+generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):PSA_SUCCESS
+
+PSA generate key: RSA, maximum size exceeded
+depends_on:MBEDCRYPTO_RSA_C:MBEDCRYPTO_GENPRIME
+generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:PSA_VENDOR_RSA_MAX_KEY_BITS+1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED
+
+PSA generate key: ECC, SECP256R1, good
+depends_on:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_ECDSA_C
+generate_key:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):256:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:PSA_SUCCESS
+
+PSA generate key: ECC, SECP256R1, incorrect bit size
+depends_on:MBEDCRYPTO_ECP_C:MBEDCRYPTO_ECP_DP_SECP256R1_ENABLED:MBEDCRYPTO_ECDSA_C
+generate_key:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:PSA_ERROR_INVALID_ARGUMENT
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
new file mode 100644
index 0000000..77e3e51
--- /dev/null
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -0,0 +1,3172 @@
+/* BEGIN_HEADER */
+#include <stdint.h>
+
+#if defined(MBEDCRYPTO_PSA_CRYPTO_SPM)
+#include "spm/psa_defs.h"
+#endif
+
+#include "mbedcrypto/asn1write.h"
+#include "psa/crypto.h"
+
+#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
+
+#if(UINT32_MAX > SIZE_MAX)
+#define PSA_CRYPTO_TEST_SIZE_T_RANGE( x ) ( ( x ) <= SIZE_MAX )
+#else
+#define PSA_CRYPTO_TEST_SIZE_T_RANGE( x ) 1
+#endif
+
+/** An invalid export length that will never be set by psa_export_key(). */
+static const size_t INVALID_EXPORT_LENGTH = ~0U;
+
+/** Test if a buffer is all-bits zero.
+ *
+ * \param buffer    Pointer to the beginning of the buffer.
+ * \param size      Size of the buffer in bytes.
+ *
+ * \return          1 if the buffer is all-bits-zero.
+ * \return          0 if there is at least one nonzero byte.
+ */
+static int mem_is_zero( void *buffer, size_t size )
+{
+    size_t i;
+    for( i = 0; i < size; i++ )
+    {
+        if( ( (unsigned char *) buffer )[i] != 0 )
+            return( 0 );
+    }
+    return( 1 );
+}
+
+static int key_type_is_raw_bytes( psa_key_type_t type )
+{
+    psa_key_type_t category = type & PSA_KEY_TYPE_CATEGORY_MASK;
+    return( category == PSA_KEY_TYPE_RAW_DATA ||
+            category == PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
+}
+
+/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
+static int asn1_write_10x( unsigned char **p,
+                           unsigned char *start,
+                           size_t bits,
+                           unsigned char x )
+{
+    int ret;
+    int len = bits / 8 + 1;
+    if( bits == 0 )
+        return( MBEDCRYPTO_ERR_ASN1_INVALID_DATA );
+    if( bits <= 8 && x >= 1 << ( bits - 1 ) )
+        return( MBEDCRYPTO_ERR_ASN1_INVALID_DATA );
+    if( *p < start || *p - start < (ptrdiff_t) len )
+        return( MBEDCRYPTO_ERR_ASN1_BUF_TOO_SMALL );
+    *p -= len;
+    ( *p )[len-1] = x;
+    if( bits % 8 == 0 )
+        ( *p )[1] |= 1;
+    else
+        ( *p )[0] |= 1 << ( bits % 8 );
+    MBEDCRYPTO_ASN1_CHK_ADD( len, mbedcrypto_asn1_write_len( p, start, len ) );
+    MBEDCRYPTO_ASN1_CHK_ADD( len, mbedcrypto_asn1_write_tag( p, start,
+                                                       MBEDCRYPTO_ASN1_INTEGER ) );
+    return( len );
+}
+
+static int construct_fake_rsa_key( unsigned char *buffer,
+                                   size_t buffer_size,
+                                   unsigned char **p,
+                                   size_t bits,
+                                   int keypair )
+{
+    size_t half_bits = ( bits + 1 ) / 2;
+    int ret;
+    int len = 0;
+    /* Construct something that looks like a DER encoding of
+     * as defined by PKCS#1 v2.2 (RFC 8017) section A.1.2:
+     *   RSAPrivateKey ::= SEQUENCE {
+     *       version           Version,
+     *       modulus           INTEGER,  -- n
+     *       publicExponent    INTEGER,  -- e
+     *       privateExponent   INTEGER,  -- d
+     *       prime1            INTEGER,  -- p
+     *       prime2            INTEGER,  -- q
+     *       exponent1         INTEGER,  -- d mod (p-1)
+     *       exponent2         INTEGER,  -- d mod (q-1)
+     *       coefficient       INTEGER,  -- (inverse of q) mod p
+     *       otherPrimeInfos   OtherPrimeInfos OPTIONAL
+     *   }
+     * Or, for a public key, the same structure with only
+     * version, modulus and publicExponent.
+     */
+    *p = buffer + buffer_size;
+    if( keypair )
+    {
+        MBEDCRYPTO_ASN1_CHK_ADD( len, /* pq */
+                              asn1_write_10x( p, buffer, half_bits, 1 ) );
+        MBEDCRYPTO_ASN1_CHK_ADD( len, /* dq */
+                              asn1_write_10x( p, buffer, half_bits, 1 ) );
+        MBEDCRYPTO_ASN1_CHK_ADD( len, /* dp */
+                              asn1_write_10x( p, buffer, half_bits, 1 ) );
+        MBEDCRYPTO_ASN1_CHK_ADD( len, /* q */
+                              asn1_write_10x( p, buffer, half_bits, 1 ) );
+        MBEDCRYPTO_ASN1_CHK_ADD( len, /* p != q to pass mbedcrypto sanity checks */
+                              asn1_write_10x( p, buffer, half_bits, 3 ) );
+        MBEDCRYPTO_ASN1_CHK_ADD( len, /* d */
+                              asn1_write_10x( p, buffer, bits, 1 ) );
+    }
+    MBEDCRYPTO_ASN1_CHK_ADD( len, /* e = 65537 */
+                          asn1_write_10x( p, buffer, 17, 1 ) );
+    MBEDCRYPTO_ASN1_CHK_ADD( len, /* n */
+                          asn1_write_10x( p, buffer, bits, 1 ) );
+    if( keypair )
+        MBEDCRYPTO_ASN1_CHK_ADD( len, /* version = 0 */
+                              mbedcrypto_asn1_write_int( p, buffer, 0 ) );
+    MBEDCRYPTO_ASN1_CHK_ADD( len, mbedcrypto_asn1_write_len( p, buffer, len ) );
+    {
+        const unsigned char tag =
+            MBEDCRYPTO_ASN1_CONSTRUCTED | MBEDCRYPTO_ASN1_SEQUENCE;
+        MBEDCRYPTO_ASN1_CHK_ADD( len, mbedcrypto_asn1_write_tag( p, buffer, tag ) );
+    }
+    return( len );
+}
+
+static int exercise_mac_key( psa_key_slot_t key,
+                             psa_key_usage_t usage,
+                             psa_algorithm_t alg )
+{
+    psa_mac_operation_t operation;
+    const unsigned char input[] = "foo";
+    unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
+    size_t mac_length = sizeof( mac );
+
+    if( usage & PSA_KEY_USAGE_SIGN )
+    {
+        TEST_ASSERT( psa_mac_sign_setup( &operation,
+                                         key, alg ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_mac_update( &operation,
+                                     input, sizeof( input ) ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_mac_sign_finish( &operation,
+                                          mac, sizeof( mac ),
+                                          &mac_length ) == PSA_SUCCESS );
+    }
+
+    if( usage & PSA_KEY_USAGE_VERIFY )
+    {
+        psa_status_t verify_status =
+            ( usage & PSA_KEY_USAGE_SIGN ?
+              PSA_SUCCESS :
+              PSA_ERROR_INVALID_SIGNATURE );
+        TEST_ASSERT( psa_mac_verify_setup( &operation,
+                                           key, alg ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_mac_update( &operation,
+                                     input, sizeof( input ) ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_mac_verify_finish( &operation,
+                                            mac,
+                                            mac_length ) == verify_status );
+    }
+
+    return( 1 );
+
+exit:
+    psa_mac_abort( &operation );
+    return( 0 );
+}
+
+static int exercise_cipher_key( psa_key_slot_t key,
+                                psa_key_usage_t usage,
+                                psa_algorithm_t alg )
+{
+    psa_cipher_operation_t operation;
+    unsigned char iv[16] = {0};
+    size_t iv_length = sizeof( iv );
+    const unsigned char plaintext[16] = "Hello, world...";
+    unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
+    size_t ciphertext_length = sizeof( ciphertext );
+    unsigned char decrypted[sizeof( ciphertext )];
+    size_t part_length;
+
+    if( usage & PSA_KEY_USAGE_ENCRYPT )
+    {
+        TEST_ASSERT( psa_cipher_encrypt_setup( &operation,
+                                               key, alg ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_cipher_generate_iv( &operation,
+                                             iv, sizeof( iv ),
+                                             &iv_length ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_cipher_update( &operation,
+                                        plaintext, sizeof( plaintext ),
+                                        ciphertext, sizeof( ciphertext ),
+                                        &ciphertext_length ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_cipher_finish( &operation,
+                                        ciphertext + ciphertext_length,
+                                        sizeof( ciphertext ) - ciphertext_length,
+                                        &part_length ) == PSA_SUCCESS );
+        ciphertext_length += part_length;
+    }
+
+    if( usage & PSA_KEY_USAGE_DECRYPT )
+    {
+        psa_status_t status;
+        psa_key_type_t type = PSA_KEY_TYPE_NONE;
+        if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
+        {
+            size_t bits;
+            TEST_ASSERT( psa_get_key_information( key, &type, &bits ) );
+            iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE( type );
+        }
+        TEST_ASSERT( psa_cipher_decrypt_setup( &operation,
+                                               key, alg ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_cipher_set_iv( &operation,
+                                        iv, iv_length ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_cipher_update( &operation,
+                                        ciphertext, ciphertext_length,
+                                        decrypted, sizeof( decrypted ),
+                                        &part_length ) == PSA_SUCCESS );
+        status = psa_cipher_finish( &operation,
+                                    decrypted + part_length,
+                                    sizeof( decrypted ) - part_length,
+                                    &part_length );
+        /* For a stream cipher, all inputs are valid. For a block cipher,
+         * if the input is some aribtrary data rather than an actual
+         ciphertext, a padding error is likely.  */
+        if( ( usage & PSA_KEY_USAGE_ENCRYPT ) ||
+            PSA_BLOCK_CIPHER_BLOCK_SIZE( type ) == 1 )
+            TEST_ASSERT( status == PSA_SUCCESS );
+        else
+            TEST_ASSERT( status == PSA_SUCCESS ||
+                         status == PSA_ERROR_INVALID_PADDING );
+    }
+
+    return( 1 );
+
+exit:
+    psa_cipher_abort( &operation );
+    return( 0 );
+}
+
+static int exercise_aead_key( psa_key_slot_t key,
+                              psa_key_usage_t usage,
+                              psa_algorithm_t alg )
+{
+    unsigned char nonce[16] = {0};
+    size_t nonce_length = sizeof( nonce );
+    unsigned char plaintext[16] = "Hello, world...";
+    unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
+    size_t ciphertext_length = sizeof( ciphertext );
+    size_t plaintext_length = sizeof( ciphertext );
+
+    if( usage & PSA_KEY_USAGE_ENCRYPT )
+    {
+        TEST_ASSERT( psa_aead_encrypt( key, alg,
+                                       nonce, nonce_length,
+                                       NULL, 0,
+                                       plaintext, sizeof( plaintext ),
+                                       ciphertext, sizeof( ciphertext ),
+                                       &ciphertext_length ) == PSA_SUCCESS );
+    }
+
+    if( usage & PSA_KEY_USAGE_DECRYPT )
+    {
+        psa_status_t verify_status =
+            ( usage & PSA_KEY_USAGE_ENCRYPT ?
+              PSA_SUCCESS :
+              PSA_ERROR_INVALID_SIGNATURE );
+        TEST_ASSERT( psa_aead_decrypt( key, alg,
+                                       nonce, nonce_length,
+                                       NULL, 0,
+                                       ciphertext, ciphertext_length,
+                                       plaintext, sizeof( plaintext ),
+                                       &plaintext_length ) == verify_status );
+    }
+
+    return( 1 );
+
+exit:
+    return( 0 );
+}
+
+static int exercise_signature_key( psa_key_slot_t key,
+                                   psa_key_usage_t usage,
+                                   psa_algorithm_t alg )
+{
+    unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
+    size_t payload_length = 16;
+    unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
+    size_t signature_length = sizeof( signature );
+
+    if( usage & PSA_KEY_USAGE_SIGN )
+    {
+        /* Some algorithms require the payload to have the size of
+         * the hash encoded in the algorithm. Use this input size
+         * even for algorithms that allow other input sizes. */
+        psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
+        if( hash_alg != 0 )
+            payload_length = PSA_HASH_SIZE( hash_alg );
+        TEST_ASSERT( psa_asymmetric_sign( key, alg,
+                                          payload, payload_length,
+                                          signature, sizeof( signature ),
+                                          &signature_length ) == PSA_SUCCESS );
+    }
+
+    if( usage & PSA_KEY_USAGE_VERIFY )
+    {
+        psa_status_t verify_status =
+            ( usage & PSA_KEY_USAGE_SIGN ?
+              PSA_SUCCESS :
+              PSA_ERROR_INVALID_SIGNATURE );
+        TEST_ASSERT( psa_asymmetric_verify( key, alg,
+                                            payload, payload_length,
+                                            signature, signature_length ) ==
+                     verify_status );
+    }
+
+    return( 1 );
+
+exit:
+    return( 0 );
+}
+
+static int exercise_asymmetric_encryption_key( psa_key_slot_t key,
+                                               psa_key_usage_t usage,
+                                               psa_algorithm_t alg )
+{
+    unsigned char plaintext[256] = "Hello, world...";
+    unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
+    size_t ciphertext_length = sizeof( ciphertext );
+    size_t plaintext_length = 16;
+
+    if( usage & PSA_KEY_USAGE_ENCRYPT )
+    {
+        TEST_ASSERT(
+            psa_asymmetric_encrypt( key, alg,
+                                    plaintext, plaintext_length,
+                                    NULL, 0,
+                                    ciphertext, sizeof( ciphertext ),
+                                    &ciphertext_length ) == PSA_SUCCESS );
+    }
+
+    if( usage & PSA_KEY_USAGE_DECRYPT )
+    {
+        psa_status_t status =
+            psa_asymmetric_decrypt( key, alg,
+                                    ciphertext, ciphertext_length,
+                                    NULL, 0,
+                                    plaintext, sizeof( plaintext ),
+                                    &plaintext_length );
+        TEST_ASSERT( status == PSA_SUCCESS ||
+                     ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
+                       ( status == PSA_ERROR_INVALID_ARGUMENT ||
+                         status == PSA_ERROR_INVALID_PADDING ) ) );
+    }
+
+    return( 1 );
+
+exit:
+    return( 0 );
+}
+
+static int exercise_key_derivation_key( psa_key_slot_t key,
+                                        psa_key_usage_t usage,
+                                        psa_algorithm_t alg )
+{
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    unsigned char label[16] = "This is a label.";
+    size_t label_length = sizeof( label );
+    unsigned char seed[16] = "abcdefghijklmnop";
+    size_t seed_length = sizeof( seed );
+    unsigned char output[1];
+
+    if( usage & PSA_KEY_USAGE_DERIVE )
+    {
+        TEST_ASSERT( psa_key_derivation( &generator,
+                                         key, alg,
+                                         label, label_length,
+                                         seed, seed_length,
+                                         sizeof( output ) ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_generator_read( &generator,
+                                         output,
+                                         sizeof( output ) ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+    }
+
+    return( 1 );
+
+exit:
+    return( 0 );
+}
+
+static int exercise_key( psa_key_slot_t slot,
+                         psa_key_usage_t usage,
+                         psa_algorithm_t alg )
+{
+    int ok;
+    if( alg == 0 )
+        ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
+    else if( PSA_ALG_IS_MAC( alg ) )
+        ok = exercise_mac_key( slot, usage, alg );
+    else if( PSA_ALG_IS_CIPHER( alg ) )
+        ok = exercise_cipher_key( slot, usage, alg );
+    else if( PSA_ALG_IS_AEAD( alg ) )
+        ok = exercise_aead_key( slot, usage, alg );
+    else if( PSA_ALG_IS_SIGN( alg ) )
+        ok = exercise_signature_key( slot, usage, alg );
+    else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
+        ok = exercise_asymmetric_encryption_key( slot, usage, alg );
+    else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
+        ok = exercise_key_derivation_key( slot, usage, alg );
+    else
+    {
+        char message[40];
+        mbedcrypto_snprintf( message, sizeof( message ),
+                          "No code to exercise alg=0x%08lx",
+                          (unsigned long) alg );
+        test_fail( message, __LINE__, __FILE__ );
+        ok = 0;
+    }
+    return( ok );
+}
+
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDCRYPTO_PSA_CRYPTO_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE */
+void init_deinit( )
+{
+    psa_status_t status;
+    int i;
+    for( i = 0; i <= 1; i++ )
+    {
+        status = psa_crypto_init( );
+        TEST_ASSERT( status == PSA_SUCCESS );
+        status = psa_crypto_init( );
+        TEST_ASSERT( status == PSA_SUCCESS );
+        mbedcrypto_psa_crypto_free( );
+    }
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void fill_slots( int max_arg )
+{
+    /* Fill all the slots until we run out of memory or out of slots,
+     * or until some limit specified in the test data for the sake of
+     * implementations with an essentially unlimited number of slots.
+     * This test assumes that available slots are numbered from 1. */
+
+    psa_key_slot_t slot;
+    psa_key_slot_t max = 0;
+    psa_key_policy_t policy;
+    uint8_t exported[sizeof( max )];
+    size_t exported_size;
+    psa_status_t status;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, 0 );
+
+    for( max = 1; max <= (size_t) max_arg; max++ )
+    {
+        status = psa_set_key_policy( max, &policy );
+        /* Stop filling slots if we run out of memory or out of
+         * available slots. */
+        TEST_ASSERT( status == PSA_SUCCESS ||
+                     status == PSA_ERROR_INSUFFICIENT_MEMORY ||
+                     status == PSA_ERROR_INVALID_ARGUMENT );
+        if( status != PSA_SUCCESS )
+            break;
+        status = psa_import_key( max, PSA_KEY_TYPE_RAW_DATA,
+                                 (uint8_t*) &max, sizeof( max ) );
+        /* Since psa_set_key_policy succeeded, we know that the slot
+         * number is valid. But we may legitimately run out of memory. */
+        TEST_ASSERT( status == PSA_SUCCESS ||
+                     status == PSA_ERROR_INSUFFICIENT_MEMORY );
+        if( status != PSA_SUCCESS )
+            break;
+    }
+    /* `max` is now the first slot number that wasn't filled. */
+    max -= 1;
+
+    for( slot = 1; slot <= max; slot++ )
+    {
+        TEST_ASSERT( psa_export_key( slot,
+                                     exported, sizeof( exported ),
+                                     &exported_size ) == PSA_SUCCESS );
+        TEST_ASSERT( exported_size == sizeof( slot ) );
+        TEST_ASSERT( memcmp( exported, &slot, sizeof( slot ) ) == 0 );
+    }
+
+exit:
+    /* Do not destroy the keys. mbedcrypto_psa_crypto_free() should do it. */
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void import( HexParam_t *data, int type, int expected_status_arg )
+{
+    int slot = 1;
+    psa_status_t expected_status = expected_status_arg;
+    psa_status_t status;
+
+    TEST_ASSERT( data != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( data->len ) );
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    status = psa_import_key( slot, type, data->x, data->len );
+    TEST_ASSERT( status == expected_status );
+    if( status == PSA_SUCCESS )
+        TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS );
+
+exit:
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
+{
+    int slot = 1;
+    size_t bits = bits_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_status_t status;
+    psa_key_type_t type =
+        keypair ? PSA_KEY_TYPE_RSA_KEYPAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
+    size_t buffer_size = /* Slight overapproximations */
+        keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
+    unsigned char *buffer = mbedcrypto_calloc( 1, buffer_size );
+    unsigned char *p;
+    int ret;
+    size_t length;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    TEST_ASSERT( buffer != NULL );
+
+    TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
+                                                 bits, keypair ) ) >= 0 );
+    length = ret;
+
+    /* Try importing the key */
+    status = psa_import_key( slot, type, p, length );
+    TEST_ASSERT( status == expected_status );
+    if( status == PSA_SUCCESS )
+        TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS );
+
+exit:
+    mbedcrypto_free( buffer );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void import_export( HexParam_t *data,
+                    int type_arg,
+                    int alg_arg,
+                    int usage_arg,
+                    int expected_bits,
+                    int export_size_delta,
+                    int expected_export_status_arg,
+                    int canonical_input )
+{
+    int slot = 1;
+    int slot2 = slot + 1;
+    psa_key_type_t type = type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_export_status = expected_export_status_arg;
+    psa_status_t status;
+    unsigned char *exported = NULL;
+    unsigned char *reexported = NULL;
+    size_t export_size;
+    size_t exported_length = INVALID_EXPORT_LENGTH;
+    size_t reexported_length;
+    psa_key_type_t got_type;
+    size_t got_bits;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( data != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( data->len ) );
+    export_size = (ptrdiff_t) data->len + export_size_delta;
+    exported = mbedcrypto_calloc( 1, export_size );
+    TEST_ASSERT( export_size == 0 || exported != NULL );
+    if( ! canonical_input )
+    {
+        reexported = mbedcrypto_calloc( 1, export_size );
+        TEST_ASSERT( export_size == 0 || reexported != NULL );
+    }
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, usage_arg, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    /* Import the key */
+    TEST_ASSERT( psa_import_key( slot, type,
+                                 data->x, data->len ) == PSA_SUCCESS );
+
+    /* Test the key information */
+    TEST_ASSERT( psa_get_key_information( slot,
+                                          &got_type,
+                                          &got_bits ) == PSA_SUCCESS );
+    TEST_ASSERT( got_type == type );
+    TEST_ASSERT( got_bits == (size_t) expected_bits );
+
+    /* Export the key */
+    status = psa_export_key( slot,
+                             exported, export_size,
+                             &exported_length );
+    TEST_ASSERT( status == expected_export_status );
+
+    /* The exported length must be set by psa_export_key() to a value between 0
+     * and export_size. On errors, the exported length must be 0. */
+    TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
+    TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
+    TEST_ASSERT( exported_length <= export_size );
+
+    TEST_ASSERT( mem_is_zero( exported + exported_length,
+                              export_size - exported_length ) );
+    if( status != PSA_SUCCESS )
+    {
+        TEST_ASSERT( exported_length == 0 );
+        goto destroy;
+    }
+
+    if( canonical_input )
+    {
+        TEST_ASSERT( exported_length == data->len );
+        TEST_ASSERT( memcmp( exported, data->x, data->len ) == 0 );
+    }
+    else
+    {
+        TEST_ASSERT( psa_set_key_policy( slot2, &policy ) == PSA_SUCCESS );
+
+        TEST_ASSERT( psa_import_key( slot2, type,
+                                     exported,
+                                     export_size ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_export_key( slot2,
+                                     reexported,
+                                     export_size,
+                                     &reexported_length ) == PSA_SUCCESS );
+        TEST_ASSERT( reexported_length == exported_length );
+        TEST_ASSERT( memcmp( reexported, exported,
+                             exported_length ) == 0 );
+    }
+
+destroy:
+    /* Destroy the key */
+    TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_get_key_information(
+                     slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT );
+
+exit:
+    mbedcrypto_free( exported );
+    mbedcrypto_free( reexported );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void import_export_public_key( HexParam_t *data,
+                               int type_arg,
+                               int alg_arg,
+                               int expected_bits,
+                               int public_key_expected_length,
+                               int expected_export_status_arg )
+{
+    int slot = 1;
+    psa_key_type_t type = type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_export_status = expected_export_status_arg;
+    psa_status_t status;
+    unsigned char *exported = NULL;
+    size_t export_size;
+    size_t exported_length = INVALID_EXPORT_LENGTH;
+    psa_key_type_t got_type;
+    size_t got_bits;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( data != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( data->len ) );
+    export_size = (ptrdiff_t) data->len;
+    exported = mbedcrypto_calloc( 1, export_size );
+    TEST_ASSERT( exported != NULL );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    /* Import the key */
+    TEST_ASSERT( psa_import_key( slot, type,
+                                 data->x, data->len ) == PSA_SUCCESS );
+
+    /* Test the key information */
+    TEST_ASSERT( psa_get_key_information( slot,
+                                          &got_type,
+                                          &got_bits ) == PSA_SUCCESS );
+    TEST_ASSERT( got_type == type );
+    TEST_ASSERT( got_bits == (size_t) expected_bits );
+
+    /* Export the key */
+    status = psa_export_public_key( slot,
+                                    exported, export_size,
+                                    &exported_length );
+    TEST_ASSERT( status == expected_export_status );
+    TEST_ASSERT( exported_length == (size_t) public_key_expected_length );
+    TEST_ASSERT( mem_is_zero( exported + exported_length,
+                              export_size - exported_length ) );
+    if( status != PSA_SUCCESS )
+        goto destroy;
+
+destroy:
+    /* Destroy the key */
+    TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_get_key_information(
+                     slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT );
+
+exit:
+    mbedcrypto_free( exported );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void import_and_exercise_key( HexParam_t *data,
+                              int type_arg,
+                              int bits_arg,
+                              int alg_arg )
+{
+    int slot = 1;
+    psa_key_type_t type = type_arg;
+    size_t bits = bits_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_key_usage_t usage =
+        ( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) ?
+          ( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
+            PSA_KEY_USAGE_VERIFY :
+            PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY ) :
+          PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
+          PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) ?
+          ( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
+            PSA_KEY_USAGE_ENCRYPT :
+            PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT ) :
+          PSA_ALG_IS_KEY_DERIVATION( alg ) ? PSA_KEY_USAGE_DERIVE :
+          0 );
+    psa_key_policy_t policy;
+    psa_key_type_t got_type;
+    size_t got_bits;
+    psa_status_t status;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, usage, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    /* Import the key */
+    status = psa_import_key( slot, type, data->x, data->len );
+    TEST_ASSERT( status == PSA_SUCCESS );
+
+    /* Test the key information */
+    TEST_ASSERT( psa_get_key_information( slot,
+                                          &got_type,
+                                          &got_bits ) == PSA_SUCCESS );
+    TEST_ASSERT( got_type == type );
+    TEST_ASSERT( got_bits == bits );
+
+    /* Do something with the key according to its type and permitted usage. */
+    if( ! exercise_key( slot, usage, alg ) )
+        goto exit;
+
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void key_policy( int usage_arg, int alg_arg )
+{
+    int key_slot = 1;
+    psa_algorithm_t alg = alg_arg;
+    psa_key_usage_t usage = usage_arg;
+    psa_key_type_t key_type = PSA_KEY_TYPE_AES;
+    unsigned char key[32] = {0};
+    psa_key_policy_t policy_set;
+    psa_key_policy_t policy_get;
+
+    memset( key, 0x2a, sizeof( key ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy_set );
+    psa_key_policy_init( &policy_get );
+
+    psa_key_policy_set_usage( &policy_set, usage, alg );
+
+    TEST_ASSERT( psa_key_policy_get_usage( &policy_set ) == usage );
+    TEST_ASSERT( psa_key_policy_get_algorithm( &policy_set ) == alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy_set ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key, sizeof( key ) ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_get_key_policy( key_slot, &policy_get ) == PSA_SUCCESS );
+
+    TEST_ASSERT( policy_get.usage == policy_set.usage );
+    TEST_ASSERT( policy_get.alg == policy_set.alg );
+
+exit:
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mac_key_policy( int policy_usage,
+                     int policy_alg,
+                     int key_type,
+                     HexParam_t *key_data,
+                     int exercise_alg )
+{
+    int key_slot = 1;
+    psa_key_policy_t policy;
+    psa_mac_operation_t operation;
+    psa_status_t status;
+    unsigned char mac[PSA_MAC_MAX_SIZE];
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+
+    status = psa_mac_sign_setup( &operation, key_slot, exercise_alg );
+    if( policy_alg == exercise_alg &&
+        ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
+        TEST_ASSERT( status == PSA_SUCCESS );
+    else
+        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+    psa_mac_abort( &operation );
+
+    memset( mac, 0, sizeof( mac ) );
+    status = psa_mac_verify_setup( &operation, key_slot, exercise_alg );
+    if( policy_alg == exercise_alg &&
+        ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
+        TEST_ASSERT( status == PSA_SUCCESS );
+    else
+        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+
+exit:
+    psa_mac_abort( &operation );
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void cipher_key_policy( int policy_usage,
+                        int policy_alg,
+                        int key_type,
+                        HexParam_t *key_data,
+                        int exercise_alg )
+{
+    int key_slot = 1;
+    psa_key_policy_t policy;
+    psa_cipher_operation_t operation;
+    psa_status_t status;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+
+    status = psa_cipher_encrypt_setup( &operation, key_slot, exercise_alg );
+    if( policy_alg == exercise_alg &&
+        ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
+        TEST_ASSERT( status == PSA_SUCCESS );
+    else
+        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+    psa_cipher_abort( &operation );
+
+    status = psa_cipher_decrypt_setup( &operation, key_slot, exercise_alg );
+    if( policy_alg == exercise_alg &&
+        ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
+        TEST_ASSERT( status == PSA_SUCCESS );
+    else
+        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+
+exit:
+    psa_cipher_abort( &operation );
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aead_key_policy( int policy_usage,
+                      int policy_alg,
+                      int key_type,
+                      HexParam_t *key_data,
+                      int nonce_length_arg,
+                      int tag_length_arg,
+                      int exercise_alg )
+{
+    int key_slot = 1;
+    psa_key_policy_t policy;
+    psa_status_t status;
+    unsigned char nonce[16] = {0};
+    size_t nonce_length = nonce_length_arg;
+    unsigned char tag[16];
+    size_t tag_length = tag_length_arg;
+    size_t output_length;
+
+    TEST_ASSERT( nonce_length <= sizeof( nonce ) );
+    TEST_ASSERT( tag_length <= sizeof( tag ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+
+    status = psa_aead_encrypt( key_slot, exercise_alg,
+                               nonce, nonce_length,
+                               NULL, 0,
+                               NULL, 0,
+                               tag, tag_length,
+                               &output_length );
+    if( policy_alg == exercise_alg &&
+        ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
+        TEST_ASSERT( status == PSA_SUCCESS );
+    else
+        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+
+    memset( tag, 0, sizeof( tag ) );
+    status = psa_aead_decrypt( key_slot, exercise_alg,
+                               nonce, nonce_length,
+                               NULL, 0,
+                               tag, tag_length,
+                               NULL, 0,
+                               &output_length );
+    if( policy_alg == exercise_alg &&
+        ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
+        TEST_ASSERT( status == PSA_ERROR_INVALID_SIGNATURE );
+    else
+        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+
+exit:
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void asymmetric_encryption_key_policy( int policy_usage,
+                                       int policy_alg,
+                                       int key_type,
+                                       HexParam_t *key_data,
+                                       int exercise_alg )
+{
+    int key_slot = 1;
+    psa_key_policy_t policy;
+    psa_status_t status;
+    size_t key_bits;
+    size_t buffer_length;
+    unsigned char *buffer = NULL;
+    size_t output_length;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_get_key_information( key_slot,
+                                          NULL,
+                                          &key_bits ) == PSA_SUCCESS );
+    buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
+                                                        exercise_alg );
+    buffer = mbedcrypto_calloc( 1, buffer_length );
+    TEST_ASSERT( buffer != NULL );
+
+    status = psa_asymmetric_encrypt( key_slot, exercise_alg,
+                                     NULL, 0,
+                                     NULL, 0,
+                                     buffer, buffer_length,
+                                     &output_length );
+    if( policy_alg == exercise_alg &&
+        ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
+        TEST_ASSERT( status == PSA_SUCCESS );
+    else
+        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+
+    memset( buffer, 0, buffer_length );
+    status = psa_asymmetric_decrypt( key_slot, exercise_alg,
+                                     buffer, buffer_length,
+                                     NULL, 0,
+                                     buffer, buffer_length,
+                                     &output_length );
+    if( policy_alg == exercise_alg &&
+        ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
+        TEST_ASSERT( status == PSA_ERROR_INVALID_PADDING );
+    else
+        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+
+exit:
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+    mbedcrypto_free( buffer );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void asymmetric_signature_key_policy( int policy_usage,
+                                      int policy_alg,
+                                      int key_type,
+                                      HexParam_t *key_data,
+                                      int exercise_alg )
+{
+    int key_slot = 1;
+    psa_key_policy_t policy;
+    psa_status_t status;
+    unsigned char payload[16] = {1};
+    size_t payload_length = sizeof( payload );
+    unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
+    size_t signature_length;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+
+    status = psa_asymmetric_sign( key_slot, exercise_alg,
+                                  payload, payload_length,
+                                  signature, sizeof( signature ),
+                                  &signature_length );
+    if( policy_alg == exercise_alg &&
+        ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
+        TEST_ASSERT( status == PSA_SUCCESS );
+    else
+        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+
+    memset( signature, 0, sizeof( signature ) );
+    status = psa_asymmetric_verify( key_slot, exercise_alg,
+                                    payload, payload_length,
+                                    signature, sizeof( signature ) );
+    if( policy_alg == exercise_alg &&
+        ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
+        TEST_ASSERT( status == PSA_ERROR_INVALID_SIGNATURE );
+    else
+        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+
+exit:
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void derive_key_policy( int policy_usage,
+                        int policy_alg,
+                        int key_type,
+                        HexParam_t *key_data,
+                        int exercise_alg )
+{
+    int key_slot = 1;
+    psa_key_policy_t policy;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    psa_status_t status;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+
+    status = psa_key_derivation( &generator, key_slot,
+                                 exercise_alg,
+                                 NULL, 0,
+                                 NULL, 0,
+                                 1 );
+    if( policy_alg == exercise_alg &&
+        ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
+        TEST_ASSERT( status == PSA_SUCCESS );
+    else
+        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+
+exit:
+    psa_generator_abort( &generator );
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void key_lifetime( int lifetime_arg )
+{
+    int key_slot = 1;
+    psa_key_type_t key_type = PSA_ALG_CBC_BASE;
+    unsigned char key[32] = {0};
+    psa_key_lifetime_t lifetime_set = lifetime_arg;
+    psa_key_lifetime_t lifetime_get;
+
+    memset( key, 0x2a, sizeof( key ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_set_key_lifetime( key_slot,
+                                       lifetime_set ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key, sizeof( key ) ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_get_key_lifetime( key_slot,
+                                       &lifetime_get ) == PSA_SUCCESS );
+
+    TEST_ASSERT( lifetime_get == lifetime_set );
+
+exit:
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void key_lifetime_set_fail( int key_slot_arg,
+                            int lifetime_arg,
+                            int expected_status_arg )
+{
+    psa_key_slot_t key_slot = key_slot_arg;
+    psa_key_lifetime_t lifetime_set = lifetime_arg;
+    psa_status_t actual_status;
+    psa_status_t expected_status = expected_status_arg;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    actual_status = psa_set_key_lifetime( key_slot, lifetime_set );
+
+    if( actual_status == PSA_SUCCESS )
+        actual_status = psa_set_key_lifetime( key_slot, lifetime_set );
+
+    TEST_ASSERT( expected_status == actual_status );
+
+exit:
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void hash_setup( int alg_arg,
+                 int expected_status_arg )
+{
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_hash_operation_t operation;
+    psa_status_t status;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    status = psa_hash_setup( &operation, alg );
+    psa_hash_abort( &operation );
+    TEST_ASSERT( status == expected_status );
+
+exit:
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void hash_finish( int alg_arg, HexParam_t *input, HexParam_t *expected_hash )
+{
+    psa_algorithm_t alg = alg_arg;
+    unsigned char actual_hash[PSA_HASH_MAX_SIZE];
+    size_t actual_hash_length;
+    psa_hash_operation_t operation;
+
+    TEST_ASSERT( expected_hash->len == PSA_HASH_SIZE( alg ) );
+    TEST_ASSERT( expected_hash->len <= PSA_HASH_MAX_SIZE );
+
+    TEST_ASSERT( input != NULL );
+    TEST_ASSERT( expected_hash != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_hash->len ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_hash_setup( &operation, alg ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_hash_update( &operation,
+                                  input->x, input->len ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_hash_finish( &operation,
+                                  actual_hash, sizeof( actual_hash ),
+                                  &actual_hash_length ) == PSA_SUCCESS );
+    TEST_ASSERT( actual_hash_length == expected_hash->len );
+    TEST_ASSERT( memcmp( expected_hash->x, actual_hash,
+                         expected_hash->len ) == 0 );
+
+exit:
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void hash_verify( int alg_arg, HexParam_t *input, HexParam_t *expected_hash )
+{
+    psa_algorithm_t alg = alg_arg;
+    psa_hash_operation_t operation;
+
+    TEST_ASSERT( expected_hash->len == PSA_HASH_SIZE( alg ) );
+    TEST_ASSERT( expected_hash->len <= PSA_HASH_MAX_SIZE );
+
+    TEST_ASSERT( input != NULL );
+    TEST_ASSERT( expected_hash != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_hash->len ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_hash_setup( &operation, alg ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_hash_update( &operation,
+                                  input->x,
+                                  input->len ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_hash_verify( &operation,
+                                  expected_hash->x,
+                                  expected_hash->len ) == PSA_SUCCESS );
+
+exit:
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mac_setup( int key_type_arg,
+                HexParam_t *key,
+                int alg_arg,
+                int expected_status_arg )
+{
+    int key_slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_mac_operation_t operation;
+    psa_key_policy_t policy;
+    psa_status_t status;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy,
+                              PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
+                              alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key->x, key->len ) == PSA_SUCCESS );
+
+    status = psa_mac_sign_setup( &operation, key_slot, alg );
+    psa_mac_abort( &operation );
+    TEST_ASSERT( status == expected_status );
+
+exit:
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mac_verify( int key_type_arg,
+                 HexParam_t *key,
+                 int alg_arg,
+                 HexParam_t *input,
+                 HexParam_t *expected_mac )
+{
+    int key_slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_mac_operation_t operation;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
+
+    TEST_ASSERT( key != NULL );
+    TEST_ASSERT( input != NULL );
+    TEST_ASSERT( expected_mac != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_mac->len ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key->x, key->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_mac_verify_setup( &operation,
+                                       key_slot, alg ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_destroy_key( key_slot ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_mac_update( &operation,
+                                 input->x, input->len ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_mac_verify_finish( &operation,
+                                        expected_mac->x,
+                                        expected_mac->len ) == PSA_SUCCESS );
+
+exit:
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void cipher_setup( int key_type_arg,
+                   HexParam_t *key,
+                   int alg_arg,
+                   int expected_status_arg )
+{
+    int key_slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_cipher_operation_t operation;
+    psa_key_policy_t policy;
+    psa_status_t status;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key->x, key->len ) == PSA_SUCCESS );
+
+    status = psa_cipher_encrypt_setup( &operation, key_slot, alg );
+    psa_cipher_abort( &operation );
+    TEST_ASSERT( status == expected_status );
+
+exit:
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void cipher_encrypt( int alg_arg, int key_type_arg,
+                     HexParam_t *key,
+                     HexParam_t *input, HexParam_t *expected_output,
+                     int expected_status_arg )
+{
+    int key_slot = 1;
+    psa_status_t status;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_status = expected_status_arg;
+    unsigned char iv[16] = {0};
+    size_t iv_size;
+    unsigned char *output = NULL;
+    size_t output_buffer_size = 0;
+    size_t function_output_length = 0;
+    size_t total_output_length = 0;
+    psa_cipher_operation_t operation;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key != NULL );
+    TEST_ASSERT( input != NULL );
+    TEST_ASSERT( expected_output != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_output->len ) );
+
+    iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    memset( iv, 0x2a, iv_size );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key->x, key->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_cipher_encrypt_setup( &operation,
+                                           key_slot, alg ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_cipher_set_iv( &operation,
+                                    iv, iv_size ) == PSA_SUCCESS );
+    output_buffer_size = (size_t) input->len +
+                         PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    output = mbedcrypto_calloc( 1, output_buffer_size );
+    TEST_ASSERT( output != NULL );
+
+    TEST_ASSERT( psa_cipher_update( &operation,
+                                    input->x, input->len,
+                                    output, output_buffer_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+    total_output_length += function_output_length;
+    status = psa_cipher_finish( &operation,
+                                output + function_output_length,
+                                output_buffer_size,
+                                &function_output_length );
+    total_output_length += function_output_length;
+
+    TEST_ASSERT( status == expected_status );
+    if( expected_status == PSA_SUCCESS )
+    {
+        TEST_ASSERT( psa_cipher_abort( &operation ) == PSA_SUCCESS );
+        TEST_ASSERT( total_output_length == expected_output->len );
+        TEST_ASSERT( memcmp( expected_output->x, output,
+                             expected_output->len ) == 0 );
+    }
+
+exit:
+    mbedcrypto_free( output );
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
+                               HexParam_t *key,
+                               HexParam_t *input,
+                               int first_part_size,
+                               HexParam_t *expected_output )
+{
+    int key_slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    unsigned char iv[16] = {0};
+    size_t iv_size;
+    unsigned char *output = NULL;
+    size_t output_buffer_size = 0;
+    size_t function_output_length = 0;
+    size_t total_output_length = 0;
+    psa_cipher_operation_t operation;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key != NULL );
+    TEST_ASSERT( input != NULL );
+    TEST_ASSERT( expected_output != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_output->len ) );
+
+    iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    memset( iv, 0x2a, iv_size );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key->x, key->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_cipher_encrypt_setup( &operation,
+                                           key_slot, alg ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_cipher_set_iv( &operation,
+                                    iv, sizeof( iv ) ) == PSA_SUCCESS );
+    output_buffer_size = (size_t) input->len +
+                         PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    output = mbedcrypto_calloc( 1, output_buffer_size );
+    TEST_ASSERT( output != NULL );
+
+    TEST_ASSERT( (unsigned int) first_part_size < input->len );
+    TEST_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
+                                    output, output_buffer_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+    total_output_length += function_output_length;
+    TEST_ASSERT( psa_cipher_update( &operation,
+                                    input->x + first_part_size,
+                                    input->len - first_part_size,
+                                    output, output_buffer_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+    total_output_length += function_output_length;
+    TEST_ASSERT( psa_cipher_finish( &operation,
+                                    output + function_output_length,
+                                    output_buffer_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+    total_output_length += function_output_length;
+    TEST_ASSERT( psa_cipher_abort( &operation ) == PSA_SUCCESS );
+
+    TEST_ASSERT( total_output_length == expected_output->len );
+    TEST_ASSERT( memcmp( expected_output->x, output,
+                         expected_output->len ) == 0 );
+
+exit:
+    mbedcrypto_free( output );
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
+                               HexParam_t *key,
+                               HexParam_t *input,
+                               int first_part_size,
+                               HexParam_t *expected_output )
+{
+    int key_slot = 1;
+
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    unsigned char iv[16] = {0};
+    size_t iv_size;
+    unsigned char *output = NULL;
+    size_t output_buffer_size = 0;
+    size_t function_output_length = 0;
+    size_t total_output_length = 0;
+    psa_cipher_operation_t operation;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key != NULL );
+    TEST_ASSERT( input != NULL );
+    TEST_ASSERT( expected_output != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_output->len ) );
+
+    iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    memset( iv, 0x2a, iv_size );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key->x, key->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_cipher_decrypt_setup( &operation,
+                                           key_slot, alg ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_cipher_set_iv( &operation,
+                                    iv, sizeof( iv ) ) == PSA_SUCCESS );
+
+    output_buffer_size = (size_t) input->len +
+                         PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    output = mbedcrypto_calloc( 1, output_buffer_size );
+    TEST_ASSERT( output != NULL );
+
+    TEST_ASSERT( (unsigned int) first_part_size < input->len );
+    TEST_ASSERT( psa_cipher_update( &operation,
+                                    input->x, first_part_size,
+                                    output, output_buffer_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+    total_output_length += function_output_length;
+    TEST_ASSERT( psa_cipher_update( &operation,
+                                    input->x + first_part_size,
+                                    input->len - first_part_size,
+                                    output, output_buffer_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+    total_output_length += function_output_length;
+    TEST_ASSERT( psa_cipher_finish( &operation,
+                                    output + function_output_length,
+                                    output_buffer_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+    total_output_length += function_output_length;
+    TEST_ASSERT( psa_cipher_abort( &operation ) == PSA_SUCCESS );
+
+    TEST_ASSERT( total_output_length == expected_output->len );
+    TEST_ASSERT( memcmp( expected_output->x, output,
+                         expected_output->len ) == 0 );
+
+exit:
+    mbedcrypto_free( output );
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void cipher_decrypt( int alg_arg, int key_type_arg,
+                     HexParam_t *key,
+                     HexParam_t *input, HexParam_t *expected_output,
+                     int expected_status_arg )
+{
+    int key_slot = 1;
+    psa_status_t status;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_status = expected_status_arg;
+    unsigned char iv[16] = {0};
+    size_t iv_size;
+    unsigned char *output = NULL;
+    size_t output_buffer_size = 0;
+    size_t function_output_length = 0;
+    size_t total_output_length = 0;
+    psa_cipher_operation_t operation;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key != NULL );
+    TEST_ASSERT( input != NULL );
+    TEST_ASSERT( expected_output != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_output->len ) );
+
+    iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    memset( iv, 0x2a, iv_size );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key->x, key->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_cipher_decrypt_setup( &operation,
+                                           key_slot, alg ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_cipher_set_iv( &operation,
+                                    iv, iv_size ) == PSA_SUCCESS );
+
+    output_buffer_size = (size_t) input->len +
+                         PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    output = mbedcrypto_calloc( 1, output_buffer_size );
+    TEST_ASSERT( output != NULL );
+
+    TEST_ASSERT( psa_cipher_update( &operation,
+                                    input->x, input->len,
+                                    output, output_buffer_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+    total_output_length += function_output_length;
+    status = psa_cipher_finish( &operation,
+                                output + function_output_length,
+                                output_buffer_size,
+                                &function_output_length );
+    total_output_length += function_output_length;
+    TEST_ASSERT( status == expected_status );
+
+    if( expected_status == PSA_SUCCESS )
+    {
+        TEST_ASSERT( psa_cipher_abort( &operation ) == PSA_SUCCESS );
+        TEST_ASSERT( total_output_length == expected_output->len );
+        TEST_ASSERT( memcmp( expected_output->x, output,
+                             expected_output->len ) == 0 );
+    }
+
+exit:
+    mbedcrypto_free( output );
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void cipher_verify_output( int alg_arg, int key_type_arg,
+                           HexParam_t *key,
+                           HexParam_t *input )
+{
+    int key_slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    unsigned char iv[16] = {0};
+    size_t iv_size = 16;
+    size_t iv_length = 0;
+    unsigned char *output1 = NULL;
+    size_t output1_size = 0;
+    size_t output1_length = 0;
+    unsigned char *output2 = NULL;
+    size_t output2_size = 0;
+    size_t output2_length = 0;
+    size_t function_output_length = 0;
+    psa_cipher_operation_t operation1;
+    psa_cipher_operation_t operation2;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key != NULL );
+    TEST_ASSERT( input != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key->x, key->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_cipher_encrypt_setup( &operation1,
+                                           key_slot, alg ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_cipher_decrypt_setup( &operation2,
+                                           key_slot, alg ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_cipher_generate_iv( &operation1,
+                                         iv, iv_size,
+                                         &iv_length ) == PSA_SUCCESS );
+    output1_size = (size_t) input->len +
+                   PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    output1 = mbedcrypto_calloc( 1, output1_size );
+    TEST_ASSERT( output1 != NULL );
+
+    TEST_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
+                                    output1, output1_size,
+                                    &output1_length ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_cipher_finish( &operation1,
+                                    output1 + output1_length, output1_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+
+    output1_length += function_output_length;
+
+    TEST_ASSERT( psa_cipher_abort( &operation1 ) == PSA_SUCCESS );
+
+    output2_size = output1_length;
+    output2 = mbedcrypto_calloc( 1, output2_size );
+    TEST_ASSERT( output2 != NULL );
+
+    TEST_ASSERT( psa_cipher_set_iv( &operation2,
+                                    iv, iv_length ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
+                                    output2, output2_size,
+                                    &output2_length ) == PSA_SUCCESS );
+    function_output_length = 0;
+    TEST_ASSERT( psa_cipher_finish( &operation2,
+                                    output2 + output2_length,
+                                    output2_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+
+    output2_length += function_output_length;
+
+    TEST_ASSERT( psa_cipher_abort( &operation2 ) == PSA_SUCCESS );
+
+    TEST_ASSERT( input->len == output2_length );
+    TEST_ASSERT( memcmp( input->x, output2, input->len ) == 0 );
+
+exit:
+    mbedcrypto_free( output1 );
+    mbedcrypto_free( output2 );
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void cipher_verify_output_multipart( int alg_arg,
+                                     int key_type_arg,
+                                     HexParam_t *key,
+                                     HexParam_t *input,
+                                     int first_part_size )
+{
+    int key_slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    unsigned char iv[16] = {0};
+    size_t iv_size = 16;
+    size_t iv_length = 0;
+    unsigned char *output1 = NULL;
+    size_t output1_buffer_size = 0;
+    size_t output1_length = 0;
+    unsigned char *output2 = NULL;
+    size_t output2_buffer_size = 0;
+    size_t output2_length = 0;
+    size_t function_output_length;
+    psa_cipher_operation_t operation1;
+    psa_cipher_operation_t operation2;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key != NULL );
+    TEST_ASSERT( input != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key->x, key->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_cipher_encrypt_setup( &operation1,
+                                           key_slot, alg ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_cipher_decrypt_setup( &operation2,
+                                           key_slot, alg ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_cipher_generate_iv( &operation1,
+                                         iv, iv_size,
+                                         &iv_length ) == PSA_SUCCESS );
+    output1_buffer_size = (size_t) input->len +
+                          PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    output1 = mbedcrypto_calloc( 1, output1_buffer_size );
+    TEST_ASSERT( output1 != NULL );
+
+    TEST_ASSERT( (unsigned int) first_part_size < input->len );
+
+    TEST_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
+                                    output1, output1_buffer_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+    output1_length += function_output_length;
+
+    TEST_ASSERT( psa_cipher_update( &operation1,
+                                    input->x + first_part_size,
+                                    input->len - first_part_size,
+                                    output1, output1_buffer_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+    output1_length += function_output_length;
+
+    TEST_ASSERT( psa_cipher_finish( &operation1,
+                                    output1 + output1_length,
+                                    output1_buffer_size - output1_length,
+                                    &function_output_length ) == PSA_SUCCESS );
+    output1_length += function_output_length;
+
+    TEST_ASSERT( psa_cipher_abort( &operation1 ) == PSA_SUCCESS );
+
+    output2_buffer_size = output1_length;
+    output2 = mbedcrypto_calloc( 1, output2_buffer_size );
+    TEST_ASSERT( output2 != NULL );
+
+    TEST_ASSERT( psa_cipher_set_iv( &operation2,
+                                    iv, iv_length ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
+                                    output2, output2_buffer_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+    output2_length += function_output_length;
+
+    TEST_ASSERT( psa_cipher_update( &operation2,
+                                    output1 + first_part_size,
+                                    output1_length - first_part_size,
+                                    output2, output2_buffer_size,
+                                    &function_output_length ) == PSA_SUCCESS );
+    output2_length += function_output_length;
+
+    TEST_ASSERT( psa_cipher_finish( &operation2,
+                                    output2 + output2_length,
+                                    output2_buffer_size - output2_length,
+                                    &function_output_length ) == PSA_SUCCESS );
+    output2_length += function_output_length;
+
+    TEST_ASSERT( psa_cipher_abort( &operation2 ) == PSA_SUCCESS );
+
+    TEST_ASSERT( input->len == output2_length );
+    TEST_ASSERT( memcmp( input->x, output2, input->len ) == 0 );
+
+exit:
+    mbedcrypto_free( output1 );
+    mbedcrypto_free( output2 );
+    psa_destroy_key( key_slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aead_encrypt_decrypt( int key_type_arg,
+                           HexParam_t * key_data,
+                           int alg_arg,
+                           HexParam_t * input_data,
+                           HexParam_t * nonce,
+                           HexParam_t * additional_data,
+                           int expected_result_arg )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    unsigned char *output_data = NULL;
+    size_t output_size = 0;
+    size_t output_length = 0;
+    unsigned char *output_data2 = NULL;
+    size_t output_length2 = 0;
+    size_t tag_length = 16;
+    psa_status_t expected_result = expected_result_arg;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key_data != NULL );
+    TEST_ASSERT( input_data != NULL );
+    TEST_ASSERT( nonce != NULL );
+    TEST_ASSERT( additional_data != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( nonce->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( additional_data->len ) );
+
+    output_size = input_data->len + tag_length;
+    output_data = mbedcrypto_calloc( 1, output_size );
+    TEST_ASSERT( output_data != NULL );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy,
+                              PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
+                              alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_aead_encrypt( slot, alg,
+                                   nonce->x, nonce->len,
+                                   additional_data->x,
+                                   additional_data->len,
+                                   input_data->x, input_data->len,
+                                   output_data, output_size,
+                                   &output_length ) == expected_result );
+
+    if( PSA_SUCCESS == expected_result )
+    {
+        output_data2 = mbedcrypto_calloc( 1, output_length );
+        TEST_ASSERT( output_data2 != NULL );
+
+        TEST_ASSERT( psa_aead_decrypt( slot, alg,
+                                       nonce->x, nonce->len,
+                                       additional_data->x,
+                                       additional_data->len,
+                                       output_data, output_length,
+                                       output_data2, output_length,
+                                       &output_length2 ) == expected_result );
+
+        TEST_ASSERT( memcmp( input_data->x, output_data2,
+                             input_data->len ) == 0 );
+    }
+
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_free( output_data );
+    mbedcrypto_free( output_data2 );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aead_encrypt( int key_type_arg, HexParam_t * key_data,
+                   int alg_arg, HexParam_t * input_data,
+                   HexParam_t * additional_data, HexParam_t * nonce,
+                   HexParam_t * expected_result )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    unsigned char *output_data = NULL;
+    size_t output_size = 0;
+    size_t output_length = 0;
+    size_t tag_length = 16;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key_data != NULL );
+    TEST_ASSERT( input_data != NULL );
+    TEST_ASSERT( additional_data != NULL );
+    TEST_ASSERT( nonce != NULL );
+    TEST_ASSERT( expected_result != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( additional_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( nonce->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_result->len ) );
+
+    output_size = input_data->len + tag_length;
+    output_data = mbedcrypto_calloc( 1, output_size );
+    TEST_ASSERT( output_data != NULL );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT , alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_aead_encrypt( slot, alg,
+                                   nonce->x, nonce->len,
+                                   additional_data->x, additional_data->len,
+                                   input_data->x, input_data->len,
+                                   output_data, output_size,
+                                   &output_length ) == PSA_SUCCESS );
+
+    TEST_ASSERT( memcmp( output_data, expected_result->x,
+                         output_length ) == 0 );
+
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_free( output_data );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void aead_decrypt( int key_type_arg, HexParam_t * key_data,
+                   int alg_arg, HexParam_t * input_data,
+                   HexParam_t * additional_data, HexParam_t * nonce,
+                   HexParam_t * expected_data, int expected_result_arg )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    unsigned char *output_data = NULL;
+    size_t output_size = 0;
+    size_t output_length = 0;
+    size_t tag_length = 16;
+    psa_key_policy_t policy;
+    psa_status_t expected_result = expected_result_arg;
+
+    TEST_ASSERT( key_data != NULL );
+    TEST_ASSERT( input_data != NULL );
+    TEST_ASSERT( additional_data != NULL );
+    TEST_ASSERT( nonce != NULL );
+    TEST_ASSERT( expected_data != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( additional_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( nonce->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_data->len ) );
+
+    output_size = input_data->len + tag_length;
+    output_data = mbedcrypto_calloc( 1, output_size );
+    TEST_ASSERT( output_data != NULL );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT , alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_aead_decrypt( slot, alg,
+                                   nonce->x, nonce->len,
+                                   additional_data->x,
+                                   additional_data->len,
+                                   input_data->x, input_data->len,
+                                   output_data, output_size,
+                                   &output_length ) == expected_result );
+
+    if( expected_result == PSA_SUCCESS )
+    {
+        TEST_ASSERT( memcmp( output_data, expected_data->x,
+                             output_length ) == 0 );
+    }
+
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_free( output_data );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void signature_size( int type_arg,
+                     int bits,
+                     int alg_arg,
+                     int expected_size_arg )
+{
+    psa_key_type_t type = type_arg;
+    psa_algorithm_t alg = alg_arg;
+    size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
+    TEST_ASSERT( actual_size == (size_t) expected_size_arg );
+exit:
+    ;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void sign_deterministic( int key_type_arg, HexParam_t *key_data,
+                         int alg_arg, HexParam_t *input_data,
+                         HexParam_t *output_data )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    size_t key_bits;
+    unsigned char *signature = NULL;
+    size_t signature_size;
+    size_t signature_length = 0xdeadbeef;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key_data != NULL );
+    TEST_ASSERT( input_data != NULL );
+    TEST_ASSERT( output_data != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( output_data->len ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_get_key_information( slot,
+                                          NULL,
+                                          &key_bits ) == PSA_SUCCESS );
+
+    /* Allocate a buffer which has the size advertized by the
+     * library. */
+    signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
+                                                      key_bits, alg );
+    TEST_ASSERT( signature_size != 0 );
+    TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
+    signature = mbedcrypto_calloc( 1, signature_size );
+    TEST_ASSERT( signature != NULL );
+
+    /* Perform the signature. */
+    TEST_ASSERT( psa_asymmetric_sign( slot, alg,
+                                      input_data->x, input_data->len,
+                                      signature, signature_size,
+                                      &signature_length ) == PSA_SUCCESS );
+    /* Verify that the signature is what is expected. */
+    TEST_ASSERT( signature_length == output_data->len );
+    TEST_ASSERT( memcmp( signature, output_data->x,
+                         output_data->len ) == 0 );
+
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_free( signature );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void sign_fail( int key_type_arg, HexParam_t *key_data,
+                int alg_arg, HexParam_t *input_data,
+                int signature_size_arg, int expected_status_arg )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    size_t signature_size = signature_size_arg;
+    psa_status_t actual_status;
+    psa_status_t expected_status = expected_status_arg;
+    unsigned char *signature = NULL;
+    size_t signature_length = 0xdeadbeef;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key_data != NULL );
+    TEST_ASSERT( input_data != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
+
+    signature = mbedcrypto_calloc( 1, signature_size );
+    TEST_ASSERT( signature != NULL );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    actual_status = psa_asymmetric_sign( slot, alg,
+                                         input_data->x, input_data->len,
+                                         signature, signature_size,
+                                         &signature_length );
+    TEST_ASSERT( actual_status == expected_status );
+    /* The value of *signature_length is unspecified on error, but
+     * whatever it is, it should be less than signature_size, so that
+     * if the caller tries to read *signature_length bytes without
+     * checking the error code then they don't overflow a buffer. */
+    TEST_ASSERT( signature_length <= signature_size );
+
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_free( signature );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void sign_verify( int key_type_arg, HexParam_t *key_data,
+                  int alg_arg, HexParam_t *input_data )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    size_t key_bits;
+    unsigned char *signature = NULL;
+    size_t signature_size;
+    size_t signature_length = 0xdeadbeef;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy,
+                              PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
+                              alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_get_key_information( slot,
+                                          NULL,
+                                          &key_bits ) == PSA_SUCCESS );
+
+    /* Allocate a buffer which has the size advertized by the
+     * library. */
+    signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
+                                                      key_bits, alg );
+    TEST_ASSERT( signature_size != 0 );
+    TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
+    signature = mbedcrypto_calloc( 1, signature_size );
+    TEST_ASSERT( signature != NULL );
+
+    /* Perform the signature. */
+    TEST_ASSERT( psa_asymmetric_sign( slot, alg,
+                                      input_data->x, input_data->len,
+                                      signature, signature_size,
+                                      &signature_length ) == PSA_SUCCESS );
+    /* Check that the signature length looks sensible. */
+    TEST_ASSERT( signature_length <= signature_size );
+    TEST_ASSERT( signature_length > 0 );
+
+    /* Use the library to verify that the signature is correct. */
+    TEST_ASSERT( psa_asymmetric_verify(
+                     slot, alg,
+                     input_data->x, input_data->len,
+                     signature, signature_length ) == PSA_SUCCESS );
+
+    if( input_data->len != 0 )
+    {
+        /* Flip a bit in the input and verify that the signature is now
+         * detected as invalid. Flip a bit at the beginning, not at the end,
+         * because ECDSA may ignore the last few bits of the input. */
+        input_data->x[0] ^= 1;
+        TEST_ASSERT( psa_asymmetric_verify(
+                         slot, alg,
+                         input_data->x, input_data->len,
+                         signature,
+                         signature_length ) == PSA_ERROR_INVALID_SIGNATURE );
+    }
+
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_free( signature );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void asymmetric_verify( int key_type_arg, HexParam_t *key_data,
+                        int alg_arg, HexParam_t *hash_data,
+                        HexParam_t *signature_data )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
+
+    TEST_ASSERT( key_data != NULL );
+    TEST_ASSERT( hash_data != NULL );
+    TEST_ASSERT( signature_data != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( hash_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( signature_data->len ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_asymmetric_verify( slot, alg,
+                                        hash_data->x, hash_data->len,
+                                        signature_data->x,
+                                        signature_data->len ) == PSA_SUCCESS );
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void asymmetric_verify_fail( int key_type_arg, HexParam_t *key_data,
+                             int alg_arg, HexParam_t *hash_data,
+                             HexParam_t *signature_data,
+                             int expected_status_arg )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t actual_status;
+    psa_status_t expected_status = expected_status_arg;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key_data != NULL );
+    TEST_ASSERT( hash_data != NULL );
+    TEST_ASSERT( signature_data != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( hash_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( signature_data->len ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    actual_status = psa_asymmetric_verify( slot, alg,
+                                           hash_data->x, hash_data->len,
+                                           signature_data->x,
+                                           signature_data->len );
+
+    TEST_ASSERT( actual_status == expected_status );
+
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void asymmetric_encrypt( int key_type_arg,
+                         HexParam_t *key_data,
+                         int alg_arg,
+                         HexParam_t *input_data,
+                         HexParam_t *label,
+                         int expected_output_length_arg,
+                         int expected_status_arg )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    size_t expected_output_length = expected_output_length_arg;
+    size_t key_bits;
+    unsigned char *output = NULL;
+    size_t output_size;
+    size_t output_length = ~0;
+    psa_status_t actual_status;
+    psa_status_t expected_status = expected_status_arg;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    /* Import the key */
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    /* Determine the maximum output length */
+    TEST_ASSERT( psa_get_key_information( slot,
+                                          NULL,
+                                          &key_bits ) == PSA_SUCCESS );
+    output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
+    output = mbedcrypto_calloc( 1, output_size );
+    TEST_ASSERT( output_size == 0 || output != NULL );
+
+    /* Encrypt the input */
+    actual_status = psa_asymmetric_encrypt( slot, alg,
+                                            input_data->x, input_data->len,
+                                            label->x, label->len,
+                                            output, output_size,
+                                            &output_length );
+    TEST_ASSERT( actual_status == expected_status );
+    TEST_ASSERT( output_length == expected_output_length );
+
+    /* If the label is empty, the test framework puts a non-null pointer
+     * in label->x. Test that a null pointer works as well. */
+    if( label->len == 0 )
+    {
+        output_length = ~0;
+        memset( output, 0, output_size );
+        actual_status = psa_asymmetric_encrypt( slot, alg,
+                                                input_data->x, input_data->len,
+                                                NULL, label->len,
+                                                output, output_size,
+                                                &output_length );
+        TEST_ASSERT( actual_status == expected_status );
+        TEST_ASSERT( output_length == expected_output_length );
+    }
+
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_free( output );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void asymmetric_encrypt_decrypt( int key_type_arg,
+                                 HexParam_t *key_data,
+                                 int alg_arg,
+                                 HexParam_t *input_data,
+                                 HexParam_t *label )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    size_t key_bits;
+    unsigned char *output = NULL;
+    size_t output_size;
+    size_t output_length = ~0;
+    unsigned char *output2 = NULL;
+    size_t output2_size;
+    size_t output2_length = ~0;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key_data != NULL );
+    TEST_ASSERT( input_data != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy,
+                              PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
+                              alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+
+    /* Determine the maximum ciphertext length */
+    TEST_ASSERT( psa_get_key_information( slot,
+                                          NULL,
+                                          &key_bits ) == PSA_SUCCESS );
+    output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
+    output = mbedcrypto_calloc( 1, output_size );
+    TEST_ASSERT( output != NULL );
+    output2_size = input_data->len;
+    output2 = mbedcrypto_calloc( 1, output2_size );
+    TEST_ASSERT( output2 != NULL );
+
+    /* We test encryption by checking that encrypt-then-decrypt gives back
+     * the original plaintext because of the non-optional random
+     * part of encryption process which prevents using fixed vectors. */
+    TEST_ASSERT( psa_asymmetric_encrypt( slot, alg,
+                                         input_data->x, input_data->len,
+                                         label->x, label->len,
+                                         output, output_size,
+                                         &output_length ) == PSA_SUCCESS );
+    /* We don't know what ciphertext length to expect, but check that
+     * it looks sensible. */
+    TEST_ASSERT( output_length <= output_size );
+
+    TEST_ASSERT( psa_asymmetric_decrypt( slot, alg,
+                                         output, output_length,
+                                         label->x, label->len,
+                                         output2, output2_size,
+                                         &output2_length ) == PSA_SUCCESS );
+    TEST_ASSERT( output2_length == input_data->len );
+    TEST_ASSERT( memcmp( input_data->x, output2,
+                         input_data->len ) == 0 );
+
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_free( output );
+    mbedcrypto_free( output2 );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void asymmetric_decrypt( int key_type_arg,
+                         HexParam_t *key_data,
+                         int alg_arg,
+                         HexParam_t *input_data,
+                         HexParam_t *label,
+                         HexParam_t *expected_data )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    unsigned char *output = NULL;
+    size_t output_size = 0;
+    size_t output_length = ~0;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key_data != NULL );
+    TEST_ASSERT( input_data != NULL );
+    TEST_ASSERT( expected_data != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_data->len ) );
+
+    output_size = key_data->len;
+    output = mbedcrypto_calloc( 1, output_size );
+    TEST_ASSERT( output != NULL );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_asymmetric_decrypt( slot, alg,
+                                         input_data->x, input_data->len,
+                                         label->x, label->len,
+                                         output,
+                                         output_size,
+                                         &output_length ) == PSA_SUCCESS );
+    TEST_ASSERT( expected_data->len == output_length );
+    TEST_ASSERT( memcmp( expected_data->x, output, output_length ) == 0 );
+
+    /* If the label is empty, the test framework puts a non-null pointer
+     * in label->x. Test that a null pointer works as well. */
+    if( label->len == 0 )
+    {
+        output_length = ~0;
+        memset( output, 0, output_size );
+        TEST_ASSERT( psa_asymmetric_decrypt( slot, alg,
+                                             input_data->x, input_data->len,
+                                             NULL, label->len,
+                                             output,
+                                             output_size,
+                                             &output_length ) == PSA_SUCCESS );
+        TEST_ASSERT( expected_data->len == output_length );
+        TEST_ASSERT( memcmp( expected_data->x, output, output_length ) == 0 );
+    }
+
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_free( output );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void asymmetric_decrypt_fail( int key_type_arg,
+                              HexParam_t *key_data,
+                              int alg_arg,
+                              HexParam_t *input_data,
+                              HexParam_t *label,
+                              int expected_status_arg  )
+{
+    int slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    unsigned char *output = NULL;
+    size_t output_size = 0;
+    size_t output_length = ~0;
+    psa_status_t actual_status;
+    psa_status_t expected_status = expected_status_arg;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( key_data != NULL );
+    TEST_ASSERT( input_data != NULL );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
+    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
+
+    output_size = key_data->len;
+    output = mbedcrypto_calloc( 1, output_size );
+    TEST_ASSERT( output != NULL );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    actual_status = psa_asymmetric_decrypt( slot, alg,
+                                            input_data->x, input_data->len,
+                                            label->x, label->len,
+                                            output, output_size,
+                                            &output_length );
+    TEST_ASSERT( actual_status == expected_status );
+    TEST_ASSERT( output_length <= output_size );
+
+    /* If the label is empty, the test framework puts a non-null pointer
+     * in label->x. Test that a null pointer works as well. */
+    if( label->len == 0 )
+    {
+        output_length = ~0;
+        memset( output, 0, output_size );
+        actual_status = psa_asymmetric_decrypt( slot, alg,
+                                                input_data->x, input_data->len,
+                                                NULL, label->len,
+                                                output, output_size,
+                                                &output_length );
+        TEST_ASSERT( actual_status == expected_status );
+        TEST_ASSERT( output_length <= output_size );
+    }
+
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_free( output );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void derive_setup( int key_type_arg,
+                   HexParam_t *key_data,
+                   int alg_arg,
+                   HexParam_t *salt,
+                   HexParam_t *label,
+                   int requested_capacity_arg,
+                   int expected_status_arg )
+{
+    psa_key_slot_t slot = 1;
+    size_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    size_t requested_capacity = requested_capacity_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, key_type,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_key_derivation( &generator, slot, alg,
+                                     salt->x, salt->len,
+                                     label->x, label->len,
+                                     requested_capacity ) == expected_status );
+
+exit:
+    psa_generator_abort( &generator );
+    psa_destroy_key( slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void derive_output( int alg_arg,
+                    HexParam_t *key_data,
+                    HexParam_t *salt,
+                    HexParam_t *label,
+                    int requested_capacity_arg,
+                    HexParam_t *expected_output1,
+                    HexParam_t *expected_output2 )
+{
+    psa_key_slot_t slot = 1;
+    psa_algorithm_t alg = alg_arg;
+    size_t requested_capacity = requested_capacity_arg;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    uint8_t *expected_outputs[2] =
+        {expected_output1->x, expected_output2->x};
+    size_t output_sizes[2] =
+        {expected_output1->len, expected_output2->len};
+    size_t output_buffer_size = 0;
+    uint8_t *output_buffer = NULL;
+    size_t expected_capacity;
+    size_t current_capacity;
+    psa_key_policy_t policy;
+    psa_status_t status;
+    unsigned i;
+
+    for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
+    {
+        if( output_sizes[i] > output_buffer_size )
+            output_buffer_size = output_sizes[i];
+        if( output_sizes[i] == 0 )
+            expected_outputs[i] = NULL;
+    }
+    output_buffer = mbedcrypto_calloc( 1, output_buffer_size );
+    TEST_ASSERT( output_buffer != NULL );
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, PSA_KEY_TYPE_DERIVE,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    /* Extraction phase. */
+    TEST_ASSERT( psa_key_derivation( &generator, slot, alg,
+                                     salt->x, salt->len,
+                                     label->x, label->len,
+                                     requested_capacity ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_get_generator_capacity( &generator,
+                                             &current_capacity ) ==
+                 PSA_SUCCESS );
+    TEST_ASSERT( current_capacity == requested_capacity );
+    expected_capacity = requested_capacity;
+
+    /* Expansion phase. */
+    for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
+    {
+        /* Read some bytes. */
+        status = psa_generator_read( &generator,
+                                     output_buffer, output_sizes[i] );
+        if( expected_capacity == 0 && output_sizes[i] == 0 )
+        {
+            /* Reading 0 bytes when 0 bytes are available can go either way. */
+            TEST_ASSERT( status == PSA_SUCCESS ||
+                         status == PSA_ERROR_INSUFFICIENT_CAPACITY );
+            continue;
+        }
+        else if( expected_capacity == 0 ||
+                 output_sizes[i] > expected_capacity )
+        {
+            /* Capacity exceeded. */
+            TEST_ASSERT( status == PSA_ERROR_INSUFFICIENT_CAPACITY );
+            expected_capacity = 0;
+            continue;
+        }
+        /* Success. Check the read data. */
+        TEST_ASSERT( status == PSA_SUCCESS );
+        if( output_sizes[i] != 0 )
+            TEST_ASSERT( memcmp( output_buffer, expected_outputs[i],
+                                 output_sizes[i] ) == 0 );
+        /* Check the generator status. */
+        expected_capacity -= output_sizes[i];
+        TEST_ASSERT( psa_get_generator_capacity( &generator,
+                                                 &current_capacity ) ==
+                     PSA_SUCCESS );
+        TEST_ASSERT( expected_capacity == current_capacity );
+    }
+    TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+
+exit:
+    mbedcrypto_free( output_buffer );
+    psa_generator_abort( &generator );
+    psa_destroy_key( slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void derive_full( int alg_arg,
+                  HexParam_t *key_data,
+                  HexParam_t *salt,
+                  HexParam_t *label,
+                  int requested_capacity_arg )
+{
+    psa_key_slot_t slot = 1;
+    psa_algorithm_t alg = alg_arg;
+    size_t requested_capacity = requested_capacity_arg;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    unsigned char output_buffer[16];
+    size_t expected_capacity = requested_capacity;
+    size_t current_capacity;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( slot, PSA_KEY_TYPE_DERIVE,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    /* Extraction phase. */
+    TEST_ASSERT( psa_key_derivation( &generator, slot, alg,
+                                     salt->x, salt->len,
+                                     label->x, label->len,
+                                     requested_capacity ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_get_generator_capacity( &generator,
+                                             &current_capacity ) ==
+                 PSA_SUCCESS );
+    TEST_ASSERT( current_capacity == expected_capacity );
+
+    /* Expansion phase. */
+    while( current_capacity > 0 )
+    {
+        size_t read_size = sizeof( output_buffer );
+        if( read_size > current_capacity )
+            read_size = current_capacity;
+        TEST_ASSERT( psa_generator_read( &generator,
+                                         output_buffer,
+                                         read_size ) == PSA_SUCCESS );
+        expected_capacity -= read_size;
+        TEST_ASSERT( psa_get_generator_capacity( &generator,
+                                                 &current_capacity ) ==
+                     PSA_SUCCESS );
+        TEST_ASSERT( current_capacity == expected_capacity );
+    }
+
+    /* Check that the generator refuses to go over capacity. */
+    TEST_ASSERT( psa_generator_read( &generator,
+                                     output_buffer,
+                                     1 ) == PSA_ERROR_INSUFFICIENT_CAPACITY );
+
+    TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+
+exit:
+    psa_generator_abort( &generator );
+    psa_destroy_key( slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void derive_key_exercise( int alg_arg,
+                          HexParam_t *key_data,
+                          HexParam_t *salt,
+                          HexParam_t *label,
+                          int derived_type_arg,
+                          int derived_bits_arg,
+                          int derived_usage_arg,
+                          int derived_alg_arg )
+{
+    psa_key_slot_t base_key = 1;
+    psa_key_slot_t derived_key = 2;
+    psa_algorithm_t alg = alg_arg;
+    psa_key_type_t derived_type = derived_type_arg;
+    size_t derived_bits = derived_bits_arg;
+    psa_key_usage_t derived_usage = derived_usage_arg;
+    psa_algorithm_t derived_alg = derived_alg_arg;
+    size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    psa_key_policy_t policy;
+    psa_key_type_t got_type;
+    size_t got_bits;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
+    TEST_ASSERT( psa_set_key_policy( base_key, &policy ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_import_key( base_key, PSA_KEY_TYPE_DERIVE,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    /* Derive a key. */
+    TEST_ASSERT( psa_key_derivation( &generator, base_key, alg,
+                                     salt->x, salt->len,
+                                     label->x, label->len,
+                                     capacity ) == PSA_SUCCESS );
+    psa_key_policy_set_usage( &policy, derived_usage, derived_alg );
+    TEST_ASSERT( psa_set_key_policy( derived_key, &policy ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_generator_import_key( derived_key,
+                                           derived_type,
+                                           derived_bits,
+                                           &generator ) == PSA_SUCCESS );
+
+    /* Test the key information */
+    TEST_ASSERT( psa_get_key_information( derived_key,
+                                          &got_type,
+                                          &got_bits ) == PSA_SUCCESS );
+    TEST_ASSERT( got_type == derived_type );
+    TEST_ASSERT( got_bits == derived_bits );
+
+    /* Exercise the derived key. */
+    if( ! exercise_key( derived_key, derived_usage, derived_alg ) )
+        goto exit;
+
+exit:
+    psa_generator_abort( &generator );
+    psa_destroy_key( base_key );
+    psa_destroy_key( derived_key );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void derive_key_export( int alg_arg,
+                        HexParam_t *key_data,
+                        HexParam_t *salt,
+                        HexParam_t *label,
+                        int bytes1_arg,
+                        int bytes2_arg )
+{
+    psa_key_slot_t base_key = 1;
+    psa_key_slot_t derived_key = 2;
+    psa_algorithm_t alg = alg_arg;
+    size_t bytes1 = bytes1_arg;
+    size_t bytes2 = bytes2_arg;
+    size_t capacity = bytes1 + bytes2;
+    psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+    uint8_t *output_buffer = mbedcrypto_calloc( 1, capacity );
+    uint8_t *export_buffer = mbedcrypto_calloc( 1, capacity );
+    psa_key_policy_t policy;
+    size_t length;
+
+    TEST_ASSERT( output_buffer != NULL );
+    TEST_ASSERT( export_buffer != NULL );
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
+    TEST_ASSERT( psa_set_key_policy( base_key, &policy ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_import_key( base_key, PSA_KEY_TYPE_DERIVE,
+                                 key_data->x,
+                                 key_data->len ) == PSA_SUCCESS );
+
+    /* Derive some material and output it. */
+    TEST_ASSERT( psa_key_derivation( &generator, base_key, alg,
+                                     salt->x, salt->len,
+                                     label->x, label->len,
+                                     capacity ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_generator_read( &generator,
+                                     output_buffer,
+                                     capacity ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+
+    /* Derive the same output again, but this time store it in key objects. */
+    TEST_ASSERT( psa_key_derivation( &generator, base_key, alg,
+                                     salt->x, salt->len,
+                                     label->x, label->len,
+                                     capacity ) == PSA_SUCCESS );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, 0 );
+    TEST_ASSERT( psa_set_key_policy( derived_key, &policy ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_generator_import_key( derived_key,
+                                           PSA_KEY_TYPE_RAW_DATA,
+                                           PSA_BYTES_TO_BITS( bytes1 ),
+                                           &generator ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_export_key( derived_key,
+                                 export_buffer, bytes1,
+                                 &length ) == PSA_SUCCESS );
+    TEST_ASSERT( length == bytes1 );
+    TEST_ASSERT( psa_destroy_key( derived_key ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_set_key_policy( derived_key, &policy ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_generator_import_key( derived_key,
+                                           PSA_KEY_TYPE_RAW_DATA,
+                                           PSA_BYTES_TO_BITS( bytes2 ),
+                                           &generator ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_export_key( derived_key,
+                                 export_buffer + bytes1, bytes2,
+                                 &length ) == PSA_SUCCESS );
+    TEST_ASSERT( length == bytes2 );
+
+    /* Compare the outputs from the two runs. */
+    TEST_ASSERT( memcmp( output_buffer, export_buffer, capacity ) == 0 );
+
+exit:
+    mbedcrypto_free( output_buffer );
+    mbedcrypto_free( export_buffer );
+    psa_generator_abort( &generator );
+    psa_destroy_key( base_key );
+    psa_destroy_key( derived_key );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void generate_random( int bytes_arg )
+{
+    size_t bytes = bytes_arg;
+    const unsigned char trail[] = "don't overwrite me";
+    unsigned char *output = mbedcrypto_calloc( 1, bytes + sizeof( trail ) );
+    unsigned char *changed = mbedcrypto_calloc( 1, bytes );
+    size_t i;
+    unsigned run;
+
+    TEST_ASSERT( output != NULL );
+    TEST_ASSERT( bytes == 0 || changed != NULL );
+    memcpy( output + bytes, trail, sizeof( trail ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    /* Run several times, to ensure that every output byte will be
+     * nonzero at least once with overwhelming probability
+     * (2^(-8*number_of_runs)). */
+    for( run = 0; run < 10; run++ )
+    {
+        memset( output, 0, bytes );
+        TEST_ASSERT( psa_generate_random( output, bytes ) == PSA_SUCCESS );
+
+        /* Check that no more than bytes have been overwritten */
+        TEST_ASSERT( memcmp( output + bytes, trail, sizeof( trail ) ) == 0 );
+
+        for( i = 0; i < bytes; i++ )
+        {
+            if( output[i] != 0 )
+                ++changed[i];
+        }
+    }
+
+    /* Check that every byte was changed to nonzero at least once. This
+     * validates that psa_generate_random is overwriting every byte of
+     * the output buffer. */
+    for( i = 0; i < bytes; i++ )
+    {
+        TEST_ASSERT( changed[i] != 0 );
+    }
+
+exit:
+    mbedcrypto_psa_crypto_free( );
+    mbedcrypto_free( output );
+    mbedcrypto_free( changed );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void generate_key( int type_arg,
+                   int bits_arg,
+                   int usage_arg,
+                   int alg_arg,
+                   int expected_status_arg )
+{
+    int slot = 1;
+    psa_key_type_t type = type_arg;
+    psa_key_usage_t usage = usage_arg;
+    size_t bits = bits_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_key_type_t got_type;
+    size_t got_bits;
+    unsigned char exported[616] = {0}; /* enough for a 1024-bit RSA key */
+    size_t exported_length;
+    psa_status_t expected_export_status =
+        usage & PSA_KEY_USAGE_EXPORT ? PSA_SUCCESS : PSA_ERROR_NOT_PERMITTED;
+    psa_status_t expected_info_status =
+        expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_EMPTY_SLOT;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, usage, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    /* Generate a key */
+    TEST_ASSERT( psa_generate_key( slot, type, bits,
+                                   NULL, 0 ) == expected_status );
+
+    /* Test the key information */
+    TEST_ASSERT( psa_get_key_information( slot,
+                                          &got_type,
+                                          &got_bits ) == expected_info_status );
+    if( expected_info_status != PSA_SUCCESS )
+        goto exit;
+    TEST_ASSERT( got_type == type );
+    TEST_ASSERT( got_bits == bits );
+
+    /* Export the key */
+    TEST_ASSERT( psa_export_key( slot,
+                                 exported, sizeof( exported ),
+                                 &exported_length ) == expected_export_status );
+    if( expected_export_status == PSA_SUCCESS )
+    {
+        if( key_type_is_raw_bytes( type ) )
+            TEST_ASSERT( exported_length == ( bits + 7 ) / 8 );
+#if defined(MBEDCRYPTO_DES_C)
+        if( type == PSA_KEY_TYPE_DES )
+        {
+            /* Check the parity bits. */
+            unsigned i;
+            for( i = 0; i < bits / 8; i++ )
+            {
+                unsigned bit_count = 0;
+                unsigned m;
+                for( m = 1; m <= 0x100; m <<= 1 )
+                {
+                    if( exported[i] & m )
+                        ++bit_count;
+                }
+                TEST_ASSERT( bit_count % 2 != 0 );
+            }
+        }
+#endif
+#if defined(MBEDCRYPTO_RSA_C) && defined(MBEDCRYPTO_PK_PARSE_C)
+        if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
+        {
+            /* Sanity check: does this look like the beginning of a PKCS#8
+             * RSA key pair? Assumes bits is a multiple of 8. */
+            size_t n_bytes = bits / 8 + 1;
+            size_t n_encoded_bytes;
+            unsigned char *n_end;
+            TEST_ASSERT( exported_length >= 7 + ( n_bytes + 3 ) * 9 / 2 );
+            TEST_ASSERT( exported[0] == 0x30 );
+            TEST_ASSERT( exported[1] == 0x82 ); // assumes >=416-bit key
+            TEST_ASSERT( exported[4] == 0x02 );
+            TEST_ASSERT( exported[5] == 0x01 );
+            TEST_ASSERT( exported[6] == 0x00 );
+            TEST_ASSERT( exported[7] == 0x02 );
+            n_encoded_bytes = exported[8];
+            n_end = exported + 9 + n_encoded_bytes;
+            if( n_encoded_bytes & 0x80 )
+            {
+                n_encoded_bytes = ( n_encoded_bytes & 0x7f ) << 7;
+                n_encoded_bytes |= exported[9] & 0x7f;
+                n_end += 1;
+            }
+            /* The encoding of n should start with a 0 byte since it should
+             * have its high bit set. However Mbed Crypto is not compliant and
+             * generates an invalid, but widely tolerated, encoding of
+             * positive INTEGERs with a bit size that is a multiple of 8
+             * with no leading 0 byte. Accept this here. */
+            TEST_ASSERT( n_bytes == n_encoded_bytes ||
+                         n_bytes == n_encoded_bytes + 1 );
+            if( n_bytes == n_encoded_bytes )
+                TEST_ASSERT( exported[n_encoded_bytes <= 127 ? 9 : 10] == 0x00 );
+            /* Sanity check: e must be 3 */
+            TEST_ASSERT( n_end[0] == 0x02 );
+            TEST_ASSERT( n_end[1] == 0x03 );
+            TEST_ASSERT( n_end[2] == 0x01 );
+            TEST_ASSERT( n_end[3] == 0x00 );
+            TEST_ASSERT( n_end[4] == 0x01 );
+            TEST_ASSERT( n_end[5] == 0x02 );
+        }
+#endif /* MBEDCRYPTO_RSA_C */
+#if defined(MBEDCRYPTO_ECP_C)
+        if( PSA_KEY_TYPE_IS_ECC( type ) )
+        {
+            /* Sanity check: does this look like the beginning of a PKCS#8
+             * elliptic curve key pair? */
+            TEST_ASSERT( exported_length >= bits * 3 / 8 + 10 );
+            TEST_ASSERT( exported[0] == 0x30 );
+        }
+#endif /* MBEDCRYPTO_ECP_C */
+    }
+
+    /* Do something with the key according to its type and permitted usage. */
+    if( ! exercise_key( slot, usage, alg ) )
+        goto exit;
+
+exit:
+    psa_destroy_key( slot );
+    mbedcrypto_psa_crypto_free( );
+}
+/* END_CASE */