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,
+ ¤t_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,
+ ¤t_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,
+ ¤t_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,
+ ¤t_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 */