Downgraded mbedtls and updated for latest dynarmic
This commit is contained in:
333
externals/mbedtls/scripts/abi_check.py
vendored
333
externals/mbedtls/scripts/abi_check.py
vendored
@@ -1,94 +1,59 @@
|
||||
#!/usr/bin/env python3
|
||||
"""This script compares the interfaces of two versions of Mbed TLS, looking
|
||||
for backward incompatibilities between two different Git revisions within
|
||||
an Mbed TLS repository. It must be run from the root of a Git working tree.
|
||||
|
||||
### How the script works ###
|
||||
|
||||
For the source (API) and runtime (ABI) interface compatibility, this script
|
||||
is a small wrapper around the abi-compliance-checker and abi-dumper tools,
|
||||
applying them to compare the header and library files.
|
||||
|
||||
For the storage format, this script compares the automatically generated
|
||||
storage tests and the manual read tests, and complains if there is a
|
||||
reduction in coverage. A change in test data will be signaled as a
|
||||
coverage reduction since the old test data is no longer present. A change in
|
||||
how test data is presented will be signaled as well; this would be a false
|
||||
positive.
|
||||
|
||||
The results of the API/ABI comparison are either formatted as HTML and stored
|
||||
at a configurable location, or are given as a brief list of problems.
|
||||
Returns 0 on success, 1 on non-compliance, and 2 if there is an error
|
||||
while running the script.
|
||||
|
||||
### How to interpret non-compliance ###
|
||||
|
||||
This script has relatively common false positives. In many scenarios, it only
|
||||
reports a pass if there is a strict textual match between the old version and
|
||||
the new version, and it reports problems where there is a sufficient semantic
|
||||
match but not a textual match. This section lists some common false positives.
|
||||
This is not an exhaustive list: in the end what matters is whether we are
|
||||
breaking a backward compatibility goal.
|
||||
|
||||
**API**: the goal is that if an application works with the old version of the
|
||||
library, it can be recompiled against the new version and will still work.
|
||||
This is normally validated by comparing the declarations in `include/*/*.h`.
|
||||
A failure is a declaration that has disappeared or that now has a different
|
||||
type.
|
||||
|
||||
* It's ok to change or remove macros and functions that are documented as
|
||||
for internal use only or as experimental.
|
||||
* It's ok to rename function or macro parameters as long as the semantics
|
||||
has not changed.
|
||||
* It's ok to change or remove structure fields that are documented as
|
||||
private.
|
||||
* It's ok to add fields to a structure that already had private fields
|
||||
or was documented as extensible.
|
||||
|
||||
**ABI**: the goal is that if an application was built against the old version
|
||||
of the library, the same binary will work when linked against the new version.
|
||||
This is normally validated by comparing the symbols exported by `libmbed*.so`.
|
||||
A failure is a symbol that is no longer exported by the same library or that
|
||||
now has a different type.
|
||||
|
||||
* All ABI changes are acceptable if the library version is bumped
|
||||
(see `scripts/bump_version.sh`).
|
||||
* ABI changes that concern functions which are declared only inside the
|
||||
library directory, and not in `include/*/*.h`, are acceptable only if
|
||||
the function was only ever used inside the same library (libmbedcrypto,
|
||||
libmbedx509, libmbedtls). As a counter example, if the old version
|
||||
of libmbedtls calls mbedtls_foo() from libmbedcrypto, and the new version
|
||||
of libmbedcrypto no longer has a compatible mbedtls_foo(), this does
|
||||
require a version bump for libmbedcrypto.
|
||||
|
||||
**Storage format**: the goal is to check that persistent keys stored by the
|
||||
old version can be read by the new version. This is normally validated by
|
||||
comparing the `*read*` test cases in `test_suite*storage_format*.data`.
|
||||
A failure is a storage read test case that is no longer present with the same
|
||||
function name and parameter list.
|
||||
|
||||
* It's ok if the same test data is present, but its presentation has changed,
|
||||
for example if a test function is renamed or has different parameters.
|
||||
* It's ok if redundant tests are removed.
|
||||
|
||||
**Generated test coverage**: the goal is to check that automatically
|
||||
generated tests have as much coverage as before. This is normally validated
|
||||
by comparing the test cases that are automatically generated by a script.
|
||||
A failure is a generated test case that is no longer present with the same
|
||||
function name and parameter list.
|
||||
|
||||
* It's ok if the same test data is present, but its presentation has changed,
|
||||
for example if a test function is renamed or has different parameters.
|
||||
* It's ok if redundant tests are removed.
|
||||
"""
|
||||
Purpose
|
||||
|
||||
This script is a small wrapper around the abi-compliance-checker and
|
||||
abi-dumper tools, applying them to compare the ABI and API of the library
|
||||
files from two different Git revisions within an Mbed TLS repository.
|
||||
The results of the comparison are either formatted as HTML and stored at
|
||||
a configurable location, or are given as a brief list of problems.
|
||||
Returns 0 on success, 1 on ABI/API non-compliance, and 2 if there is an error
|
||||
while running the script. Note: must be run from Mbed TLS root.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import traceback
|
||||
import shutil
|
||||
@@ -101,8 +66,6 @@ from types import SimpleNamespace
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from mbedtls_dev import build_tree
|
||||
|
||||
|
||||
class AbiChecker:
|
||||
"""API and ABI checker."""
|
||||
@@ -115,9 +78,6 @@ class AbiChecker:
|
||||
configuration.report_dir: directory for output files
|
||||
configuration.keep_all_reports: if false, delete old reports
|
||||
configuration.brief: if true, output shorter report to stdout
|
||||
configuration.check_abi: if true, compare ABIs
|
||||
configuration.check_api: if true, compare APIs
|
||||
configuration.check_storage: if true, compare storage format tests
|
||||
configuration.skip_file: path to file containing symbols and types to skip
|
||||
"""
|
||||
self.repo_path = "."
|
||||
@@ -131,15 +91,15 @@ class AbiChecker:
|
||||
self.old_version = old_version
|
||||
self.new_version = new_version
|
||||
self.skip_file = configuration.skip_file
|
||||
self.check_abi = configuration.check_abi
|
||||
self.check_api = configuration.check_api
|
||||
if self.check_abi != self.check_api:
|
||||
raise Exception('Checking API without ABI or vice versa is not supported')
|
||||
self.check_storage_tests = configuration.check_storage
|
||||
self.brief = configuration.brief
|
||||
self.git_command = "git"
|
||||
self.make_command = "make"
|
||||
|
||||
@staticmethod
|
||||
def check_repo_path():
|
||||
if not all(os.path.isdir(d) for d in ["include", "library", "tests"]):
|
||||
raise Exception("Must be run from Mbed TLS root")
|
||||
|
||||
def _setup_logger(self):
|
||||
self.log = logging.getLogger()
|
||||
if self.verbose:
|
||||
@@ -275,93 +235,6 @@ class AbiChecker:
|
||||
self.log.debug(abi_dump_output.decode("utf-8"))
|
||||
version.abi_dumps[mbed_module] = output_path
|
||||
|
||||
@staticmethod
|
||||
def _normalize_storage_test_case_data(line):
|
||||
"""Eliminate cosmetic or irrelevant details in storage format test cases."""
|
||||
line = re.sub(r'\s+', r'', line)
|
||||
return line
|
||||
|
||||
def _read_storage_tests(self,
|
||||
directory,
|
||||
filename,
|
||||
is_generated,
|
||||
storage_tests):
|
||||
"""Record storage tests from the given file.
|
||||
|
||||
Populate the storage_tests dictionary with test cases read from
|
||||
filename under directory.
|
||||
"""
|
||||
at_paragraph_start = True
|
||||
description = None
|
||||
full_path = os.path.join(directory, filename)
|
||||
with open(full_path) as fd:
|
||||
for line_number, line in enumerate(fd, 1):
|
||||
line = line.strip()
|
||||
if not line:
|
||||
at_paragraph_start = True
|
||||
continue
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
if at_paragraph_start:
|
||||
description = line.strip()
|
||||
at_paragraph_start = False
|
||||
continue
|
||||
if line.startswith('depends_on:'):
|
||||
continue
|
||||
# We've reached a test case data line
|
||||
test_case_data = self._normalize_storage_test_case_data(line)
|
||||
if not is_generated:
|
||||
# In manual test data, only look at read tests.
|
||||
function_name = test_case_data.split(':', 1)[0]
|
||||
if 'read' not in function_name.split('_'):
|
||||
continue
|
||||
metadata = SimpleNamespace(
|
||||
filename=filename,
|
||||
line_number=line_number,
|
||||
description=description
|
||||
)
|
||||
storage_tests[test_case_data] = metadata
|
||||
|
||||
@staticmethod
|
||||
def _list_generated_test_data_files(git_worktree_path):
|
||||
"""List the generated test data files."""
|
||||
output = subprocess.check_output(
|
||||
['tests/scripts/generate_psa_tests.py', '--list'],
|
||||
cwd=git_worktree_path,
|
||||
).decode('ascii')
|
||||
return [line for line in output.split('\n') if line]
|
||||
|
||||
def _get_storage_format_tests(self, version, git_worktree_path):
|
||||
"""Record the storage format tests for the specified git version.
|
||||
|
||||
The storage format tests are the test suite data files whose name
|
||||
contains "storage_format".
|
||||
|
||||
The version must be checked out at git_worktree_path.
|
||||
|
||||
This function creates or updates the generated data files.
|
||||
"""
|
||||
# Existing test data files. This may be missing some automatically
|
||||
# generated files if they haven't been generated yet.
|
||||
storage_data_files = set(glob.glob(
|
||||
'tests/suites/test_suite_*storage_format*.data'
|
||||
))
|
||||
# Discover and (re)generate automatically generated data files.
|
||||
to_be_generated = set()
|
||||
for filename in self._list_generated_test_data_files(git_worktree_path):
|
||||
if 'storage_format' in filename:
|
||||
storage_data_files.add(filename)
|
||||
to_be_generated.add(filename)
|
||||
subprocess.check_call(
|
||||
['tests/scripts/generate_psa_tests.py'] + sorted(to_be_generated),
|
||||
cwd=git_worktree_path,
|
||||
)
|
||||
for test_file in sorted(storage_data_files):
|
||||
self._read_storage_tests(git_worktree_path,
|
||||
test_file,
|
||||
test_file in to_be_generated,
|
||||
version.storage_tests)
|
||||
|
||||
def _cleanup_worktree(self, git_worktree_path):
|
||||
"""Remove the specified git worktree."""
|
||||
shutil.rmtree(git_worktree_path)
|
||||
@@ -373,14 +246,11 @@ class AbiChecker:
|
||||
self.log.debug(worktree_output.decode("utf-8"))
|
||||
|
||||
def _get_abi_dump_for_ref(self, version):
|
||||
"""Generate the interface information for the specified git revision."""
|
||||
"""Generate the ABI dumps for the specified git revision."""
|
||||
git_worktree_path = self._get_clean_worktree_for_git_revision(version)
|
||||
self._update_git_submodules(git_worktree_path, version)
|
||||
if self.check_abi:
|
||||
self._build_shared_libraries(git_worktree_path, version)
|
||||
self._get_abi_dumps_from_shared_libraries(version)
|
||||
if self.check_storage_tests:
|
||||
self._get_storage_format_tests(version, git_worktree_path)
|
||||
self._build_shared_libraries(git_worktree_path, version)
|
||||
self._get_abi_dumps_from_shared_libraries(version)
|
||||
self._cleanup_worktree(git_worktree_path)
|
||||
|
||||
def _remove_children_with_tag(self, parent, tag):
|
||||
@@ -458,37 +328,6 @@ class AbiChecker:
|
||||
os.remove(output_path)
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def _is_storage_format_compatible(old_tests, new_tests,
|
||||
compatibility_report):
|
||||
"""Check whether all tests present in old_tests are also in new_tests.
|
||||
|
||||
Append a message regarding compatibility to compatibility_report.
|
||||
"""
|
||||
missing = frozenset(old_tests.keys()).difference(new_tests.keys())
|
||||
for test_data in sorted(missing):
|
||||
metadata = old_tests[test_data]
|
||||
compatibility_report.append(
|
||||
'Test case from {} line {} "{}" has disappeared: {}'.format(
|
||||
metadata.filename, metadata.line_number,
|
||||
metadata.description, test_data
|
||||
)
|
||||
)
|
||||
compatibility_report.append(
|
||||
'FAIL: {}/{} storage format test cases have changed or disappeared.'.format(
|
||||
len(missing), len(old_tests)
|
||||
) if missing else
|
||||
'PASS: All {} storage format test cases are preserved.'.format(
|
||||
len(old_tests)
|
||||
)
|
||||
)
|
||||
compatibility_report.append(
|
||||
'Info: number of storage format tests cases: {} -> {}.'.format(
|
||||
len(old_tests), len(new_tests)
|
||||
)
|
||||
)
|
||||
return not missing
|
||||
|
||||
def get_abi_compatibility_report(self):
|
||||
"""Generate a report of the differences between the reference ABI
|
||||
and the new ABI. ABI dumps from self.old_version and self.new_version
|
||||
@@ -498,22 +337,12 @@ class AbiChecker:
|
||||
self._pretty_revision(self.new_version)
|
||||
)]
|
||||
compliance_return_code = 0
|
||||
|
||||
if self.check_abi:
|
||||
shared_modules = list(set(self.old_version.modules.keys()) &
|
||||
set(self.new_version.modules.keys()))
|
||||
for mbed_module in shared_modules:
|
||||
if not self._is_library_compatible(mbed_module,
|
||||
compatibility_report):
|
||||
compliance_return_code = 1
|
||||
|
||||
if self.check_storage_tests:
|
||||
if not self._is_storage_format_compatible(
|
||||
self.old_version.storage_tests,
|
||||
self.new_version.storage_tests,
|
||||
compatibility_report):
|
||||
shared_modules = list(set(self.old_version.modules.keys()) &
|
||||
set(self.new_version.modules.keys()))
|
||||
for mbed_module in shared_modules:
|
||||
if not self._is_library_compatible(mbed_module,
|
||||
compatibility_report):
|
||||
compliance_return_code = 1
|
||||
|
||||
for version in [self.old_version, self.new_version]:
|
||||
for mbed_module, mbed_module_dump in version.abi_dumps.items():
|
||||
os.remove(mbed_module_dump)
|
||||
@@ -525,9 +354,8 @@ class AbiChecker:
|
||||
def check_for_abi_changes(self):
|
||||
"""Generate a report of ABI differences
|
||||
between self.old_rev and self.new_rev."""
|
||||
build_tree.check_repo_path()
|
||||
if self.check_api or self.check_abi:
|
||||
self.check_abi_tools_are_installed()
|
||||
self.check_repo_path()
|
||||
self.check_abi_tools_are_installed()
|
||||
self._get_abi_dump_for_ref(self.old_version)
|
||||
self._get_abi_dump_for_ref(self.new_version)
|
||||
return self.get_abi_compatibility_report()
|
||||
@@ -536,7 +364,17 @@ class AbiChecker:
|
||||
def run_main():
|
||||
try:
|
||||
parser = argparse.ArgumentParser(
|
||||
description=__doc__
|
||||
description=(
|
||||
"""This script is a small wrapper around the
|
||||
abi-compliance-checker and abi-dumper tools, applying them
|
||||
to compare the ABI and API of the library files from two
|
||||
different Git revisions within an Mbed TLS repository.
|
||||
The results of the comparison are either formatted as HTML and
|
||||
stored at a configurable location, or are given as a brief list
|
||||
of problems. Returns 0 on success, 1 on ABI/API non-compliance,
|
||||
and 2 if there is an error while running the script.
|
||||
Note: must be run from Mbed TLS root."""
|
||||
)
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v", "--verbose", action="store_true",
|
||||
@@ -586,24 +424,6 @@ def run_main():
|
||||
"(typically \"-s identifiers\" after running "
|
||||
"\"tests/scripts/list-identifiers.sh --internal\")")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--check-abi",
|
||||
action='store_true', default=True,
|
||||
help="Perform ABI comparison (default: yes)"
|
||||
)
|
||||
parser.add_argument("--no-check-abi", action='store_false', dest='check_abi')
|
||||
parser.add_argument(
|
||||
"--check-api",
|
||||
action='store_true', default=True,
|
||||
help="Perform API comparison (default: yes)"
|
||||
)
|
||||
parser.add_argument("--no-check-api", action='store_false', dest='check_api')
|
||||
parser.add_argument(
|
||||
"--check-storage",
|
||||
action='store_true', default=True,
|
||||
help="Perform storage tests comparison (default: yes)"
|
||||
)
|
||||
parser.add_argument("--no-check-storage", action='store_false', dest='check_storage')
|
||||
parser.add_argument(
|
||||
"-b", "--brief", action="store_true",
|
||||
help="output only the list of issues to stdout, instead of a full report",
|
||||
@@ -620,7 +440,6 @@ def run_main():
|
||||
crypto_repository=abi_args.old_crypto_repo,
|
||||
crypto_revision=abi_args.old_crypto_rev,
|
||||
abi_dumps={},
|
||||
storage_tests={},
|
||||
modules={}
|
||||
)
|
||||
new_version = SimpleNamespace(
|
||||
@@ -631,7 +450,6 @@ def run_main():
|
||||
crypto_repository=abi_args.new_crypto_repo,
|
||||
crypto_revision=abi_args.new_crypto_rev,
|
||||
abi_dumps={},
|
||||
storage_tests={},
|
||||
modules={}
|
||||
)
|
||||
configuration = SimpleNamespace(
|
||||
@@ -639,9 +457,6 @@ def run_main():
|
||||
report_dir=abi_args.report_dir,
|
||||
keep_all_reports=abi_args.keep_all_reports,
|
||||
brief=abi_args.brief,
|
||||
check_abi=abi_args.check_abi,
|
||||
check_api=abi_args.check_api,
|
||||
check_storage=abi_args.check_storage,
|
||||
skip_file=abi_args.skip_file
|
||||
)
|
||||
abi_check = AbiChecker(old_version, new_version, configuration)
|
||||
|
||||
45
externals/mbedtls/scripts/apidoc_full.sh
vendored
45
externals/mbedtls/scripts/apidoc_full.sh
vendored
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Generate doxygen documentation with a full mbedtls_config.h (this ensures that every
|
||||
# Generate doxygen documentation with a full config.h (this ensures that every
|
||||
# available flag is documented, and avoids warnings about documentation
|
||||
# without a corresponding #define).
|
||||
#
|
||||
@@ -9,10 +9,49 @@
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
|
||||
set -eu
|
||||
|
||||
CONFIG_H='include/mbedtls/mbedtls_config.h'
|
||||
CONFIG_H='include/mbedtls/config.h'
|
||||
|
||||
if [ -r $CONFIG_H ]; then :; else
|
||||
echo "$CONFIG_H not found" >&2
|
||||
@@ -22,7 +61,7 @@ fi
|
||||
CONFIG_BAK=${CONFIG_H}.bak
|
||||
cp -p $CONFIG_H $CONFIG_BAK
|
||||
|
||||
scripts/config.py realfull
|
||||
scripts/config.pl realfull
|
||||
make apidoc
|
||||
|
||||
mv $CONFIG_BAK $CONFIG_H
|
||||
|
||||
150
externals/mbedtls/scripts/assemble_changelog.py
vendored
150
externals/mbedtls/scripts/assemble_changelog.py
vendored
@@ -20,6 +20,45 @@ You must run this program from within a git working directory.
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
|
||||
import argparse
|
||||
from collections import OrderedDict, namedtuple
|
||||
@@ -48,23 +87,18 @@ class LostContent(Exception):
|
||||
message = ('Lost content from {}: "{}"'.format(filename, line))
|
||||
super().__init__(message)
|
||||
|
||||
class FilePathError(Exception):
|
||||
def __init__(self, filenames):
|
||||
message = ('Changelog filenames do not end with .txt: {}'.format(", ".join(filenames)))
|
||||
super().__init__(message)
|
||||
|
||||
# The category names we use in the changelog.
|
||||
# If you edit this, update ChangeLog.d/README.md.
|
||||
STANDARD_CATEGORIES = (
|
||||
'API changes',
|
||||
'Default behavior changes',
|
||||
'Requirement changes',
|
||||
'New deprecations',
|
||||
'Removals',
|
||||
'Features',
|
||||
'Security',
|
||||
'Bugfix',
|
||||
'Changes',
|
||||
b'API changes',
|
||||
b'Default behavior changes',
|
||||
b'Requirement changes',
|
||||
b'New deprecations',
|
||||
b'Removals',
|
||||
b'Features',
|
||||
b'Security',
|
||||
b'Bugfix',
|
||||
b'Changes',
|
||||
)
|
||||
|
||||
# The maximum line length for an entry
|
||||
@@ -115,15 +149,14 @@ class ChangelogFormat:
|
||||
class TextChangelogFormat(ChangelogFormat):
|
||||
"""The traditional Mbed TLS changelog format."""
|
||||
|
||||
_unreleased_version_text = '= {} x.x.x branch released xxxx-xx-xx'
|
||||
_unreleased_version_text = b'= mbed TLS x.x.x branch released xxxx-xx-xx'
|
||||
@classmethod
|
||||
def is_released_version(cls, title):
|
||||
# Look for an incomplete release date
|
||||
return not re.search(r'[0-9x]{4}-[0-9x]{2}-[0-9x]?x', title)
|
||||
return not re.search(br'[0-9x]{4}-[0-9x]{2}-[0-9x]?x', title)
|
||||
|
||||
_top_version_re = re.compile(r'(?:\A|\n)(=[^\n]*\n+)(.*?\n)(?:=|$)',
|
||||
_top_version_re = re.compile(br'(?:\A|\n)(=[^\n]*\n+)(.*?\n)(?:=|$)',
|
||||
re.DOTALL)
|
||||
_name_re = re.compile(r'=\s(.*)\s[0-9x]+\.', re.DOTALL)
|
||||
@classmethod
|
||||
def extract_top_version(cls, changelog_file_content):
|
||||
"""A version section starts with a line starting with '='."""
|
||||
@@ -132,20 +165,19 @@ class TextChangelogFormat(ChangelogFormat):
|
||||
top_version_end = m.end(2)
|
||||
top_version_title = m.group(1)
|
||||
top_version_body = m.group(2)
|
||||
name = re.match(cls._name_re, top_version_title).group(1)
|
||||
if cls.is_released_version(top_version_title):
|
||||
top_version_end = top_version_start
|
||||
top_version_title = cls._unreleased_version_text.format(name) + '\n\n'
|
||||
top_version_body = ''
|
||||
top_version_title = cls._unreleased_version_text + b'\n\n'
|
||||
top_version_body = b''
|
||||
return (changelog_file_content[:top_version_start],
|
||||
top_version_title, top_version_body,
|
||||
changelog_file_content[top_version_end:])
|
||||
|
||||
@classmethod
|
||||
def version_title_text(cls, version_title):
|
||||
return re.sub(r'\n.*', version_title, re.DOTALL)
|
||||
return re.sub(br'\n.*', version_title, re.DOTALL)
|
||||
|
||||
_category_title_re = re.compile(r'(^\w.*)\n+', re.MULTILINE)
|
||||
_category_title_re = re.compile(br'(^\w.*)\n+', re.MULTILINE)
|
||||
@classmethod
|
||||
def split_categories(cls, version_body):
|
||||
"""A category title is a line with the title in column 0."""
|
||||
@@ -158,10 +190,10 @@ class TextChangelogFormat(ChangelogFormat):
|
||||
title_starts = [m.start(1) for m in title_matches]
|
||||
body_starts = [m.end(0) for m in title_matches]
|
||||
body_ends = title_starts[1:] + [len(version_body)]
|
||||
bodies = [version_body[body_start:body_end].rstrip('\n') + '\n'
|
||||
bodies = [version_body[body_start:body_end].rstrip(b'\n') + b'\n'
|
||||
for (body_start, body_end) in zip(body_starts, body_ends)]
|
||||
title_lines = [version_body[:pos].count('\n') for pos in title_starts]
|
||||
body_lines = [version_body[:pos].count('\n') for pos in body_starts]
|
||||
title_lines = [version_body[:pos].count(b'\n') for pos in title_starts]
|
||||
body_lines = [version_body[:pos].count(b'\n') for pos in body_starts]
|
||||
return [CategoryContent(title_match.group(1), title_line,
|
||||
body, body_line)
|
||||
for title_match, title_line, body, body_line
|
||||
@@ -171,9 +203,9 @@ class TextChangelogFormat(ChangelogFormat):
|
||||
def format_category(cls, title, body):
|
||||
# `split_categories` ensures that each body ends with a newline.
|
||||
# Make sure that there is additionally a blank line between categories.
|
||||
if not body.endswith('\n\n'):
|
||||
body += '\n'
|
||||
return title + '\n' + body
|
||||
if not body.endswith(b'\n\n'):
|
||||
body += b'\n'
|
||||
return title + b'\n' + body
|
||||
|
||||
class ChangeLog:
|
||||
"""An Mbed TLS changelog.
|
||||
@@ -194,10 +226,10 @@ class ChangeLog:
|
||||
# Only accept dotted version numbers (e.g. "3.1", not "3").
|
||||
# Refuse ".x" in a version number where x is a letter: this indicates
|
||||
# a version that is not yet released. Something like "3.1a" is accepted.
|
||||
_version_number_re = re.compile(r'[0-9]+\.[0-9A-Za-z.]+')
|
||||
_incomplete_version_number_re = re.compile(r'.*\.[A-Za-z]')
|
||||
_only_url_re = re.compile(r'^\s*\w+://\S+\s*$')
|
||||
_has_url_re = re.compile(r'.*://.*')
|
||||
_version_number_re = re.compile(br'[0-9]+\.[0-9A-Za-z.]+')
|
||||
_incomplete_version_number_re = re.compile(br'.*\.[A-Za-z]')
|
||||
_only_url_re = re.compile(br'^\s*\w+://\S+\s*$')
|
||||
_has_url_re = re.compile(br'.*://.*')
|
||||
|
||||
def add_categories_from_text(self, filename, line_offset,
|
||||
text, allow_unknown_category):
|
||||
@@ -213,7 +245,7 @@ class ChangeLog:
|
||||
raise InputFormatError(filename,
|
||||
line_offset + category.title_line,
|
||||
'Unknown category: "{}"',
|
||||
category.name)
|
||||
category.name.decode('utf8'))
|
||||
|
||||
body_split = category.body.splitlines()
|
||||
|
||||
@@ -245,9 +277,8 @@ class ChangeLog:
|
||||
# Split the top version section into categories.
|
||||
self.categories = OrderedDict()
|
||||
for category in STANDARD_CATEGORIES:
|
||||
self.categories[category] = ''
|
||||
offset = (self.header + self.top_version_title).count('\n') + 1
|
||||
|
||||
self.categories[category] = b''
|
||||
offset = (self.header + self.top_version_title).count(b'\n') + 1
|
||||
self.add_categories_from_text(input_stream.name, offset,
|
||||
top_version_body, True)
|
||||
|
||||
@@ -260,7 +291,7 @@ class ChangeLog:
|
||||
def write(self, filename):
|
||||
"""Write the changelog to the specified file.
|
||||
"""
|
||||
with open(filename, 'w', encoding='utf-8') as out:
|
||||
with open(filename, 'wb') as out:
|
||||
out.write(self.header)
|
||||
out.write(self.top_version_title)
|
||||
for title, body in self.categories.items():
|
||||
@@ -299,7 +330,7 @@ class EntryFileSortKey:
|
||||
hashes = subprocess.check_output(['git', 'log', '--format=%H',
|
||||
'--follow',
|
||||
'--', filename])
|
||||
m = re.search('(.+)$', hashes.decode('ascii'))
|
||||
m = re.search(b'(.+)$', hashes)
|
||||
if not m:
|
||||
# The git output is empty. This means that the file was
|
||||
# never checked in.
|
||||
@@ -316,8 +347,8 @@ class EntryFileSortKey:
|
||||
"""
|
||||
text = subprocess.check_output(['git', 'rev-list',
|
||||
'--merges', *options,
|
||||
'..'.join([some_hash, target])])
|
||||
return text.decode('ascii').rstrip('\n').split('\n')
|
||||
b'..'.join([some_hash, target])])
|
||||
return text.rstrip(b'\n').split(b'\n')
|
||||
|
||||
@classmethod
|
||||
def merge_hash(cls, some_hash):
|
||||
@@ -325,7 +356,7 @@ class EntryFileSortKey:
|
||||
|
||||
Return None if the given commit was never merged.
|
||||
"""
|
||||
target = 'HEAD'
|
||||
target = b'HEAD'
|
||||
# List the merges from some_hash to the target in two ways.
|
||||
# The ancestry list is the ones that are both descendants of
|
||||
# some_hash and ancestors of the target.
|
||||
@@ -403,15 +434,14 @@ def check_output(generated_output_file, main_input_file, merged_files):
|
||||
is also present in an output file. This is not perfect but good enough
|
||||
for now.
|
||||
"""
|
||||
with open(generated_output_file, 'r', encoding='utf-8') as fd:
|
||||
generated_output = set(fd)
|
||||
for line in open(main_input_file, 'r', encoding='utf-8'):
|
||||
generated_output = set(open(generated_output_file, 'rb'))
|
||||
for line in open(main_input_file, 'rb'):
|
||||
if line not in generated_output:
|
||||
raise LostContent('original file', line)
|
||||
for merged_file in merged_files:
|
||||
for line in open(merged_file, 'rb'):
|
||||
if line not in generated_output:
|
||||
raise LostContent('original file', line)
|
||||
for merged_file in merged_files:
|
||||
for line in open(merged_file, 'r', encoding='utf-8'):
|
||||
if line not in generated_output:
|
||||
raise LostContent(merged_file, line)
|
||||
raise LostContent(merged_file, line)
|
||||
|
||||
def finish_output(changelog, output_file, input_file, merged_files):
|
||||
"""Write the changelog to the output file.
|
||||
@@ -439,21 +469,8 @@ def list_files_to_merge(options):
|
||||
"""List the entry files to merge, oldest first.
|
||||
|
||||
"Oldest" is defined by `EntryFileSortKey`.
|
||||
|
||||
Also check for required .txt extension
|
||||
"""
|
||||
files_to_merge = glob.glob(os.path.join(options.dir, '*'))
|
||||
|
||||
# Ignore 00README.md
|
||||
readme = os.path.join(options.dir, "00README.md")
|
||||
if readme in files_to_merge:
|
||||
files_to_merge.remove(readme)
|
||||
|
||||
# Identify files without the required .txt extension
|
||||
bad_files = [x for x in files_to_merge if not x.endswith(".txt")]
|
||||
if bad_files:
|
||||
raise FilePathError(bad_files)
|
||||
|
||||
files_to_merge = glob.glob(os.path.join(options.dir, '*.txt'))
|
||||
files_to_merge.sort(key=EntryFileSortKey)
|
||||
return files_to_merge
|
||||
|
||||
@@ -461,19 +478,18 @@ def merge_entries(options):
|
||||
"""Merge changelog entries into the changelog file.
|
||||
|
||||
Read the changelog file from options.input.
|
||||
Check that all entries have a .txt extension
|
||||
Read entries to merge from the directory options.dir.
|
||||
Write the new changelog to options.output.
|
||||
Remove the merged entries if options.keep_entries is false.
|
||||
"""
|
||||
with open(options.input, 'r', encoding='utf-8') as input_file:
|
||||
with open(options.input, 'rb') as input_file:
|
||||
changelog = ChangeLog(input_file, TextChangelogFormat)
|
||||
files_to_merge = list_files_to_merge(options)
|
||||
if not files_to_merge:
|
||||
sys.stderr.write('There are no pending changelog entries.\n')
|
||||
return
|
||||
for filename in files_to_merge:
|
||||
with open(filename, 'r', encoding='utf-8') as input_file:
|
||||
with open(filename, 'rb') as input_file:
|
||||
changelog.add_file(input_file)
|
||||
finish_output(changelog, options.output, options.input, files_to_merge)
|
||||
if not options.keep_entries:
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Python modules required to build Mbed TLS in ordinary conditions.
|
||||
|
||||
# Required to (re-)generate source files. Not needed if the generated source
|
||||
# files are already present and up-to-date.
|
||||
-r driver.requirements.txt
|
||||
73
externals/mbedtls/scripts/bump_version.sh
vendored
73
externals/mbedtls/scripts/bump_version.sh
vendored
@@ -3,6 +3,45 @@
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# Purpose
|
||||
#
|
||||
# Sets the version numbers in the source code to those given.
|
||||
@@ -12,8 +51,6 @@
|
||||
# [ -v | --verbose ] [ -h | --help ]
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
VERSION=""
|
||||
SOVERSION=""
|
||||
|
||||
@@ -69,10 +106,6 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ $VERBOSE ] && echo "Bumping VERSION in CMakeLists.txt"
|
||||
sed -e "s/ VERSION [0-9.]\{1,\}/ VERSION $VERSION/g" < CMakeLists.txt > tmp
|
||||
mv tmp CMakeLists.txt
|
||||
|
||||
[ $VERBOSE ] && echo "Bumping VERSION in library/CMakeLists.txt"
|
||||
sed -e "s/ VERSION [0-9.]\{1,\}/ VERSION $VERSION/g" < library/CMakeLists.txt > tmp
|
||||
mv tmp library/CMakeLists.txt
|
||||
@@ -84,7 +117,7 @@ then
|
||||
mv tmp library/CMakeLists.txt
|
||||
|
||||
[ $VERBOSE ] && echo "Bumping SOVERSION for libmbedcrypto in library/Makefile"
|
||||
sed -e "s/SOEXT_CRYPTO?=so.[0-9]\{1,\}/SOEXT_CRYPTO?=so.$SO_CRYPTO/g" < library/Makefile > tmp
|
||||
sed -e "s/SOEXT_CRYPTO=so.[0-9]\{1,\}/SOEXT_CRYPTO=so.$SO_CRYPTO/g" < library/Makefile > tmp
|
||||
mv tmp library/Makefile
|
||||
fi
|
||||
|
||||
@@ -95,7 +128,7 @@ then
|
||||
mv tmp library/CMakeLists.txt
|
||||
|
||||
[ $VERBOSE ] && echo "Bumping SOVERSION for libmbedx509 in library/Makefile"
|
||||
sed -e "s/SOEXT_X509?=so.[0-9]\{1,\}/SOEXT_X509?=so.$SO_X509/g" < library/Makefile > tmp
|
||||
sed -e "s/SOEXT_X509=so.[0-9]\{1,\}/SOEXT_X509=so.$SO_X509/g" < library/Makefile > tmp
|
||||
mv tmp library/Makefile
|
||||
fi
|
||||
|
||||
@@ -106,22 +139,22 @@ then
|
||||
mv tmp library/CMakeLists.txt
|
||||
|
||||
[ $VERBOSE ] && echo "Bumping SOVERSION for libmbedtls in library/Makefile"
|
||||
sed -e "s/SOEXT_TLS?=so.[0-9]\{1,\}/SOEXT_TLS?=so.$SO_TLS/g" < library/Makefile > tmp
|
||||
sed -e "s/SOEXT_TLS=so.[0-9]\{1,\}/SOEXT_TLS=so.$SO_TLS/g" < library/Makefile > tmp
|
||||
mv tmp library/Makefile
|
||||
fi
|
||||
|
||||
[ $VERBOSE ] && echo "Bumping VERSION in include/mbedtls/build_info.h"
|
||||
[ $VERBOSE ] && echo "Bumping VERSION in include/mbedtls/version.h"
|
||||
read MAJOR MINOR PATCH <<<$(IFS="."; echo $VERSION)
|
||||
VERSION_NR="$( printf "0x%02X%02X%02X00" $MAJOR $MINOR $PATCH )"
|
||||
cat include/mbedtls/build_info.h | \
|
||||
sed -e "s/\(# *define *[A-Z]*_VERSION\)_MAJOR .\{1,\}/\1_MAJOR $MAJOR/" | \
|
||||
sed -e "s/\(# *define *[A-Z]*_VERSION\)_MINOR .\{1,\}/\1_MINOR $MINOR/" | \
|
||||
sed -e "s/\(# *define *[A-Z]*_VERSION\)_PATCH .\{1,\}/\1_PATCH $PATCH/" | \
|
||||
sed -e "s/\(# *define *[A-Z]*_VERSION\)_NUMBER .\{1,\}/\1_NUMBER $VERSION_NR/" | \
|
||||
sed -e "s/\(# *define *[A-Z]*_VERSION\)_STRING .\{1,\}/\1_STRING \"$VERSION\"/" | \
|
||||
sed -e "s/\(# *define *[A-Z]*_VERSION\)_STRING_FULL .\{1,\}/\1_STRING_FULL \"Mbed TLS $VERSION\"/" \
|
||||
cat include/mbedtls/version.h | \
|
||||
sed -e "s/_VERSION_MAJOR .\{1,\}/_VERSION_MAJOR $MAJOR/" | \
|
||||
sed -e "s/_VERSION_MINOR .\{1,\}/_VERSION_MINOR $MINOR/" | \
|
||||
sed -e "s/_VERSION_PATCH .\{1,\}/_VERSION_PATCH $PATCH/" | \
|
||||
sed -e "s/_VERSION_NUMBER .\{1,\}/_VERSION_NUMBER $VERSION_NR/" | \
|
||||
sed -e "s/_VERSION_STRING .\{1,\}/_VERSION_STRING \"$VERSION\"/" | \
|
||||
sed -e "s/_VERSION_STRING_FULL .\{1,\}/_VERSION_STRING_FULL \"mbed TLS $VERSION\"/" \
|
||||
> tmp
|
||||
mv tmp include/mbedtls/build_info.h
|
||||
mv tmp include/mbedtls/version.h
|
||||
|
||||
[ $VERBOSE ] && echo "Bumping version in tests/suites/test_suite_version.data"
|
||||
sed -e "s/version:\".\{1,\}/version:\"$VERSION\"/g" < tests/suites/test_suite_version.data > tmp
|
||||
@@ -130,14 +163,14 @@ mv tmp tests/suites/test_suite_version.data
|
||||
[ $VERBOSE ] && echo "Bumping PROJECT_NAME in doxygen/mbedtls.doxyfile and doxygen/input/doc_mainpage.h"
|
||||
for i in doxygen/mbedtls.doxyfile doxygen/input/doc_mainpage.h;
|
||||
do
|
||||
sed -e "s/\\([Mm]bed TLS v\\)[0-9][0-9.]*/\\1$VERSION/g" < $i > tmp
|
||||
sed -e "s/mbed TLS v[0-9\.]\{1,\}/mbed TLS v$VERSION/g" < $i > tmp
|
||||
mv tmp $i
|
||||
done
|
||||
|
||||
[ $VERBOSE ] && echo "Re-generating library/error.c"
|
||||
scripts/generate_errors.pl
|
||||
|
||||
[ $VERBOSE ] && echo "Re-generating programs/test/query_config.c"
|
||||
[ $VERBOSE ] && echo "Re-generating programs/ssl/query_config.c"
|
||||
scripts/generate_query_config.pl
|
||||
|
||||
[ $VERBOSE ] && echo "Re-generating library/version_features.c"
|
||||
|
||||
24
externals/mbedtls/scripts/ci.requirements.txt
vendored
24
externals/mbedtls/scripts/ci.requirements.txt
vendored
@@ -1,24 +0,0 @@
|
||||
# Python package requirements for Mbed TLS testing.
|
||||
|
||||
-r driver.requirements.txt
|
||||
|
||||
# Use a known version of Pylint, because new versions tend to add warnings
|
||||
# that could start rejecting our code.
|
||||
# 2.4.4 is the version in Ubuntu 20.04. It supports Python >=3.5.
|
||||
pylint == 2.4.4
|
||||
|
||||
# Use the earliest version of mypy that works with our code base.
|
||||
# See https://github.com/Mbed-TLS/mbedtls/pull/3953 .
|
||||
mypy >= 0.780
|
||||
|
||||
# At the time of writing, only needed for tests/scripts/audit-validity-dates.py.
|
||||
# It needs >=35.0.0 for correct operation, and that requires Python >=3.6,
|
||||
# but our CI has Python 3.5. So let pip install the newest version that's
|
||||
# compatible with the running Python: this way we get something good enough
|
||||
# for mypy and pylint under Python 3.5, and we also get something good enough
|
||||
# to run audit-validity-dates.py on Python >=3.6.
|
||||
cryptography # >= 35.0.0
|
||||
|
||||
# For building `tests/data_files/server9-bad-saltlen.crt` and check python
|
||||
# files.
|
||||
asn1crypto
|
||||
952
externals/mbedtls/scripts/code_size_compare.py
vendored
952
externals/mbedtls/scripts/code_size_compare.py
vendored
@@ -1,952 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
This script is for comparing the size of the library files from two
|
||||
different Git revisions within an Mbed TLS repository.
|
||||
The results of the comparison is formatted as csv and stored at a
|
||||
configurable location.
|
||||
Note: must be run from Mbed TLS root.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import typing
|
||||
from enum import Enum
|
||||
|
||||
from mbedtls_dev import build_tree
|
||||
from mbedtls_dev import logging_util
|
||||
from mbedtls_dev import typing_util
|
||||
|
||||
class SupportedArch(Enum):
|
||||
"""Supported architecture for code size measurement."""
|
||||
AARCH64 = 'aarch64'
|
||||
AARCH32 = 'aarch32'
|
||||
ARMV8_M = 'armv8-m'
|
||||
X86_64 = 'x86_64'
|
||||
X86 = 'x86'
|
||||
|
||||
|
||||
class SupportedConfig(Enum):
|
||||
"""Supported configuration for code size measurement."""
|
||||
DEFAULT = 'default'
|
||||
TFM_MEDIUM = 'tfm-medium'
|
||||
|
||||
|
||||
# Static library
|
||||
MBEDTLS_STATIC_LIB = {
|
||||
'CRYPTO': 'library/libmbedcrypto.a',
|
||||
'X509': 'library/libmbedx509.a',
|
||||
'TLS': 'library/libmbedtls.a',
|
||||
}
|
||||
|
||||
class CodeSizeDistinctInfo: # pylint: disable=too-few-public-methods
|
||||
"""Data structure to store possibly distinct information for code size
|
||||
comparison."""
|
||||
def __init__( #pylint: disable=too-many-arguments
|
||||
self,
|
||||
version: str,
|
||||
git_rev: str,
|
||||
arch: str,
|
||||
config: str,
|
||||
compiler: str,
|
||||
opt_level: str,
|
||||
) -> None:
|
||||
"""
|
||||
:param: version: which version to compare with for code size.
|
||||
:param: git_rev: Git revision to calculate code size.
|
||||
:param: arch: architecture to measure code size on.
|
||||
:param: config: Configuration type to calculate code size.
|
||||
(See SupportedConfig)
|
||||
:param: compiler: compiler used to build library/*.o.
|
||||
:param: opt_level: Options that control optimization. (E.g. -Os)
|
||||
"""
|
||||
self.version = version
|
||||
self.git_rev = git_rev
|
||||
self.arch = arch
|
||||
self.config = config
|
||||
self.compiler = compiler
|
||||
self.opt_level = opt_level
|
||||
# Note: Variables below are not initialized by class instantiation.
|
||||
self.pre_make_cmd = [] #type: typing.List[str]
|
||||
self.make_cmd = ''
|
||||
|
||||
def get_info_indication(self):
|
||||
"""Return a unique string to indicate Code Size Distinct Information."""
|
||||
return '{git_rev}-{arch}-{config}-{compiler}'.format(**self.__dict__)
|
||||
|
||||
|
||||
class CodeSizeCommonInfo: # pylint: disable=too-few-public-methods
|
||||
"""Data structure to store common information for code size comparison."""
|
||||
def __init__(
|
||||
self,
|
||||
host_arch: str,
|
||||
measure_cmd: str,
|
||||
) -> None:
|
||||
"""
|
||||
:param host_arch: host architecture.
|
||||
:param measure_cmd: command to measure code size for library/*.o.
|
||||
"""
|
||||
self.host_arch = host_arch
|
||||
self.measure_cmd = measure_cmd
|
||||
|
||||
def get_info_indication(self):
|
||||
"""Return a unique string to indicate Code Size Common Information."""
|
||||
return '{measure_tool}'\
|
||||
.format(measure_tool=self.measure_cmd.strip().split(' ')[0])
|
||||
|
||||
class CodeSizeResultInfo: # pylint: disable=too-few-public-methods
|
||||
"""Data structure to store result options for code size comparison."""
|
||||
def __init__( #pylint: disable=too-many-arguments
|
||||
self,
|
||||
record_dir: str,
|
||||
comp_dir: str,
|
||||
with_markdown=False,
|
||||
stdout=False,
|
||||
show_all=False,
|
||||
) -> None:
|
||||
"""
|
||||
:param record_dir: directory to store code size record.
|
||||
:param comp_dir: directory to store results of code size comparision.
|
||||
:param with_markdown: write comparision result into a markdown table.
|
||||
(Default: False)
|
||||
:param stdout: direct comparison result into sys.stdout.
|
||||
(Default False)
|
||||
:param show_all: show all objects in comparison result. (Default False)
|
||||
"""
|
||||
self.record_dir = record_dir
|
||||
self.comp_dir = comp_dir
|
||||
self.with_markdown = with_markdown
|
||||
self.stdout = stdout
|
||||
self.show_all = show_all
|
||||
|
||||
|
||||
DETECT_ARCH_CMD = "cc -dM -E - < /dev/null"
|
||||
def detect_arch() -> str:
|
||||
"""Auto-detect host architecture."""
|
||||
cc_output = subprocess.check_output(DETECT_ARCH_CMD, shell=True).decode()
|
||||
if '__aarch64__' in cc_output:
|
||||
return SupportedArch.AARCH64.value
|
||||
if '__arm__' in cc_output:
|
||||
return SupportedArch.AARCH32.value
|
||||
if '__x86_64__' in cc_output:
|
||||
return SupportedArch.X86_64.value
|
||||
if '__i386__' in cc_output:
|
||||
return SupportedArch.X86.value
|
||||
else:
|
||||
print("Unknown host architecture, cannot auto-detect arch.")
|
||||
sys.exit(1)
|
||||
|
||||
TFM_MEDIUM_CONFIG_H = 'configs/ext/tfm_mbedcrypto_config_profile_medium.h'
|
||||
TFM_MEDIUM_CRYPTO_CONFIG_H = 'configs/ext/crypto_config_profile_medium.h'
|
||||
|
||||
CONFIG_H = 'include/mbedtls/mbedtls_config.h'
|
||||
CRYPTO_CONFIG_H = 'include/psa/crypto_config.h'
|
||||
BACKUP_SUFFIX = '.code_size.bak'
|
||||
|
||||
class CodeSizeBuildInfo: # pylint: disable=too-few-public-methods
|
||||
"""Gather information used to measure code size.
|
||||
|
||||
It collects information about architecture, configuration in order to
|
||||
infer build command for code size measurement.
|
||||
"""
|
||||
|
||||
SupportedArchConfig = [
|
||||
'-a ' + SupportedArch.AARCH64.value + ' -c ' + SupportedConfig.DEFAULT.value,
|
||||
'-a ' + SupportedArch.AARCH32.value + ' -c ' + SupportedConfig.DEFAULT.value,
|
||||
'-a ' + SupportedArch.X86_64.value + ' -c ' + SupportedConfig.DEFAULT.value,
|
||||
'-a ' + SupportedArch.X86.value + ' -c ' + SupportedConfig.DEFAULT.value,
|
||||
'-a ' + SupportedArch.ARMV8_M.value + ' -c ' + SupportedConfig.TFM_MEDIUM.value,
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
size_dist_info: CodeSizeDistinctInfo,
|
||||
host_arch: str,
|
||||
logger: logging.Logger,
|
||||
) -> None:
|
||||
"""
|
||||
:param size_dist_info:
|
||||
CodeSizeDistinctInfo containing info for code size measurement.
|
||||
- size_dist_info.arch: architecture to measure code size on.
|
||||
- size_dist_info.config: configuration type to measure
|
||||
code size with.
|
||||
- size_dist_info.compiler: compiler used to build library/*.o.
|
||||
- size_dist_info.opt_level: Options that control optimization.
|
||||
(E.g. -Os)
|
||||
:param host_arch: host architecture.
|
||||
:param logger: logging module
|
||||
"""
|
||||
self.arch = size_dist_info.arch
|
||||
self.config = size_dist_info.config
|
||||
self.compiler = size_dist_info.compiler
|
||||
self.opt_level = size_dist_info.opt_level
|
||||
|
||||
self.make_cmd = ['make', '-j', 'lib']
|
||||
|
||||
self.host_arch = host_arch
|
||||
self.logger = logger
|
||||
|
||||
def check_correctness(self) -> bool:
|
||||
"""Check whether we are using proper / supported combination
|
||||
of information to build library/*.o."""
|
||||
|
||||
# default config
|
||||
if self.config == SupportedConfig.DEFAULT.value and \
|
||||
self.arch == self.host_arch:
|
||||
return True
|
||||
# TF-M
|
||||
elif self.arch == SupportedArch.ARMV8_M.value and \
|
||||
self.config == SupportedConfig.TFM_MEDIUM.value:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def infer_pre_make_command(self) -> typing.List[str]:
|
||||
"""Infer command to set up proper configuration before running make."""
|
||||
pre_make_cmd = [] #type: typing.List[str]
|
||||
if self.config == SupportedConfig.TFM_MEDIUM.value:
|
||||
pre_make_cmd.append('cp {src} {dest}'
|
||||
.format(src=TFM_MEDIUM_CONFIG_H, dest=CONFIG_H))
|
||||
pre_make_cmd.append('cp {src} {dest}'
|
||||
.format(src=TFM_MEDIUM_CRYPTO_CONFIG_H,
|
||||
dest=CRYPTO_CONFIG_H))
|
||||
|
||||
return pre_make_cmd
|
||||
|
||||
def infer_make_cflags(self) -> str:
|
||||
"""Infer CFLAGS by instance attributes in CodeSizeDistinctInfo."""
|
||||
cflags = [] #type: typing.List[str]
|
||||
|
||||
# set optimization level
|
||||
cflags.append(self.opt_level)
|
||||
# set compiler by config
|
||||
if self.config == SupportedConfig.TFM_MEDIUM.value:
|
||||
self.compiler = 'armclang'
|
||||
cflags.append('-mcpu=cortex-m33')
|
||||
# set target
|
||||
if self.compiler == 'armclang':
|
||||
cflags.append('--target=arm-arm-none-eabi')
|
||||
|
||||
return ' '.join(cflags)
|
||||
|
||||
def infer_make_command(self) -> str:
|
||||
"""Infer make command by CFLAGS and CC."""
|
||||
|
||||
if self.check_correctness():
|
||||
# set CFLAGS=
|
||||
self.make_cmd.append('CFLAGS=\'{}\''.format(self.infer_make_cflags()))
|
||||
# set CC=
|
||||
self.make_cmd.append('CC={}'.format(self.compiler))
|
||||
return ' '.join(self.make_cmd)
|
||||
else:
|
||||
self.logger.error("Unsupported combination of architecture: {} " \
|
||||
"and configuration: {}.\n"
|
||||
.format(self.arch,
|
||||
self.config))
|
||||
self.logger.error("Please use supported combination of " \
|
||||
"architecture and configuration:")
|
||||
for comb in CodeSizeBuildInfo.SupportedArchConfig:
|
||||
self.logger.error(comb)
|
||||
self.logger.error("")
|
||||
self.logger.error("For your system, please use:")
|
||||
for comb in CodeSizeBuildInfo.SupportedArchConfig:
|
||||
if "default" in comb and self.host_arch not in comb:
|
||||
continue
|
||||
self.logger.error(comb)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
class CodeSizeCalculator:
|
||||
""" A calculator to calculate code size of library/*.o based on
|
||||
Git revision and code size measurement tool.
|
||||
"""
|
||||
|
||||
def __init__( #pylint: disable=too-many-arguments
|
||||
self,
|
||||
git_rev: str,
|
||||
pre_make_cmd: typing.List[str],
|
||||
make_cmd: str,
|
||||
measure_cmd: str,
|
||||
logger: logging.Logger,
|
||||
) -> None:
|
||||
"""
|
||||
:param git_rev: Git revision. (E.g: commit)
|
||||
:param pre_make_cmd: command to set up proper config before running make.
|
||||
:param make_cmd: command to build library/*.o.
|
||||
:param measure_cmd: command to measure code size for library/*.o.
|
||||
:param logger: logging module
|
||||
"""
|
||||
self.repo_path = "."
|
||||
self.git_command = "git"
|
||||
self.make_clean = 'make clean'
|
||||
|
||||
self.git_rev = git_rev
|
||||
self.pre_make_cmd = pre_make_cmd
|
||||
self.make_cmd = make_cmd
|
||||
self.measure_cmd = measure_cmd
|
||||
self.logger = logger
|
||||
|
||||
@staticmethod
|
||||
def validate_git_revision(git_rev: str) -> str:
|
||||
result = subprocess.check_output(["git", "rev-parse", "--verify",
|
||||
git_rev + "^{commit}"],
|
||||
shell=False, universal_newlines=True)
|
||||
return result[:7]
|
||||
|
||||
def _create_git_worktree(self) -> str:
|
||||
"""Create a separate worktree for Git revision.
|
||||
If Git revision is current, use current worktree instead."""
|
||||
|
||||
if self.git_rev == 'current':
|
||||
self.logger.debug("Using current work directory.")
|
||||
git_worktree_path = self.repo_path
|
||||
else:
|
||||
self.logger.debug("Creating git worktree for {}."
|
||||
.format(self.git_rev))
|
||||
git_worktree_path = os.path.join(self.repo_path,
|
||||
"temp-" + self.git_rev)
|
||||
subprocess.check_output(
|
||||
[self.git_command, "worktree", "add", "--detach",
|
||||
git_worktree_path, self.git_rev], cwd=self.repo_path,
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
|
||||
return git_worktree_path
|
||||
|
||||
@staticmethod
|
||||
def backup_config_files(restore: bool) -> None:
|
||||
"""Backup / Restore config files."""
|
||||
if restore:
|
||||
shutil.move(CONFIG_H + BACKUP_SUFFIX, CONFIG_H)
|
||||
shutil.move(CRYPTO_CONFIG_H + BACKUP_SUFFIX, CRYPTO_CONFIG_H)
|
||||
else:
|
||||
shutil.copy(CONFIG_H, CONFIG_H + BACKUP_SUFFIX)
|
||||
shutil.copy(CRYPTO_CONFIG_H, CRYPTO_CONFIG_H + BACKUP_SUFFIX)
|
||||
|
||||
def _build_libraries(self, git_worktree_path: str) -> None:
|
||||
"""Build library/*.o in the specified worktree."""
|
||||
|
||||
self.logger.debug("Building library/*.o for {}."
|
||||
.format(self.git_rev))
|
||||
my_environment = os.environ.copy()
|
||||
try:
|
||||
if self.git_rev == 'current':
|
||||
self.backup_config_files(restore=False)
|
||||
for pre_cmd in self.pre_make_cmd:
|
||||
subprocess.check_output(
|
||||
pre_cmd, env=my_environment, shell=True,
|
||||
cwd=git_worktree_path, stderr=subprocess.STDOUT,
|
||||
universal_newlines=True
|
||||
)
|
||||
subprocess.check_output(
|
||||
self.make_clean, env=my_environment, shell=True,
|
||||
cwd=git_worktree_path, stderr=subprocess.STDOUT,
|
||||
universal_newlines=True
|
||||
)
|
||||
subprocess.check_output(
|
||||
self.make_cmd, env=my_environment, shell=True,
|
||||
cwd=git_worktree_path, stderr=subprocess.STDOUT,
|
||||
universal_newlines=True
|
||||
)
|
||||
if self.git_rev == 'current':
|
||||
self.backup_config_files(restore=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
self._handle_called_process_error(e, git_worktree_path)
|
||||
|
||||
def _gen_raw_code_size(self, git_worktree_path: str) -> typing.Dict[str, str]:
|
||||
"""Measure code size by a tool and return in UTF-8 encoding."""
|
||||
|
||||
self.logger.debug("Measuring code size for {} by `{}`."
|
||||
.format(self.git_rev,
|
||||
self.measure_cmd.strip().split(' ')[0]))
|
||||
|
||||
res = {}
|
||||
for mod, st_lib in MBEDTLS_STATIC_LIB.items():
|
||||
try:
|
||||
result = subprocess.check_output(
|
||||
[self.measure_cmd + ' ' + st_lib], cwd=git_worktree_path,
|
||||
shell=True, universal_newlines=True
|
||||
)
|
||||
res[mod] = result
|
||||
except subprocess.CalledProcessError as e:
|
||||
self._handle_called_process_error(e, git_worktree_path)
|
||||
|
||||
return res
|
||||
|
||||
def _remove_worktree(self, git_worktree_path: str) -> None:
|
||||
"""Remove temporary worktree."""
|
||||
if git_worktree_path != self.repo_path:
|
||||
self.logger.debug("Removing temporary worktree {}."
|
||||
.format(git_worktree_path))
|
||||
subprocess.check_output(
|
||||
[self.git_command, "worktree", "remove", "--force",
|
||||
git_worktree_path], cwd=self.repo_path,
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
|
||||
def _handle_called_process_error(self, e: subprocess.CalledProcessError,
|
||||
git_worktree_path: str) -> None:
|
||||
"""Handle a CalledProcessError and quit the program gracefully.
|
||||
Remove any extra worktrees so that the script may be called again."""
|
||||
|
||||
# Tell the user what went wrong
|
||||
self.logger.error(e, exc_info=True)
|
||||
self.logger.error("Process output:\n {}".format(e.output))
|
||||
|
||||
# Quit gracefully by removing the existing worktree
|
||||
self._remove_worktree(git_worktree_path)
|
||||
sys.exit(-1)
|
||||
|
||||
def cal_libraries_code_size(self) -> typing.Dict[str, str]:
|
||||
"""Do a complete round to calculate code size of library/*.o
|
||||
by measurement tool.
|
||||
|
||||
:return A dictionary of measured code size
|
||||
- typing.Dict[mod: str]
|
||||
"""
|
||||
|
||||
git_worktree_path = self._create_git_worktree()
|
||||
try:
|
||||
self._build_libraries(git_worktree_path)
|
||||
res = self._gen_raw_code_size(git_worktree_path)
|
||||
finally:
|
||||
self._remove_worktree(git_worktree_path)
|
||||
|
||||
return res
|
||||
|
||||
|
||||
class CodeSizeGenerator:
|
||||
""" A generator based on size measurement tool for library/*.o.
|
||||
|
||||
This is an abstract class. To use it, derive a class that implements
|
||||
write_record and write_comparison methods, then call both of them with
|
||||
proper arguments.
|
||||
"""
|
||||
def __init__(self, logger: logging.Logger) -> None:
|
||||
"""
|
||||
:param logger: logging module
|
||||
"""
|
||||
self.logger = logger
|
||||
|
||||
def write_record(
|
||||
self,
|
||||
git_rev: str,
|
||||
code_size_text: typing.Dict[str, str],
|
||||
output: typing_util.Writable
|
||||
) -> None:
|
||||
"""Write size record into a file.
|
||||
|
||||
:param git_rev: Git revision. (E.g: commit)
|
||||
:param code_size_text:
|
||||
string output (utf-8) from measurement tool of code size.
|
||||
- typing.Dict[mod: str]
|
||||
:param output: output stream which the code size record is written to.
|
||||
(Note: Normally write code size record into File)
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def write_comparison( #pylint: disable=too-many-arguments
|
||||
self,
|
||||
old_rev: str,
|
||||
new_rev: str,
|
||||
output: typing_util.Writable,
|
||||
with_markdown=False,
|
||||
show_all=False
|
||||
) -> None:
|
||||
"""Write a comparision result into a stream between two Git revisions.
|
||||
|
||||
:param old_rev: old Git revision to compared with.
|
||||
:param new_rev: new Git revision to compared with.
|
||||
:param output: output stream which the code size record is written to.
|
||||
(File / sys.stdout)
|
||||
:param with_markdown: write comparision result in a markdown table.
|
||||
(Default: False)
|
||||
:param show_all: show all objects in comparison result. (Default False)
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class CodeSizeGeneratorWithSize(CodeSizeGenerator):
|
||||
"""Code Size Base Class for size record saving and writing."""
|
||||
|
||||
class SizeEntry: # pylint: disable=too-few-public-methods
|
||||
"""Data Structure to only store information of code size."""
|
||||
def __init__(self, text: int, data: int, bss: int, dec: int):
|
||||
self.text = text
|
||||
self.data = data
|
||||
self.bss = bss
|
||||
self.total = dec # total <=> dec
|
||||
|
||||
def __init__(self, logger: logging.Logger) -> None:
|
||||
""" Variable code_size is used to store size info for any Git revisions.
|
||||
:param code_size:
|
||||
Data Format as following:
|
||||
code_size = {
|
||||
git_rev: {
|
||||
module: {
|
||||
file_name: SizeEntry,
|
||||
...
|
||||
},
|
||||
...
|
||||
},
|
||||
...
|
||||
}
|
||||
"""
|
||||
super().__init__(logger)
|
||||
self.code_size = {} #type: typing.Dict[str, typing.Dict]
|
||||
self.mod_total_suffix = '-' + 'TOTALS'
|
||||
|
||||
def _set_size_record(self, git_rev: str, mod: str, size_text: str) -> None:
|
||||
"""Store size information for target Git revision and high-level module.
|
||||
|
||||
size_text Format: text data bss dec hex filename
|
||||
"""
|
||||
size_record = {}
|
||||
for line in size_text.splitlines()[1:]:
|
||||
data = line.split()
|
||||
if re.match(r'\s*\(TOTALS\)', data[5]):
|
||||
data[5] = mod + self.mod_total_suffix
|
||||
# file_name: SizeEntry(text, data, bss, dec)
|
||||
size_record[data[5]] = CodeSizeGeneratorWithSize.SizeEntry(
|
||||
int(data[0]), int(data[1]), int(data[2]), int(data[3]))
|
||||
self.code_size.setdefault(git_rev, {}).update({mod: size_record})
|
||||
|
||||
def read_size_record(self, git_rev: str, fname: str) -> None:
|
||||
"""Read size information from csv file and write it into code_size.
|
||||
|
||||
fname Format: filename text data bss dec
|
||||
"""
|
||||
mod = ""
|
||||
size_record = {}
|
||||
with open(fname, 'r') as csv_file:
|
||||
for line in csv_file:
|
||||
data = line.strip().split()
|
||||
# check if we find the beginning of a module
|
||||
if data and data[0] in MBEDTLS_STATIC_LIB:
|
||||
mod = data[0]
|
||||
continue
|
||||
|
||||
if mod:
|
||||
# file_name: SizeEntry(text, data, bss, dec)
|
||||
size_record[data[0]] = CodeSizeGeneratorWithSize.SizeEntry(
|
||||
int(data[1]), int(data[2]), int(data[3]), int(data[4]))
|
||||
|
||||
# check if we hit record for the end of a module
|
||||
m = re.match(r'\w+' + self.mod_total_suffix, line)
|
||||
if m:
|
||||
if git_rev in self.code_size:
|
||||
self.code_size[git_rev].update({mod: size_record})
|
||||
else:
|
||||
self.code_size[git_rev] = {mod: size_record}
|
||||
mod = ""
|
||||
size_record = {}
|
||||
|
||||
def write_record(
|
||||
self,
|
||||
git_rev: str,
|
||||
code_size_text: typing.Dict[str, str],
|
||||
output: typing_util.Writable
|
||||
) -> None:
|
||||
"""Write size information to a file.
|
||||
|
||||
Writing Format: filename text data bss total(dec)
|
||||
"""
|
||||
for mod, size_text in code_size_text.items():
|
||||
self._set_size_record(git_rev, mod, size_text)
|
||||
|
||||
format_string = "{:<30} {:>7} {:>7} {:>7} {:>7}\n"
|
||||
output.write(format_string.format("filename",
|
||||
"text", "data", "bss", "total"))
|
||||
|
||||
for mod, f_size in self.code_size[git_rev].items():
|
||||
output.write("\n" + mod + "\n")
|
||||
for fname, size_entry in f_size.items():
|
||||
output.write(format_string
|
||||
.format(fname,
|
||||
size_entry.text, size_entry.data,
|
||||
size_entry.bss, size_entry.total))
|
||||
|
||||
def write_comparison( #pylint: disable=too-many-arguments
|
||||
self,
|
||||
old_rev: str,
|
||||
new_rev: str,
|
||||
output: typing_util.Writable,
|
||||
with_markdown=False,
|
||||
show_all=False
|
||||
) -> None:
|
||||
# pylint: disable=too-many-locals
|
||||
"""Write comparison result into a file.
|
||||
|
||||
Writing Format:
|
||||
Markdown Output:
|
||||
filename new(text) new(data) change(text) change(data)
|
||||
CSV Output:
|
||||
filename new(text) new(data) old(text) old(data) change(text) change(data)
|
||||
"""
|
||||
header_line = ["filename", "new(text)", "old(text)", "change(text)",
|
||||
"new(data)", "old(data)", "change(data)"]
|
||||
if with_markdown:
|
||||
dash_line = [":----", "----:", "----:", "----:",
|
||||
"----:", "----:", "----:"]
|
||||
# | filename | new(text) | new(data) | change(text) | change(data) |
|
||||
line_format = "| {0:<30} | {1:>9} | {4:>9} | {3:>12} | {6:>12} |\n"
|
||||
bold_text = lambda x: '**' + str(x) + '**'
|
||||
else:
|
||||
# filename new(text) new(data) old(text) old(data) change(text) change(data)
|
||||
line_format = "{0:<30} {1:>9} {4:>9} {2:>10} {5:>10} {3:>12} {6:>12}\n"
|
||||
|
||||
def cal_sect_change(
|
||||
old_size: typing.Optional[CodeSizeGeneratorWithSize.SizeEntry],
|
||||
new_size: typing.Optional[CodeSizeGeneratorWithSize.SizeEntry],
|
||||
sect: str
|
||||
) -> typing.List:
|
||||
"""Inner helper function to calculate size change for a section.
|
||||
|
||||
Convention for special cases:
|
||||
- If the object has been removed in new Git revision,
|
||||
the size is minus code size of old Git revision;
|
||||
the size change is marked as `Removed`,
|
||||
- If the object only exists in new Git revision,
|
||||
the size is code size of new Git revision;
|
||||
the size change is marked as `None`,
|
||||
|
||||
:param: old_size: code size for objects in old Git revision.
|
||||
:param: new_size: code size for objects in new Git revision.
|
||||
:param: sect: section to calculate from `size` tool. This could be
|
||||
any instance variable in SizeEntry.
|
||||
:return: List of [section size of objects for new Git revision,
|
||||
section size of objects for old Git revision,
|
||||
section size change of objects between two Git revisions]
|
||||
"""
|
||||
if old_size and new_size:
|
||||
new_attr = new_size.__dict__[sect]
|
||||
old_attr = old_size.__dict__[sect]
|
||||
delta = new_attr - old_attr
|
||||
change_attr = '{0:{1}}'.format(delta, '+' if delta else '')
|
||||
elif old_size:
|
||||
new_attr = 'Removed'
|
||||
old_attr = old_size.__dict__[sect]
|
||||
delta = - old_attr
|
||||
change_attr = '{0:{1}}'.format(delta, '+' if delta else '')
|
||||
elif new_size:
|
||||
new_attr = new_size.__dict__[sect]
|
||||
old_attr = 'NotCreated'
|
||||
delta = new_attr
|
||||
change_attr = '{0:{1}}'.format(delta, '+' if delta else '')
|
||||
else:
|
||||
# Should never happen
|
||||
new_attr = 'Error'
|
||||
old_attr = 'Error'
|
||||
change_attr = 'Error'
|
||||
return [new_attr, old_attr, change_attr]
|
||||
|
||||
# sort dictionary by key
|
||||
sort_by_k = lambda item: item[0].lower()
|
||||
def get_results(
|
||||
f_rev_size:
|
||||
typing.Dict[str,
|
||||
typing.Dict[str,
|
||||
CodeSizeGeneratorWithSize.SizeEntry]]
|
||||
) -> typing.List:
|
||||
"""Return List of results in the format of:
|
||||
[filename, new(text), old(text), change(text),
|
||||
new(data), old(data), change(data)]
|
||||
"""
|
||||
res = []
|
||||
for fname, revs_size in sorted(f_rev_size.items(), key=sort_by_k):
|
||||
old_size = revs_size.get(old_rev)
|
||||
new_size = revs_size.get(new_rev)
|
||||
|
||||
text_sect = cal_sect_change(old_size, new_size, 'text')
|
||||
data_sect = cal_sect_change(old_size, new_size, 'data')
|
||||
# skip the files that haven't changed in code size
|
||||
if not show_all and text_sect[-1] == '0' and data_sect[-1] == '0':
|
||||
continue
|
||||
|
||||
res.append([fname, *text_sect, *data_sect])
|
||||
return res
|
||||
|
||||
# write header
|
||||
output.write(line_format.format(*header_line))
|
||||
if with_markdown:
|
||||
output.write(line_format.format(*dash_line))
|
||||
for mod in MBEDTLS_STATIC_LIB:
|
||||
# convert self.code_size to:
|
||||
# {
|
||||
# file_name: {
|
||||
# old_rev: SizeEntry,
|
||||
# new_rev: SizeEntry
|
||||
# },
|
||||
# ...
|
||||
# }
|
||||
f_rev_size = {} #type: typing.Dict[str, typing.Dict]
|
||||
for fname, size_entry in self.code_size[old_rev][mod].items():
|
||||
f_rev_size.setdefault(fname, {}).update({old_rev: size_entry})
|
||||
for fname, size_entry in self.code_size[new_rev][mod].items():
|
||||
f_rev_size.setdefault(fname, {}).update({new_rev: size_entry})
|
||||
|
||||
mod_total_sz = f_rev_size.pop(mod + self.mod_total_suffix)
|
||||
res = get_results(f_rev_size)
|
||||
total_clm = get_results({mod + self.mod_total_suffix: mod_total_sz})
|
||||
if with_markdown:
|
||||
# bold row of mod-TOTALS in markdown table
|
||||
total_clm = [[bold_text(j) for j in i] for i in total_clm]
|
||||
res += total_clm
|
||||
|
||||
# write comparison result
|
||||
for line in res:
|
||||
output.write(line_format.format(*line))
|
||||
|
||||
|
||||
class CodeSizeComparison:
|
||||
"""Compare code size between two Git revisions."""
|
||||
|
||||
def __init__( #pylint: disable=too-many-arguments
|
||||
self,
|
||||
old_size_dist_info: CodeSizeDistinctInfo,
|
||||
new_size_dist_info: CodeSizeDistinctInfo,
|
||||
size_common_info: CodeSizeCommonInfo,
|
||||
result_options: CodeSizeResultInfo,
|
||||
logger: logging.Logger,
|
||||
) -> None:
|
||||
"""
|
||||
:param old_size_dist_info: CodeSizeDistinctInfo containing old distinct
|
||||
info to compare code size with.
|
||||
:param new_size_dist_info: CodeSizeDistinctInfo containing new distinct
|
||||
info to take as comparision base.
|
||||
:param size_common_info: CodeSizeCommonInfo containing common info for
|
||||
both old and new size distinct info and
|
||||
measurement tool.
|
||||
:param result_options: CodeSizeResultInfo containing results options for
|
||||
code size record and comparision.
|
||||
:param logger: logging module
|
||||
"""
|
||||
|
||||
self.logger = logger
|
||||
|
||||
self.old_size_dist_info = old_size_dist_info
|
||||
self.new_size_dist_info = new_size_dist_info
|
||||
self.size_common_info = size_common_info
|
||||
# infer pre make command
|
||||
self.old_size_dist_info.pre_make_cmd = CodeSizeBuildInfo(
|
||||
self.old_size_dist_info, self.size_common_info.host_arch,
|
||||
self.logger).infer_pre_make_command()
|
||||
self.new_size_dist_info.pre_make_cmd = CodeSizeBuildInfo(
|
||||
self.new_size_dist_info, self.size_common_info.host_arch,
|
||||
self.logger).infer_pre_make_command()
|
||||
# infer make command
|
||||
self.old_size_dist_info.make_cmd = CodeSizeBuildInfo(
|
||||
self.old_size_dist_info, self.size_common_info.host_arch,
|
||||
self.logger).infer_make_command()
|
||||
self.new_size_dist_info.make_cmd = CodeSizeBuildInfo(
|
||||
self.new_size_dist_info, self.size_common_info.host_arch,
|
||||
self.logger).infer_make_command()
|
||||
# initialize size parser with corresponding measurement tool
|
||||
self.code_size_generator = self.__generate_size_parser()
|
||||
|
||||
self.result_options = result_options
|
||||
self.csv_dir = os.path.abspath(self.result_options.record_dir)
|
||||
os.makedirs(self.csv_dir, exist_ok=True)
|
||||
self.comp_dir = os.path.abspath(self.result_options.comp_dir)
|
||||
os.makedirs(self.comp_dir, exist_ok=True)
|
||||
|
||||
def __generate_size_parser(self):
|
||||
"""Generate a parser for the corresponding measurement tool."""
|
||||
if re.match(r'size', self.size_common_info.measure_cmd.strip()):
|
||||
return CodeSizeGeneratorWithSize(self.logger)
|
||||
else:
|
||||
self.logger.error("Unsupported measurement tool: `{}`."
|
||||
.format(self.size_common_info.measure_cmd
|
||||
.strip().split(' ')[0]))
|
||||
sys.exit(1)
|
||||
|
||||
def cal_code_size(
|
||||
self,
|
||||
size_dist_info: CodeSizeDistinctInfo
|
||||
) -> typing.Dict[str, str]:
|
||||
"""Calculate code size of library/*.o in a UTF-8 encoding"""
|
||||
|
||||
return CodeSizeCalculator(size_dist_info.git_rev,
|
||||
size_dist_info.pre_make_cmd,
|
||||
size_dist_info.make_cmd,
|
||||
self.size_common_info.measure_cmd,
|
||||
self.logger).cal_libraries_code_size()
|
||||
|
||||
def gen_code_size_report(self, size_dist_info: CodeSizeDistinctInfo) -> None:
|
||||
"""Generate code size record and write it into a file."""
|
||||
|
||||
self.logger.info("Start to generate code size record for {}."
|
||||
.format(size_dist_info.git_rev))
|
||||
output_file = os.path.join(
|
||||
self.csv_dir,
|
||||
'{}-{}.csv'
|
||||
.format(size_dist_info.get_info_indication(),
|
||||
self.size_common_info.get_info_indication()))
|
||||
# Check if the corresponding record exists
|
||||
if size_dist_info.git_rev != "current" and \
|
||||
os.path.exists(output_file):
|
||||
self.logger.debug("Code size csv file for {} already exists."
|
||||
.format(size_dist_info.git_rev))
|
||||
self.code_size_generator.read_size_record(
|
||||
size_dist_info.git_rev, output_file)
|
||||
else:
|
||||
# measure code size
|
||||
code_size_text = self.cal_code_size(size_dist_info)
|
||||
|
||||
self.logger.debug("Generating code size csv for {}."
|
||||
.format(size_dist_info.git_rev))
|
||||
output = open(output_file, "w")
|
||||
self.code_size_generator.write_record(
|
||||
size_dist_info.git_rev, code_size_text, output)
|
||||
|
||||
def gen_code_size_comparison(self) -> None:
|
||||
"""Generate results of code size changes between two Git revisions,
|
||||
old and new.
|
||||
|
||||
- Measured code size result of these two Git revisions must be available.
|
||||
- The result is directed into either file / stdout depending on
|
||||
the option, size_common_info.result_options.stdout. (Default: file)
|
||||
"""
|
||||
|
||||
self.logger.info("Start to generate comparision result between "\
|
||||
"{} and {}."
|
||||
.format(self.old_size_dist_info.git_rev,
|
||||
self.new_size_dist_info.git_rev))
|
||||
if self.result_options.stdout:
|
||||
output = sys.stdout
|
||||
else:
|
||||
output_file = os.path.join(
|
||||
self.comp_dir,
|
||||
'{}-{}-{}.{}'
|
||||
.format(self.old_size_dist_info.get_info_indication(),
|
||||
self.new_size_dist_info.get_info_indication(),
|
||||
self.size_common_info.get_info_indication(),
|
||||
'md' if self.result_options.with_markdown else 'csv'))
|
||||
output = open(output_file, "w")
|
||||
|
||||
self.logger.debug("Generating comparison results between {} and {}."
|
||||
.format(self.old_size_dist_info.git_rev,
|
||||
self.new_size_dist_info.git_rev))
|
||||
if self.result_options.with_markdown or self.result_options.stdout:
|
||||
print("Measure code size between {} and {} by `{}`."
|
||||
.format(self.old_size_dist_info.get_info_indication(),
|
||||
self.new_size_dist_info.get_info_indication(),
|
||||
self.size_common_info.get_info_indication()),
|
||||
file=output)
|
||||
self.code_size_generator.write_comparison(
|
||||
self.old_size_dist_info.git_rev,
|
||||
self.new_size_dist_info.git_rev,
|
||||
output, self.result_options.with_markdown,
|
||||
self.result_options.show_all)
|
||||
|
||||
def get_comparision_results(self) -> None:
|
||||
"""Compare size of library/*.o between self.old_size_dist_info and
|
||||
self.old_size_dist_info and generate the result file."""
|
||||
build_tree.check_repo_path()
|
||||
self.gen_code_size_report(self.old_size_dist_info)
|
||||
self.gen_code_size_report(self.new_size_dist_info)
|
||||
self.gen_code_size_comparison()
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=(__doc__))
|
||||
group_required = parser.add_argument_group(
|
||||
'required arguments',
|
||||
'required arguments to parse for running ' + os.path.basename(__file__))
|
||||
group_required.add_argument(
|
||||
'-o', '--old-rev', type=str, required=True,
|
||||
help='old Git revision for comparison.')
|
||||
|
||||
group_optional = parser.add_argument_group(
|
||||
'optional arguments',
|
||||
'optional arguments to parse for running ' + os.path.basename(__file__))
|
||||
group_optional.add_argument(
|
||||
'--record-dir', type=str, default='code_size_records',
|
||||
help='directory where code size record is stored. '
|
||||
'(Default: code_size_records)')
|
||||
group_optional.add_argument(
|
||||
'--comp-dir', type=str, default='comparison',
|
||||
help='directory where comparison result is stored. '
|
||||
'(Default: comparison)')
|
||||
group_optional.add_argument(
|
||||
'-n', '--new-rev', type=str, default='current',
|
||||
help='new Git revision as comparison base. '
|
||||
'(Default is the current work directory, including uncommitted '
|
||||
'changes.)')
|
||||
group_optional.add_argument(
|
||||
'-a', '--arch', type=str, default=detect_arch(),
|
||||
choices=list(map(lambda s: s.value, SupportedArch)),
|
||||
help='Specify architecture for code size comparison. '
|
||||
'(Default is the host architecture.)')
|
||||
group_optional.add_argument(
|
||||
'-c', '--config', type=str, default=SupportedConfig.DEFAULT.value,
|
||||
choices=list(map(lambda s: s.value, SupportedConfig)),
|
||||
help='Specify configuration type for code size comparison. '
|
||||
'(Default is the current Mbed TLS configuration.)')
|
||||
group_optional.add_argument(
|
||||
'--markdown', action='store_true', dest='markdown',
|
||||
help='Show comparision of code size in a markdown table. '
|
||||
'(Only show the files that have changed).')
|
||||
group_optional.add_argument(
|
||||
'--stdout', action='store_true', dest='stdout',
|
||||
help='Set this option to direct comparison result into sys.stdout. '
|
||||
'(Default: file)')
|
||||
group_optional.add_argument(
|
||||
'--show-all', action='store_true', dest='show_all',
|
||||
help='Show all the objects in comparison result, including the ones '
|
||||
'that haven\'t changed in code size. (Default: False)')
|
||||
group_optional.add_argument(
|
||||
'--verbose', action='store_true', dest='verbose',
|
||||
help='Show logs in detail for code size measurement. '
|
||||
'(Default: False)')
|
||||
comp_args = parser.parse_args()
|
||||
|
||||
logger = logging.getLogger()
|
||||
logging_util.configure_logger(logger, split_level=logging.NOTSET)
|
||||
logger.setLevel(logging.DEBUG if comp_args.verbose else logging.INFO)
|
||||
|
||||
if os.path.isfile(comp_args.record_dir):
|
||||
logger.error("record directory: {} is not a directory"
|
||||
.format(comp_args.record_dir))
|
||||
sys.exit(1)
|
||||
if os.path.isfile(comp_args.comp_dir):
|
||||
logger.error("comparison directory: {} is not a directory"
|
||||
.format(comp_args.comp_dir))
|
||||
sys.exit(1)
|
||||
|
||||
comp_args.old_rev = CodeSizeCalculator.validate_git_revision(
|
||||
comp_args.old_rev)
|
||||
if comp_args.new_rev != 'current':
|
||||
comp_args.new_rev = CodeSizeCalculator.validate_git_revision(
|
||||
comp_args.new_rev)
|
||||
|
||||
# version, git_rev, arch, config, compiler, opt_level
|
||||
old_size_dist_info = CodeSizeDistinctInfo(
|
||||
'old', comp_args.old_rev, comp_args.arch, comp_args.config, 'cc', '-Os')
|
||||
new_size_dist_info = CodeSizeDistinctInfo(
|
||||
'new', comp_args.new_rev, comp_args.arch, comp_args.config, 'cc', '-Os')
|
||||
# host_arch, measure_cmd
|
||||
size_common_info = CodeSizeCommonInfo(
|
||||
detect_arch(), 'size -t')
|
||||
# record_dir, comp_dir, with_markdown, stdout, show_all
|
||||
result_options = CodeSizeResultInfo(
|
||||
comp_args.record_dir, comp_args.comp_dir,
|
||||
comp_args.markdown, comp_args.stdout, comp_args.show_all)
|
||||
|
||||
logger.info("Measure code size between {} and {} by `{}`."
|
||||
.format(old_size_dist_info.get_info_indication(),
|
||||
new_size_dist_info.get_info_indication(),
|
||||
size_common_info.get_info_indication()))
|
||||
CodeSizeComparison(old_size_dist_info, new_size_dist_info,
|
||||
size_common_info, result_options,
|
||||
logger).get_comparision_results()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
222
externals/mbedtls/scripts/code_style.py
vendored
222
externals/mbedtls/scripts/code_style.py
vendored
@@ -1,222 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Check or fix the code style by running Uncrustify.
|
||||
|
||||
This script must be run from the root of a Git work tree containing Mbed TLS.
|
||||
"""
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import FrozenSet, List, Optional
|
||||
|
||||
UNCRUSTIFY_SUPPORTED_VERSION = "0.75.1"
|
||||
CONFIG_FILE = ".uncrustify.cfg"
|
||||
UNCRUSTIFY_EXE = "uncrustify"
|
||||
UNCRUSTIFY_ARGS = ["-c", CONFIG_FILE]
|
||||
CHECK_GENERATED_FILES = "tests/scripts/check-generated-files.sh"
|
||||
|
||||
def print_err(*args):
|
||||
print("Error: ", *args, file=sys.stderr)
|
||||
|
||||
# Print the file names that will be skipped and the help message
|
||||
def print_skip(files_to_skip):
|
||||
print()
|
||||
print(*files_to_skip, sep=", SKIP\n", end=", SKIP\n")
|
||||
print("Warning: The listed files will be skipped because\n"
|
||||
"they are not known to git.")
|
||||
print()
|
||||
|
||||
# Match FILENAME(s) in "check SCRIPT (FILENAME...)"
|
||||
CHECK_CALL_RE = re.compile(r"\n\s*check\s+[^\s#$&*?;|]+([^\n#$&*?;|]+)",
|
||||
re.ASCII)
|
||||
def list_generated_files() -> FrozenSet[str]:
|
||||
"""Return the names of generated files.
|
||||
|
||||
We don't reformat generated files, since the result might be different
|
||||
from the output of the generator. Ideally the result of the generator
|
||||
would conform to the code style, but this would be difficult, especially
|
||||
with respect to the placement of line breaks in long logical lines.
|
||||
"""
|
||||
# Parse check-generated-files.sh to get an up-to-date list of
|
||||
# generated files. Read the file rather than calling it so that
|
||||
# this script only depends on Git, Python and uncrustify, and not other
|
||||
# tools such as sh or grep which might not be available on Windows.
|
||||
# This introduces a limitation: check-generated-files.sh must have
|
||||
# the expected format and must list the files explicitly, not through
|
||||
# wildcards or command substitution.
|
||||
content = open(CHECK_GENERATED_FILES, encoding="utf-8").read()
|
||||
checks = re.findall(CHECK_CALL_RE, content)
|
||||
return frozenset(word for s in checks for word in s.split())
|
||||
|
||||
def get_src_files(since: Optional[str]) -> List[str]:
|
||||
"""
|
||||
Use git to get a list of the source files.
|
||||
|
||||
The optional argument since is a commit, indicating to only list files
|
||||
that have changed since that commit. Without this argument, list all
|
||||
files known to git.
|
||||
|
||||
Only C files are included, and certain files (generated, or 3rdparty)
|
||||
are excluded.
|
||||
"""
|
||||
file_patterns = ["*.[hc]",
|
||||
"tests/suites/*.function",
|
||||
"scripts/data_files/*.fmt"]
|
||||
output = subprocess.check_output(["git", "ls-files"] + file_patterns,
|
||||
universal_newlines=True)
|
||||
src_files = output.split()
|
||||
if since:
|
||||
# get all files changed in commits since the starting point
|
||||
cmd = ["git", "log", since + "..HEAD", "--name-only", "--pretty=", "--"] + src_files
|
||||
output = subprocess.check_output(cmd, universal_newlines=True)
|
||||
committed_changed_files = output.split()
|
||||
# and also get all files with uncommitted changes
|
||||
cmd = ["git", "diff", "--name-only", "--"] + src_files
|
||||
output = subprocess.check_output(cmd, universal_newlines=True)
|
||||
uncommitted_changed_files = output.split()
|
||||
src_files = list(set(committed_changed_files + uncommitted_changed_files))
|
||||
|
||||
generated_files = list_generated_files()
|
||||
# Don't correct style for third-party files (and, for simplicity,
|
||||
# companion files in the same subtree), or for automatically
|
||||
# generated files (we're correcting the templates instead).
|
||||
src_files = [filename for filename in src_files
|
||||
if not (filename.startswith("3rdparty/") or
|
||||
filename in generated_files)]
|
||||
return src_files
|
||||
|
||||
def get_uncrustify_version() -> str:
|
||||
"""
|
||||
Get the version string from Uncrustify
|
||||
"""
|
||||
result = subprocess.run([UNCRUSTIFY_EXE, "--version"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
check=False)
|
||||
if result.returncode != 0:
|
||||
print_err("Could not get Uncrustify version:", str(result.stderr, "utf-8"))
|
||||
return ""
|
||||
else:
|
||||
return str(result.stdout, "utf-8")
|
||||
|
||||
def check_style_is_correct(src_file_list: List[str]) -> bool:
|
||||
"""
|
||||
Check the code style and output a diff for each file whose style is
|
||||
incorrect.
|
||||
"""
|
||||
style_correct = True
|
||||
for src_file in src_file_list:
|
||||
uncrustify_cmd = [UNCRUSTIFY_EXE] + UNCRUSTIFY_ARGS + [src_file]
|
||||
result = subprocess.run(uncrustify_cmd, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, check=False)
|
||||
if result.returncode != 0:
|
||||
print_err("Uncrustify returned " + str(result.returncode) +
|
||||
" correcting file " + src_file)
|
||||
return False
|
||||
|
||||
# Uncrustify makes changes to the code and places the result in a new
|
||||
# file with the extension ".uncrustify". To get the changes (if any)
|
||||
# simply diff the 2 files.
|
||||
diff_cmd = ["diff", "-u", src_file, src_file + ".uncrustify"]
|
||||
cp = subprocess.run(diff_cmd, check=False)
|
||||
|
||||
if cp.returncode == 1:
|
||||
print(src_file + " changed - code style is incorrect.")
|
||||
style_correct = False
|
||||
elif cp.returncode != 0:
|
||||
raise subprocess.CalledProcessError(cp.returncode, cp.args,
|
||||
cp.stdout, cp.stderr)
|
||||
|
||||
# Tidy up artifact
|
||||
os.remove(src_file + ".uncrustify")
|
||||
|
||||
return style_correct
|
||||
|
||||
def fix_style_single_pass(src_file_list: List[str]) -> bool:
|
||||
"""
|
||||
Run Uncrustify once over the source files.
|
||||
"""
|
||||
code_change_args = UNCRUSTIFY_ARGS + ["--no-backup"]
|
||||
for src_file in src_file_list:
|
||||
uncrustify_cmd = [UNCRUSTIFY_EXE] + code_change_args + [src_file]
|
||||
result = subprocess.run(uncrustify_cmd, check=False)
|
||||
if result.returncode != 0:
|
||||
print_err("Uncrustify with file returned: " +
|
||||
str(result.returncode) + " correcting file " +
|
||||
src_file)
|
||||
return False
|
||||
return True
|
||||
|
||||
def fix_style(src_file_list: List[str]) -> int:
|
||||
"""
|
||||
Fix the code style. This takes 2 passes of Uncrustify.
|
||||
"""
|
||||
if not fix_style_single_pass(src_file_list):
|
||||
return 1
|
||||
if not fix_style_single_pass(src_file_list):
|
||||
return 1
|
||||
|
||||
# Guard against future changes that cause the codebase to require
|
||||
# more passes.
|
||||
if not check_style_is_correct(src_file_list):
|
||||
print_err("Code style still incorrect after second run of Uncrustify.")
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def main() -> int:
|
||||
"""
|
||||
Main with command line arguments.
|
||||
"""
|
||||
uncrustify_version = get_uncrustify_version().strip()
|
||||
if UNCRUSTIFY_SUPPORTED_VERSION not in uncrustify_version:
|
||||
print("Warning: Using unsupported Uncrustify version '" +
|
||||
uncrustify_version + "'")
|
||||
print("Note: The only supported version is " +
|
||||
UNCRUSTIFY_SUPPORTED_VERSION)
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-f', '--fix', action='store_true',
|
||||
help=('modify source files to fix the code style '
|
||||
'(default: print diff, do not modify files)'))
|
||||
parser.add_argument('-s', '--since', metavar='COMMIT', const='development', nargs='?',
|
||||
help=('only check files modified since the specified commit'
|
||||
' (e.g. --since=HEAD~3 or --since=development). If no'
|
||||
' commit is specified, default to development.'))
|
||||
# --subset is almost useless: it only matters if there are no files
|
||||
# ('code_style.py' without arguments checks all files known to Git,
|
||||
# 'code_style.py --subset' does nothing). In particular,
|
||||
# 'code_style.py --fix --subset ...' is intended as a stable ("porcelain")
|
||||
# way to restyle a possibly empty set of files.
|
||||
parser.add_argument('--subset', action='store_true',
|
||||
help='only check the specified files (default with non-option arguments)')
|
||||
parser.add_argument('operands', nargs='*', metavar='FILE',
|
||||
help='files to check (files MUST be known to git, if none: check all)')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
covered = frozenset(get_src_files(args.since))
|
||||
# We only check files that are known to git
|
||||
if args.subset or args.operands:
|
||||
src_files = [f for f in args.operands if f in covered]
|
||||
skip_src_files = [f for f in args.operands if f not in covered]
|
||||
if skip_src_files:
|
||||
print_skip(skip_src_files)
|
||||
else:
|
||||
src_files = list(covered)
|
||||
|
||||
if args.fix:
|
||||
# Fix mode
|
||||
return fix_style(src_files)
|
||||
else:
|
||||
# Check mode
|
||||
if check_style_is_correct(src_files):
|
||||
print("Checked {} files, style ok.".format(len(src_files)))
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
123
externals/mbedtls/scripts/common.make
vendored
123
externals/mbedtls/scripts/common.make
vendored
@@ -1,123 +0,0 @@
|
||||
# To compile on SunOS: add "-lsocket -lnsl" to LDFLAGS
|
||||
|
||||
ifndef MBEDTLS_PATH
|
||||
MBEDTLS_PATH := ..
|
||||
endif
|
||||
|
||||
CFLAGS ?= -O2
|
||||
WARNING_CFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
|
||||
WARNING_CXXFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
|
||||
LDFLAGS ?=
|
||||
|
||||
LOCAL_CFLAGS = $(WARNING_CFLAGS) -I$(MBEDTLS_TEST_PATH)/include -I$(MBEDTLS_PATH)/include -D_FILE_OFFSET_BITS=64
|
||||
LOCAL_CXXFLAGS = $(WARNING_CXXFLAGS) -I$(MBEDTLS_PATH)/include -I$(MBEDTLS_PATH)/tests/include -D_FILE_OFFSET_BITS=64
|
||||
LOCAL_LDFLAGS = ${MBEDTLS_TEST_OBJS} \
|
||||
-L$(MBEDTLS_PATH)/library \
|
||||
-lmbedtls$(SHARED_SUFFIX) \
|
||||
-lmbedx509$(SHARED_SUFFIX) \
|
||||
-lmbedcrypto$(SHARED_SUFFIX)
|
||||
|
||||
include $(MBEDTLS_PATH)/3rdparty/Makefile.inc
|
||||
LOCAL_CFLAGS+=$(THIRDPARTY_INCLUDES)
|
||||
|
||||
ifndef SHARED
|
||||
MBEDLIBS=$(MBEDTLS_PATH)/library/libmbedcrypto.a $(MBEDTLS_PATH)/library/libmbedx509.a $(MBEDTLS_PATH)/library/libmbedtls.a
|
||||
else
|
||||
MBEDLIBS=$(MBEDTLS_PATH)/library/libmbedcrypto.$(DLEXT) $(MBEDTLS_PATH)/library/libmbedx509.$(DLEXT) $(MBEDTLS_PATH)/library/libmbedtls.$(DLEXT)
|
||||
endif
|
||||
|
||||
ifdef DEBUG
|
||||
LOCAL_CFLAGS += -g3
|
||||
endif
|
||||
|
||||
# if we're running on Windows, build for Windows
|
||||
ifdef WINDOWS
|
||||
WINDOWS_BUILD=1
|
||||
endif
|
||||
|
||||
## Usage: $(call remove_enabled_options,PREPROCESSOR_INPUT)
|
||||
## Remove the preprocessor symbols that are set in the current configuration
|
||||
## from PREPROCESSOR_INPUT. Also normalize whitespace.
|
||||
## Example:
|
||||
## $(call remove_enabled_options,MBEDTLS_FOO MBEDTLS_BAR)
|
||||
## This expands to an empty string "" if MBEDTLS_FOO and MBEDTLS_BAR are both
|
||||
## enabled, to "MBEDTLS_FOO" if MBEDTLS_BAR is enabled but MBEDTLS_FOO is
|
||||
## disabled, etc.
|
||||
##
|
||||
## This only works with a Unix-like shell environment (Bourne/POSIX-style shell
|
||||
## and standard commands) and a Unix-like compiler (supporting -E). In
|
||||
## other environments, the output is likely to be empty.
|
||||
define remove_enabled_options
|
||||
$(strip $(shell
|
||||
exec 2>/dev/null;
|
||||
{ echo '#include <mbedtls/build_info.h>'; echo $(1); } |
|
||||
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -E - |
|
||||
tail -n 1
|
||||
))
|
||||
endef
|
||||
|
||||
ifdef WINDOWS_BUILD
|
||||
DLEXT=dll
|
||||
EXEXT=.exe
|
||||
LOCAL_LDFLAGS += -lws2_32 -lbcrypt
|
||||
ifdef SHARED
|
||||
SHARED_SUFFIX=.$(DLEXT)
|
||||
endif
|
||||
|
||||
else # Not building for Windows
|
||||
DLEXT ?= so
|
||||
EXEXT=
|
||||
SHARED_SUFFIX=
|
||||
ifndef THREADING
|
||||
# Auto-detect configurations with pthread.
|
||||
# If the call to remove_enabled_options returns "control", the symbols
|
||||
# are confirmed set and we link with pthread.
|
||||
# If the auto-detection fails, the result of the call is empty and
|
||||
# we keep THREADING undefined.
|
||||
ifeq (control,$(call remove_enabled_options,control MBEDTLS_THREADING_C MBEDTLS_THREADING_PTHREAD))
|
||||
THREADING := pthread
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(THREADING),pthread)
|
||||
LOCAL_LDFLAGS += -lpthread
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef WINDOWS
|
||||
PYTHON ?= python
|
||||
else
|
||||
PYTHON ?= $(shell if type python3 >/dev/null 2>/dev/null; then echo python3; else echo python; fi)
|
||||
endif
|
||||
|
||||
# See root Makefile
|
||||
GEN_FILES ?= yes
|
||||
ifdef GEN_FILES
|
||||
gen_file_dep =
|
||||
else
|
||||
gen_file_dep = |
|
||||
endif
|
||||
|
||||
default: all
|
||||
|
||||
$(MBEDLIBS):
|
||||
$(MAKE) -C $(MBEDTLS_PATH)/library
|
||||
|
||||
neat: clean
|
||||
ifndef WINDOWS
|
||||
rm -f $(GENERATED_FILES)
|
||||
else
|
||||
for %f in ($(subst /,\,$(GENERATED_FILES))) if exist %f del /Q /F %f
|
||||
endif
|
||||
|
||||
# Auxiliary modules used by tests and some sample programs
|
||||
MBEDTLS_CORE_TEST_OBJS = $(patsubst %.c,%.o,$(wildcard \
|
||||
${MBEDTLS_TEST_PATH}/src/*.c \
|
||||
${MBEDTLS_TEST_PATH}/src/drivers/*.c \
|
||||
))
|
||||
# Additional auxiliary modules for TLS testing
|
||||
MBEDTLS_TLS_TEST_OBJS = $(patsubst %.c,%.o,$(wildcard \
|
||||
${MBEDTLS_TEST_PATH}/src/test_helpers/*.c \
|
||||
))
|
||||
|
||||
MBEDTLS_TEST_OBJS = $(MBEDTLS_CORE_TEST_OBJS) $(MBEDTLS_TLS_TEST_OBJS)
|
||||
347
externals/mbedtls/scripts/config.pl
vendored
347
externals/mbedtls/scripts/config.pl
vendored
@@ -1,14 +1,339 @@
|
||||
#!/usr/bin/env perl
|
||||
# Backward compatibility redirection
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# Purpose
|
||||
#
|
||||
# Comments and uncomments #define lines in the given header file and optionally
|
||||
# sets their value or can get the value. This is to provide scripting control of
|
||||
# what preprocessor symbols, and therefore what build time configuration flags
|
||||
# are set in the 'config.h' file.
|
||||
#
|
||||
# Usage: config.pl [-f <file> | --file <file>] [-o | --force]
|
||||
# [set <symbol> <value> | unset <symbol> | get <symbol> |
|
||||
# full | realfull]
|
||||
#
|
||||
# Full usage description provided below.
|
||||
#
|
||||
# The following options are disabled instead of enabled with "full".
|
||||
#
|
||||
# * Options that require additional build dependencies or unusual hardware.
|
||||
# * Options that make testing less effective.
|
||||
# * Options that are incompatible with other options, or more generally that
|
||||
# interact with other parts of the code in such a way that a bulk enabling
|
||||
# is not a good way to test them.
|
||||
# * Options that remove features.
|
||||
#
|
||||
# The baremetal configuration excludes options that require a library or
|
||||
# operating system feature that is typically not present on bare metal
|
||||
# systems. It also excludes debugging features that increase the code size
|
||||
# of other modules.
|
||||
# Features that are excluded from "full" won't be in "baremetal" either.
|
||||
|
||||
## Copyright The Mbed TLS Contributors
|
||||
## SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
##
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
my $py = $0;
|
||||
$py =~ s/\.pl$/.py/ or die "Unable to determine the name of the Python script";
|
||||
exec 'python3', $py, @ARGV;
|
||||
print STDERR "$0: python3: $!. Trying python instead.\n";
|
||||
exec 'python', $py, @ARGV;
|
||||
print STDERR "$0: python: $!\n";
|
||||
exit 127;
|
||||
my $config_file = "include/mbedtls/config.h";
|
||||
my $usage = <<EOU;
|
||||
$0 [-f <file> | --file <file>] [-o | --force]
|
||||
[set <symbol> <value> | unset <symbol> | get <symbol> |
|
||||
full | realfull | baremetal]
|
||||
|
||||
Commands
|
||||
set <symbol> [<value>] - Uncomments or adds a #define for the <symbol> to
|
||||
the configuration file, and optionally making it
|
||||
of <value>.
|
||||
If the symbol isn't present in the file an error
|
||||
is returned.
|
||||
unset <symbol> - Comments out the #define for the given symbol if
|
||||
present in the configuration file.
|
||||
get <symbol> - Finds the #define for the given symbol, returning
|
||||
an exitcode of 0 if the symbol is found, and 1 if
|
||||
not. The value of the symbol is output if one is
|
||||
specified in the configuration file.
|
||||
full - Uncomments all #define's in the configuration file
|
||||
excluding some reserved symbols, until the
|
||||
'Module configuration options' section
|
||||
realfull - Uncomments all #define's with no exclusions
|
||||
baremetal - Sets full configuration suitable for baremetal build.
|
||||
|
||||
Options
|
||||
-f | --file <filename> - The file or file path for the configuration file
|
||||
to edit. When omitted, the following default is
|
||||
used:
|
||||
$config_file
|
||||
-o | --force - If the symbol isn't present in the configuration
|
||||
file when setting its value, a #define is
|
||||
appended to the end of the file.
|
||||
|
||||
EOU
|
||||
|
||||
my @excluded = qw(
|
||||
MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
|
||||
MBEDTLS_DEPRECATED_REMOVED
|
||||
MBEDTLS_DEPRECATED_WARNING
|
||||
MBEDTLS_ECP_NO_INTERNAL_RNG
|
||||
MBEDTLS_HAVE_SSE2
|
||||
MBEDTLS_MEMORY_BACKTRACE
|
||||
MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
MBEDTLS_MEMORY_DEBUG
|
||||
MBEDTLS_NO_64BIT_MULTIPLICATION
|
||||
MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
|
||||
MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
MBEDTLS_NO_UDBL_DIVISION
|
||||
MBEDTLS_PKCS11_C
|
||||
MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
|
||||
MBEDTLS_REMOVE_3DES_CIPHERSUITES
|
||||
MBEDTLS_REMOVE_ARC4_CIPHERSUITES
|
||||
MBEDTLS_RSA_NO_CRT
|
||||
MBEDTLS_SSL_HW_RECORD_ACCEL
|
||||
MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
|
||||
MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
|
||||
MBEDTLS_TEST_NULL_ENTROPY
|
||||
MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
|
||||
MBEDTLS_ZLIB_SUPPORT
|
||||
_ALT\s*$
|
||||
);
|
||||
|
||||
# Things that should be disabled in "baremetal"
|
||||
my @excluded_baremetal = qw(
|
||||
MBEDTLS_DEBUG_C
|
||||
MBEDTLS_ENTROPY_NV_SEED
|
||||
MBEDTLS_FS_IO
|
||||
MBEDTLS_HAVEGE_C
|
||||
MBEDTLS_HAVE_TIME
|
||||
MBEDTLS_HAVE_TIME_DATE
|
||||
MBEDTLS_MEMORY_BACKTRACE
|
||||
MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
MBEDTLS_NET_C
|
||||
MBEDTLS_PLATFORM_FPRINTF_ALT
|
||||
MBEDTLS_PLATFORM_NV_SEED_ALT
|
||||
MBEDTLS_PLATFORM_TIME_ALT
|
||||
MBEDTLS_TEST_HOOKS
|
||||
MBEDTLS_THREADING_C
|
||||
MBEDTLS_THREADING_PTHREAD
|
||||
MBEDTLS_TIMING_C
|
||||
);
|
||||
|
||||
# Things that should be enabled in "full" even if they match @excluded.
|
||||
# Platform ALTs enable global variables that allow configuring the behavior
|
||||
# but default to the default behavior, except for PLATFORM_SETUP_TEARDOWN_ALT
|
||||
# which requires the application to provide relevant functions like
|
||||
# non-platform ALTs.
|
||||
my @non_excluded = qw(
|
||||
PLATFORM_(?!SETUP_TEARDOWN_)[A-Z_0-9]+_ALT
|
||||
);
|
||||
|
||||
# Things that should be enabled in "baremetal"
|
||||
my @non_excluded_baremetal = qw(
|
||||
MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
);
|
||||
|
||||
# Process the command line arguments
|
||||
|
||||
my $force_option = 0;
|
||||
|
||||
my ($arg, $name, $value, $action);
|
||||
|
||||
while ($arg = shift) {
|
||||
|
||||
# Check if the argument is an option
|
||||
if ($arg eq "-f" || $arg eq "--file") {
|
||||
$config_file = shift;
|
||||
|
||||
-f $config_file or die "No such file: $config_file\n";
|
||||
|
||||
}
|
||||
elsif ($arg eq "-o" || $arg eq "--force") {
|
||||
$force_option = 1;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
# ...else assume it's a command
|
||||
$action = $arg;
|
||||
|
||||
if ($action eq "full" || $action eq "realfull" || $action eq "baremetal" ) {
|
||||
# No additional parameters
|
||||
die $usage if @ARGV;
|
||||
|
||||
}
|
||||
elsif ($action eq "unset" || $action eq "get") {
|
||||
die $usage unless @ARGV;
|
||||
$name = shift;
|
||||
|
||||
}
|
||||
elsif ($action eq "set") {
|
||||
die $usage unless @ARGV;
|
||||
$name = shift;
|
||||
$value = shift if @ARGV;
|
||||
|
||||
}
|
||||
else {
|
||||
die "Command '$action' not recognised.\n\n".$usage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# If no command was specified, exit...
|
||||
if ( not defined($action) ){ die $usage; }
|
||||
|
||||
# Check the config file is present
|
||||
if (! -f $config_file) {
|
||||
|
||||
chdir '..' or die;
|
||||
|
||||
# Confirm this is the project root directory and try again
|
||||
if ( !(-d 'scripts' && -d 'include' && -d 'library' && -f $config_file) ) {
|
||||
die "If no file specified, must be run from the project root or scripts directory.\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Now read the file and process the contents
|
||||
|
||||
open my $config_read, '<', $config_file or die "read $config_file: $!\n";
|
||||
my @config_lines = <$config_read>;
|
||||
close $config_read;
|
||||
|
||||
# Add required baremetal symbols to the list that is included.
|
||||
if ( $action eq "baremetal" ) {
|
||||
@non_excluded = ( @non_excluded, @non_excluded_baremetal );
|
||||
}
|
||||
|
||||
my ($exclude_re, $no_exclude_re, $exclude_baremetal_re);
|
||||
if ($action eq "realfull") {
|
||||
$exclude_re = qr/^$/;
|
||||
$no_exclude_re = qr/./;
|
||||
} else {
|
||||
$exclude_re = join '|', @excluded;
|
||||
$no_exclude_re = join '|', @non_excluded;
|
||||
}
|
||||
if ( $action eq "baremetal" ) {
|
||||
$exclude_baremetal_re = join '|', @excluded_baremetal;
|
||||
}
|
||||
|
||||
my $config_write = undef;
|
||||
if ($action ne "get") {
|
||||
open $config_write, '>', $config_file or die "write $config_file: $!\n";
|
||||
}
|
||||
|
||||
my $done;
|
||||
for my $line (@config_lines) {
|
||||
if ($action eq "full" || $action eq "realfull" || $action eq "baremetal" ) {
|
||||
if ($line =~ /name SECTION: Module configuration options/) {
|
||||
$done = 1;
|
||||
}
|
||||
|
||||
if (!$done && $line =~ m!^//\s?#define! &&
|
||||
( $line !~ /$exclude_re/ || $line =~ /$no_exclude_re/ ) &&
|
||||
( $action ne "baremetal" || ( $line !~ /$exclude_baremetal_re/ ) ) ) {
|
||||
$line =~ s!^//\s?!!;
|
||||
}
|
||||
if (!$done && $line =~ m!^\s?#define! &&
|
||||
! ( ( $line !~ /$exclude_re/ || $line =~ /$no_exclude_re/ ) &&
|
||||
( $action ne "baremetal" || ( $line !~ /$exclude_baremetal_re/ ) ) ) ) {
|
||||
$line =~ s!^!//!;
|
||||
}
|
||||
} elsif ($action eq "unset") {
|
||||
if (!$done && $line =~ /^\s*#define\s*$name\b/) {
|
||||
$line = '//' . $line;
|
||||
$done = 1;
|
||||
}
|
||||
} elsif (!$done && $action eq "set") {
|
||||
if ($line =~ m!^(?://)?\s*#define\s*$name\b!) {
|
||||
$line = "#define $name";
|
||||
$line .= " $value" if defined $value && $value ne "";
|
||||
$line .= "\n";
|
||||
$done = 1;
|
||||
}
|
||||
} elsif (!$done && $action eq "get") {
|
||||
if ($line =~ /^\s*#define\s*$name(?:\s+(.*?))\s*(?:$|\/\*|\/\/)/) {
|
||||
$value = $1;
|
||||
$done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (defined $config_write) {
|
||||
print $config_write $line or die "write $config_file: $!\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Did the set command work?
|
||||
if ($action eq "set" && $force_option && !$done) {
|
||||
|
||||
# If the force option was set, append the symbol to the end of the file
|
||||
my $line = "#define $name";
|
||||
$line .= " $value" if defined $value && $value ne "";
|
||||
$line .= "\n";
|
||||
$done = 1;
|
||||
|
||||
print $config_write $line or die "write $config_file: $!\n";
|
||||
}
|
||||
|
||||
if (defined $config_write) {
|
||||
close $config_write or die "close $config_file: $!\n";
|
||||
}
|
||||
|
||||
if ($action eq "get") {
|
||||
if ($done) {
|
||||
if ($value ne '') {
|
||||
print "$value\n";
|
||||
}
|
||||
exit 0;
|
||||
} else {
|
||||
# If the symbol was not found, return an error
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($action eq "full" && !$done) {
|
||||
die "Configuration section was not found in $config_file\n";
|
||||
|
||||
}
|
||||
|
||||
if ($action ne "full" && $action ne "unset" && !$done) {
|
||||
die "A #define for the symbol $name was not found in $config_file\n";
|
||||
}
|
||||
|
||||
__END__
|
||||
|
||||
602
externals/mbedtls/scripts/config.py
vendored
602
externals/mbedtls/scripts/config.py
vendored
@@ -1,602 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""Mbed TLS configuration file manipulation library and tool
|
||||
|
||||
Basic usage, to read the Mbed TLS configuration:
|
||||
config = ConfigFile()
|
||||
if 'MBEDTLS_RSA_C' in config: print('RSA is enabled')
|
||||
"""
|
||||
|
||||
# Note that as long as Mbed TLS 2.28 LTS is maintained, the version of
|
||||
# this script in the mbedtls-2.28 branch must remain compatible with
|
||||
# Python 3.4. The version in development may only use more recent features
|
||||
# in parts that are not backported to 2.28.
|
||||
|
||||
## Copyright The Mbed TLS Contributors
|
||||
## SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
##
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
class Setting:
|
||||
"""Representation of one Mbed TLS mbedtls_config.h setting.
|
||||
|
||||
Fields:
|
||||
* name: the symbol name ('MBEDTLS_xxx').
|
||||
* value: the value of the macro. The empty string for a plain #define
|
||||
with no value.
|
||||
* active: True if name is defined, False if a #define for name is
|
||||
present in mbedtls_config.h but commented out.
|
||||
* section: the name of the section that contains this symbol.
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
def __init__(self, active, name, value='', section=None):
|
||||
self.active = active
|
||||
self.name = name
|
||||
self.value = value
|
||||
self.section = section
|
||||
|
||||
class Config:
|
||||
"""Representation of the Mbed TLS configuration.
|
||||
|
||||
In the documentation of this class, a symbol is said to be *active*
|
||||
if there is a #define for it that is not commented out, and *known*
|
||||
if there is a #define for it whether commented out or not.
|
||||
|
||||
This class supports the following protocols:
|
||||
* `name in config` is `True` if the symbol `name` is active, `False`
|
||||
otherwise (whether `name` is inactive or not known).
|
||||
* `config[name]` is the value of the macro `name`. If `name` is inactive,
|
||||
raise `KeyError` (even if `name` is known).
|
||||
* `config[name] = value` sets the value associated to `name`. `name`
|
||||
must be known, but does not need to be set. This does not cause
|
||||
name to become set.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.settings = {}
|
||||
|
||||
def __contains__(self, name):
|
||||
"""True if the given symbol is active (i.e. set).
|
||||
|
||||
False if the given symbol is not set, even if a definition
|
||||
is present but commented out.
|
||||
"""
|
||||
return name in self.settings and self.settings[name].active
|
||||
|
||||
def all(self, *names):
|
||||
"""True if all the elements of names are active (i.e. set)."""
|
||||
return all(self.__contains__(name) for name in names)
|
||||
|
||||
def any(self, *names):
|
||||
"""True if at least one symbol in names are active (i.e. set)."""
|
||||
return any(self.__contains__(name) for name in names)
|
||||
|
||||
def known(self, name):
|
||||
"""True if a #define for name is present, whether it's commented out or not."""
|
||||
return name in self.settings
|
||||
|
||||
def __getitem__(self, name):
|
||||
"""Get the value of name, i.e. what the preprocessor symbol expands to.
|
||||
|
||||
If name is not known, raise KeyError. name does not need to be active.
|
||||
"""
|
||||
return self.settings[name].value
|
||||
|
||||
def get(self, name, default=None):
|
||||
"""Get the value of name. If name is inactive (not set), return default.
|
||||
|
||||
If a #define for name is present and not commented out, return
|
||||
its expansion, even if this is the empty string.
|
||||
|
||||
If a #define for name is present but commented out, return default.
|
||||
"""
|
||||
if name in self.settings:
|
||||
return self.settings[name].value
|
||||
else:
|
||||
return default
|
||||
|
||||
def __setitem__(self, name, value):
|
||||
"""If name is known, set its value.
|
||||
|
||||
If name is not known, raise KeyError.
|
||||
"""
|
||||
self.settings[name].value = value
|
||||
|
||||
def set(self, name, value=None):
|
||||
"""Set name to the given value and make it active.
|
||||
|
||||
If value is None and name is already known, don't change its value.
|
||||
If value is None and name is not known, set its value to the empty
|
||||
string.
|
||||
"""
|
||||
if name in self.settings:
|
||||
if value is not None:
|
||||
self.settings[name].value = value
|
||||
self.settings[name].active = True
|
||||
else:
|
||||
self.settings[name] = Setting(True, name, value=value)
|
||||
|
||||
def unset(self, name):
|
||||
"""Make name unset (inactive).
|
||||
|
||||
name remains known if it was known before.
|
||||
"""
|
||||
if name not in self.settings:
|
||||
return
|
||||
self.settings[name].active = False
|
||||
|
||||
def adapt(self, adapter):
|
||||
"""Run adapter on each known symbol and (de)activate it accordingly.
|
||||
|
||||
`adapter` must be a function that returns a boolean. It is called as
|
||||
`adapter(name, active, section)` for each setting, where `active` is
|
||||
`True` if `name` is set and `False` if `name` is known but unset,
|
||||
and `section` is the name of the section containing `name`. If
|
||||
`adapter` returns `True`, then set `name` (i.e. make it active),
|
||||
otherwise unset `name` (i.e. make it known but inactive).
|
||||
"""
|
||||
for setting in self.settings.values():
|
||||
setting.active = adapter(setting.name, setting.active,
|
||||
setting.section)
|
||||
|
||||
def change_matching(self, regexs, enable):
|
||||
"""Change all symbols matching one of the regexs to the desired state."""
|
||||
if not regexs:
|
||||
return
|
||||
regex = re.compile('|'.join(regexs))
|
||||
for setting in self.settings.values():
|
||||
if regex.search(setting.name):
|
||||
setting.active = enable
|
||||
|
||||
def is_full_section(section):
|
||||
"""Is this section affected by "config.py full" and friends?"""
|
||||
return section.endswith('support') or section.endswith('modules')
|
||||
|
||||
def realfull_adapter(_name, active, section):
|
||||
"""Activate all symbols found in the global and boolean feature sections.
|
||||
|
||||
This is intended for building the documentation, including the
|
||||
documentation of settings that are activated by defining an optional
|
||||
preprocessor macro.
|
||||
|
||||
Do not activate definitions in the section containing symbols that are
|
||||
supposed to be defined and documented in their own module.
|
||||
"""
|
||||
if section == 'Module configuration options':
|
||||
return active
|
||||
return True
|
||||
|
||||
# The goal of the full configuration is to have everything that can be tested
|
||||
# together. This includes deprecated or insecure options. It excludes:
|
||||
# * Options that require additional build dependencies or unusual hardware.
|
||||
# * Options that make testing less effective.
|
||||
# * Options that are incompatible with other options, or more generally that
|
||||
# interact with other parts of the code in such a way that a bulk enabling
|
||||
# is not a good way to test them.
|
||||
# * Options that remove features.
|
||||
EXCLUDE_FROM_FULL = frozenset([
|
||||
#pylint: disable=line-too-long
|
||||
'MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH', # interacts with CTR_DRBG_128_BIT_KEY
|
||||
'MBEDTLS_AES_USE_HARDWARE_ONLY', # hardware dependency
|
||||
'MBEDTLS_BLOCK_CIPHER_NO_DECRYPT', # incompatible with ECB in PSA, CBC/XTS/NIST_KW/DES
|
||||
'MBEDTLS_CTR_DRBG_USE_128_BIT_KEY', # interacts with ENTROPY_FORCE_SHA256
|
||||
'MBEDTLS_DEPRECATED_REMOVED', # conflicts with deprecated options
|
||||
'MBEDTLS_DEPRECATED_WARNING', # conflicts with deprecated options
|
||||
'MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED', # influences the use of ECDH in TLS
|
||||
'MBEDTLS_ECP_NO_FALLBACK', # removes internal ECP implementation
|
||||
'MBEDTLS_ECP_WITH_MPI_UINT', # disables the default ECP and is experimental
|
||||
'MBEDTLS_ENTROPY_FORCE_SHA256', # interacts with CTR_DRBG_128_BIT_KEY
|
||||
'MBEDTLS_HAVE_SSE2', # hardware dependency
|
||||
'MBEDTLS_MEMORY_BACKTRACE', # depends on MEMORY_BUFFER_ALLOC_C
|
||||
'MBEDTLS_MEMORY_BUFFER_ALLOC_C', # makes sanitizers (e.g. ASan) less effective
|
||||
'MBEDTLS_MEMORY_DEBUG', # depends on MEMORY_BUFFER_ALLOC_C
|
||||
'MBEDTLS_NO_64BIT_MULTIPLICATION', # influences anything that uses bignum
|
||||
'MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES', # removes a feature
|
||||
'MBEDTLS_NO_PLATFORM_ENTROPY', # removes a feature
|
||||
'MBEDTLS_NO_UDBL_DIVISION', # influences anything that uses bignum
|
||||
'MBEDTLS_PSA_P256M_DRIVER_ENABLED', # influences SECP256R1 KeyGen/ECDH/ECDSA
|
||||
'MBEDTLS_PLATFORM_NO_STD_FUNCTIONS', # removes a feature
|
||||
'MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG', # behavior change + build dependency
|
||||
'MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER', # incompatible with USE_PSA_CRYPTO
|
||||
'MBEDTLS_PSA_CRYPTO_SPM', # platform dependency (PSA SPM)
|
||||
'MBEDTLS_PSA_INJECT_ENTROPY', # conflicts with platform entropy sources
|
||||
'MBEDTLS_RSA_NO_CRT', # influences the use of RSA in X.509 and TLS
|
||||
'MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY', # interacts with *_USE_A64_CRYPTO_IF_PRESENT
|
||||
'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY', # interacts with *_USE_ARMV8_A_CRYPTO_IF_PRESENT
|
||||
'MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY', # interacts with *_USE_A64_CRYPTO_IF_PRESENT
|
||||
'MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT', # setting *_USE_ARMV8_A_CRYPTO is sufficient
|
||||
'MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN', # build dependency (clang+memsan)
|
||||
'MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND', # build dependency (valgrind headers)
|
||||
'MBEDTLS_X509_REMOVE_INFO', # removes a feature
|
||||
])
|
||||
|
||||
def is_seamless_alt(name):
|
||||
"""Whether the xxx_ALT symbol should be included in the full configuration.
|
||||
|
||||
Include alternative implementations of platform functions, which are
|
||||
configurable function pointers that default to the built-in function.
|
||||
This way we test that the function pointers exist and build correctly
|
||||
without changing the behavior, and tests can verify that the function
|
||||
pointers are used by modifying those pointers.
|
||||
|
||||
Exclude alternative implementations of library functions since they require
|
||||
an implementation of the relevant functions and an xxx_alt.h header.
|
||||
"""
|
||||
if name in (
|
||||
'MBEDTLS_PLATFORM_GMTIME_R_ALT',
|
||||
'MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT',
|
||||
'MBEDTLS_PLATFORM_MS_TIME_ALT',
|
||||
'MBEDTLS_PLATFORM_ZEROIZE_ALT',
|
||||
):
|
||||
# Similar to non-platform xxx_ALT, requires platform_alt.h
|
||||
return False
|
||||
return name.startswith('MBEDTLS_PLATFORM_')
|
||||
|
||||
def include_in_full(name):
|
||||
"""Rules for symbols in the "full" configuration."""
|
||||
if name in EXCLUDE_FROM_FULL:
|
||||
return False
|
||||
if name.endswith('_ALT'):
|
||||
return is_seamless_alt(name)
|
||||
return True
|
||||
|
||||
def full_adapter(name, active, section):
|
||||
"""Config adapter for "full"."""
|
||||
if not is_full_section(section):
|
||||
return active
|
||||
return include_in_full(name)
|
||||
|
||||
# The baremetal configuration excludes options that require a library or
|
||||
# operating system feature that is typically not present on bare metal
|
||||
# systems. Features that are excluded from "full" won't be in "baremetal"
|
||||
# either (unless explicitly turned on in baremetal_adapter) so they don't
|
||||
# need to be repeated here.
|
||||
EXCLUDE_FROM_BAREMETAL = frozenset([
|
||||
#pylint: disable=line-too-long
|
||||
'MBEDTLS_ENTROPY_NV_SEED', # requires a filesystem and FS_IO or alternate NV seed hooks
|
||||
'MBEDTLS_FS_IO', # requires a filesystem
|
||||
'MBEDTLS_HAVE_TIME', # requires a clock
|
||||
'MBEDTLS_HAVE_TIME_DATE', # requires a clock
|
||||
'MBEDTLS_NET_C', # requires POSIX-like networking
|
||||
'MBEDTLS_PLATFORM_FPRINTF_ALT', # requires FILE* from stdio.h
|
||||
'MBEDTLS_PLATFORM_NV_SEED_ALT', # requires a filesystem and ENTROPY_NV_SEED
|
||||
'MBEDTLS_PLATFORM_TIME_ALT', # requires a clock and HAVE_TIME
|
||||
'MBEDTLS_PSA_CRYPTO_SE_C', # requires a filesystem and PSA_CRYPTO_STORAGE_C
|
||||
'MBEDTLS_PSA_CRYPTO_STORAGE_C', # requires a filesystem
|
||||
'MBEDTLS_PSA_ITS_FILE_C', # requires a filesystem
|
||||
'MBEDTLS_THREADING_C', # requires a threading interface
|
||||
'MBEDTLS_THREADING_PTHREAD', # requires pthread
|
||||
'MBEDTLS_TIMING_C', # requires a clock
|
||||
'MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT', # requires an OS for runtime-detection
|
||||
'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT', # requires an OS for runtime-detection
|
||||
'MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT', # requires an OS for runtime-detection
|
||||
])
|
||||
|
||||
def keep_in_baremetal(name):
|
||||
"""Rules for symbols in the "baremetal" configuration."""
|
||||
if name in EXCLUDE_FROM_BAREMETAL:
|
||||
return False
|
||||
return True
|
||||
|
||||
def baremetal_adapter(name, active, section):
|
||||
"""Config adapter for "baremetal"."""
|
||||
if not is_full_section(section):
|
||||
return active
|
||||
if name == 'MBEDTLS_NO_PLATFORM_ENTROPY':
|
||||
# No OS-provided entropy source
|
||||
return True
|
||||
return include_in_full(name) and keep_in_baremetal(name)
|
||||
|
||||
# This set contains options that are mostly for debugging or test purposes,
|
||||
# and therefore should be excluded when doing code size measurements.
|
||||
# Options that are their own module (such as MBEDTLS_ERROR_C) are not listed
|
||||
# and therefore will be included when doing code size measurements.
|
||||
EXCLUDE_FOR_SIZE = frozenset([
|
||||
'MBEDTLS_DEBUG_C', # large code size increase in TLS
|
||||
'MBEDTLS_SELF_TEST', # increases the size of many modules
|
||||
'MBEDTLS_TEST_HOOKS', # only useful with the hosted test framework, increases code size
|
||||
])
|
||||
|
||||
def baremetal_size_adapter(name, active, section):
|
||||
if name in EXCLUDE_FOR_SIZE:
|
||||
return False
|
||||
return baremetal_adapter(name, active, section)
|
||||
|
||||
def include_in_crypto(name):
|
||||
"""Rules for symbols in a crypto configuration."""
|
||||
if name.startswith('MBEDTLS_X509_') or \
|
||||
name.startswith('MBEDTLS_SSL_') or \
|
||||
name.startswith('MBEDTLS_KEY_EXCHANGE_'):
|
||||
return False
|
||||
if name in [
|
||||
'MBEDTLS_DEBUG_C', # part of libmbedtls
|
||||
'MBEDTLS_NET_C', # part of libmbedtls
|
||||
'MBEDTLS_PKCS7_C', # part of libmbedx509
|
||||
]:
|
||||
return False
|
||||
return True
|
||||
|
||||
def crypto_adapter(adapter):
|
||||
"""Modify an adapter to disable non-crypto symbols.
|
||||
|
||||
``crypto_adapter(adapter)(name, active, section)`` is like
|
||||
``adapter(name, active, section)``, but unsets all X.509 and TLS symbols.
|
||||
"""
|
||||
def continuation(name, active, section):
|
||||
if not include_in_crypto(name):
|
||||
return False
|
||||
if adapter is None:
|
||||
return active
|
||||
return adapter(name, active, section)
|
||||
return continuation
|
||||
|
||||
DEPRECATED = frozenset([
|
||||
'MBEDTLS_PSA_CRYPTO_SE_C',
|
||||
])
|
||||
def no_deprecated_adapter(adapter):
|
||||
"""Modify an adapter to disable deprecated symbols.
|
||||
|
||||
``no_deprecated_adapter(adapter)(name, active, section)`` is like
|
||||
``adapter(name, active, section)``, but unsets all deprecated symbols
|
||||
and sets ``MBEDTLS_DEPRECATED_REMOVED``.
|
||||
"""
|
||||
def continuation(name, active, section):
|
||||
if name == 'MBEDTLS_DEPRECATED_REMOVED':
|
||||
return True
|
||||
if name in DEPRECATED:
|
||||
return False
|
||||
if adapter is None:
|
||||
return active
|
||||
return adapter(name, active, section)
|
||||
return continuation
|
||||
|
||||
def no_platform_adapter(adapter):
|
||||
"""Modify an adapter to disable platform symbols.
|
||||
|
||||
``no_platform_adapter(adapter)(name, active, section)`` is like
|
||||
``adapter(name, active, section)``, but unsets all platform symbols other
|
||||
``than MBEDTLS_PLATFORM_C.
|
||||
"""
|
||||
def continuation(name, active, section):
|
||||
# Allow MBEDTLS_PLATFORM_C but remove all other platform symbols.
|
||||
if name.startswith('MBEDTLS_PLATFORM_') and name != 'MBEDTLS_PLATFORM_C':
|
||||
return False
|
||||
if adapter is None:
|
||||
return active
|
||||
return adapter(name, active, section)
|
||||
return continuation
|
||||
|
||||
class ConfigFile(Config):
|
||||
"""Representation of the Mbed TLS configuration read for a file.
|
||||
|
||||
See the documentation of the `Config` class for methods to query
|
||||
and modify the configuration.
|
||||
"""
|
||||
|
||||
_path_in_tree = 'include/mbedtls/mbedtls_config.h'
|
||||
default_path = [_path_in_tree,
|
||||
os.path.join(os.path.dirname(__file__),
|
||||
os.pardir,
|
||||
_path_in_tree),
|
||||
os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))),
|
||||
_path_in_tree)]
|
||||
|
||||
def __init__(self, filename=None):
|
||||
"""Read the Mbed TLS configuration file."""
|
||||
if filename is None:
|
||||
for candidate in self.default_path:
|
||||
if os.path.lexists(candidate):
|
||||
filename = candidate
|
||||
break
|
||||
else:
|
||||
raise Exception('Mbed TLS configuration file not found',
|
||||
self.default_path)
|
||||
super().__init__()
|
||||
self.filename = filename
|
||||
self.current_section = 'header'
|
||||
with open(filename, 'r', encoding='utf-8') as file:
|
||||
self.templates = [self._parse_line(line) for line in file]
|
||||
self.current_section = None
|
||||
|
||||
def set(self, name, value=None):
|
||||
if name not in self.settings:
|
||||
self.templates.append((name, '', '#define ' + name + ' '))
|
||||
super().set(name, value)
|
||||
|
||||
_define_line_regexp = (r'(?P<indentation>\s*)' +
|
||||
r'(?P<commented_out>(//\s*)?)' +
|
||||
r'(?P<define>#\s*define\s+)' +
|
||||
r'(?P<name>\w+)' +
|
||||
r'(?P<arguments>(?:\((?:\w|\s|,)*\))?)' +
|
||||
r'(?P<separator>\s*)' +
|
||||
r'(?P<value>.*)')
|
||||
_section_line_regexp = (r'\s*/?\*+\s*[\\@]name\s+SECTION:\s*' +
|
||||
r'(?P<section>.*)[ */]*')
|
||||
_config_line_regexp = re.compile(r'|'.join([_define_line_regexp,
|
||||
_section_line_regexp]))
|
||||
def _parse_line(self, line):
|
||||
"""Parse a line in mbedtls_config.h and return the corresponding template."""
|
||||
line = line.rstrip('\r\n')
|
||||
m = re.match(self._config_line_regexp, line)
|
||||
if m is None:
|
||||
return line
|
||||
elif m.group('section'):
|
||||
self.current_section = m.group('section')
|
||||
return line
|
||||
else:
|
||||
active = not m.group('commented_out')
|
||||
name = m.group('name')
|
||||
value = m.group('value')
|
||||
template = (name,
|
||||
m.group('indentation'),
|
||||
m.group('define') + name +
|
||||
m.group('arguments') + m.group('separator'))
|
||||
self.settings[name] = Setting(active, name, value,
|
||||
self.current_section)
|
||||
return template
|
||||
|
||||
def _format_template(self, name, indent, middle):
|
||||
"""Build a line for mbedtls_config.h for the given setting.
|
||||
|
||||
The line has the form "<indent>#define <name> <value>"
|
||||
where <middle> is "#define <name> ".
|
||||
"""
|
||||
setting = self.settings[name]
|
||||
value = setting.value
|
||||
if value is None:
|
||||
value = ''
|
||||
# Normally the whitespace to separate the symbol name from the
|
||||
# value is part of middle, and there's no whitespace for a symbol
|
||||
# with no value. But if a symbol has been changed from having a
|
||||
# value to not having one, the whitespace is wrong, so fix it.
|
||||
if value:
|
||||
if middle[-1] not in '\t ':
|
||||
middle += ' '
|
||||
else:
|
||||
middle = middle.rstrip()
|
||||
return ''.join([indent,
|
||||
'' if setting.active else '//',
|
||||
middle,
|
||||
value]).rstrip()
|
||||
|
||||
def write_to_stream(self, output):
|
||||
"""Write the whole configuration to output."""
|
||||
for template in self.templates:
|
||||
if isinstance(template, str):
|
||||
line = template
|
||||
else:
|
||||
line = self._format_template(*template)
|
||||
output.write(line + '\n')
|
||||
|
||||
def write(self, filename=None):
|
||||
"""Write the whole configuration to the file it was read from.
|
||||
|
||||
If filename is specified, write to this file instead.
|
||||
"""
|
||||
if filename is None:
|
||||
filename = self.filename
|
||||
with open(filename, 'w', encoding='utf-8') as output:
|
||||
self.write_to_stream(output)
|
||||
|
||||
if __name__ == '__main__':
|
||||
def main():
|
||||
"""Command line mbedtls_config.h manipulation tool."""
|
||||
parser = argparse.ArgumentParser(description="""
|
||||
Mbed TLS configuration file manipulation tool.
|
||||
""")
|
||||
parser.add_argument('--file', '-f',
|
||||
help="""File to read (and modify if requested).
|
||||
Default: {}.
|
||||
""".format(ConfigFile.default_path))
|
||||
parser.add_argument('--force', '-o',
|
||||
action='store_true',
|
||||
help="""For the set command, if SYMBOL is not
|
||||
present, add a definition for it.""")
|
||||
parser.add_argument('--write', '-w', metavar='FILE',
|
||||
help="""File to write to instead of the input file.""")
|
||||
subparsers = parser.add_subparsers(dest='command',
|
||||
title='Commands')
|
||||
parser_get = subparsers.add_parser('get',
|
||||
help="""Find the value of SYMBOL
|
||||
and print it. Exit with
|
||||
status 0 if a #define for SYMBOL is
|
||||
found, 1 otherwise.
|
||||
""")
|
||||
parser_get.add_argument('symbol', metavar='SYMBOL')
|
||||
parser_set = subparsers.add_parser('set',
|
||||
help="""Set SYMBOL to VALUE.
|
||||
If VALUE is omitted, just uncomment
|
||||
the #define for SYMBOL.
|
||||
Error out of a line defining
|
||||
SYMBOL (commented or not) is not
|
||||
found, unless --force is passed.
|
||||
""")
|
||||
parser_set.add_argument('symbol', metavar='SYMBOL')
|
||||
parser_set.add_argument('value', metavar='VALUE', nargs='?',
|
||||
default='')
|
||||
parser_set_all = subparsers.add_parser('set-all',
|
||||
help="""Uncomment all #define
|
||||
whose name contains a match for
|
||||
REGEX.""")
|
||||
parser_set_all.add_argument('regexs', metavar='REGEX', nargs='*')
|
||||
parser_unset = subparsers.add_parser('unset',
|
||||
help="""Comment out the #define
|
||||
for SYMBOL. Do nothing if none
|
||||
is present.""")
|
||||
parser_unset.add_argument('symbol', metavar='SYMBOL')
|
||||
parser_unset_all = subparsers.add_parser('unset-all',
|
||||
help="""Comment out all #define
|
||||
whose name contains a match for
|
||||
REGEX.""")
|
||||
parser_unset_all.add_argument('regexs', metavar='REGEX', nargs='*')
|
||||
|
||||
def add_adapter(name, function, description):
|
||||
subparser = subparsers.add_parser(name, help=description)
|
||||
subparser.set_defaults(adapter=function)
|
||||
add_adapter('baremetal', baremetal_adapter,
|
||||
"""Like full, but exclude features that require platform
|
||||
features such as file input-output.""")
|
||||
add_adapter('baremetal_size', baremetal_size_adapter,
|
||||
"""Like baremetal, but exclude debugging features.
|
||||
Useful for code size measurements.""")
|
||||
add_adapter('full', full_adapter,
|
||||
"""Uncomment most features.
|
||||
Exclude alternative implementations and platform support
|
||||
options, as well as some options that are awkward to test.
|
||||
""")
|
||||
add_adapter('full_no_deprecated', no_deprecated_adapter(full_adapter),
|
||||
"""Uncomment most non-deprecated features.
|
||||
Like "full", but without deprecated features.
|
||||
""")
|
||||
add_adapter('full_no_platform', no_platform_adapter(full_adapter),
|
||||
"""Uncomment most non-platform features.
|
||||
Like "full", but without platform features.
|
||||
""")
|
||||
add_adapter('realfull', realfull_adapter,
|
||||
"""Uncomment all boolean #defines.
|
||||
Suitable for generating documentation, but not for building.""")
|
||||
add_adapter('crypto', crypto_adapter(None),
|
||||
"""Only include crypto features. Exclude X.509 and TLS.""")
|
||||
add_adapter('crypto_baremetal', crypto_adapter(baremetal_adapter),
|
||||
"""Like baremetal, but with only crypto features,
|
||||
excluding X.509 and TLS.""")
|
||||
add_adapter('crypto_full', crypto_adapter(full_adapter),
|
||||
"""Like full, but with only crypto features,
|
||||
excluding X.509 and TLS.""")
|
||||
|
||||
args = parser.parse_args()
|
||||
config = ConfigFile(args.file)
|
||||
if args.command is None:
|
||||
parser.print_help()
|
||||
return 1
|
||||
elif args.command == 'get':
|
||||
if args.symbol in config:
|
||||
value = config[args.symbol]
|
||||
if value:
|
||||
sys.stdout.write(value + '\n')
|
||||
return 0 if args.symbol in config else 1
|
||||
elif args.command == 'set':
|
||||
if not args.force and args.symbol not in config.settings:
|
||||
sys.stderr.write("A #define for the symbol {} "
|
||||
"was not found in {}\n"
|
||||
.format(args.symbol, config.filename))
|
||||
return 1
|
||||
config.set(args.symbol, value=args.value)
|
||||
elif args.command == 'set-all':
|
||||
config.change_matching(args.regexs, True)
|
||||
elif args.command == 'unset':
|
||||
config.unset(args.symbol)
|
||||
elif args.command == 'unset-all':
|
||||
config.change_matching(args.regexs, False)
|
||||
else:
|
||||
config.adapt(args.adapter)
|
||||
config.write(args.write)
|
||||
return 0
|
||||
|
||||
# Import modules only used by main only if main is defined and called.
|
||||
# pylint: disable=wrong-import-position
|
||||
import argparse
|
||||
import sys
|
||||
sys.exit(main())
|
||||
@@ -1,71 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"_comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z_a-z][0-9A-Z_a-z]*$"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"const": ["opaque"]
|
||||
},
|
||||
"location": {
|
||||
"type": ["integer","string"],
|
||||
"pattern": "^(0x|0X)?[a-fA-F0-9]+$"
|
||||
},
|
||||
"mbedtls/h_condition": {
|
||||
"type": "string"
|
||||
},
|
||||
"headers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"capabilities": {
|
||||
"type": "array",
|
||||
"items": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"_comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"mbedtls/c_condition": {
|
||||
"type": "string"
|
||||
},
|
||||
"entry_points": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"names": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[A-Z_a-z][0-9A-Z_a-z]*$": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z_a-z][0-9A-Z_a-z]*$"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"entry_points"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"prefix",
|
||||
"type",
|
||||
"location",
|
||||
"capabilities"
|
||||
]
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"_comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z_a-z][0-9A-Z_a-z]*$"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"const": ["transparent"]
|
||||
},
|
||||
"mbedtls/h_condition": {
|
||||
"type": "string"
|
||||
},
|
||||
"headers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"capabilities": {
|
||||
"type": "array",
|
||||
"items": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"_comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"mbedtls/c_condition": {
|
||||
"type": "string"
|
||||
},
|
||||
"entry_points": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"names": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[A-Z_a-z][0-9A-Z_a-z]*$": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z_a-z][0-9A-Z_a-z]*$"
|
||||
}
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"type": "boolean",
|
||||
"default": "false"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"entry_points"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"prefix",
|
||||
"type",
|
||||
"capabilities"
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
["mbedtls_test_opaque_driver.json","mbedtls_test_transparent_driver.json","p256_transparent_driver.json"]
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"prefix": "mbedtls_test",
|
||||
"type": "opaque",
|
||||
"location": "0x7fffff",
|
||||
"mbedtls/h_condition": "defined(PSA_CRYPTO_DRIVER_TEST)",
|
||||
"headers": ["test/drivers/test_driver.h"],
|
||||
"capabilities": [
|
||||
{
|
||||
"_comment": "The Mbed TLS opaque driver supports import key/export key/export_public key",
|
||||
"mbedtls/c_condition": "defined(PSA_CRYPTO_DRIVER_TEST)",
|
||||
"entry_points": ["import_key", "export_key", "export_public_key"]
|
||||
},
|
||||
{
|
||||
"_comment": "The Mbed TLS opaque driver supports copy key/ get builtin key",
|
||||
"mbedtls/c_condition": "defined(PSA_CRYPTO_DRIVER_TEST)",
|
||||
"entry_points": ["copy_key", "get_builtin_key"],
|
||||
"names": {"copy_key":"mbedtls_test_opaque_copy_key", "get_builtin_key":"mbedtls_test_opaque_get_builtin_key"}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"prefix": "mbedtls_test",
|
||||
"type": "transparent",
|
||||
"mbedtls/h_condition": "defined(PSA_CRYPTO_DRIVER_TEST)",
|
||||
"headers": ["test/drivers/test_driver.h"],
|
||||
"capabilities": [
|
||||
{
|
||||
"_comment": "The Mbed TLS transparent driver supports import key/export key",
|
||||
"mbedtls/c_condition": "defined(PSA_CRYPTO_DRIVER_TEST)",
|
||||
"entry_points": ["import_key"],
|
||||
"fallback": true
|
||||
},
|
||||
{
|
||||
"_comment": "The Mbed TLS transparent driver supports export_public key",
|
||||
"mbedtls/c_condition": "defined(PSA_CRYPTO_DRIVER_TEST)",
|
||||
"entry_points": ["export_public_key"],
|
||||
"fallback": true,
|
||||
"names": {"export_public_key":"mbedtls_test_transparent_export_public_key"}
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"prefix": "p256",
|
||||
"type": "transparent",
|
||||
"mbedtls/h_condition": "defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)",
|
||||
"headers": ["../3rdparty/p256-m/p256-m_driver_entrypoints.h"],
|
||||
"capabilities": [
|
||||
{
|
||||
"mbedtls/c_condition": "defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)",
|
||||
"_comment_entry_points": "This is not the complete list of entry points supported by this driver, only those that are currently supported in JSON. See docs/psa-driver-example-and-guide.md",
|
||||
"entry_points": ["import_key", "export_public_key"],
|
||||
"algorithms": ["PSA_ALG_ECDH", "PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)"],
|
||||
"key_types": [
|
||||
"PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)",
|
||||
"PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)"
|
||||
],
|
||||
"key_sizes": [256],
|
||||
"fallback": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
{# One Shot function's dispatch code for opaque drivers.
|
||||
Expected inputs:
|
||||
* drivers: the list of driver descriptions.
|
||||
* entry_point: the name of the entry point that this function dispatches to.
|
||||
* entry_point_param(driver): the parameters to pass to the entry point.
|
||||
* nest_indent: number of extra spaces to indent the code to.
|
||||
-#}
|
||||
{% for driver in drivers if driver.type == "opaque" -%}
|
||||
{% for capability in driver.capabilities if entry_point in capability.entry_points -%}
|
||||
#if ({% if capability['mbedtls/c_condition'] is defined -%}{{ capability['mbedtls/c_condition'] }} {% else -%} {{ 1 }} {% endif %})
|
||||
{%- filter indent(width = nest_indent) %}
|
||||
case {{ driver.location }}:
|
||||
return( {{ entry_point_name(capability, entry_point, driver) }}({{entry_point_param(driver) | indent(20)}}));
|
||||
{% endfilter -%}
|
||||
#endif
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
@@ -1,19 +0,0 @@
|
||||
{# One Shot function's dispatch code for transparent drivers.
|
||||
Expected inputs:
|
||||
* drivers: the list of driver descriptions.
|
||||
* entry_point: the name of the entry point that this function dispatches to.
|
||||
* entry_point_param(driver): the parameters to pass to the entry point.
|
||||
* nest_indent: number of extra spaces to indent the code to.
|
||||
-#}
|
||||
{% for driver in drivers if driver.type == "transparent" -%}
|
||||
{% for capability in driver.capabilities if entry_point in capability.entry_points -%}
|
||||
#if ({% if capability['mbedtls/c_condition'] is defined -%}{{ capability['mbedtls/c_condition'] }} {% else -%} {{ 1 }} {% endif %})
|
||||
{%- filter indent(width = nest_indent) %}
|
||||
status = {{ entry_point_name(capability, entry_point, driver) }}({{entry_point_param(driver) | indent(20)}});
|
||||
|
||||
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||
return( status );
|
||||
{% endfilter -%}
|
||||
#endif
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,224 +0,0 @@
|
||||
/*
|
||||
* Functions to delegate cryptographic operations to an available
|
||||
* and appropriate accelerator.
|
||||
* Warning: This file is now auto-generated.
|
||||
*/
|
||||
/* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
|
||||
/* BEGIN-common headers */
|
||||
#include "common.h"
|
||||
#include "psa_crypto_aead.h"
|
||||
#include "psa_crypto_cipher.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_driver_wrappers_no_static.h"
|
||||
#include "psa_crypto_hash.h"
|
||||
#include "psa_crypto_mac.h"
|
||||
#include "psa_crypto_pake.h"
|
||||
#include "psa_crypto_rsa.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
/* END-common headers */
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
/* BEGIN-driver headers */
|
||||
{% for driver in drivers -%}
|
||||
/* Headers for {{driver.prefix}} {{driver.type}} driver */
|
||||
{% if driver['mbedtls/h_condition'] is defined -%}
|
||||
#if {{ driver['mbedtls/h_condition'] }}
|
||||
{% endif -%}
|
||||
{% for header in driver.headers -%}
|
||||
#include "{{ header }}"
|
||||
{% endfor %}
|
||||
{% if driver['mbedtls/h_condition'] is defined -%}
|
||||
#endif
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
/* END-driver headers */
|
||||
|
||||
/* Auto-generated values depending on which drivers are registered.
|
||||
* ID 0 is reserved for unallocated operations.
|
||||
* ID 1 is reserved for the Mbed TLS software driver. */
|
||||
/* BEGIN-driver id definition */
|
||||
#define PSA_CRYPTO_MBED_TLS_DRIVER_ID (1)
|
||||
{% for driver in drivers -%}
|
||||
#define {{(driver.prefix + "_" + driver.type + "_driver_id").upper()}} ({{ loop.index + 1 }})
|
||||
{% endfor %}
|
||||
/* END-driver id */
|
||||
|
||||
/* BEGIN-Common Macro definitions */
|
||||
{% macro entry_point_name(capability, entry_point, driver) -%}
|
||||
{% if capability.name is defined and entry_point in capability.names.keys() -%}
|
||||
{{ capability.names[entry_point]}}
|
||||
{% else -%}
|
||||
{{driver.prefix}}_{{driver.type}}_{{entry_point}}
|
||||
{% endif -%}
|
||||
{% endmacro %}
|
||||
/* END-Common Macro definitions */
|
||||
|
||||
/* Support the 'old' SE interface when asked to */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/* PSA_CRYPTO_DRIVER_PRESENT is defined when either a new-style or old-style
|
||||
* SE driver is present, to avoid unused argument errors at compile time. */
|
||||
#ifndef PSA_CRYPTO_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_DRIVER_PRESENT
|
||||
#endif
|
||||
#include "psa_crypto_se.h"
|
||||
#endif
|
||||
|
||||
/** Get the key buffer size required to store the key material of a key
|
||||
* associated with an opaque driver.
|
||||
*
|
||||
* \param[in] attributes The key attributes.
|
||||
* \param[out] key_buffer_size Minimum buffer size to contain the key material
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The minimum size for a buffer to contain the key material has been
|
||||
* returned successfully.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The type and/or the size in bits of the key or the combination of
|
||||
* the two is not supported.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The key is declared with a lifetime not known to us.
|
||||
*/
|
||||
psa_status_t psa_driver_wrapper_get_key_buffer_size(
|
||||
const psa_key_attributes_t *attributes,
|
||||
size_t *key_buffer_size )
|
||||
{
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
|
||||
psa_key_type_t key_type = attributes->core.type;
|
||||
size_t key_bits = attributes->core.bits;
|
||||
|
||||
*key_buffer_size = 0;
|
||||
switch( location )
|
||||
{
|
||||
#if defined(PSA_CRYPTO_DRIVER_TEST)
|
||||
case PSA_CRYPTO_TEST_DRIVER_LOCATION:
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
|
||||
/* Emulate property 'builtin_key_size' */
|
||||
if( psa_key_id_is_builtin(
|
||||
MBEDTLS_SVC_KEY_ID_GET_KEY_ID(
|
||||
psa_get_key_id( attributes ) ) ) )
|
||||
{
|
||||
*key_buffer_size = sizeof( psa_drv_slot_number_t );
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
|
||||
*key_buffer_size = mbedtls_test_opaque_size_function( key_type,
|
||||
key_bits );
|
||||
return( ( *key_buffer_size != 0 ) ?
|
||||
PSA_SUCCESS : PSA_ERROR_NOT_SUPPORTED );
|
||||
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||
|
||||
default:
|
||||
(void)key_type;
|
||||
(void)key_bits;
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t psa_driver_wrapper_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
uint8_t *data, size_t data_size, size_t *data_length )
|
||||
|
||||
{
|
||||
{% with entry_point = "export_public_key" -%}
|
||||
{% macro entry_point_param(driver) -%}
|
||||
attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length
|
||||
{% endmacro %}
|
||||
psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(
|
||||
psa_get_key_lifetime( attributes ) );
|
||||
|
||||
/* Try dynamically-registered SE interface first */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
const psa_drv_se_t *drv;
|
||||
psa_drv_se_context_t *drv_context;
|
||||
|
||||
if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
|
||||
{
|
||||
if( ( drv->key_management == NULL ) ||
|
||||
( drv->key_management->p_export_public == NULL ) )
|
||||
{
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
return( drv->key_management->p_export_public(
|
||||
drv_context,
|
||||
*( (psa_key_slot_number_t *)key_buffer ),
|
||||
data, data_size, data_length ) );
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
|
||||
switch( location )
|
||||
{
|
||||
case PSA_KEY_LOCATION_LOCAL_STORAGE:
|
||||
/* Key is stored in the slot in export representation, so
|
||||
* cycle through all known transparent accelerators */
|
||||
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
{% with nest_indent=12 %}
|
||||
{% include "OS-template-transparent.jinja" -%}
|
||||
{% endwith -%}
|
||||
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
|
||||
/* Fell through, meaning no accelerator supports this operation */
|
||||
return( psa_export_public_key_internal( attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length ) );
|
||||
|
||||
/* Add cases for opaque driver here */
|
||||
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
{% with nest_indent=8 %}
|
||||
{% include "OS-template-opaque.jinja" -%}
|
||||
{% endwith -%}
|
||||
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
|
||||
default:
|
||||
/* Key is declared with a lifetime not known to us */
|
||||
return( status );
|
||||
}
|
||||
{% endwith %}
|
||||
}
|
||||
|
||||
psa_status_t psa_driver_wrapper_get_builtin_key(
|
||||
psa_drv_slot_number_t slot_number,
|
||||
psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
|
||||
{
|
||||
{% with entry_point = "get_builtin_key" -%}
|
||||
{% macro entry_point_param(driver) -%}
|
||||
slot_number,
|
||||
attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
key_buffer_length
|
||||
{% endmacro %}
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
|
||||
switch( location )
|
||||
{
|
||||
#if defined(PSA_CRYPTO_DRIVER_TEST)
|
||||
{% with nest_indent=8 %}
|
||||
{% include "OS-template-opaque.jinja" -%}
|
||||
{% endwith -%}
|
||||
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||
default:
|
||||
(void) slot_number;
|
||||
(void) key_buffer;
|
||||
(void) key_buffer_size;
|
||||
(void) key_buffer_length;
|
||||
return( PSA_ERROR_DOES_NOT_EXIST );
|
||||
}
|
||||
{% endwith %}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
176
externals/mbedtls/scripts/data_files/error.fmt
vendored
176
externals/mbedtls/scripts/data_files/error.fmt
vendored
@@ -3,157 +3,143 @@
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*
|
||||
* This file is provided under the Apache License 2.0, or the
|
||||
* GNU General Public License v2.0 or later.
|
||||
*
|
||||
* **********
|
||||
* Apache License 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.
|
||||
*
|
||||
* **********
|
||||
*
|
||||
* **********
|
||||
* GNU General Public License v2.0 or later:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* **********
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "mbedtls/error.h"
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
|
||||
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#if defined(MBEDTLS_ERROR_C)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#define mbedtls_snprintf snprintf
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
HEADER_INCLUDED
|
||||
|
||||
const char *mbedtls_high_level_strerr(int error_code)
|
||||
{
|
||||
int high_level_error_code;
|
||||
|
||||
if (error_code < 0) {
|
||||
error_code = -error_code;
|
||||
}
|
||||
|
||||
/* Extract the high-level part from the error code. */
|
||||
high_level_error_code = error_code & 0xFF80;
|
||||
|
||||
switch (high_level_error_code) {
|
||||
/* Begin Auto-Generated Code. */
|
||||
HIGH_LEVEL_CODE_CHECKS
|
||||
/* End Auto-Generated Code. */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *mbedtls_low_level_strerr(int error_code)
|
||||
{
|
||||
int low_level_error_code;
|
||||
|
||||
if (error_code < 0) {
|
||||
error_code = -error_code;
|
||||
}
|
||||
|
||||
/* Extract the low-level part from the error code. */
|
||||
low_level_error_code = error_code & ~0xFF80;
|
||||
|
||||
switch (low_level_error_code) {
|
||||
/* Begin Auto-Generated Code. */
|
||||
LOW_LEVEL_CODE_CHECKS
|
||||
/* End Auto-Generated Code. */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mbedtls_strerror(int ret, char *buf, size_t buflen)
|
||||
void mbedtls_strerror( int ret, char *buf, size_t buflen )
|
||||
{
|
||||
size_t len;
|
||||
int use_ret;
|
||||
const char *high_level_error_description = NULL;
|
||||
const char *low_level_error_description = NULL;
|
||||
|
||||
if (buflen == 0) {
|
||||
if( buflen == 0 )
|
||||
return;
|
||||
}
|
||||
|
||||
memset(buf, 0x00, buflen);
|
||||
memset( buf, 0x00, buflen );
|
||||
|
||||
if (ret < 0) {
|
||||
if( ret < 0 )
|
||||
ret = -ret;
|
||||
}
|
||||
|
||||
if (ret & 0xFF80) {
|
||||
if( ret & 0xFF80 )
|
||||
{
|
||||
use_ret = ret & 0xFF80;
|
||||
|
||||
// Translate high level error code.
|
||||
high_level_error_description = mbedtls_high_level_strerr(ret);
|
||||
// High level error codes
|
||||
//
|
||||
// BEGIN generated code
|
||||
HIGH_LEVEL_CODE_CHECKS
|
||||
// END generated code
|
||||
|
||||
if (high_level_error_description == NULL) {
|
||||
mbedtls_snprintf(buf, buflen, "UNKNOWN ERROR CODE (%04X)", (unsigned int) use_ret);
|
||||
} else {
|
||||
mbedtls_snprintf(buf, buflen, "%s", high_level_error_description);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C)
|
||||
// Early return in case of a fatal error - do not try to translate low
|
||||
// level code.
|
||||
if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) {
|
||||
return;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_TLS_C */
|
||||
if( strlen( buf ) == 0 )
|
||||
mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
|
||||
}
|
||||
|
||||
use_ret = ret & ~0xFF80;
|
||||
|
||||
if (use_ret == 0) {
|
||||
if( use_ret == 0 )
|
||||
return;
|
||||
}
|
||||
|
||||
// If high level code is present, make a concatenation between both
|
||||
// error strings.
|
||||
//
|
||||
len = strlen(buf);
|
||||
len = strlen( buf );
|
||||
|
||||
if (len > 0) {
|
||||
if (buflen - len < 5) {
|
||||
if( len > 0 )
|
||||
{
|
||||
if( buflen - len < 5 )
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_snprintf(buf + len, buflen - len, " : ");
|
||||
mbedtls_snprintf( buf + len, buflen - len, " : " );
|
||||
|
||||
buf += len + 3;
|
||||
buflen -= len + 3;
|
||||
}
|
||||
|
||||
// Translate low level error code.
|
||||
low_level_error_description = mbedtls_low_level_strerr(ret);
|
||||
// Low level error codes
|
||||
//
|
||||
// BEGIN generated code
|
||||
LOW_LEVEL_CODE_CHECKS
|
||||
// END generated code
|
||||
|
||||
if (low_level_error_description == NULL) {
|
||||
mbedtls_snprintf(buf, buflen, "UNKNOWN ERROR CODE (%04X)", (unsigned int) use_ret);
|
||||
} else {
|
||||
mbedtls_snprintf(buf, buflen, "%s", low_level_error_description);
|
||||
}
|
||||
if( strlen( buf ) != 0 )
|
||||
return;
|
||||
|
||||
mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
|
||||
}
|
||||
|
||||
#else /* MBEDTLS_ERROR_C */
|
||||
|
||||
/*
|
||||
* Provide a dummy implementation when MBEDTLS_ERROR_C is not defined
|
||||
* Provide an non-function in case MBEDTLS_ERROR_C is not defined
|
||||
*/
|
||||
void mbedtls_strerror(int ret, char *buf, size_t buflen)
|
||||
void mbedtls_strerror( int ret, char *buf, size_t buflen )
|
||||
{
|
||||
((void) ret);
|
||||
|
||||
if (buflen > 0) {
|
||||
if( buflen > 0 )
|
||||
buf[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_ERROR_C */
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
void (*mbedtls_test_hook_error_add)(int, int, const char *, int);
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */
|
||||
|
||||
@@ -1,32 +1,78 @@
|
||||
/*
|
||||
* Query Mbed TLS compile time configurations from mbedtls_config.h
|
||||
* Query Mbed TLS compile time configurations from config.h
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*
|
||||
* This file is provided under the Apache License 2.0, or the
|
||||
* GNU General Public License v2.0 or later.
|
||||
*
|
||||
* **********
|
||||
* Apache License 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.
|
||||
*
|
||||
* **********
|
||||
*
|
||||
* **********
|
||||
* GNU General Public License v2.0 or later:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* **********
|
||||
*/
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "query_config.h"
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
|
||||
/*
|
||||
* Include all the headers with public APIs in case they define a macro to its
|
||||
* default value when that configuration is not set in mbedtls_config.h, or
|
||||
* for PSA_WANT macros, in case they're auto-defined based on mbedtls_config.h
|
||||
* rather than defined directly in crypto_config.h.
|
||||
* default value when that configuration is not set in the config.h.
|
||||
*/
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/aesni.h"
|
||||
#include "mbedtls/arc4.h"
|
||||
#include "mbedtls/aria.h"
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "mbedtls/asn1write.h"
|
||||
#include "mbedtls/base64.h"
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "mbedtls/blowfish.h"
|
||||
#include "mbedtls/camellia.h"
|
||||
#include "mbedtls/ccm.h"
|
||||
#include "mbedtls/certs.h"
|
||||
#include "mbedtls/chacha20.h"
|
||||
#include "mbedtls/chachapoly.h"
|
||||
#include "mbedtls/cipher.h"
|
||||
@@ -40,23 +86,27 @@
|
||||
#include "mbedtls/ecjpake.h"
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/entropy_poll.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "mbedtls/havege.h"
|
||||
#include "mbedtls/hkdf.h"
|
||||
#include "mbedtls/hmac_drbg.h"
|
||||
#include "mbedtls/md.h"
|
||||
#include "mbedtls/md2.h"
|
||||
#include "mbedtls/md4.h"
|
||||
#include "mbedtls/md5.h"
|
||||
#include "mbedtls/memory_buffer_alloc.h"
|
||||
#include "mbedtls/net_sockets.h"
|
||||
#include "mbedtls/nist_kw.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/padlock.h"
|
||||
#include "mbedtls/pem.h"
|
||||
#include "mbedtls/pk.h"
|
||||
#include "mbedtls/pkcs11.h"
|
||||
#include "mbedtls/pkcs12.h"
|
||||
#include "mbedtls/pkcs5.h"
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#include "mbedtls/platform_time.h"
|
||||
#endif
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/poly1305.h"
|
||||
#include "mbedtls/ripemd160.h"
|
||||
@@ -68,6 +118,7 @@
|
||||
#include "mbedtls/ssl_cache.h"
|
||||
#include "mbedtls/ssl_ciphersuites.h"
|
||||
#include "mbedtls/ssl_cookie.h"
|
||||
#include "mbedtls/ssl_internal.h"
|
||||
#include "mbedtls/ssl_ticket.h"
|
||||
#include "mbedtls/threading.h"
|
||||
#include "mbedtls/timing.h"
|
||||
@@ -76,6 +127,7 @@
|
||||
#include "mbedtls/x509_crl.h"
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#include "mbedtls/x509_csr.h"
|
||||
#include "mbedtls/xtea.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -86,12 +138,7 @@
|
||||
*/
|
||||
#define MACRO_EXPANSION_TO_STR(macro) MACRO_NAME_TO_STR(macro)
|
||||
#define MACRO_NAME_TO_STR(macro) \
|
||||
mbedtls_printf("%s", strlen( #macro "") > 0 ? #macro "\n" : "")
|
||||
|
||||
#define STRINGIFY(macro) #macro
|
||||
#define OUTPUT_MACRO_NAME_VALUE(macro) mbedtls_printf( #macro "%s\n", \
|
||||
(STRINGIFY(macro) "")[0] != 0 ? "=" STRINGIFY( \
|
||||
macro) : "")
|
||||
mbedtls_printf( "%s", strlen( #macro "" ) > 0 ? #macro "\n" : "" )
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
/*
|
||||
@@ -106,16 +153,12 @@
|
||||
#pragma warning(disable:4003)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
int query_config(const char *config)
|
||||
int query_config( const char *config )
|
||||
{
|
||||
CHECK_CONFIG /* If the symbol is not found, return an error */
|
||||
return 1;
|
||||
CHECK_CONFIG /* If the symbol is not found, return an error */
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
void list_config(void)
|
||||
{
|
||||
LIST_CONFIG
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
2174
externals/mbedtls/scripts/data_files/rename-1.3-2.0.txt
vendored
Normal file
2174
externals/mbedtls/scripts/data_files/rename-1.3-2.0.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,9 +3,52 @@
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*
|
||||
* This file is provided under the Apache License 2.0, or the
|
||||
* GNU General Public License v2.0 or later.
|
||||
*
|
||||
* **********
|
||||
* Apache License 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.
|
||||
*
|
||||
* **********
|
||||
*
|
||||
* **********
|
||||
* GNU General Public License v2.0 or later:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* **********
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_VERSION_C)
|
||||
|
||||
@@ -13,38 +56,30 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static const char * const features[] = {
|
||||
static const char *features[] = {
|
||||
#if defined(MBEDTLS_VERSION_FEATURES)
|
||||
FEATURE_DEFINES
|
||||
FEATURE_DEFINES
|
||||
#endif /* MBEDTLS_VERSION_FEATURES */
|
||||
NULL
|
||||
};
|
||||
|
||||
int mbedtls_version_check_feature(const char *feature)
|
||||
int mbedtls_version_check_feature( const char *feature )
|
||||
{
|
||||
const char * const *idx = features;
|
||||
const char **idx = features;
|
||||
|
||||
if (*idx == NULL) {
|
||||
return -2;
|
||||
}
|
||||
if( *idx == NULL )
|
||||
return( -2 );
|
||||
|
||||
if (feature == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if( feature == NULL )
|
||||
return( -1 );
|
||||
|
||||
if (strncmp(feature, "MBEDTLS_", 8)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
feature += 8;
|
||||
|
||||
while (*idx != NULL) {
|
||||
if (!strcmp(*idx, feature)) {
|
||||
return 0;
|
||||
}
|
||||
while( *idx != NULL )
|
||||
{
|
||||
if( !strcmp( *idx, feature ) )
|
||||
return( 0 );
|
||||
idx++;
|
||||
}
|
||||
return -1;
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_VERSION_C */
|
||||
|
||||
@@ -89,17 +89,18 @@
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>
|
||||
INCLUDE_DIRECTORIES
|
||||
</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ShowProgress>NotSet</ShowProgress>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
@@ -108,17 +109,18 @@ INCLUDE_DIRECTORIES
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>
|
||||
INCLUDE_DIRECTORIES
|
||||
</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ShowProgress>NotSet</ShowProgress>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
@@ -128,13 +130,13 @@ INCLUDE_DIRECTORIES
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>
|
||||
INCLUDE_DIRECTORIES
|
||||
</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -142,19 +144,19 @@ INCLUDE_DIRECTORIES
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>
|
||||
INCLUDE_DIRECTORIES
|
||||
</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -162,7 +164,7 @@ INCLUDE_DIRECTORIES
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
@@ -80,65 +80,62 @@
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_USRDLL;MBEDTLS_EXPORTS;KRML_VERIFIED_UINT128;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>
|
||||
INCLUDE_DIRECTORIES
|
||||
</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MBEDTLS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_USRDLL;MBEDTLS_EXPORTS;KRML_VERIFIED_UINT128;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>
|
||||
INCLUDE_DIRECTORIES
|
||||
</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MBEDTLS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_USRDLL;MBEDTLS_EXPORTS;KRML_VERIFIED_UINT128;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>
|
||||
INCLUDE_DIRECTORIES
|
||||
</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MBEDTLS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;MBEDTLS_EXPORTS;KRML_VERIFIED_UINT128;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>
|
||||
INCLUDE_DIRECTORIES
|
||||
</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;MBEDTLS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -1,8 +1,6 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.31101.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual C++ Express 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mbedTLS", "mbedTLS.vcxproj", "{46CF2D25-6A36-4189-B59C-E4815388E554}"
|
||||
EndProject
|
||||
APP_ENTRIES
|
||||
101
externals/mbedtls/scripts/data_files/vs6-app-template.dsp
vendored
Normal file
101
externals/mbedtls/scripts/data_files/vs6-app-template.dsp
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
# Microsoft Developer Studio Project File - Name="<APPNAME>" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=<APPNAME> - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "<APPNAME>.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "<APPNAME>.mak" CFG="<APPNAME> - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "<APPNAME> - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "<APPNAME> - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "<APPNAME> - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir ""
|
||||
# PROP BASE Intermediate_Dir "temp"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir ""
|
||||
# PROP Intermediate_Dir "temp"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x40c /d "NDEBUG"
|
||||
# ADD RSC /l 0x40c /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "<APPNAME> - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir ""
|
||||
# PROP BASE Intermediate_Dir "temp"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir ""
|
||||
# PROP Intermediate_Dir "temp"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x40c /d "_DEBUG"
|
||||
# ADD RSC /l 0x40c /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "<APPNAME> - Win32 Release"
|
||||
# Name "<APPNAME> - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\programs\<PATHNAME>.c
|
||||
# ADD CPP /I "../../include"
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
94
externals/mbedtls/scripts/data_files/vs6-main-template.dsp
vendored
Normal file
94
externals/mbedtls/scripts/data_files/vs6-main-template.dsp
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
# Microsoft Developer Studio Project File - Name="mbedtls" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=mbedtls - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "mbedtls.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "mbedtls.mak" CFG="mbedtls - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "mbedtls - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "mbedtls - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "mbedtls - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir ""
|
||||
# PROP BASE Intermediate_Dir "temp"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir ""
|
||||
# PROP Intermediate_Dir "temp"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x40c /d "NDEBUG"
|
||||
# ADD RSC /l 0x40c /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "mbedtls - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir ""
|
||||
# PROP BASE Intermediate_Dir "temp"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir ""
|
||||
# PROP Intermediate_Dir "temp"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /GX /Z7 /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x40c /d "_DEBUG"
|
||||
# ADD RSC /l 0x40c /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "mbedtls - Win32 Release"
|
||||
# Name "mbedtls - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
SOURCE_ENTRIES
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
HEADER_ENTRIES
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
18
externals/mbedtls/scripts/data_files/vs6-workspace-template.dsw
vendored
Normal file
18
externals/mbedtls/scripts/data_files/vs6-workspace-template.dsw
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
APP_ENTRIES
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
# Python package requirements for driver implementers.
|
||||
|
||||
# Jinja2 <3.0 needs an older version of markupsafe, but does not
|
||||
# declare it.
|
||||
# https://github.com/pallets/markupsafe/issues/282
|
||||
# https://github.com/pallets/jinja/issues/1585
|
||||
markupsafe < 2.1
|
||||
|
||||
# Use the version of Jinja that's in Ubuntu 20.04.
|
||||
# See https://github.com/Mbed-TLS/mbedtls/pull/5067#discussion_r738794607 .
|
||||
# Note that Jinja 3.0 drops support for Python 3.5, so we need to support
|
||||
# Jinja 2.x as long as we're still using Python 3.5 anywhere.
|
||||
# Jinja 2.10.1 doesn't support Python 3.10+
|
||||
Jinja2 >= 2.10.1; python_version < '3.10'
|
||||
Jinja2 >= 2.10.3; python_version >= '3.10'
|
||||
# Jinja2 >=2.10, <3.0 needs a separate package for type annotations
|
||||
types-Jinja2 >= 2.11.9
|
||||
jsonschema >= 3.2.0
|
||||
types-jsonschema >= 3.2.0
|
||||
69
externals/mbedtls/scripts/ecc-heap.sh
vendored
69
externals/mbedtls/scripts/ecc-heap.sh
vendored
@@ -9,10 +9,49 @@
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
|
||||
set -eu
|
||||
|
||||
CONFIG_H='include/mbedtls/mbedtls_config.h'
|
||||
CONFIG_H='include/mbedtls/config.h'
|
||||
|
||||
if [ -r $CONFIG_H ]; then :; else
|
||||
echo "$CONFIG_H not found" >&2
|
||||
@@ -25,7 +64,7 @@ if grep -i cmake Makefile >/dev/null; then :; else
|
||||
fi
|
||||
|
||||
if git status | grep -F $CONFIG_H >/dev/null 2>&1; then
|
||||
echo "mbedtls_config.h not clean" >&2
|
||||
echo "config.h not clean" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -45,39 +84,29 @@ cat << EOF >$CONFIG_H
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_ASN1_WRITE_C
|
||||
#define MBEDTLS_ECDSA_C
|
||||
#define MBEDTLS_SHA256_C // ECDSA benchmark needs it
|
||||
#define MBEDTLS_SHA224_C // SHA256 requires this for now
|
||||
#define MBEDTLS_ECDH_C
|
||||
|
||||
// NIST curves >= 256 bits
|
||||
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
|
||||
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
|
||||
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
|
||||
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
|
||||
// SECP "koblitz-like" curve >= 256 bits
|
||||
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
|
||||
// Brainpool curves (no specialised "mod p" routine)
|
||||
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
|
||||
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
|
||||
#define MBEDTLS_ECP_DP_BP512R1_ENABLED
|
||||
// Montgomery curves
|
||||
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
#define MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
|
||||
#define MBEDTLS_HAVE_ASM // just make things a bit faster
|
||||
#define MBEDTLS_ECP_NIST_OPTIM // faster and less allocations
|
||||
#include "check_config.h"
|
||||
|
||||
//#define MBEDTLS_ECP_WINDOW_SIZE 4
|
||||
//#define MBEDTLS_ECP_WINDOW_SIZE 6
|
||||
//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1
|
||||
EOF
|
||||
|
||||
for F in 0 1; do
|
||||
for W in 2 3 4; do
|
||||
scripts/config.py set MBEDTLS_ECP_WINDOW_SIZE $W
|
||||
scripts/config.py set MBEDTLS_ECP_FIXED_POINT_OPTIM $F
|
||||
for W in 2 3 4 5 6; do
|
||||
scripts/config.pl set MBEDTLS_ECP_WINDOW_SIZE $W
|
||||
scripts/config.pl set MBEDTLS_ECP_FIXED_POINT_OPTIM $F
|
||||
make benchmark >/dev/null 2>&1
|
||||
echo "fixed point optim = $F, max window size = $W"
|
||||
echo "--------------------------------------------"
|
||||
programs/test/benchmark ecdh ecdsa
|
||||
programs/test/benchmark
|
||||
done
|
||||
done
|
||||
|
||||
|
||||
237
externals/mbedtls/scripts/ecp_comb_table.py
vendored
237
externals/mbedtls/scripts/ecp_comb_table.py
vendored
@@ -1,237 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Purpose
|
||||
|
||||
This script dumps comb table of ec curve. When you add a new ec curve, you
|
||||
can use this script to generate codes to define `<curve>_T` in ecp_curves.c
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
HOW_TO_ADD_NEW_CURVE = """
|
||||
If you are trying to add new curve, you can follow these steps:
|
||||
|
||||
1. Define curve parameters (<curve>_p, <curve>_gx, etc...) in ecp_curves.c.
|
||||
2. Add a macro to define <curve>_T to NULL following these parameters.
|
||||
3. Build mbedcrypto
|
||||
4. Run this script with an argument of new curve
|
||||
5. Copy the output of this script into ecp_curves.c and replace the macro added
|
||||
in Step 2
|
||||
6. Rebuild and test if everything is ok
|
||||
|
||||
Replace the <curve> in the above with the name of the curve you want to add."""
|
||||
|
||||
CC = os.getenv('CC', 'cc')
|
||||
MBEDTLS_LIBRARY_PATH = os.getenv('MBEDTLS_LIBRARY_PATH', "library")
|
||||
|
||||
SRC_DUMP_COMB_TABLE = r'''
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
static void dump_mpi_initialize( const char *name, const mbedtls_mpi *d )
|
||||
{
|
||||
uint8_t buf[128] = {0};
|
||||
size_t olen;
|
||||
uint8_t *p;
|
||||
|
||||
olen = mbedtls_mpi_size( d );
|
||||
mbedtls_mpi_write_binary_le( d, buf, olen );
|
||||
printf("static const mbedtls_mpi_uint %s[] = {\n", name);
|
||||
for (p = buf; p < buf + olen; p += 8) {
|
||||
printf( " BYTES_TO_T_UINT_8( 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X ),\n",
|
||||
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7] );
|
||||
}
|
||||
printf("};\n");
|
||||
}
|
||||
|
||||
static void dump_T( const mbedtls_ecp_group *grp )
|
||||
{
|
||||
char name[128];
|
||||
|
||||
printf( "#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1\n" );
|
||||
|
||||
for (size_t i = 0; i < grp->T_size; ++i) {
|
||||
snprintf( name, sizeof(name), "%s_T_%zu_X", CURVE_NAME, i );
|
||||
dump_mpi_initialize( name, &grp->T[i].X );
|
||||
|
||||
snprintf( name, sizeof(name), "%s_T_%zu_Y", CURVE_NAME, i );
|
||||
dump_mpi_initialize( name, &grp->T[i].Y );
|
||||
}
|
||||
printf( "static const mbedtls_ecp_point %s_T[%zu] = {\n", CURVE_NAME, grp->T_size );
|
||||
size_t olen;
|
||||
for (size_t i = 0; i < grp->T_size; ++i) {
|
||||
int z;
|
||||
if ( mbedtls_mpi_cmp_int(&grp->T[i].Z, 0) == 0 ) {
|
||||
z = 0;
|
||||
} else if ( mbedtls_mpi_cmp_int(&grp->T[i].Z, 1) == 0 ) {
|
||||
z = 1;
|
||||
} else {
|
||||
fprintf( stderr, "Unexpected value of Z (i = %d)\n", (int)i );
|
||||
exit( 1 );
|
||||
}
|
||||
printf( " ECP_POINT_INIT_XY_Z%d(%s_T_%zu_X, %s_T_%zu_Y),\n",
|
||||
z,
|
||||
CURVE_NAME, i,
|
||||
CURVE_NAME, i
|
||||
);
|
||||
}
|
||||
printf("};\n#endif\n\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int rc;
|
||||
mbedtls_mpi m;
|
||||
mbedtls_ecp_point R;
|
||||
mbedtls_ecp_group grp;
|
||||
|
||||
mbedtls_ecp_group_init( &grp );
|
||||
rc = mbedtls_ecp_group_load( &grp, CURVE_ID );
|
||||
if (rc != 0) {
|
||||
char buf[100];
|
||||
mbedtls_strerror( rc, buf, sizeof(buf) );
|
||||
fprintf( stderr, "mbedtls_ecp_group_load: %s (-0x%x)\n", buf, -rc );
|
||||
return 1;
|
||||
}
|
||||
grp.T = NULL;
|
||||
mbedtls_ecp_point_init( &R );
|
||||
mbedtls_mpi_init( &m);
|
||||
mbedtls_mpi_lset( &m, 1 );
|
||||
rc = mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL );
|
||||
if ( rc != 0 ) {
|
||||
char buf[100];
|
||||
mbedtls_strerror( rc, buf, sizeof(buf) );
|
||||
fprintf( stderr, "mbedtls_ecp_mul: %s (-0x%x)\n", buf, -rc );
|
||||
return 1;
|
||||
}
|
||||
if ( grp.T == NULL ) {
|
||||
fprintf( stderr, "grp.T is not generated. Please make sure"
|
||||
"MBEDTLS_ECP_FIXED_POINT_OPTIM is enabled in mbedtls_config.h\n" );
|
||||
return 1;
|
||||
}
|
||||
dump_T( &grp );
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
|
||||
SRC_DUMP_KNOWN_CURVE = r'''
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "mbedtls/ecp.h"
|
||||
|
||||
int main() {
|
||||
const mbedtls_ecp_curve_info *info = mbedtls_ecp_curve_list();
|
||||
mbedtls_ecp_group grp;
|
||||
|
||||
mbedtls_ecp_group_init( &grp );
|
||||
while ( info->name != NULL ) {
|
||||
mbedtls_ecp_group_load( &grp, info->grp_id );
|
||||
if ( mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) {
|
||||
printf( " %s", info->name );
|
||||
}
|
||||
info++;
|
||||
}
|
||||
printf( "\n" );
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
|
||||
|
||||
def join_src_path(*args):
|
||||
return os.path.normpath(os.path.join(os.path.dirname(__file__), "..", *args))
|
||||
|
||||
|
||||
def run_c_source(src, cflags):
|
||||
"""
|
||||
Compile and run C source code
|
||||
:param src: the c language code to run
|
||||
:param cflags: additional cflags passing to compiler
|
||||
:return:
|
||||
"""
|
||||
binname = tempfile.mktemp(prefix="mbedtls")
|
||||
fd, srcname = tempfile.mkstemp(prefix="mbedtls", suffix=".c")
|
||||
srcfile = os.fdopen(fd, mode="w")
|
||||
srcfile.write(src)
|
||||
srcfile.close()
|
||||
args = [CC,
|
||||
*cflags,
|
||||
'-I' + join_src_path("include"),
|
||||
"-o", binname,
|
||||
'-L' + MBEDTLS_LIBRARY_PATH,
|
||||
srcname,
|
||||
'-lmbedcrypto']
|
||||
|
||||
p = subprocess.run(args=args, check=False)
|
||||
if p.returncode != 0:
|
||||
return False
|
||||
p = subprocess.run(args=[binname], check=False, env={
|
||||
'LD_LIBRARY_PATH': MBEDTLS_LIBRARY_PATH
|
||||
})
|
||||
if p.returncode != 0:
|
||||
return False
|
||||
os.unlink(srcname)
|
||||
os.unlink(binname)
|
||||
return True
|
||||
|
||||
|
||||
def compute_curve(curve):
|
||||
"""compute comb table for curve"""
|
||||
r = run_c_source(
|
||||
SRC_DUMP_COMB_TABLE,
|
||||
[
|
||||
'-g',
|
||||
'-DCURVE_ID=MBEDTLS_ECP_DP_%s' % curve.upper(),
|
||||
'-DCURVE_NAME="%s"' % curve.lower(),
|
||||
])
|
||||
if not r:
|
||||
print("""\
|
||||
Unable to compile and run utility.""", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def usage():
|
||||
print("""
|
||||
Usage: python %s <curve>...
|
||||
|
||||
Arguments:
|
||||
curve Specify one or more curve names (e.g secp256r1)
|
||||
|
||||
All possible curves: """ % sys.argv[0])
|
||||
run_c_source(SRC_DUMP_KNOWN_CURVE, [])
|
||||
print("""
|
||||
Environment Variable:
|
||||
CC Specify which c compile to use to compile utility.
|
||||
MBEDTLS_LIBRARY_PATH
|
||||
Specify the path to mbedcrypto library. (e.g. build/library/)
|
||||
|
||||
How to add a new curve: %s""" % HOW_TO_ADD_NEW_CURVE)
|
||||
|
||||
|
||||
def run_main():
|
||||
shared_lib_path = os.path.normpath(os.path.join(MBEDTLS_LIBRARY_PATH, "libmbedcrypto.so"))
|
||||
static_lib_path = os.path.normpath(os.path.join(MBEDTLS_LIBRARY_PATH, "libmbedcrypto.a"))
|
||||
if not os.path.exists(shared_lib_path) and not os.path.exists(static_lib_path):
|
||||
print("Warning: both '%s' and '%s' are not exists. This script will use "
|
||||
"the library from your system instead of the library compiled by "
|
||||
"this source directory.\n"
|
||||
"You can specify library path using environment variable "
|
||||
"'MBEDTLS_LIBRARY_PATH'." % (shared_lib_path, static_lib_path),
|
||||
file=sys.stderr)
|
||||
|
||||
if len(sys.argv) <= 1:
|
||||
usage()
|
||||
else:
|
||||
for curve in sys.argv[1:]:
|
||||
compute_curve(curve)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run_main()
|
||||
20
externals/mbedtls/scripts/find-mem-leak.cocci
vendored
Normal file
20
externals/mbedtls/scripts/find-mem-leak.cocci
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
@@
|
||||
expression x, y;
|
||||
statement S;
|
||||
@@
|
||||
x = mbedtls_calloc(...);
|
||||
y = mbedtls_calloc(...);
|
||||
...
|
||||
* if (x == NULL || y == NULL)
|
||||
S
|
||||
|
||||
@@
|
||||
expression x, y;
|
||||
statement S;
|
||||
@@
|
||||
if (
|
||||
* (x = mbedtls_calloc(...)) == NULL
|
||||
||
|
||||
* (y = mbedtls_calloc(...)) == NULL
|
||||
)
|
||||
S
|
||||
57
externals/mbedtls/scripts/footprint.sh
vendored
57
externals/mbedtls/scripts/footprint.sh
vendored
@@ -3,13 +3,52 @@
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# Purpose
|
||||
#
|
||||
# This script determines ROM size (or code size) for the standard Mbed TLS
|
||||
# This script determines ROM size (or code size) for the standard mbed TLS
|
||||
# configurations, when built for a Cortex M3/M4 target.
|
||||
#
|
||||
# Configurations included:
|
||||
# default include/mbedtls/mbedtls_config.h
|
||||
# default include/mbedtls/config.h
|
||||
# thread configs/config-thread.h
|
||||
# suite-b configs/config-suite-b.h
|
||||
# psk configs/config-ccm-psk-tls1_2.h
|
||||
@@ -18,7 +57,7 @@
|
||||
#
|
||||
set -eu
|
||||
|
||||
CONFIG_H='include/mbedtls/mbedtls_config.h'
|
||||
CONFIG_H='include/mbedtls/config.h'
|
||||
|
||||
if [ -r $CONFIG_H ]; then :; else
|
||||
echo "$CONFIG_H not found" >&2
|
||||
@@ -61,10 +100,10 @@ doit()
|
||||
fi
|
||||
|
||||
{
|
||||
scripts/config.py unset MBEDTLS_NET_C || true
|
||||
scripts/config.py unset MBEDTLS_TIMING_C || true
|
||||
scripts/config.py unset MBEDTLS_FS_IO || true
|
||||
scripts/config.py --force set MBEDTLS_NO_PLATFORM_ENTROPY || true
|
||||
scripts/config.pl unset MBEDTLS_NET_C || true
|
||||
scripts/config.pl unset MBEDTLS_TIMING_C || true
|
||||
scripts/config.pl unset MBEDTLS_FS_IO || true
|
||||
scripts/config.pl --force set MBEDTLS_NO_PLATFORM_ENTROPY || true
|
||||
} >/dev/null 2>&1
|
||||
|
||||
make clean >/dev/null
|
||||
@@ -96,11 +135,11 @@ else
|
||||
fi
|
||||
|
||||
log ""
|
||||
log "Mbed TLS $MBEDTLS_VERSION$GIT_VERSION"
|
||||
log "mbed TLS $MBEDTLS_VERSION$GIT_VERSION"
|
||||
log "$( arm-none-eabi-gcc --version | head -n1 )"
|
||||
log "CFLAGS=$ARMGCC_FLAGS"
|
||||
|
||||
doit default include/mbedtls/mbedtls_config.h
|
||||
doit default include/mbedtls/config.h
|
||||
doit thread configs/config-thread.h
|
||||
doit suite-b configs/config-suite-b.h
|
||||
doit psk configs/config-ccm-psk-tls1_2.h
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate library/psa_crypto_driver_wrappers.h
|
||||
library/psa_crypto_driver_wrappers_no_static.c
|
||||
|
||||
This module is invoked by the build scripts to auto generate the
|
||||
psa_crypto_driver_wrappers.h and psa_crypto_driver_wrappers_no_static
|
||||
based on template files in script/data_files/driver_templates/.
|
||||
"""
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
from typing import NewType, Dict, Any
|
||||
from traceback import format_tb
|
||||
import argparse
|
||||
import jsonschema
|
||||
import jinja2
|
||||
from mbedtls_dev import build_tree
|
||||
|
||||
JSONSchema = NewType('JSONSchema', object)
|
||||
# The Driver is an Object, but practically it's indexable and can called a dictionary to
|
||||
# keep MyPy happy till MyPy comes with a more composite type for JsonObjects.
|
||||
Driver = NewType('Driver', dict)
|
||||
|
||||
|
||||
class JsonValidationException(Exception):
|
||||
def __init__(self, message="Json Validation Failed"):
|
||||
self.message = message
|
||||
super().__init__(self.message)
|
||||
|
||||
|
||||
class DriverReaderException(Exception):
|
||||
def __init__(self, message="Driver Reader Failed"):
|
||||
self.message = message
|
||||
super().__init__(self.message)
|
||||
|
||||
|
||||
def render(template_path: str, driver_jsoncontext: list) -> str:
|
||||
"""
|
||||
Render template from the input file and driver JSON.
|
||||
"""
|
||||
environment = jinja2.Environment(
|
||||
loader=jinja2.FileSystemLoader(os.path.dirname(template_path)),
|
||||
keep_trailing_newline=True)
|
||||
template = environment.get_template(os.path.basename(template_path))
|
||||
|
||||
return template.render(drivers=driver_jsoncontext)
|
||||
|
||||
def generate_driver_wrapper_file(template_dir: str,
|
||||
output_dir: str,
|
||||
template_file_name: str,
|
||||
driver_jsoncontext: list) -> None:
|
||||
"""
|
||||
Generate the file psa_crypto_driver_wrapper.c.
|
||||
"""
|
||||
driver_wrapper_template_filename = \
|
||||
os.path.join(template_dir, template_file_name)
|
||||
|
||||
result = render(driver_wrapper_template_filename, driver_jsoncontext)
|
||||
|
||||
with open(file=os.path.join(output_dir, os.path.splitext(template_file_name)[0]),
|
||||
mode='w',
|
||||
encoding='UTF-8') as out_file:
|
||||
out_file.write(result)
|
||||
|
||||
|
||||
def validate_json(driverjson_data: Driver, driverschema_list: dict) -> None:
|
||||
"""
|
||||
Validate the Driver JSON against an appropriate schema
|
||||
the schema passed could be that matching an opaque/ transparent driver.
|
||||
"""
|
||||
driver_type = driverjson_data["type"]
|
||||
driver_prefix = driverjson_data["prefix"]
|
||||
try:
|
||||
_schema = driverschema_list[driver_type]
|
||||
jsonschema.validate(instance=driverjson_data, schema=_schema)
|
||||
except KeyError as err:
|
||||
# This could happen if the driverjson_data.type does not exist in the provided schema list
|
||||
# schemas = {'transparent': transparent_driver_schema, 'opaque': opaque_driver_schema}
|
||||
# Print onto stdout and stderr.
|
||||
print("Unknown Driver type " + driver_type +
|
||||
" for driver " + driver_prefix, str(err))
|
||||
print("Unknown Driver type " + driver_type +
|
||||
" for driver " + driver_prefix, str(err), file=sys.stderr)
|
||||
raise JsonValidationException() from err
|
||||
|
||||
except jsonschema.exceptions.ValidationError as err:
|
||||
# Print onto stdout and stderr.
|
||||
print("Error: Failed to validate data file: {} using schema: {}."
|
||||
"\n Exception Message: \"{}\""
|
||||
" ".format(driverjson_data, _schema, str(err)))
|
||||
print("Error: Failed to validate data file: {} using schema: {}."
|
||||
"\n Exception Message: \"{}\""
|
||||
" ".format(driverjson_data, _schema, str(err)), file=sys.stderr)
|
||||
raise JsonValidationException() from err
|
||||
|
||||
|
||||
def load_driver(schemas: Dict[str, Any], driver_file: str) -> Any:
|
||||
"""loads validated json driver"""
|
||||
with open(file=driver_file, mode='r', encoding='UTF-8') as f:
|
||||
json_data = json.load(f)
|
||||
try:
|
||||
validate_json(json_data, schemas)
|
||||
except JsonValidationException as e:
|
||||
raise DriverReaderException from e
|
||||
return json_data
|
||||
|
||||
|
||||
def load_schemas(project_root: str) -> Dict[str, Any]:
|
||||
"""
|
||||
Load schemas map
|
||||
"""
|
||||
schema_file_paths = {
|
||||
'transparent': os.path.join(project_root,
|
||||
'scripts',
|
||||
'data_files',
|
||||
'driver_jsons',
|
||||
'driver_transparent_schema.json'),
|
||||
'opaque': os.path.join(project_root,
|
||||
'scripts',
|
||||
'data_files',
|
||||
'driver_jsons',
|
||||
'driver_opaque_schema.json')
|
||||
}
|
||||
driver_schema = {}
|
||||
for key, file_path in schema_file_paths.items():
|
||||
with open(file=file_path, mode='r', encoding='UTF-8') as file:
|
||||
driver_schema[key] = json.load(file)
|
||||
return driver_schema
|
||||
|
||||
|
||||
def read_driver_descriptions(project_root: str,
|
||||
json_directory: str,
|
||||
jsondriver_list: str) -> list:
|
||||
"""
|
||||
Merge driver JSON files into a single ordered JSON after validation.
|
||||
"""
|
||||
driver_schema = load_schemas(project_root)
|
||||
|
||||
with open(file=os.path.join(json_directory, jsondriver_list),
|
||||
mode='r',
|
||||
encoding='UTF-8') as driver_list_file:
|
||||
driver_list = json.load(driver_list_file)
|
||||
|
||||
return [load_driver(schemas=driver_schema,
|
||||
driver_file=os.path.join(json_directory, driver_file_name))
|
||||
for driver_file_name in driver_list]
|
||||
|
||||
|
||||
def trace_exception(e: Exception, file=sys.stderr) -> None:
|
||||
"""Prints exception trace to the given TextIO handle"""
|
||||
print("Exception: type: %s, message: %s, trace: %s" % (
|
||||
e.__class__, str(e), format_tb(e.__traceback__)
|
||||
), file)
|
||||
|
||||
|
||||
TEMPLATE_FILENAMES = ["psa_crypto_driver_wrappers.h.jinja",
|
||||
"psa_crypto_driver_wrappers_no_static.c.jinja"]
|
||||
|
||||
def main() -> int:
|
||||
"""
|
||||
Main with command line arguments.
|
||||
"""
|
||||
def_arg_project_root = build_tree.guess_project_root()
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--project-root', default=def_arg_project_root,
|
||||
help='root directory of repo source code')
|
||||
parser.add_argument('--template-dir',
|
||||
help='directory holding the driver templates')
|
||||
parser.add_argument('--json-dir',
|
||||
help='directory holding the driver JSONs')
|
||||
parser.add_argument('output_directory', nargs='?',
|
||||
help='output file\'s location')
|
||||
args = parser.parse_args()
|
||||
|
||||
project_root = os.path.abspath(args.project_root)
|
||||
|
||||
crypto_core_directory = build_tree.crypto_core_directory(project_root)
|
||||
|
||||
output_directory = args.output_directory if args.output_directory is not None else \
|
||||
crypto_core_directory
|
||||
|
||||
template_directory = args.template_dir if args.template_dir is not None else \
|
||||
os.path.join(project_root,
|
||||
'scripts',
|
||||
'data_files',
|
||||
'driver_templates')
|
||||
json_directory = args.json_dir if args.json_dir is not None else \
|
||||
os.path.join(project_root,
|
||||
'scripts',
|
||||
'data_files',
|
||||
'driver_jsons')
|
||||
|
||||
try:
|
||||
# Read and validate list of driver jsons from driverlist.json
|
||||
merged_driver_json = read_driver_descriptions(project_root,
|
||||
json_directory,
|
||||
'driverlist.json')
|
||||
except DriverReaderException as e:
|
||||
trace_exception(e)
|
||||
return 1
|
||||
for template_filename in TEMPLATE_FILENAMES:
|
||||
generate_driver_wrapper_file(template_directory, output_directory,
|
||||
template_filename, merged_driver_json)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
126
externals/mbedtls/scripts/generate_errors.pl
vendored
126
externals/mbedtls/scripts/generate_errors.pl
vendored
@@ -7,9 +7,47 @@
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my ($include_dir, $data_dir, $error_file);
|
||||
|
||||
@@ -33,63 +71,35 @@ if( @ARGV ) {
|
||||
|
||||
my $error_format_file = $data_dir.'/error.fmt';
|
||||
|
||||
my @low_level_modules = qw( AES ARIA ASN1 BASE64 BIGNUM
|
||||
my @low_level_modules = qw( AES ARC4 ARIA ASN1 BASE64 BIGNUM BLOWFISH
|
||||
CAMELLIA CCM CHACHA20 CHACHAPOLY CMAC CTR_DRBG DES
|
||||
ENTROPY ERROR GCM HKDF HMAC_DRBG LMS MD5
|
||||
ENTROPY GCM HKDF HMAC_DRBG MD2 MD4 MD5
|
||||
NET OID PADLOCK PBKDF2 PLATFORM POLY1305 RIPEMD160
|
||||
SHA1 SHA256 SHA512 SHA3 THREADING );
|
||||
SHA1 SHA256 SHA512 THREADING XTEA );
|
||||
my @high_level_modules = qw( CIPHER DHM ECP MD
|
||||
PEM PK PKCS12 PKCS5
|
||||
RSA SSL X509 PKCS7 );
|
||||
RSA SSL X509 );
|
||||
|
||||
my $line_separator = $/;
|
||||
undef $/;
|
||||
|
||||
open(FORMAT_FILE, '<:crlf', "$error_format_file") or die "Opening error format file '$error_format_file': $!";
|
||||
open(FORMAT_FILE, "$error_format_file") or die "Opening error format file '$error_format_file': $!";
|
||||
my $error_format = <FORMAT_FILE>;
|
||||
close(FORMAT_FILE);
|
||||
|
||||
my @files = glob qq("$include_dir/*.h");
|
||||
$/ = $line_separator;
|
||||
|
||||
my @files = <$include_dir/*.h>;
|
||||
my @necessary_include_files;
|
||||
my @matches;
|
||||
foreach my $file (@files) {
|
||||
open(FILE, '<:crlf', $file) or die("$0: $file: $!");
|
||||
my $content = <FILE>;
|
||||
open(FILE, "$file");
|
||||
my @grep_res = grep(/^\s*#define\s+MBEDTLS_ERR_\w+\s+\-0x[0-9A-Fa-f]+/, <FILE>);
|
||||
push(@matches, @grep_res);
|
||||
close FILE;
|
||||
my $found = 0;
|
||||
while ($content =~ m[
|
||||
# Both the before-comment and the after-comment are optional.
|
||||
# Only the comment content is a regex capture group. The comment
|
||||
# start and end parts are outside the capture group.
|
||||
(?:/\*[*!](?!<) # Doxygen before-comment start
|
||||
((?:[^*]|\*+[^*/])*) # $1: Comment content (no */ inside)
|
||||
\*/)? # Comment end
|
||||
\s*\#\s*define\s+(MBEDTLS_ERR_\w+) # $2: name
|
||||
\s+\-(0[Xx][0-9A-Fa-f]+)\s* # $3: value (without the sign)
|
||||
(?:/\*[*!]< # Doxygen after-comment start
|
||||
((?:[^*]|\*+[^*/])*) # $4: Comment content (no */ inside)
|
||||
\*/)? # Comment end
|
||||
]gsx) {
|
||||
my ($before, $name, $value, $after) = ($1, $2, $3, $4);
|
||||
# Discard Doxygen comments that are coincidentally present before
|
||||
# an error definition but not attached to it. This is ad hoc, based
|
||||
# on what actually matters (or mattered at some point).
|
||||
undef $before if defined($before) && $before =~ /\s*\\name\s/s;
|
||||
die "Description neither before nor after $name in $file\n"
|
||||
if !defined($before) && !defined($after);
|
||||
die "Description both before and after $name in $file\n"
|
||||
if defined($before) && defined($after);
|
||||
my $description = (defined($before) ? $before : $after);
|
||||
$description =~ s/^\s+//;
|
||||
$description =~ s/\n( *\*)? */ /g;
|
||||
$description =~ s/\.?\s+$//;
|
||||
push @matches, [$name, $value, $description];
|
||||
++$found;
|
||||
}
|
||||
if ($found) {
|
||||
my $include_name = $file;
|
||||
$include_name =~ s!.*/!!;
|
||||
push @necessary_include_files, $include_name;
|
||||
}
|
||||
my $include_name = $file;
|
||||
$include_name =~ s!.*/!!;
|
||||
push @necessary_include_files, $include_name if @grep_res;
|
||||
}
|
||||
|
||||
my $ll_old_define = "";
|
||||
@@ -103,14 +113,20 @@ my %included_headers;
|
||||
|
||||
my %error_codes_seen;
|
||||
|
||||
foreach my $match (@matches)
|
||||
foreach my $line (@matches)
|
||||
{
|
||||
my ($error_name, $error_code, $description) = @$match;
|
||||
next if ($line =~ /compat-1.2.h/);
|
||||
my ($error_name, $error_code) = $line =~ /(MBEDTLS_ERR_\w+)\s+\-(0x\w+)/;
|
||||
my ($description) = $line =~ /\/\*\*< (.*?)\.? \*\//;
|
||||
|
||||
die "Duplicated error code: $error_code ($error_name)\n"
|
||||
if( $error_codes_seen{$error_code}++ );
|
||||
|
||||
$description =~ s/\\/\\\\/g;
|
||||
if ($description eq "") {
|
||||
$description = "DESCRIPTION MISSING";
|
||||
warn "Missing description for $error_name\n";
|
||||
}
|
||||
|
||||
my ($module_name) = $error_name =~ /^MBEDTLS_ERR_([^_]+)/;
|
||||
|
||||
@@ -124,7 +140,6 @@ foreach my $match (@matches)
|
||||
$define_name = "ASN1_PARSE" if ($define_name eq "ASN1");
|
||||
$define_name = "SSL_TLS" if ($define_name eq "SSL");
|
||||
$define_name = "PEM_PARSE,PEM_WRITE" if ($define_name eq "PEM");
|
||||
$define_name = "PKCS7" if ($define_name eq "PKCS7");
|
||||
|
||||
my $include_name = $module_name;
|
||||
$include_name =~ tr/A-Z/a-z/;
|
||||
@@ -151,7 +166,7 @@ foreach my $match (@matches)
|
||||
{
|
||||
$code_check = \$ll_code_check;
|
||||
$old_define = \$ll_old_define;
|
||||
$white_space = ' ';
|
||||
$white_space = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -192,8 +207,19 @@ foreach my $match (@matches)
|
||||
${$old_define} = $define_name;
|
||||
}
|
||||
|
||||
${$code_check} .= "${white_space}case -($error_name):\n".
|
||||
"${white_space} return( \"$module_name - $description\" );\n"
|
||||
if ($error_name eq "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE")
|
||||
{
|
||||
${$code_check} .= "${white_space}if( use_ret == -($error_name) )\n".
|
||||
"${white_space}\{\n".
|
||||
"${white_space} mbedtls_snprintf( buf, buflen, \"$module_name - $description\" );\n".
|
||||
"${white_space} return;\n".
|
||||
"${white_space}}\n"
|
||||
}
|
||||
else
|
||||
{
|
||||
${$code_check} .= "${white_space}if( use_ret == -($error_name) )\n".
|
||||
"${white_space} mbedtls_snprintf( buf, buflen, \"$module_name - $description\" );\n"
|
||||
}
|
||||
};
|
||||
|
||||
if ($ll_old_define ne "")
|
||||
|
||||
60
externals/mbedtls/scripts/generate_features.pl
vendored
60
externals/mbedtls/scripts/generate_features.pl
vendored
@@ -2,6 +2,45 @@
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
|
||||
use strict;
|
||||
|
||||
@@ -27,19 +66,19 @@ if( @ARGV ) {
|
||||
|
||||
my $feature_format_file = $data_dir.'/version_features.fmt';
|
||||
|
||||
my @sections = ( "System support", "Mbed TLS modules",
|
||||
"Mbed TLS feature support" );
|
||||
my @sections = ( "System support", "mbed TLS modules",
|
||||
"mbed TLS feature support" );
|
||||
|
||||
my $line_separator = $/;
|
||||
undef $/;
|
||||
|
||||
open(FORMAT_FILE, '<:crlf', "$feature_format_file") or die "Opening feature format file '$feature_format_file': $!";
|
||||
open(FORMAT_FILE, "$feature_format_file") or die "Opening feature format file '$feature_format_file': $!";
|
||||
my $feature_format = <FORMAT_FILE>;
|
||||
close(FORMAT_FILE);
|
||||
|
||||
$/ = $line_separator;
|
||||
|
||||
open(CONFIG_H, '<:crlf', "$include_dir/mbedtls_config.h") || die("Failure when opening mbedtls_config.h: $!");
|
||||
open(CONFIG_H, "$include_dir/config.h") || die("Failure when opening config.h: $!");
|
||||
|
||||
my $feature_defines = "";
|
||||
my $in_section = 0;
|
||||
@@ -54,14 +93,11 @@ while (my $line = <CONFIG_H>)
|
||||
$in_section = 0;
|
||||
next;
|
||||
}
|
||||
# Strip leading MBEDTLS_ to save binary size
|
||||
my ($mbedtls_prefix, $define) = $line =~ /#define (MBEDTLS_)?(\w+)/;
|
||||
if (!$mbedtls_prefix) {
|
||||
die "Feature does not start with 'MBEDTLS_': $line\n";
|
||||
}
|
||||
$feature_defines .= "#if defined(MBEDTLS_${define})\n";
|
||||
$feature_defines .= " \"${define}\", //no-check-names\n";
|
||||
$feature_defines .= "#endif /* MBEDTLS_${define} */\n";
|
||||
|
||||
my ($define) = $line =~ /#define (\w+)/;
|
||||
$feature_defines .= "#if defined(${define})\n";
|
||||
$feature_defines .= " \"${define}\",\n";
|
||||
$feature_defines .= "#endif /* ${define} */\n";
|
||||
}
|
||||
|
||||
if (!$in_section) {
|
||||
|
||||
332
externals/mbedtls/scripts/generate_psa_constants.py
vendored
332
externals/mbedtls/scripts/generate_psa_constants.py
vendored
@@ -1,332 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""Generate psa_constant_names_generated.c
|
||||
which is included by programs/psa/psa_constant_names.c.
|
||||
The code generated by this module is only meant to be used in the context
|
||||
of that program.
|
||||
|
||||
An argument passed to this script will modify the output directory where the
|
||||
file is written:
|
||||
* by default (no arguments passed): writes to programs/psa/
|
||||
* OUTPUT_FILE_DIR passed: writes to OUTPUT_FILE_DIR/
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from mbedtls_dev import build_tree
|
||||
from mbedtls_dev import macro_collector
|
||||
|
||||
OUTPUT_TEMPLATE = '''\
|
||||
/* Automatically generated by generate_psa_constant.py. DO NOT EDIT. */
|
||||
|
||||
static const char *psa_strerror(psa_status_t status)
|
||||
{
|
||||
switch (status) {
|
||||
%(status_cases)s
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *psa_ecc_family_name(psa_ecc_family_t curve)
|
||||
{
|
||||
switch (curve) {
|
||||
%(ecc_curve_cases)s
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *psa_dh_family_name(psa_dh_family_t group)
|
||||
{
|
||||
switch (group) {
|
||||
%(dh_group_cases)s
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *psa_hash_algorithm_name(psa_algorithm_t hash_alg)
|
||||
{
|
||||
switch (hash_alg) {
|
||||
%(hash_algorithm_cases)s
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *psa_ka_algorithm_name(psa_algorithm_t ka_alg)
|
||||
{
|
||||
switch (ka_alg) {
|
||||
%(ka_algorithm_cases)s
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int psa_snprint_key_type(char *buffer, size_t buffer_size,
|
||||
psa_key_type_t type)
|
||||
{
|
||||
size_t required_size = 0;
|
||||
switch (type) {
|
||||
%(key_type_cases)s
|
||||
default:
|
||||
%(key_type_code)s{
|
||||
return snprintf(buffer, buffer_size,
|
||||
"0x%%04x", (unsigned) type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
buffer[0] = 0;
|
||||
return (int) required_size;
|
||||
}
|
||||
|
||||
#define NO_LENGTH_MODIFIER 0xfffffffflu
|
||||
static int psa_snprint_algorithm(char *buffer, size_t buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
size_t required_size = 0;
|
||||
psa_algorithm_t core_alg = alg;
|
||||
unsigned long length_modifier = NO_LENGTH_MODIFIER;
|
||||
if (PSA_ALG_IS_MAC(alg)) {
|
||||
core_alg = PSA_ALG_TRUNCATED_MAC(alg, 0);
|
||||
if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
|
||||
append(&buffer, buffer_size, &required_size,
|
||||
"PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(", 33);
|
||||
length_modifier = PSA_MAC_TRUNCATED_LENGTH(alg);
|
||||
} else if (core_alg != alg) {
|
||||
append(&buffer, buffer_size, &required_size,
|
||||
"PSA_ALG_TRUNCATED_MAC(", 22);
|
||||
length_modifier = PSA_MAC_TRUNCATED_LENGTH(alg);
|
||||
}
|
||||
} else if (PSA_ALG_IS_AEAD(alg)) {
|
||||
core_alg = PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg);
|
||||
if (core_alg == 0) {
|
||||
/* For unknown AEAD algorithms, there is no "default tag length". */
|
||||
core_alg = alg;
|
||||
} else if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
|
||||
append(&buffer, buffer_size, &required_size,
|
||||
"PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(", 43);
|
||||
length_modifier = PSA_ALG_AEAD_GET_TAG_LENGTH(alg);
|
||||
} else if (core_alg != alg) {
|
||||
append(&buffer, buffer_size, &required_size,
|
||||
"PSA_ALG_AEAD_WITH_SHORTENED_TAG(", 32);
|
||||
length_modifier = PSA_ALG_AEAD_GET_TAG_LENGTH(alg);
|
||||
}
|
||||
} else if (PSA_ALG_IS_KEY_AGREEMENT(alg) &&
|
||||
!PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
|
||||
core_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
|
||||
append(&buffer, buffer_size, &required_size,
|
||||
"PSA_ALG_KEY_AGREEMENT(", 22);
|
||||
append_with_alg(&buffer, buffer_size, &required_size,
|
||||
psa_ka_algorithm_name,
|
||||
PSA_ALG_KEY_AGREEMENT_GET_BASE(alg));
|
||||
append(&buffer, buffer_size, &required_size, ", ", 2);
|
||||
}
|
||||
switch (core_alg) {
|
||||
%(algorithm_cases)s
|
||||
default:
|
||||
%(algorithm_code)s{
|
||||
append_integer(&buffer, buffer_size, &required_size,
|
||||
"0x%%08lx", (unsigned long) core_alg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (core_alg != alg) {
|
||||
if (length_modifier != NO_LENGTH_MODIFIER) {
|
||||
append(&buffer, buffer_size, &required_size, ", ", 2);
|
||||
append_integer(&buffer, buffer_size, &required_size,
|
||||
"%%lu", length_modifier);
|
||||
}
|
||||
append(&buffer, buffer_size, &required_size, ")", 1);
|
||||
}
|
||||
buffer[0] = 0;
|
||||
return (int) required_size;
|
||||
}
|
||||
|
||||
static int psa_snprint_key_usage(char *buffer, size_t buffer_size,
|
||||
psa_key_usage_t usage)
|
||||
{
|
||||
size_t required_size = 0;
|
||||
if (usage == 0) {
|
||||
if (buffer_size > 1) {
|
||||
buffer[0] = '0';
|
||||
buffer[1] = 0;
|
||||
} else if (buffer_size == 1) {
|
||||
buffer[0] = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
%(key_usage_code)s
|
||||
if (usage != 0) {
|
||||
if (required_size != 0) {
|
||||
append(&buffer, buffer_size, &required_size, " | ", 3);
|
||||
}
|
||||
append_integer(&buffer, buffer_size, &required_size,
|
||||
"0x%%08lx", (unsigned long) usage);
|
||||
} else {
|
||||
buffer[0] = 0;
|
||||
}
|
||||
return (int) required_size;
|
||||
}
|
||||
|
||||
/* End of automatically generated file. */
|
||||
'''
|
||||
|
||||
KEY_TYPE_FROM_CURVE_TEMPLATE = '''if (%(tester)s(type)) {
|
||||
append_with_curve(&buffer, buffer_size, &required_size,
|
||||
"%(builder)s", %(builder_length)s,
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(type));
|
||||
} else '''
|
||||
|
||||
KEY_TYPE_FROM_GROUP_TEMPLATE = '''if (%(tester)s(type)) {
|
||||
append_with_group(&buffer, buffer_size, &required_size,
|
||||
"%(builder)s", %(builder_length)s,
|
||||
PSA_KEY_TYPE_DH_GET_FAMILY(type));
|
||||
} else '''
|
||||
|
||||
ALGORITHM_FROM_HASH_TEMPLATE = '''if (%(tester)s(core_alg)) {
|
||||
append(&buffer, buffer_size, &required_size,
|
||||
"%(builder)s(", %(builder_length)s + 1);
|
||||
append_with_alg(&buffer, buffer_size, &required_size,
|
||||
psa_hash_algorithm_name,
|
||||
PSA_ALG_GET_HASH(core_alg));
|
||||
append(&buffer, buffer_size, &required_size, ")", 1);
|
||||
} else '''
|
||||
|
||||
BIT_TEST_TEMPLATE = '''\
|
||||
if (%(var)s & %(flag)s) {
|
||||
if (required_size != 0) {
|
||||
append(&buffer, buffer_size, &required_size, " | ", 3);
|
||||
}
|
||||
append(&buffer, buffer_size, &required_size, "%(flag)s", %(length)d);
|
||||
%(var)s ^= %(flag)s;
|
||||
}\
|
||||
'''
|
||||
|
||||
class CaseBuilder(macro_collector.PSAMacroCollector):
|
||||
"""Collect PSA crypto macro definitions and write value recognition functions.
|
||||
|
||||
1. Call `read_file` on the input header file(s).
|
||||
2. Call `write_file` to write ``psa_constant_names_generated.c``.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(include_intermediate=True)
|
||||
|
||||
@staticmethod
|
||||
def _make_return_case(name):
|
||||
return 'case %(name)s: return "%(name)s";' % {'name': name}
|
||||
|
||||
@staticmethod
|
||||
def _make_append_case(name):
|
||||
template = ('case %(name)s: '
|
||||
'append(&buffer, buffer_size, &required_size, "%(name)s", %(length)d); '
|
||||
'break;')
|
||||
return template % {'name': name, 'length': len(name)}
|
||||
|
||||
@staticmethod
|
||||
def _make_bit_test(var, flag):
|
||||
return BIT_TEST_TEMPLATE % {'var': var,
|
||||
'flag': flag,
|
||||
'length': len(flag)}
|
||||
|
||||
def _make_status_cases(self):
|
||||
return '\n '.join(map(self._make_return_case,
|
||||
sorted(self.statuses)))
|
||||
|
||||
def _make_ecc_curve_cases(self):
|
||||
return '\n '.join(map(self._make_return_case,
|
||||
sorted(self.ecc_curves)))
|
||||
|
||||
def _make_dh_group_cases(self):
|
||||
return '\n '.join(map(self._make_return_case,
|
||||
sorted(self.dh_groups)))
|
||||
|
||||
def _make_key_type_cases(self):
|
||||
return '\n '.join(map(self._make_append_case,
|
||||
sorted(self.key_types)))
|
||||
|
||||
@staticmethod
|
||||
def _make_key_type_from_curve_code(builder, tester):
|
||||
return KEY_TYPE_FROM_CURVE_TEMPLATE % {'builder': builder,
|
||||
'builder_length': len(builder),
|
||||
'tester': tester}
|
||||
|
||||
@staticmethod
|
||||
def _make_key_type_from_group_code(builder, tester):
|
||||
return KEY_TYPE_FROM_GROUP_TEMPLATE % {'builder': builder,
|
||||
'builder_length': len(builder),
|
||||
'tester': tester}
|
||||
|
||||
def _make_ecc_key_type_code(self):
|
||||
d = self.key_types_from_curve
|
||||
make = self._make_key_type_from_curve_code
|
||||
return ''.join([make(k, d[k]) for k in sorted(d.keys())])
|
||||
|
||||
def _make_dh_key_type_code(self):
|
||||
d = self.key_types_from_group
|
||||
make = self._make_key_type_from_group_code
|
||||
return ''.join([make(k, d[k]) for k in sorted(d.keys())])
|
||||
|
||||
def _make_hash_algorithm_cases(self):
|
||||
return '\n '.join(map(self._make_return_case,
|
||||
sorted(self.hash_algorithms)))
|
||||
|
||||
def _make_ka_algorithm_cases(self):
|
||||
return '\n '.join(map(self._make_return_case,
|
||||
sorted(self.ka_algorithms)))
|
||||
|
||||
def _make_algorithm_cases(self):
|
||||
return '\n '.join(map(self._make_append_case,
|
||||
sorted(self.algorithms)))
|
||||
|
||||
@staticmethod
|
||||
def _make_algorithm_from_hash_code(builder, tester):
|
||||
return ALGORITHM_FROM_HASH_TEMPLATE % {'builder': builder,
|
||||
'builder_length': len(builder),
|
||||
'tester': tester}
|
||||
|
||||
def _make_algorithm_code(self):
|
||||
d = self.algorithms_from_hash
|
||||
make = self._make_algorithm_from_hash_code
|
||||
return ''.join([make(k, d[k]) for k in sorted(d.keys())])
|
||||
|
||||
def _make_key_usage_code(self):
|
||||
return '\n'.join([self._make_bit_test('usage', bit)
|
||||
for bit in sorted(self.key_usage_flags)])
|
||||
|
||||
def write_file(self, output_file):
|
||||
"""Generate the pretty-printer function code from the gathered
|
||||
constant definitions.
|
||||
"""
|
||||
data = {}
|
||||
data['status_cases'] = self._make_status_cases()
|
||||
data['ecc_curve_cases'] = self._make_ecc_curve_cases()
|
||||
data['dh_group_cases'] = self._make_dh_group_cases()
|
||||
data['key_type_cases'] = self._make_key_type_cases()
|
||||
data['key_type_code'] = (self._make_ecc_key_type_code() +
|
||||
self._make_dh_key_type_code())
|
||||
data['hash_algorithm_cases'] = self._make_hash_algorithm_cases()
|
||||
data['ka_algorithm_cases'] = self._make_ka_algorithm_cases()
|
||||
data['algorithm_cases'] = self._make_algorithm_cases()
|
||||
data['algorithm_code'] = self._make_algorithm_code()
|
||||
data['key_usage_code'] = self._make_key_usage_code()
|
||||
output_file.write(OUTPUT_TEMPLATE % data)
|
||||
|
||||
def generate_psa_constants(header_file_names, output_file_name):
|
||||
collector = CaseBuilder()
|
||||
for header_file_name in header_file_names:
|
||||
with open(header_file_name, 'rb') as header_file:
|
||||
collector.read_file(header_file)
|
||||
temp_file_name = output_file_name + '.tmp'
|
||||
with open(temp_file_name, 'w') as output_file:
|
||||
collector.write_file(output_file)
|
||||
os.replace(temp_file_name, output_file_name)
|
||||
|
||||
if __name__ == '__main__':
|
||||
build_tree.chdir_to_root()
|
||||
# Allow to change the directory where psa_constant_names_generated.c is written to.
|
||||
OUTPUT_FILE_DIR = sys.argv[1] if len(sys.argv) == 2 else "programs/psa"
|
||||
generate_psa_constants(['include/psa/crypto_values.h',
|
||||
'include/psa/crypto_extra.h'],
|
||||
OUTPUT_FILE_DIR + '/psa_constant_names_generated.c')
|
||||
131
externals/mbedtls/scripts/generate_query_config.pl
vendored
131
externals/mbedtls/scripts/generate_query_config.pl
vendored
@@ -7,48 +7,63 @@
|
||||
# form (if any). This facilitates querying the compile time configuration of
|
||||
# the library, for example, for testing.
|
||||
#
|
||||
# The query_config.c is generated from the default configuration files
|
||||
# include/mbedtls/mbedtls_config.h and include/psa/crypto_config.h.
|
||||
# The idea is that mbedtls_config.h and crypto_config.h contain ALL the
|
||||
# The query_config.c is generated from the current configuration at
|
||||
# include/mbedtls/config.h. The idea is that the config.h contains ALL the
|
||||
# compile time configurations available in Mbed TLS (commented or uncommented).
|
||||
# This script extracts the configuration macros from the two files and this
|
||||
# This script extracts the configuration macros from the config.h and this
|
||||
# information is used to automatically generate the body of the query_config()
|
||||
# function by using the template in scripts/data_files/query_config.fmt.
|
||||
#
|
||||
# Usage: scripts/generate_query_config.pl without arguments, or
|
||||
# generate_query_config.pl mbedtls_config_file psa_crypto_config_file template_file output_file
|
||||
# Usage: ./scripts/generate_query_config.pl without arguments
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
|
||||
use strict;
|
||||
|
||||
my ($mbedtls_config_file, $psa_crypto_config_file, $query_config_format_file, $query_config_file);
|
||||
my $config_file = "./include/mbedtls/config.h";
|
||||
|
||||
my $default_mbedtls_config_file = "./include/mbedtls/mbedtls_config.h";
|
||||
my $default_psa_crypto_config_file = "./include/psa/crypto_config.h";
|
||||
my $default_query_config_format_file = "./scripts/data_files/query_config.fmt";
|
||||
my $default_query_config_file = "./programs/test/query_config.c";
|
||||
|
||||
if( @ARGV ) {
|
||||
die "Invalid number of arguments - usage: $0 [MBED_TLS_CONFIG_FILE PSA_CRYPTO_CONFIG_FILE TEMPLATE_FILE OUTPUT_FILE]" if scalar @ARGV != 4;
|
||||
($mbedtls_config_file, $psa_crypto_config_file, $query_config_format_file, $query_config_file) = @ARGV;
|
||||
|
||||
-f $mbedtls_config_file or die "No such file: $mbedtls_config_file";
|
||||
-f $psa_crypto_config_file or die "No such file: $psa_crypto_config_file";
|
||||
-f $query_config_format_file or die "No such file: $query_config_format_file";
|
||||
} else {
|
||||
$mbedtls_config_file = $default_mbedtls_config_file;
|
||||
$psa_crypto_config_file = $default_psa_crypto_config_file;
|
||||
$query_config_format_file = $default_query_config_format_file;
|
||||
$query_config_file = $default_query_config_file;
|
||||
|
||||
unless(-f $mbedtls_config_file && -f $query_config_format_file && -f $psa_crypto_config_file) {
|
||||
chdir '..' or die;
|
||||
-f $mbedtls_config_file && -f $query_config_format_file && -f $psa_crypto_config_file
|
||||
or die "No arguments supplied, must be run from project root or a first-level subdirectory\n";
|
||||
}
|
||||
}
|
||||
my $query_config_format_file = "./scripts/data_files/query_config.fmt";
|
||||
my $query_config_file = "./programs/ssl/query_config.c";
|
||||
|
||||
# Excluded macros from the generated query_config.c. For example, macros that
|
||||
# have commas or function-like macros cannot be transformed into strings easily
|
||||
@@ -56,61 +71,47 @@ if( @ARGV ) {
|
||||
# throw errors.
|
||||
my @excluded = qw(
|
||||
MBEDTLS_SSL_CIPHERSUITES
|
||||
MBEDTLS_PARAM_FAILED
|
||||
);
|
||||
my $excluded_re = join '|', @excluded;
|
||||
|
||||
open(CONFIG_FILE, "$config_file") or die "Opening config file '$config_file': $!";
|
||||
|
||||
# This variable will contain the string to replace in the CHECK_CONFIG of the
|
||||
# format file
|
||||
my $config_check = "";
|
||||
my $list_config = "";
|
||||
|
||||
for my $config_file ($mbedtls_config_file, $psa_crypto_config_file) {
|
||||
while (my $line = <CONFIG_FILE>) {
|
||||
if ($line =~ /^(\/\/)?\s*#\s*define\s+(MBEDTLS_\w+).*/) {
|
||||
my $name = $2;
|
||||
|
||||
next unless defined($config_file); # we might not have been given a PSA crypto config file
|
||||
# Skip over the macro that prevents multiple inclusion
|
||||
next if "MBEDTLS_CONFIG_H" eq $name;
|
||||
|
||||
open(CONFIG_FILE, "<", $config_file) or die "Opening config file '$config_file': $!";
|
||||
# Skip over the macro if it is in the ecluded list
|
||||
next if $name =~ /$excluded_re/;
|
||||
|
||||
while (my $line = <CONFIG_FILE>) {
|
||||
if ($line =~ /^(\/\/)?\s*#\s*define\s+(MBEDTLS_\w+|PSA_WANT_\w+).*/) {
|
||||
my $name = $2;
|
||||
|
||||
# Skip over the macro if it is in the excluded list
|
||||
next if $name =~ /$excluded_re/;
|
||||
|
||||
$config_check .= <<EOT;
|
||||
#if defined($name)
|
||||
if( strcmp( "$name", config ) == 0 )
|
||||
{
|
||||
MACRO_EXPANSION_TO_STR( $name );
|
||||
return( 0 );
|
||||
$config_check .= "#if defined($name)\n";
|
||||
$config_check .= " if( strcmp( \"$name\", config ) == 0 )\n";
|
||||
$config_check .= " {\n";
|
||||
$config_check .= " MACRO_EXPANSION_TO_STR( $name );\n";
|
||||
$config_check .= " return( 0 );\n";
|
||||
$config_check .= " }\n";
|
||||
$config_check .= "#endif /* $name */\n";
|
||||
$config_check .= "\n";
|
||||
}
|
||||
#endif /* $name */
|
||||
|
||||
EOT
|
||||
|
||||
$list_config .= <<EOT;
|
||||
#if defined($name)
|
||||
OUTPUT_MACRO_NAME_VALUE($name);
|
||||
#endif /* $name */
|
||||
|
||||
EOT
|
||||
}
|
||||
}
|
||||
|
||||
close(CONFIG_FILE);
|
||||
}
|
||||
|
||||
# Read the full format file into a string
|
||||
local $/;
|
||||
open(FORMAT_FILE, "<", $query_config_format_file) or die "Opening query config format file '$query_config_format_file': $!";
|
||||
open(FORMAT_FILE, "$query_config_format_file") or die "Opening query config format file '$query_config_format_file': $!";
|
||||
my $query_config_format = <FORMAT_FILE>;
|
||||
close(FORMAT_FILE);
|
||||
|
||||
# Replace the body of the query_config() function with the code we just wrote
|
||||
$query_config_format =~ s/CHECK_CONFIG/$config_check/g;
|
||||
$query_config_format =~ s/LIST_CONFIG/$list_config/g;
|
||||
|
||||
# Rewrite the query_config.c file
|
||||
open(QUERY_CONFIG_FILE, ">", $query_config_file) or die "Opening destination file '$query_config_file': $!";
|
||||
open(QUERY_CONFIG_FILE, ">$query_config_file") or die "Opening destination file '$query_config_file': $!";
|
||||
print QUERY_CONFIG_FILE $query_config_format;
|
||||
close(QUERY_CONFIG_FILE);
|
||||
|
||||
@@ -1,414 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""Generate library/ssl_debug_helpers_generated.c
|
||||
|
||||
The code generated by this module includes debug helper functions that can not be
|
||||
implemented by fixed codes.
|
||||
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import textwrap
|
||||
import argparse
|
||||
from mbedtls_dev import build_tree
|
||||
|
||||
|
||||
def remove_c_comments(string):
|
||||
"""
|
||||
Remove C style comments from input string
|
||||
"""
|
||||
string_pattern = r"(?P<string>\".*?\"|\'.*?\')"
|
||||
comment_pattern = r"(?P<comment>/\*.*?\*/|//[^\r\n]*$)"
|
||||
pattern = re.compile(string_pattern + r'|' + comment_pattern,
|
||||
re.MULTILINE | re.DOTALL)
|
||||
|
||||
def replacer(match):
|
||||
if match.lastgroup == 'comment':
|
||||
return ""
|
||||
return match.group()
|
||||
return pattern.sub(replacer, string)
|
||||
|
||||
|
||||
class CondDirectiveNotMatch(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def preprocess_c_source_code(source, *classes):
|
||||
"""
|
||||
Simple preprocessor for C source code.
|
||||
|
||||
Only processes condition directives without expanding them.
|
||||
Yield object according to the classes input. Most match firstly
|
||||
|
||||
If the directive pair does not match , raise CondDirectiveNotMatch.
|
||||
|
||||
Assume source code does not include comments and compile pass.
|
||||
|
||||
"""
|
||||
|
||||
pattern = re.compile(r"^[ \t]*#[ \t]*" +
|
||||
r"(?P<directive>(if[ \t]|ifndef[ \t]|ifdef[ \t]|else|endif))" +
|
||||
r"[ \t]*(?P<param>(.*\\\n)*.*$)",
|
||||
re.MULTILINE)
|
||||
stack = []
|
||||
|
||||
def _yield_objects(s, d, p, st, end):
|
||||
"""
|
||||
Output matched source piece
|
||||
"""
|
||||
nonlocal stack
|
||||
start_line, end_line = '', ''
|
||||
if stack:
|
||||
start_line = '#{} {}'.format(d, p)
|
||||
if d == 'if':
|
||||
end_line = '#endif /* {} */'.format(p)
|
||||
elif d == 'ifdef':
|
||||
end_line = '#endif /* defined({}) */'.format(p)
|
||||
else:
|
||||
end_line = '#endif /* !defined({}) */'.format(p)
|
||||
has_instance = False
|
||||
for cls in classes:
|
||||
for instance in cls.extract(s, st, end):
|
||||
if has_instance is False:
|
||||
has_instance = True
|
||||
yield pair_start, start_line
|
||||
yield instance.span()[0], instance
|
||||
if has_instance:
|
||||
yield start, end_line
|
||||
|
||||
for match in pattern.finditer(source):
|
||||
|
||||
directive = match.groupdict()['directive'].strip()
|
||||
param = match.groupdict()['param']
|
||||
start, end = match.span()
|
||||
|
||||
if directive in ('if', 'ifndef', 'ifdef'):
|
||||
stack.append((directive, param, start, end))
|
||||
continue
|
||||
|
||||
if not stack:
|
||||
raise CondDirectiveNotMatch()
|
||||
|
||||
pair_directive, pair_param, pair_start, pair_end = stack.pop()
|
||||
yield from _yield_objects(source,
|
||||
pair_directive,
|
||||
pair_param,
|
||||
pair_end,
|
||||
start)
|
||||
|
||||
if directive == 'endif':
|
||||
continue
|
||||
|
||||
if pair_directive == 'if':
|
||||
directive = 'if'
|
||||
param = "!( {} )".format(pair_param)
|
||||
elif pair_directive == 'ifdef':
|
||||
directive = 'ifndef'
|
||||
param = pair_param
|
||||
else:
|
||||
directive = 'ifdef'
|
||||
param = pair_param
|
||||
|
||||
stack.append((directive, param, start, end))
|
||||
assert not stack, len(stack)
|
||||
|
||||
|
||||
class EnumDefinition:
|
||||
"""
|
||||
Generate helper functions around enumeration.
|
||||
|
||||
Currently, it generate translation function from enum value to string.
|
||||
Enum definition looks like:
|
||||
[typedef] enum [prefix name] { [body] } [suffix name];
|
||||
|
||||
Known limitation:
|
||||
- the '}' and ';' SHOULD NOT exist in different macro blocks. Like
|
||||
```
|
||||
enum test {
|
||||
....
|
||||
#if defined(A)
|
||||
....
|
||||
};
|
||||
#else
|
||||
....
|
||||
};
|
||||
#endif
|
||||
```
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def extract(cls, source_code, start=0, end=-1):
|
||||
enum_pattern = re.compile(r'enum\s*(?P<prefix_name>\w*)\s*' +
|
||||
r'{\s*(?P<body>[^}]*)}' +
|
||||
r'\s*(?P<suffix_name>\w*)\s*;',
|
||||
re.MULTILINE | re.DOTALL)
|
||||
|
||||
for match in enum_pattern.finditer(source_code, start, end):
|
||||
yield EnumDefinition(source_code,
|
||||
span=match.span(),
|
||||
group=match.groupdict())
|
||||
|
||||
def __init__(self, source_code, span=None, group=None):
|
||||
assert isinstance(group, dict)
|
||||
prefix_name = group.get('prefix_name', None)
|
||||
suffix_name = group.get('suffix_name', None)
|
||||
body = group.get('body', None)
|
||||
assert prefix_name or suffix_name
|
||||
assert body
|
||||
assert span
|
||||
# If suffix_name exists, it is a typedef
|
||||
self._prototype = suffix_name if suffix_name else 'enum ' + prefix_name
|
||||
self._name = suffix_name if suffix_name else prefix_name
|
||||
self._body = body
|
||||
self._source = source_code
|
||||
self._span = span
|
||||
|
||||
def __repr__(self):
|
||||
return 'Enum({},{})'.format(self._name, self._span)
|
||||
|
||||
def __str__(self):
|
||||
return repr(self)
|
||||
|
||||
def span(self):
|
||||
return self._span
|
||||
|
||||
def generate_translation_function(self):
|
||||
"""
|
||||
Generate function for translating value to string
|
||||
"""
|
||||
translation_table = []
|
||||
|
||||
for line in self._body.splitlines():
|
||||
|
||||
if line.strip().startswith('#'):
|
||||
# Preprocess directive, keep it in table
|
||||
translation_table.append(line.strip())
|
||||
continue
|
||||
|
||||
if not line.strip():
|
||||
continue
|
||||
|
||||
for field in line.strip().split(','):
|
||||
if not field.strip():
|
||||
continue
|
||||
member = field.strip().split()[0]
|
||||
translation_table.append(
|
||||
'{space}case {member}:\n{space} return "{member}";'
|
||||
.format(member=member, space=' '*8)
|
||||
)
|
||||
|
||||
body = textwrap.dedent('''\
|
||||
const char *{name}_str( {prototype} in )
|
||||
{{
|
||||
switch (in) {{
|
||||
{translation_table}
|
||||
default:
|
||||
return "UNKNOWN_VALUE";
|
||||
}}
|
||||
}}
|
||||
''')
|
||||
body = body.format(translation_table='\n'.join(translation_table),
|
||||
name=self._name,
|
||||
prototype=self._prototype)
|
||||
return body
|
||||
|
||||
|
||||
class SignatureAlgorithmDefinition:
|
||||
"""
|
||||
Generate helper functions for signature algorithms.
|
||||
|
||||
It generates translation function from signature algorithm define to string.
|
||||
Signature algorithm definition looks like:
|
||||
#define MBEDTLS_TLS1_3_SIG_[ upper case signature algorithm ] [ value(hex) ]
|
||||
|
||||
Known limitation:
|
||||
- the definitions SHOULD exist in same macro blocks.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def extract(cls, source_code, start=0, end=-1):
|
||||
sig_alg_pattern = re.compile(r'#define\s+(?P<name>MBEDTLS_TLS1_3_SIG_\w+)\s+' +
|
||||
r'(?P<value>0[xX][0-9a-fA-F]+)$',
|
||||
re.MULTILINE | re.DOTALL)
|
||||
matches = list(sig_alg_pattern.finditer(source_code, start, end))
|
||||
if matches:
|
||||
yield SignatureAlgorithmDefinition(source_code, definitions=matches)
|
||||
|
||||
def __init__(self, source_code, definitions=None):
|
||||
if definitions is None:
|
||||
definitions = []
|
||||
assert isinstance(definitions, list) and definitions
|
||||
self._definitions = definitions
|
||||
self._source = source_code
|
||||
|
||||
def __repr__(self):
|
||||
return 'SigAlgs({})'.format(self._definitions[0].span())
|
||||
|
||||
def span(self):
|
||||
return self._definitions[0].span()
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
Generate function for translating value to string
|
||||
"""
|
||||
translation_table = []
|
||||
for m in self._definitions:
|
||||
name = m.groupdict()['name']
|
||||
return_val = name[len('MBEDTLS_TLS1_3_SIG_'):].lower()
|
||||
translation_table.append(
|
||||
' case {}:\n return "{}";'.format(name, return_val))
|
||||
|
||||
body = textwrap.dedent('''\
|
||||
const char *mbedtls_ssl_sig_alg_to_str( uint16_t in )
|
||||
{{
|
||||
switch( in )
|
||||
{{
|
||||
{translation_table}
|
||||
}};
|
||||
|
||||
return "UNKNOWN";
|
||||
}}''')
|
||||
body = body.format(translation_table='\n'.join(translation_table))
|
||||
return body
|
||||
|
||||
|
||||
class NamedGroupDefinition:
|
||||
"""
|
||||
Generate helper functions for named group
|
||||
|
||||
It generates translation function from named group define to string.
|
||||
Named group definition looks like:
|
||||
#define MBEDTLS_SSL_IANA_TLS_GROUP_[ upper case named group ] [ value(hex) ]
|
||||
|
||||
Known limitation:
|
||||
- the definitions SHOULD exist in same macro blocks.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def extract(cls, source_code, start=0, end=-1):
|
||||
named_group_pattern = re.compile(r'#define\s+(?P<name>MBEDTLS_SSL_IANA_TLS_GROUP_\w+)\s+' +
|
||||
r'(?P<value>0[xX][0-9a-fA-F]+)$',
|
||||
re.MULTILINE | re.DOTALL)
|
||||
matches = list(named_group_pattern.finditer(source_code, start, end))
|
||||
if matches:
|
||||
yield NamedGroupDefinition(source_code, definitions=matches)
|
||||
|
||||
def __init__(self, source_code, definitions=None):
|
||||
if definitions is None:
|
||||
definitions = []
|
||||
assert isinstance(definitions, list) and definitions
|
||||
self._definitions = definitions
|
||||
self._source = source_code
|
||||
|
||||
def __repr__(self):
|
||||
return 'NamedGroup({})'.format(self._definitions[0].span())
|
||||
|
||||
def span(self):
|
||||
return self._definitions[0].span()
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
Generate function for translating value to string
|
||||
"""
|
||||
translation_table = []
|
||||
for m in self._definitions:
|
||||
name = m.groupdict()['name']
|
||||
iana_name = name[len('MBEDTLS_SSL_IANA_TLS_GROUP_'):].lower()
|
||||
translation_table.append(' case {}:\n return "{}";'.format(name, iana_name))
|
||||
|
||||
body = textwrap.dedent('''\
|
||||
const char *mbedtls_ssl_named_group_to_str( uint16_t in )
|
||||
{{
|
||||
switch( in )
|
||||
{{
|
||||
{translation_table}
|
||||
}};
|
||||
|
||||
return "UNKOWN";
|
||||
}}''')
|
||||
body = body.format(translation_table='\n'.join(translation_table))
|
||||
return body
|
||||
|
||||
|
||||
OUTPUT_C_TEMPLATE = '''\
|
||||
/* Automatically generated by generate_ssl_debug_helpers.py. DO NOT EDIT. */
|
||||
|
||||
/**
|
||||
* \\file ssl_debug_helpers_generated.c
|
||||
*
|
||||
* \\brief Automatically generated helper functions for debugging
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
|
||||
#include "ssl_debug_helpers.h"
|
||||
|
||||
{functions}
|
||||
|
||||
#endif /* MBEDTLS_DEBUG_C */
|
||||
/* End of automatically generated file. */
|
||||
|
||||
'''
|
||||
|
||||
|
||||
def generate_ssl_debug_helpers(output_directory, mbedtls_root):
|
||||
"""
|
||||
Generate functions of debug helps
|
||||
"""
|
||||
mbedtls_root = os.path.abspath(
|
||||
mbedtls_root or build_tree.guess_mbedtls_root())
|
||||
with open(os.path.join(mbedtls_root, 'include/mbedtls/ssl.h')) as f:
|
||||
source_code = remove_c_comments(f.read())
|
||||
|
||||
definitions = dict()
|
||||
for start, instance in preprocess_c_source_code(source_code,
|
||||
EnumDefinition,
|
||||
SignatureAlgorithmDefinition,
|
||||
NamedGroupDefinition):
|
||||
if start in definitions:
|
||||
continue
|
||||
if isinstance(instance, EnumDefinition):
|
||||
definition = instance.generate_translation_function()
|
||||
else:
|
||||
definition = instance
|
||||
definitions[start] = definition
|
||||
|
||||
function_definitions = [str(v) for _, v in sorted(definitions.items())]
|
||||
if output_directory == sys.stdout:
|
||||
sys.stdout.write(OUTPUT_C_TEMPLATE.format(
|
||||
functions='\n'.join(function_definitions)))
|
||||
else:
|
||||
with open(os.path.join(output_directory, 'ssl_debug_helpers_generated.c'), 'w') as f:
|
||||
f.write(OUTPUT_C_TEMPLATE.format(
|
||||
functions='\n'.join(function_definitions)))
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Command line entry
|
||||
"""
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--mbedtls-root', nargs='?', default=None,
|
||||
help='root directory of mbedtls source code')
|
||||
parser.add_argument('output_directory', nargs='?',
|
||||
default='library', help='source/header files location')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
generate_ssl_debug_helpers(args.output_directory, args.mbedtls_root)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
195
externals/mbedtls/scripts/generate_visualc_files.pl
vendored
195
externals/mbedtls/scripts/generate_visualc_files.pl
vendored
@@ -1,112 +1,102 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# Generate main file, individual apps and solution files for
|
||||
# MS Visual Studio 2013
|
||||
# Generate main file, individual apps and solution files for MS Visual Studio
|
||||
# 2010
|
||||
#
|
||||
# Must be run from Mbed TLS root or scripts directory.
|
||||
# Must be run from mbedTLS root or scripts directory.
|
||||
# Takes no argument.
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
use Digest::MD5 'md5_hex';
|
||||
|
||||
my $vsx_dir = "visualc/VS2013";
|
||||
my $vsx_dir = "visualc/VS2010";
|
||||
my $vsx_ext = "vcxproj";
|
||||
my $vsx_app_tpl_file = "scripts/data_files/vs2013-app-template.$vsx_ext";
|
||||
my $vsx_main_tpl_file = "scripts/data_files/vs2013-main-template.$vsx_ext";
|
||||
my $vsx_app_tpl_file = "scripts/data_files/vs2010-app-template.$vsx_ext";
|
||||
my $vsx_main_tpl_file = "scripts/data_files/vs2010-main-template.$vsx_ext";
|
||||
my $vsx_main_file = "$vsx_dir/mbedTLS.$vsx_ext";
|
||||
my $vsx_sln_tpl_file = "scripts/data_files/vs2013-sln-template.sln";
|
||||
my $vsx_sln_tpl_file = "scripts/data_files/vs2010-sln-template.sln";
|
||||
my $vsx_sln_file = "$vsx_dir/mbedTLS.sln";
|
||||
|
||||
my $programs_dir = 'programs';
|
||||
my $mbedtls_header_dir = 'include/mbedtls';
|
||||
my $psa_header_dir = 'include/psa';
|
||||
my $header_dir = 'include/mbedtls';
|
||||
my $source_dir = 'library';
|
||||
my $test_source_dir = 'tests/src';
|
||||
my $test_header_dir = 'tests/include/test';
|
||||
my $test_drivers_header_dir = 'tests/include/test/drivers';
|
||||
my $test_drivers_source_dir = 'tests/src/drivers';
|
||||
|
||||
my @thirdparty_header_dirs = qw(
|
||||
3rdparty/everest/include/everest
|
||||
);
|
||||
my @thirdparty_source_dirs = qw(
|
||||
3rdparty/everest/library
|
||||
3rdparty/everest/library/kremlib
|
||||
3rdparty/everest/library/legacy
|
||||
);
|
||||
|
||||
# Directories to add to the include path.
|
||||
# Order matters in case there are files with the same name in more than
|
||||
# one directory: the compiler will use the first match.
|
||||
my @include_directories = qw(
|
||||
include
|
||||
3rdparty/everest/include/
|
||||
3rdparty/everest/include/everest
|
||||
3rdparty/everest/include/everest/vs2013
|
||||
3rdparty/everest/include/everest/kremlib
|
||||
tests/include
|
||||
);
|
||||
my $include_directories = join(';', map {"../../$_"} @include_directories);
|
||||
|
||||
# Directories to add to the include path when building the library, but not
|
||||
# when building tests or applications.
|
||||
my @library_include_directories = qw(
|
||||
library
|
||||
);
|
||||
my $library_include_directories =
|
||||
join(';', map {"../../$_"} (@library_include_directories,
|
||||
@include_directories));
|
||||
|
||||
my @excluded_files = qw(
|
||||
3rdparty/everest/library/Hacl_Curve25519.c
|
||||
);
|
||||
my %excluded_files = ();
|
||||
foreach (@excluded_files) { $excluded_files{$_} = 1 }
|
||||
|
||||
# Need windows line endings!
|
||||
my $vsx_hdr_tpl = <<EOT;
|
||||
<ClInclude Include="..\\..\\{NAME}" />
|
||||
<ClInclude Include="..\\..\\{NAME}" />\r
|
||||
EOT
|
||||
my $vsx_src_tpl = <<EOT;
|
||||
<ClCompile Include="..\\..\\{NAME}" />
|
||||
<ClCompile Include="..\\..\\{NAME}" />\r
|
||||
EOT
|
||||
|
||||
my $vsx_sln_app_entry_tpl = <<EOT;
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "{APPNAME}", "{APPNAME}.vcxproj", "{GUID}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "{APPNAME}", "{APPNAME}.vcxproj", "{GUID}"\r
|
||||
ProjectSection(ProjectDependencies) = postProject\r
|
||||
{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}\r
|
||||
EndProjectSection\r
|
||||
EndProject\r
|
||||
EOT
|
||||
|
||||
my $vsx_sln_conf_entry_tpl = <<EOT;
|
||||
{GUID}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{GUID}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{GUID}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{GUID}.Debug|x64.Build.0 = Debug|x64
|
||||
{GUID}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{GUID}.Release|Win32.Build.0 = Release|Win32
|
||||
{GUID}.Release|x64.ActiveCfg = Release|x64
|
||||
{GUID}.Release|x64.Build.0 = Release|x64
|
||||
{GUID}.Debug|Win32.ActiveCfg = Debug|Win32\r
|
||||
{GUID}.Debug|Win32.Build.0 = Debug|Win32\r
|
||||
{GUID}.Debug|x64.ActiveCfg = Debug|x64\r
|
||||
{GUID}.Debug|x64.Build.0 = Debug|x64\r
|
||||
{GUID}.Release|Win32.ActiveCfg = Release|Win32\r
|
||||
{GUID}.Release|Win32.Build.0 = Release|Win32\r
|
||||
{GUID}.Release|x64.ActiveCfg = Release|x64\r
|
||||
{GUID}.Release|x64.Build.0 = Release|x64\r
|
||||
EOT
|
||||
|
||||
exit( main() );
|
||||
|
||||
sub check_dirs {
|
||||
foreach my $d (@thirdparty_header_dirs, @thirdparty_source_dirs) {
|
||||
if (not (-d $d)) { return 0; }
|
||||
}
|
||||
return -d $vsx_dir
|
||||
&& -d $mbedtls_header_dir
|
||||
&& -d $psa_header_dir
|
||||
&& -d $header_dir
|
||||
&& -d $source_dir
|
||||
&& -d $test_source_dir
|
||||
&& -d $test_drivers_source_dir
|
||||
&& -d $test_header_dir
|
||||
&& -d $test_drivers_header_dir
|
||||
&& -d $programs_dir;
|
||||
}
|
||||
|
||||
@@ -114,7 +104,7 @@ sub slurp_file {
|
||||
my ($filename) = @_;
|
||||
|
||||
local $/ = undef;
|
||||
open my $fh, '<:crlf', $filename or die "Could not read $filename\n";
|
||||
open my $fh, '<', $filename or die "Could not read $filename\n";
|
||||
my $content = <$fh>;
|
||||
close $fh;
|
||||
|
||||
@@ -124,7 +114,7 @@ sub slurp_file {
|
||||
sub content_to_file {
|
||||
my ($content, $filename) = @_;
|
||||
|
||||
open my $fh, '>:crlf', $filename or die "Could not write to $filename\n";
|
||||
open my $fh, '>', $filename or die "Could not write to $filename\n";
|
||||
print $fh $content;
|
||||
close $fh;
|
||||
}
|
||||
@@ -144,33 +134,26 @@ sub gen_app {
|
||||
my $guid = gen_app_guid( $path );
|
||||
$path =~ s!/!\\!g;
|
||||
(my $appname = $path) =~ s/.*\\//;
|
||||
my $is_test_app = ($path =~ m/^test\\/);
|
||||
|
||||
my $srcs = "<ClCompile Include=\"..\\..\\programs\\$path.c\" \/>";
|
||||
if( $appname eq "ssl_client2" or $appname eq "ssl_server2" or
|
||||
$appname eq "query_compile_time_config" ) {
|
||||
$srcs .= "\n <ClCompile Include=\"..\\..\\programs\\test\\query_config.c\" \/>";
|
||||
}
|
||||
if( $appname eq "ssl_client2" or $appname eq "ssl_server2" ) {
|
||||
$srcs .= "\n <ClCompile Include=\"..\\..\\programs\\ssl\\ssl_test_lib.c\" \/>";
|
||||
$srcs .= "\r\n <ClCompile Include=\"..\\..\\programs\\ssl\\query_config.c\" \/>";
|
||||
}
|
||||
|
||||
my $content = $template;
|
||||
$content =~ s/<SOURCES>/$srcs/g;
|
||||
$content =~ s/<APPNAME>/$appname/g;
|
||||
$content =~ s/<GUID>/$guid/g;
|
||||
$content =~ s/INCLUDE_DIRECTORIES\n/($is_test_app ?
|
||||
$library_include_directories :
|
||||
$include_directories)/ge;
|
||||
|
||||
content_to_file( $content, "$dir/$appname.$ext" );
|
||||
}
|
||||
|
||||
sub get_app_list {
|
||||
my $makefile_contents = slurp_file('programs/Makefile');
|
||||
$makefile_contents =~ /\n\s*APPS\s*=[\\\s]*(.*?)(?<!\\)[\#\n]/s
|
||||
or die "Cannot find APPS = ... in programs/Makefile\n";
|
||||
return split /(?:\s|\\)+/, $1;
|
||||
my $app_list = `cd $programs_dir && make list`;
|
||||
die "make list failed: $!\n" if $?;
|
||||
|
||||
return split /\s+/, $app_list;
|
||||
}
|
||||
|
||||
sub gen_app_files {
|
||||
@@ -196,17 +179,14 @@ sub gen_entry_list {
|
||||
}
|
||||
|
||||
sub gen_main_file {
|
||||
my ($headers, $sources,
|
||||
$hdr_tpl, $src_tpl,
|
||||
$main_tpl, $main_out) = @_;
|
||||
my ($headers, $sources, $hdr_tpl, $src_tpl, $main_tpl, $main_out) = @_;
|
||||
|
||||
my $header_entries = gen_entry_list( $hdr_tpl, @$headers );
|
||||
my $source_entries = gen_entry_list( $src_tpl, @$sources );
|
||||
|
||||
my $out = slurp_file( $main_tpl );
|
||||
$out =~ s/SOURCE_ENTRIES\n/$source_entries/m;
|
||||
$out =~ s/HEADER_ENTRIES\n/$header_entries/m;
|
||||
$out =~ s/INCLUDE_DIRECTORIES\n/$library_include_directories/g;
|
||||
$out =~ s/SOURCE_ENTRIES\r\n/$source_entries/m;
|
||||
$out =~ s/HEADER_ENTRIES\r\n/$header_entries/m;
|
||||
|
||||
content_to_file( $out, $main_out );
|
||||
}
|
||||
@@ -232,8 +212,8 @@ sub gen_vsx_solution {
|
||||
}
|
||||
|
||||
my $out = slurp_file( $vsx_sln_tpl_file );
|
||||
$out =~ s/APP_ENTRIES\n/$app_entries/m;
|
||||
$out =~ s/CONF_ENTRIES\n/$conf_entries/m;
|
||||
$out =~ s/APP_ENTRIES\r\n/$app_entries/m;
|
||||
$out =~ s/CONF_ENTRIES\r\n/$conf_entries/m;
|
||||
|
||||
content_to_file( $out, $vsx_sln_file );
|
||||
}
|
||||
@@ -247,7 +227,7 @@ sub del_vsx_files {
|
||||
sub main {
|
||||
if( ! check_dirs() ) {
|
||||
chdir '..' or die;
|
||||
check_dirs or die "Must be run from Mbed TLS root or scripts dir\n";
|
||||
check_dirs or die "Must but run from mbedTLS root or scripts dir\n";
|
||||
}
|
||||
|
||||
# Remove old files to ensure that, for example, project files from deleted
|
||||
@@ -255,25 +235,8 @@ sub main {
|
||||
del_vsx_files();
|
||||
|
||||
my @app_list = get_app_list();
|
||||
my @header_dirs = (
|
||||
$mbedtls_header_dir,
|
||||
$psa_header_dir,
|
||||
$test_header_dir,
|
||||
$test_drivers_header_dir,
|
||||
$source_dir,
|
||||
@thirdparty_header_dirs,
|
||||
);
|
||||
my @headers = (map { <$_/*.h> } @header_dirs);
|
||||
my @source_dirs = (
|
||||
$source_dir,
|
||||
$test_source_dir,
|
||||
$test_drivers_source_dir,
|
||||
@thirdparty_source_dirs,
|
||||
);
|
||||
my @sources = (map { <$_/*.c> } @source_dirs);
|
||||
|
||||
@headers = grep { ! $excluded_files{$_} } @headers;
|
||||
@sources = grep { ! $excluded_files{$_} } @sources;
|
||||
my @headers = <$header_dir/*.h>;
|
||||
my @sources = <$source_dir/*.c>;
|
||||
map { s!/!\\!g } @headers;
|
||||
map { s!/!\\!g } @sources;
|
||||
|
||||
|
||||
82
externals/mbedtls/scripts/lcov.sh
vendored
82
externals/mbedtls/scripts/lcov.sh
vendored
@@ -1,82 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
help () {
|
||||
cat <<EOF
|
||||
Usage: $0 [-r]
|
||||
Collect coverage statistics of library code into an HTML report.
|
||||
|
||||
General instructions:
|
||||
1. Build the library with CFLAGS="--coverage -O0 -g3" and link the test
|
||||
programs with LDFLAGS="--coverage".
|
||||
This can be an out-of-tree build.
|
||||
For example (in-tree):
|
||||
make CFLAGS="--coverage -O0 -g3" LDFLAGS="--coverage"
|
||||
Or (out-of-tree):
|
||||
mkdir build-coverage && cd build-coverage &&
|
||||
cmake -D CMAKE_BUILD_TYPE=Coverage .. && make
|
||||
2. Run whatever tests you want.
|
||||
3. Run this script from the parent of the directory containing the library
|
||||
object files and coverage statistics files.
|
||||
4. Browse the coverage report in Coverage/index.html.
|
||||
5. After rework, run "$0 -r", then re-test and run "$0" to get a fresh report.
|
||||
|
||||
Options
|
||||
-r Reset traces. Run this before re-testing to get fresh measurements.
|
||||
EOF
|
||||
}
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
|
||||
set -eu
|
||||
|
||||
# Repository detection
|
||||
in_mbedtls_build_dir () {
|
||||
test -d library
|
||||
}
|
||||
|
||||
# Collect stats and build a HTML report.
|
||||
lcov_library_report () {
|
||||
rm -rf Coverage
|
||||
mkdir Coverage Coverage/tmp
|
||||
lcov --capture --initial --directory $library_dir -o Coverage/tmp/files.info
|
||||
lcov --rc lcov_branch_coverage=1 --capture --directory $library_dir -o Coverage/tmp/tests.info
|
||||
lcov --rc lcov_branch_coverage=1 --add-tracefile Coverage/tmp/files.info --add-tracefile Coverage/tmp/tests.info -o Coverage/tmp/all.info
|
||||
lcov --rc lcov_branch_coverage=1 --remove Coverage/tmp/all.info -o Coverage/tmp/final.info '*.h'
|
||||
gendesc tests/Descriptions.txt -o Coverage/tmp/descriptions
|
||||
genhtml --title "$title" --description-file Coverage/tmp/descriptions --keep-descriptions --legend --branch-coverage -o Coverage Coverage/tmp/final.info
|
||||
rm -f Coverage/tmp/*.info Coverage/tmp/descriptions
|
||||
echo "Coverage report in: Coverage/index.html"
|
||||
}
|
||||
|
||||
# Reset the traces to 0.
|
||||
lcov_reset_traces () {
|
||||
# Location with plain make
|
||||
rm -f $library_dir/*.gcda
|
||||
# Location with CMake
|
||||
rm -f $library_dir/CMakeFiles/*.dir/*.gcda
|
||||
}
|
||||
|
||||
if [ $# -gt 0 ] && [ "$1" = "--help" ]; then
|
||||
help
|
||||
exit
|
||||
fi
|
||||
|
||||
if in_mbedtls_build_dir; then
|
||||
library_dir='library'
|
||||
title='Mbed TLS'
|
||||
else
|
||||
library_dir='core'
|
||||
title='TF-PSA-Crypto'
|
||||
fi
|
||||
|
||||
main=lcov_library_report
|
||||
while getopts r OPTLET; do
|
||||
case $OPTLET in
|
||||
r) main=lcov_reset_traces;;
|
||||
*) help 2>&1; exit 120;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
"$main" "$@"
|
||||
@@ -1,10 +0,0 @@
|
||||
# Python packages that are only useful to Mbed TLS maintainers.
|
||||
|
||||
-r ci.requirements.txt
|
||||
|
||||
# For source code analyses
|
||||
clang
|
||||
|
||||
# For building some test vectors
|
||||
pycryptodomex
|
||||
pycryptodome-test-vectors
|
||||
@@ -1,15 +0,0 @@
|
||||
@rem Generate automatically-generated configuration-independent source files
|
||||
@rem and build scripts.
|
||||
@rem Perl and Python 3 must be on the PATH.
|
||||
@rem psa_crypto_driver_wrappers.h needs to be generated prior to
|
||||
@rem generate_visualc_files.pl being invoked.
|
||||
python scripts\generate_driver_wrappers.py || exit /b 1
|
||||
perl scripts\generate_errors.pl || exit /b 1
|
||||
perl scripts\generate_query_config.pl || exit /b 1
|
||||
perl scripts\generate_features.pl || exit /b 1
|
||||
python scripts\generate_ssl_debug_helpers.py || exit /b 1
|
||||
perl scripts\generate_visualc_files.pl || exit /b 1
|
||||
python scripts\generate_psa_constants.py || exit /b 1
|
||||
python tests\scripts\generate_bignum_tests.py || exit /b 1
|
||||
python tests\scripts\generate_ecp_tests.py || exit /b 1
|
||||
python tests\scripts\generate_psa_tests.py || exit /b 1
|
||||
39
externals/mbedtls/scripts/massif_max.pl
vendored
39
externals/mbedtls/scripts/massif_max.pl
vendored
@@ -4,6 +4,45 @@
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# This file needs to exist to make mbedtls_dev a package.
|
||||
# Among other things, this allows modules in this directory to make
|
||||
# relative imports.
|
||||
@@ -1,157 +0,0 @@
|
||||
"""Sample key material for asymmetric key types.
|
||||
|
||||
Meant for use in crypto_knowledge.py.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
import binascii
|
||||
import re
|
||||
from typing import Dict
|
||||
|
||||
STR_TRANS_REMOVE_BLANKS = str.maketrans('', '', ' \t\n\r')
|
||||
|
||||
def unhexlify(text: str) -> bytes:
|
||||
return binascii.unhexlify(text.translate(STR_TRANS_REMOVE_BLANKS))
|
||||
|
||||
def construct_asymmetric_key_data(src) -> Dict[str, Dict[int, bytes]]:
|
||||
"""Split key pairs into separate table entries and convert hex to bytes.
|
||||
|
||||
Input format: src[abbreviated_type][size] = (private_key_hex, public_key_hex)
|
||||
Output format: dst['PSA_KEY_TYPE_xxx'][size] = key_bytes
|
||||
"""
|
||||
dst = {} #type: Dict[str, Dict[int, bytes]]
|
||||
for typ in src:
|
||||
private = 'PSA_KEY_TYPE_' + re.sub(r'(\(|\Z)', r'_KEY_PAIR\1', typ, 1)
|
||||
public = 'PSA_KEY_TYPE_' + re.sub(r'(\(|\Z)', r'_PUBLIC_KEY\1', typ, 1)
|
||||
dst[private] = {}
|
||||
dst[public] = {}
|
||||
for size in src[typ]:
|
||||
dst[private][size] = unhexlify(src[typ][size][0])
|
||||
dst[public][size] = unhexlify(src[typ][size][1])
|
||||
return dst
|
||||
|
||||
## These are valid keys that don't try to exercise any edge cases. They're
|
||||
## either test vectors from some specification, or randomly generated. All
|
||||
## pairs consist of a private key and its public key.
|
||||
#pylint: disable=line-too-long
|
||||
ASYMMETRIC_KEY_DATA = construct_asymmetric_key_data({
|
||||
'ECC(PSA_ECC_FAMILY_SECP_K1)': {
|
||||
192: ("297ac1722ccac7589ecb240dc719842538ca974beb79f228",
|
||||
"0426b7bb38da649ac2138fc050c6548b32553dab68afebc36105d325b75538c12323cb0764789ecb992671beb2b6bef2f5"),
|
||||
225: ("0024122bf020fa113f6c0ac978dfbd41f749257a9468febdbe0dc9f7e8",
|
||||
"042cc7335f4b76042bed44ef45959a62aa215f7a5ff0c8111b8c44ed654ee71c1918326ad485b2d599fe2a6eab096ee26d977334d2bac6d61d"),
|
||||
256: ("7fa06fa02d0e911b9a47fdc17d2d962ca01e2f31d60c6212d0ed7e3bba23a7b9",
|
||||
"045c39154579efd667adc73a81015a797d2c8682cdfbd3c3553c4a185d481cdc50e42a0e1cbc3ca29a32a645e927f54beaed14c9dbbf8279d725f5495ca924b24d"),
|
||||
},
|
||||
'ECC(PSA_ECC_FAMILY_SECP_R1)': {
|
||||
192: ("d83b57a59c51358d9c8bbb898aff507f44dd14cf16917190",
|
||||
"04e35fcbee11cec3154f80a1a61df7d7612de4f2fd70c5608d0ee3a4a1a5719471adb33966dd9b035fdb774feeba94b04c"),
|
||||
224: ("872f203b3ad35b7f2ecc803c3a0e1e0b1ed61cc1afe71b189cd4c995",
|
||||
"046f00eadaa949fee3e9e1c7fa1247eecec86a0dce46418b9bd3117b981d4bd0ae7a990de912f9d060d6cb531a42d22e394ac29e81804bf160"),
|
||||
256: ("49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee",
|
||||
"047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45"),
|
||||
384: ("3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a",
|
||||
"04d9c662b50ba29ca47990450e043aeaf4f0c69b15676d112f622a71c93059af999691c5680d2b44d111579db12f4a413a2ed5c45fcfb67b5b63e00b91ebe59d09a6b1ac2c0c4282aa12317ed5914f999bc488bb132e8342cc36f2ca5e3379c747"),
|
||||
521: ("01b1b6ad07bb79e7320da59860ea28e055284f6058f279de666e06d435d2af7bda28d99fa47b7dd0963e16b0073078ee8b8a38d966a582f46d19ff95df3ad9685aae",
|
||||
"04001de142d54f69eb038ee4b7af9d3ca07736fd9cf719eb354d69879ee7f3c136fb0fbf9f08f86be5fa128ec1a051d3e6c643e85ada8ffacf3663c260bd2c844b6f5600cee8e48a9e65d09cadd89f235dee05f3b8a646be715f1f67d5b434e0ff23a1fc07ef7740193e40eeff6f3bcdfd765aa9155033524fe4f205f5444e292c4c2f6ac1"),
|
||||
},
|
||||
'ECC(PSA_ECC_FAMILY_SECP_R2)': {
|
||||
160: ("00bf539a1cdda0d7f71a50a3f98aec0a2e8e4ced1e",
|
||||
"049570d541398665adb5cfa16f5af73b3196926bbd4b876bdb80f8eab20d0f540c22f4de9c140f6d7b"),
|
||||
},
|
||||
'ECC(PSA_ECC_FAMILY_SECT_K1)': {
|
||||
163: ("03ebc8fcded2d6ab72ec0f75bdb4fd080481273e71",
|
||||
"0406f88f90b4b65950f06ce433afdb097e320f433dc2062b8a65db8fafd3c110f46bc45663fbf021ee7eb9"),
|
||||
233: ("41f08485ce587b06061c087e76e247c359de2ba9927ee013b2f1ed9ca8",
|
||||
"0401e9d7189189f773bd8f71be2c10774ba18842434dfa9312595ea545104400f45a9d5675647513ba75b079fe66a29daac2ec86a6a5d4e75c5f290c1f"),
|
||||
239: ("1a8069ce2c2c8bdd7087f2a6ab49588797e6294e979495602ab9650b9c61",
|
||||
"04068d76b9f4508762c2379db9ee8b87ad8d86d9535132ffba3b5680440cfa28eb133d4232faf1c9aba96af11aefe634a551440800d5f8185105d3072d"),
|
||||
283: ("006d627885dd48b9ec6facb5b3865377d755b75a5d51440e45211c1f600e15eff8a881a0",
|
||||
"0405f48374debceaadb46ba385fd92048fcc5b9af1a1c90408bf94a68b9378df1cbfdfb6fb026a96bea06d8f181bf10c020adbcc88b6ecff96bdc564a9649c247cede601c4be63afc3"),
|
||||
409: ("3ff5e74d932fa77db139b7c948c81e4069c72c24845574064beea8976b70267f1c6f9a503e3892ea1dcbb71fcea423faa370a8",
|
||||
"04012c587f69f68b308ba6dcb238797f4e22290ca939ae806604e2b5ab4d9caef5a74a98fd87c4f88d292dd39d92e556e16c6ecc3c019a105826eef507cd9a04119f54d5d850b3720b3792d5d03410e9105610f7e4b420166ed45604a7a1f229d80975ba6be2060e8b"),
|
||||
571: ("005008c97b4a161c0db1bac6452c72846d57337aa92d8ecb4a66eb01d2f29555ffb61a5317225dcc8ca6917d91789e227efc0bfe9eeda7ee21998cd11c3c9885056b0e55b4f75d51",
|
||||
"04050172a7fd7adf98e4e2ed2742faa5cd12731a15fb0dbbdf75b1c3cc771a4369af6f2fa00e802735650881735759ea9c79961ded18e0daa0ac59afb1d513b5bbda9962e435f454fc020b4afe1445c2302ada07d295ec2580f8849b2dfa7f956b09b4cbe4c88d3b1c217049f75d3900d36df0fa12689256b58dd2ef784ebbeb0564600cf47a841485f8cf897a68accd5a"),
|
||||
},
|
||||
'ECC(PSA_ECC_FAMILY_SECT_R1)': {
|
||||
163: ("009b05dc82d46d64a04a22e6e5ca70ca1231e68c50",
|
||||
"0400465eeb9e7258b11e33c02266bfe834b20bcb118700772796ee4704ec67651bd447e3011959a79a04cb"),
|
||||
233: ("00e5e42834e3c78758088b905deea975f28dc20ef6173e481f96e88afe7f",
|
||||
"0400cd68c8af4430c92ec7a7048becfdf00a6bae8d1b4c37286f2d336f2a0e017eca3748f4ad6d435c85867aa014eea1bd6d9d005bbd8319cab629001d"),
|
||||
283: ("004cecad915f6f3c9bbbd92d1eb101eda23f16c7dad60a57c87c7e1fd2b29b22f6d666ad",
|
||||
"04052f9ff887254c2d1440ba9e30f13e2185ba53c373b2c410dae21cf8c167f796c08134f601cbc4c570bffbc2433082cf4d9eb5ba173ecb8caec15d66a02673f60807b2daa729b765"),
|
||||
409: ("00c22422d265721a3ae2b3b2baeb77bee50416e19877af97b5fc1c700a0a88916ecb9050135883accb5e64edc77a3703f4f67a64",
|
||||
"0401aa25466b1d291846db365957b25431591e50d9c109fe2106e93bb369775896925b15a7bfec397406ab4fe6f6b1a13bf8fdcb9300fa5500a813228676b0a6c572ed96b0f4aec7e87832e7e20f17ca98ecdfd36f59c82bddb8665f1f357a73900e827885ec9e1f22"),
|
||||
571: ("026ac1cdf92a13a1b8d282da9725847908745138f5c6706b52d164e3675fcfbf86fc3e6ab2de732193267db029dd35a0599a94a118f480231cfc6ccca2ebfc1d8f54176e0f5656a1",
|
||||
"040708f3403ee9948114855c17572152a08f8054d486defef5f29cbffcfb7cfd9280746a1ac5f751a6ad902ec1e0525120e9be56f03437af196fbe60ee7856e3542ab2cf87880632d80290e39b1a2bd03c6bbf6225511c567bd2ff41d2325dc58346f2b60b1feee4dc8b2af2296c2dc52b153e0556b5d24152b07f690c3fa24e4d1d19efbdeb1037833a733654d2366c74"),
|
||||
},
|
||||
'ECC(PSA_ECC_FAMILY_SECT_R2)': {
|
||||
163: ("0210b482a458b4822d0cb21daa96819a67c8062d34",
|
||||
"0403692601144c32a6cfa369ae20ae5d43c1c764678c037bafe80c6fd2e42b7ced96171d9c5367fd3dca6f"),
|
||||
},
|
||||
'ECC(PSA_ECC_FAMILY_BRAINPOOL_P_R1)': {
|
||||
160: ("69502c4fdaf48d4fa617bdd24498b0406d0eeaac",
|
||||
"04d4b9186816358e2f9c59cf70748cb70641b22fbab65473db4b4e22a361ed7e3de7e8a8ddc4130c5c"),
|
||||
192: ("1688a2c5fbf4a3c851d76a98c3ec88f445a97996283db59f",
|
||||
"043fdd168c179ff5363dd71dcd58de9617caad791ae0c37328be9ca0bfc79cebabf6a95d1c52df5b5f3c8b1a2441cf6c88"),
|
||||
224: ("a69835dafeb5da5ab89c59860dddebcfd80b529a99f59b880882923c",
|
||||
"045fbea378fc8583b3837e3f21a457c31eaf20a54e18eb11d104b3adc47f9d1c97eb9ea4ac21740d70d88514b98bf0bc31addac1d19c4ab3cc"),
|
||||
256: ("2161d6f2db76526fa62c16f356a80f01f32f776784b36aa99799a8b7662080ff",
|
||||
"04768c8cae4abca6306db0ed81b0c4a6215c378066ec6d616c146e13f1c7df809b96ab6911c27d8a02339f0926840e55236d3d1efbe2669d090e4c4c660fada91d"),
|
||||
320: ("61b8daa7a6e5aa9fccf1ef504220b2e5a5b8c6dc7475d16d3172d7db0b2778414e4f6e8fa2032ead",
|
||||
"049caed8fb4742956cc2ad12a9a1c995e21759ef26a07bc2054136d3d2f28bb331a70e26c4c687275ab1f434be7871e115d2350c0c5f61d4d06d2bcdb67f5cb63fdb794e5947c87dc6849a58694e37e6cd"),
|
||||
384: ("3dd92e750d90d7d39fc1885cd8ad12ea9441f22b9334b4d965202adb1448ce24c5808a85dd9afc229af0a3124f755bcb",
|
||||
"04719f9d093a627e0d350385c661cebf00c61923566fe9006a3107af1d871bc6bb68985fd722ea32be316f8e783b7cd1957785f66cfc0cb195dd5c99a8e7abaa848553a584dfd2b48e76d445fe00dd8be59096d877d4696d23b4bc8db14724e66a"),
|
||||
512: ("372c9778f69f726cbca3f4a268f16b4d617d10280d79a6a029cd51879fe1012934dfe5395455337df6906dc7d6d2eea4dbb2065c0228f73b3ed716480e7d71d2",
|
||||
"0438b7ec92b61c5c6c7fbc28a4ec759d48fcd4e2e374defd5c4968a54dbef7510e517886fbfc38ea39aa529359d70a7156c35d3cbac7ce776bdb251dd64bce71234424ee7049eed072f0dbc4d79996e175d557e263763ae97095c081e73e7db2e38adc3d4c9a0487b1ede876dc1fca61c902e9a1d8722b8612928f18a24845591a"),
|
||||
},
|
||||
'ECC(PSA_ECC_FAMILY_MONTGOMERY)': {
|
||||
255: ("70076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c6a",
|
||||
"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"),
|
||||
448: ("e4e49f52686f9ee3b638528f721f1596196ffd0a1cddb64c3f216f06541805cfeb1a286dc78018095cdfec050e8007b5f4908962ba20d6c1",
|
||||
"c0d3a5a2b416a573dc9909f92f134ac01323ab8f8e36804e578588ba2d09fe7c3e737f771ca112825b548a0ffded6d6a2fd09a3e77dec30e"),
|
||||
},
|
||||
'ECC(PSA_ECC_FAMILY_TWISTED_EDWARDS)': {
|
||||
255: ("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60",
|
||||
"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"),
|
||||
448: ("6c82a562cb808d10d632be89c8513ebf6c929f34ddfa8c9f63c9960ef6e348a3528c8a3fcc2f044e39a3fc5b94492f8f032e7549a20098f95b",
|
||||
"5fd7449b59b461fd2ce787ec616ad46a1da1342485a70e1f8a0ea75d80e96778edf124769b46c7061bd6783df1e50f6cd1fa1abeafe8256180"),
|
||||
},
|
||||
'RSA': {
|
||||
1024: ("""
|
||||
3082025e
|
||||
020100
|
||||
02818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3
|
||||
0203010001
|
||||
02818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1
|
||||
024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113
|
||||
024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091
|
||||
024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d
|
||||
024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1
|
||||
024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24
|
||||
""", """
|
||||
308189
|
||||
02818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3
|
||||
0203010001
|
||||
"""),
|
||||
1536: ("""
|
||||
3082037b
|
||||
020100
|
||||
0281c100c870feb6ca6b1d2bd9f2dd99e20f1fe2d7e5192de662229dbe162bd1ba66336a7182903ca0b72796cd441c83d24bcdc3e9a2f5e4399c8a043f1c3ddf04754a66d4cfe7b3671a37dd31a9b4c13bfe06ee90f9d94ddaa06de67a52ac863e68f756736ceb014405a6160579640f831dddccc34ad0b05070e3f9954a58d1815813e1b83bcadba814789c87f1ef2ba5d738b793ec456a67360eea1b5faf1c7cc7bf24f3b2a9d0f8958b1096e0f0c335f8888d0c63a51c3c0337214fa3f5efdf6dcc35
|
||||
0203010001
|
||||
0281c06d2d670047973a87752a9d5bc14f3dae00acb01f593aa0e24cf4a49f932931de4bbfb332e2d38083da80bc0b6d538edba479f7f77d0deffb4a28e6e67ff6273585bb4cd862535c946605ab0809d65f0e38f76e4ec2c3d9b8cd6e14bcf667943892cd4b34cc6420a439abbf3d7d35ef73976dd6f9cbde35a51fa5213f0107f83e3425835d16d3c9146fc9e36ce75a09bb66cdff21dd5a776899f1cb07e282cca27be46510e9c799f0d8db275a6be085d9f3f803218ee3384265bfb1a3640e8ca1
|
||||
026100e6848c31d466fffefc547e3a3b0d3785de6f78b0dd12610843512e495611a0675509b1650b27415009838dd8e68eec6e7530553b637d602424643b33e8bc5b762e1799bc79d56b13251d36d4f201da2182416ce13574e88278ff04467ad602d9
|
||||
026100de994fdf181f02be2bf9e5f5e4e517a94993b827d1eaf609033e3a6a6f2396ae7c44e9eb594cf1044cb3ad32ea258f0c82963b27bb650ed200cde82cb993374be34be5b1c7ead5446a2b82a4486e8c1810a0b01551609fb0841d474bada802bd
|
||||
026076ddae751b73a959d0bfb8ff49e7fcd378e9be30652ecefe35c82cb8003bc29cc60ae3809909baf20c95db9516fe680865417111d8b193dbcf30281f1249de57c858bf1ba32f5bb1599800e8398a9ef25c7a642c95261da6f9c17670e97265b1
|
||||
0260732482b837d5f2a9443e23c1aa0106d83e82f6c3424673b5fdc3769c0f992d1c5c93991c7038e882fcda04414df4d7a5f4f698ead87851ce37344b60b72d7b70f9c60cae8566e7a257f8e1bef0e89df6e4c2f9d24d21d9f8889e4c7eccf91751
|
||||
026009050d94493da8f00a4ddbe9c800afe3d44b43f78a48941a79b2814a1f0b81a18a8b2347642a03b27998f5a18de9abc9ae0e54ab8294feac66dc87e854cce6f7278ac2710cb5878b592ffeb1f4f0a1853e4e8d1d0561b6efcc831a296cf7eeaf
|
||||
""", """
|
||||
3081c9
|
||||
0281c100c870feb6ca6b1d2bd9f2dd99e20f1fe2d7e5192de662229dbe162bd1ba66336a7182903ca0b72796cd441c83d24bcdc3e9a2f5e4399c8a043f1c3ddf04754a66d4cfe7b3671a37dd31a9b4c13bfe06ee90f9d94ddaa06de67a52ac863e68f756736ceb014405a6160579640f831dddccc34ad0b05070e3f9954a58d1815813e1b83bcadba814789c87f1ef2ba5d738b793ec456a67360eea1b5faf1c7cc7bf24f3b2a9d0f8958b1096e0f0c335f8888d0c63a51c3c0337214fa3f5efdf6dcc35
|
||||
0203010001
|
||||
"""),
|
||||
},
|
||||
})
|
||||
@@ -1,406 +0,0 @@
|
||||
"""Common features for bignum in test generation framework."""
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
from abc import abstractmethod
|
||||
import enum
|
||||
from typing import Iterator, List, Tuple, TypeVar, Any
|
||||
from copy import deepcopy
|
||||
from itertools import chain
|
||||
from math import ceil
|
||||
|
||||
from . import test_case
|
||||
from . import test_data_generation
|
||||
from .bignum_data import INPUTS_DEFAULT, MODULI_DEFAULT
|
||||
|
||||
T = TypeVar('T') #pylint: disable=invalid-name
|
||||
|
||||
def invmod(a: int, n: int) -> int:
|
||||
"""Return inverse of a to modulo n.
|
||||
|
||||
Equivalent to pow(a, -1, n) in Python 3.8+. Implementation is equivalent
|
||||
to long_invmod() in CPython.
|
||||
"""
|
||||
b, c = 1, 0
|
||||
while n:
|
||||
q, r = divmod(a, n)
|
||||
a, b, c, n = n, c, b - q*c, r
|
||||
# at this point a is the gcd of the original inputs
|
||||
if a == 1:
|
||||
return b
|
||||
raise ValueError("Not invertible")
|
||||
|
||||
def invmod_positive(a: int, n: int) -> int:
|
||||
"""Return a non-negative inverse of a to modulo n."""
|
||||
inv = invmod(a, n)
|
||||
return inv if inv >= 0 else inv + n
|
||||
|
||||
def hex_to_int(val: str) -> int:
|
||||
"""Implement the syntax accepted by mbedtls_test_read_mpi().
|
||||
|
||||
This is a superset of what is accepted by mbedtls_test_read_mpi_core().
|
||||
"""
|
||||
if val in ['', '-']:
|
||||
return 0
|
||||
return int(val, 16)
|
||||
|
||||
def quote_str(val: str) -> str:
|
||||
return "\"{}\"".format(val)
|
||||
|
||||
def bound_mpi(val: int, bits_in_limb: int) -> int:
|
||||
"""First number exceeding number of limbs needed for given input value."""
|
||||
return bound_mpi_limbs(limbs_mpi(val, bits_in_limb), bits_in_limb)
|
||||
|
||||
def bound_mpi_limbs(limbs: int, bits_in_limb: int) -> int:
|
||||
"""First number exceeding maximum of given number of limbs."""
|
||||
bits = bits_in_limb * limbs
|
||||
return 1 << bits
|
||||
|
||||
def limbs_mpi(val: int, bits_in_limb: int) -> int:
|
||||
"""Return the number of limbs required to store value."""
|
||||
bit_length = max(val.bit_length(), 1)
|
||||
return (bit_length + bits_in_limb - 1) // bits_in_limb
|
||||
|
||||
def combination_pairs(values: List[T]) -> List[Tuple[T, T]]:
|
||||
"""Return all pair combinations from input values."""
|
||||
return [(x, y) for x in values for y in values]
|
||||
|
||||
def bits_to_limbs(bits: int, bits_in_limb: int) -> int:
|
||||
""" Return the appropriate ammount of limbs needed to store
|
||||
a number contained in input bits"""
|
||||
return ceil(bits / bits_in_limb)
|
||||
|
||||
def hex_digits_for_limb(limbs: int, bits_in_limb: int) -> int:
|
||||
""" Return the hex digits need for a number of limbs. """
|
||||
return 2 * ((limbs * bits_in_limb) // 8)
|
||||
|
||||
def hex_digits_max_int(val: str, bits_in_limb: int) -> int:
|
||||
""" Return the first number exceeding maximum the limb space
|
||||
required to store the input hex-string value. This method
|
||||
weights on the input str_len rather than numerical value
|
||||
and works with zero-padded inputs"""
|
||||
n = ((1 << (len(val) * 4)) - 1)
|
||||
l = limbs_mpi(n, bits_in_limb)
|
||||
return bound_mpi_limbs(l, bits_in_limb)
|
||||
|
||||
def zfill_match(reference: str, target: str) -> str:
|
||||
""" Zero pad target hex-string to match the limb size of
|
||||
the reference input """
|
||||
lt = len(target)
|
||||
lr = len(reference)
|
||||
target_len = lr if lt < lr else lt
|
||||
return "{:x}".format(int(target, 16)).zfill(target_len)
|
||||
|
||||
class OperationCommon(test_data_generation.BaseTest):
|
||||
"""Common features for bignum binary operations.
|
||||
|
||||
This adds functionality common in binary operation tests.
|
||||
|
||||
Attributes:
|
||||
symbol: Symbol to use for the operation in case description.
|
||||
input_values: List of values to use as test case inputs. These are
|
||||
combined to produce pairs of values.
|
||||
input_cases: List of tuples containing pairs of test case inputs. This
|
||||
can be used to implement specific pairs of inputs.
|
||||
unique_combinations_only: Boolean to select if test case combinations
|
||||
must be unique. If True, only A,B or B,A would be included as a test
|
||||
case. If False, both A,B and B,A would be included.
|
||||
input_style: Controls the way how test data is passed to the functions
|
||||
in the generated test cases. "variable" passes them as they are
|
||||
defined in the python source. "arch_split" pads the values with
|
||||
zeroes depending on the architecture/limb size. If this is set,
|
||||
test cases are generated for all architectures.
|
||||
arity: the number of operands for the operation. Currently supported
|
||||
values are 1 and 2.
|
||||
"""
|
||||
symbol = ""
|
||||
input_values = INPUTS_DEFAULT # type: List[str]
|
||||
input_cases = [] # type: List[Any]
|
||||
dependencies = [] # type: List[Any]
|
||||
unique_combinations_only = False
|
||||
input_styles = ["variable", "fixed", "arch_split"] # type: List[str]
|
||||
input_style = "variable" # type: str
|
||||
limb_sizes = [32, 64] # type: List[int]
|
||||
arities = [1, 2]
|
||||
arity = 2
|
||||
suffix = False # for arity = 1, symbol can be prefix (default) or suffix
|
||||
|
||||
def __init__(self, val_a: str, val_b: str = "0", bits_in_limb: int = 32) -> None:
|
||||
self.val_a = val_a
|
||||
self.val_b = val_b
|
||||
# Setting the int versions here as opposed to making them @properties
|
||||
# provides earlier/more robust input validation.
|
||||
self.int_a = hex_to_int(val_a)
|
||||
self.int_b = hex_to_int(val_b)
|
||||
self.dependencies = deepcopy(self.dependencies)
|
||||
if bits_in_limb not in self.limb_sizes:
|
||||
raise ValueError("Invalid number of bits in limb!")
|
||||
if self.input_style == "arch_split":
|
||||
self.dependencies.append("MBEDTLS_HAVE_INT{:d}".format(bits_in_limb))
|
||||
self.bits_in_limb = bits_in_limb
|
||||
|
||||
@property
|
||||
def boundary(self) -> int:
|
||||
if self.arity == 1:
|
||||
return self.int_a
|
||||
elif self.arity == 2:
|
||||
return max(self.int_a, self.int_b)
|
||||
raise ValueError("Unsupported number of operands!")
|
||||
|
||||
@property
|
||||
def limb_boundary(self) -> int:
|
||||
return bound_mpi(self.boundary, self.bits_in_limb)
|
||||
|
||||
@property
|
||||
def limbs(self) -> int:
|
||||
return limbs_mpi(self.boundary, self.bits_in_limb)
|
||||
|
||||
@property
|
||||
def hex_digits(self) -> int:
|
||||
return hex_digits_for_limb(self.limbs, self.bits_in_limb)
|
||||
|
||||
def format_arg(self, val: str) -> str:
|
||||
if self.input_style not in self.input_styles:
|
||||
raise ValueError("Unknown input style!")
|
||||
if self.input_style == "variable":
|
||||
return val
|
||||
else:
|
||||
return val.zfill(self.hex_digits)
|
||||
|
||||
def format_result(self, res: int) -> str:
|
||||
res_str = '{:x}'.format(res)
|
||||
return quote_str(self.format_arg(res_str))
|
||||
|
||||
@property
|
||||
def arg_a(self) -> str:
|
||||
return self.format_arg(self.val_a)
|
||||
|
||||
@property
|
||||
def arg_b(self) -> str:
|
||||
if self.arity == 1:
|
||||
raise AttributeError("Operation is unary and doesn't have arg_b!")
|
||||
return self.format_arg(self.val_b)
|
||||
|
||||
def arguments(self) -> List[str]:
|
||||
args = [quote_str(self.arg_a)]
|
||||
if self.arity == 2:
|
||||
args.append(quote_str(self.arg_b))
|
||||
return args + self.result()
|
||||
|
||||
def description(self) -> str:
|
||||
"""Generate a description for the test case.
|
||||
|
||||
If not set, case_description uses the form A `symbol` B, where symbol
|
||||
is used to represent the operation. Descriptions of each value are
|
||||
generated to provide some context to the test case.
|
||||
"""
|
||||
if not self.case_description:
|
||||
if self.arity == 1:
|
||||
format_string = "{1:x} {0}" if self.suffix else "{0} {1:x}"
|
||||
self.case_description = format_string.format(
|
||||
self.symbol, self.int_a
|
||||
)
|
||||
elif self.arity == 2:
|
||||
self.case_description = "{:x} {} {:x}".format(
|
||||
self.int_a, self.symbol, self.int_b
|
||||
)
|
||||
return super().description()
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
return True
|
||||
|
||||
@abstractmethod
|
||||
def result(self) -> List[str]:
|
||||
"""Get the result of the operation.
|
||||
|
||||
This could be calculated during initialization and stored as `_result`
|
||||
and then returned, or calculated when the method is called.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def get_value_pairs(cls) -> Iterator[Tuple[str, str]]:
|
||||
"""Generator to yield pairs of inputs.
|
||||
|
||||
Combinations are first generated from all input values, and then
|
||||
specific cases provided.
|
||||
"""
|
||||
if cls.arity == 1:
|
||||
yield from ((a, "0") for a in cls.input_values)
|
||||
elif cls.arity == 2:
|
||||
if cls.unique_combinations_only:
|
||||
yield from combination_pairs(cls.input_values)
|
||||
else:
|
||||
yield from (
|
||||
(a, b)
|
||||
for a in cls.input_values
|
||||
for b in cls.input_values
|
||||
)
|
||||
else:
|
||||
raise ValueError("Unsupported number of operands!")
|
||||
|
||||
@classmethod
|
||||
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
|
||||
if cls.input_style not in cls.input_styles:
|
||||
raise ValueError("Unknown input style!")
|
||||
if cls.arity not in cls.arities:
|
||||
raise ValueError("Unsupported number of operands!")
|
||||
if cls.input_style == "arch_split":
|
||||
test_objects = (cls(a, b, bits_in_limb=bil)
|
||||
for a, b in cls.get_value_pairs()
|
||||
for bil in cls.limb_sizes)
|
||||
special_cases = (cls(*args, bits_in_limb=bil) # type: ignore
|
||||
for args in cls.input_cases
|
||||
for bil in cls.limb_sizes)
|
||||
else:
|
||||
test_objects = (cls(a, b)
|
||||
for a, b in cls.get_value_pairs())
|
||||
special_cases = (cls(*args) for args in cls.input_cases)
|
||||
yield from (valid_test_object.create_test_case()
|
||||
for valid_test_object in filter(
|
||||
lambda test_object: test_object.is_valid,
|
||||
chain(test_objects, special_cases)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class ModulusRepresentation(enum.Enum):
|
||||
"""Representation selector of a modulus."""
|
||||
# Numerical values aligned with the type mbedtls_mpi_mod_rep_selector
|
||||
INVALID = 0
|
||||
MONTGOMERY = 2
|
||||
OPT_RED = 3
|
||||
|
||||
def symbol(self) -> str:
|
||||
"""The C symbol for this representation selector."""
|
||||
return 'MBEDTLS_MPI_MOD_REP_' + self.name
|
||||
|
||||
@classmethod
|
||||
def supported_representations(cls) -> List['ModulusRepresentation']:
|
||||
"""Return all representations that are supported in positive test cases."""
|
||||
return [cls.MONTGOMERY, cls.OPT_RED]
|
||||
|
||||
|
||||
class ModOperationCommon(OperationCommon):
|
||||
#pylint: disable=abstract-method
|
||||
"""Target for bignum mod_raw test case generation."""
|
||||
moduli = MODULI_DEFAULT # type: List[str]
|
||||
montgomery_form_a = False
|
||||
disallow_zero_a = False
|
||||
|
||||
def __init__(self, val_n: str, val_a: str, val_b: str = "0",
|
||||
bits_in_limb: int = 64) -> None:
|
||||
super().__init__(val_a=val_a, val_b=val_b, bits_in_limb=bits_in_limb)
|
||||
self.val_n = val_n
|
||||
# Setting the int versions here as opposed to making them @properties
|
||||
# provides earlier/more robust input validation.
|
||||
self.int_n = hex_to_int(val_n)
|
||||
|
||||
def to_montgomery(self, val: int) -> int:
|
||||
return (val * self.r) % self.int_n
|
||||
|
||||
def from_montgomery(self, val: int) -> int:
|
||||
return (val * self.r_inv) % self.int_n
|
||||
|
||||
def convert_from_canonical(self, canonical: int,
|
||||
rep: ModulusRepresentation) -> int:
|
||||
"""Convert values from canonical representation to the given representation."""
|
||||
if rep is ModulusRepresentation.MONTGOMERY:
|
||||
return self.to_montgomery(canonical)
|
||||
elif rep is ModulusRepresentation.OPT_RED:
|
||||
return canonical
|
||||
else:
|
||||
raise ValueError('Modulus representation not supported: {}'
|
||||
.format(rep.name))
|
||||
|
||||
@property
|
||||
def boundary(self) -> int:
|
||||
return self.int_n
|
||||
|
||||
@property
|
||||
def arg_a(self) -> str:
|
||||
if self.montgomery_form_a:
|
||||
value_a = self.to_montgomery(self.int_a)
|
||||
else:
|
||||
value_a = self.int_a
|
||||
return self.format_arg('{:x}'.format(value_a))
|
||||
|
||||
@property
|
||||
def arg_n(self) -> str:
|
||||
return self.format_arg(self.val_n)
|
||||
|
||||
def format_arg(self, val: str) -> str:
|
||||
return super().format_arg(val).zfill(self.hex_digits)
|
||||
|
||||
def arguments(self) -> List[str]:
|
||||
return [quote_str(self.arg_n)] + super().arguments()
|
||||
|
||||
@property
|
||||
def r(self) -> int: # pylint: disable=invalid-name
|
||||
l = limbs_mpi(self.int_n, self.bits_in_limb)
|
||||
return bound_mpi_limbs(l, self.bits_in_limb)
|
||||
|
||||
@property
|
||||
def r_inv(self) -> int:
|
||||
return invmod(self.r, self.int_n)
|
||||
|
||||
@property
|
||||
def r2(self) -> int: # pylint: disable=invalid-name
|
||||
return pow(self.r, 2)
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
if self.int_a >= self.int_n:
|
||||
return False
|
||||
if self.disallow_zero_a and self.int_a == 0:
|
||||
return False
|
||||
if self.arity == 2 and self.int_b >= self.int_n:
|
||||
return False
|
||||
return True
|
||||
|
||||
def description(self) -> str:
|
||||
"""Generate a description for the test case.
|
||||
|
||||
It uses the form A `symbol` B mod N, where symbol is used to represent
|
||||
the operation.
|
||||
"""
|
||||
|
||||
if not self.case_description:
|
||||
return super().description() + " mod {:x}".format(self.int_n)
|
||||
return super().description()
|
||||
|
||||
@classmethod
|
||||
def input_cases_args(cls) -> Iterator[Tuple[Any, Any, Any]]:
|
||||
if cls.arity == 1:
|
||||
yield from ((n, a, "0") for a, n in cls.input_cases)
|
||||
elif cls.arity == 2:
|
||||
yield from ((n, a, b) for a, b, n in cls.input_cases)
|
||||
else:
|
||||
raise ValueError("Unsupported number of operands!")
|
||||
|
||||
@classmethod
|
||||
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
|
||||
if cls.input_style not in cls.input_styles:
|
||||
raise ValueError("Unknown input style!")
|
||||
if cls.arity not in cls.arities:
|
||||
raise ValueError("Unsupported number of operands!")
|
||||
if cls.input_style == "arch_split":
|
||||
test_objects = (cls(n, a, b, bits_in_limb=bil)
|
||||
for n in cls.moduli
|
||||
for a, b in cls.get_value_pairs()
|
||||
for bil in cls.limb_sizes)
|
||||
special_cases = (cls(*args, bits_in_limb=bil)
|
||||
for args in cls.input_cases_args()
|
||||
for bil in cls.limb_sizes)
|
||||
else:
|
||||
test_objects = (cls(n, a, b)
|
||||
for n in cls.moduli
|
||||
for a, b in cls.get_value_pairs())
|
||||
special_cases = (cls(*args) for args in cls.input_cases_args())
|
||||
yield from (valid_test_object.create_test_case()
|
||||
for valid_test_object in filter(
|
||||
lambda test_object: test_object.is_valid,
|
||||
chain(test_objects, special_cases)
|
||||
))
|
||||
896
externals/mbedtls/scripts/mbedtls_dev/bignum_core.py
vendored
896
externals/mbedtls/scripts/mbedtls_dev/bignum_core.py
vendored
@@ -1,896 +0,0 @@
|
||||
"""Framework classes for generation of bignum core test cases."""
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
import random
|
||||
|
||||
from typing import Dict, Iterator, List, Tuple
|
||||
|
||||
from . import test_case
|
||||
from . import test_data_generation
|
||||
from . import bignum_common
|
||||
from .bignum_data import ADD_SUB_DATA
|
||||
|
||||
class BignumCoreTarget(test_data_generation.BaseTarget):
|
||||
#pylint: disable=abstract-method, too-few-public-methods
|
||||
"""Target for bignum core test case generation."""
|
||||
target_basename = 'test_suite_bignum_core.generated'
|
||||
|
||||
|
||||
class BignumCoreShiftR(BignumCoreTarget, test_data_generation.BaseTest):
|
||||
"""Test cases for mbedtls_bignum_core_shift_r()."""
|
||||
count = 0
|
||||
test_function = "mpi_core_shift_r"
|
||||
test_name = "Core shift right"
|
||||
|
||||
DATA = [
|
||||
('00', '0', [0, 1, 8]),
|
||||
('01', '1', [0, 1, 2, 8, 64]),
|
||||
('dee5ca1a7ef10a75', '64-bit',
|
||||
list(range(11)) + [31, 32, 33, 63, 64, 65, 71, 72]),
|
||||
('002e7ab0070ad57001', '[leading 0 limb]',
|
||||
[0, 1, 8, 63, 64]),
|
||||
('a1055eb0bb1efa1150ff', '80-bit',
|
||||
[0, 1, 8, 63, 64, 65, 72, 79, 80, 81, 88, 128, 129, 136]),
|
||||
('020100000000000000001011121314151617', '138-bit',
|
||||
[0, 1, 8, 9, 16, 72, 73, 136, 137, 138, 144]),
|
||||
]
|
||||
|
||||
def __init__(self, input_hex: str, descr: str, count: int) -> None:
|
||||
self.input_hex = input_hex
|
||||
self.number_description = descr
|
||||
self.shift_count = count
|
||||
self.result = bignum_common.hex_to_int(input_hex) >> count
|
||||
|
||||
def arguments(self) -> List[str]:
|
||||
return ['"{}"'.format(self.input_hex),
|
||||
str(self.shift_count),
|
||||
'"{:0{}x}"'.format(self.result, len(self.input_hex))]
|
||||
|
||||
def description(self) -> str:
|
||||
return 'Core shift {} >> {}'.format(self.number_description,
|
||||
self.shift_count)
|
||||
|
||||
@classmethod
|
||||
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
|
||||
for input_hex, descr, counts in cls.DATA:
|
||||
for count in counts:
|
||||
yield cls(input_hex, descr, count).create_test_case()
|
||||
|
||||
|
||||
class BignumCoreShiftL(BignumCoreTarget, bignum_common.ModOperationCommon):
|
||||
"""Test cases for mbedtls_bignum_core_shift_l()."""
|
||||
|
||||
BIT_SHIFT_VALUES = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',
|
||||
'1f', '20', '21', '3f', '40', '41', '47', '48', '4f',
|
||||
'50', '51', '58', '80', '81', '88']
|
||||
DATA = ["0", "1", "40", "dee5ca1a7ef10a75", "a1055eb0bb1efa1150ff",
|
||||
"002e7ab0070ad57001", "020100000000000000001011121314151617",
|
||||
"1946e2958a85d8863ae21f4904fcc49478412534ed53eaf321f63f2a222"
|
||||
"7a3c63acbf50b6305595f90cfa8327f6db80d986fe96080bcbb5df1bdbe"
|
||||
"9b74fb8dedf2bddb3f8215b54dffd66409323bcc473e45a8fe9d08e77a51"
|
||||
"1698b5dad0416305db7fcf"]
|
||||
arity = 1
|
||||
test_function = "mpi_core_shift_l"
|
||||
test_name = "Core shift(L)"
|
||||
input_style = "arch_split"
|
||||
symbol = "<<"
|
||||
input_values = BIT_SHIFT_VALUES
|
||||
moduli = DATA
|
||||
|
||||
@property
|
||||
def val_n_max_limbs(self) -> int:
|
||||
""" Return the limb count required to store the maximum number that can
|
||||
fit in a the number of digits used by val_n """
|
||||
m = bignum_common.hex_digits_max_int(self.val_n, self.bits_in_limb) - 1
|
||||
return bignum_common.limbs_mpi(m, self.bits_in_limb)
|
||||
|
||||
def arguments(self) -> List[str]:
|
||||
return [bignum_common.quote_str(self.val_n),
|
||||
str(self.int_a)
|
||||
] + self.result()
|
||||
|
||||
def description(self) -> str:
|
||||
""" Format the output as:
|
||||
#{count} {hex input} ({input bits} {limbs capacity}) << {bit shift} """
|
||||
bits = "({} bits in {} limbs)".format(self.int_n.bit_length(), self.val_n_max_limbs)
|
||||
return "{} #{} {} {} {} {}".format(self.test_name,
|
||||
self.count,
|
||||
self.val_n,
|
||||
bits,
|
||||
self.symbol,
|
||||
self.int_a)
|
||||
|
||||
def format_result(self, res: int) -> str:
|
||||
# Override to match zero-pading for leading digits between the output and input.
|
||||
res_str = bignum_common.zfill_match(self.val_n, "{:x}".format(res))
|
||||
return bignum_common.quote_str(res_str)
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = (self.int_n << self.int_a)
|
||||
# Calculate if there is space for shifting to the left(leading zero limbs)
|
||||
mx = bignum_common.hex_digits_max_int(self.val_n, self.bits_in_limb)
|
||||
# If there are empty limbs ahead, adjust the bitmask accordingly
|
||||
result = result & (mx - 1)
|
||||
return [self.format_result(result)]
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
class BignumCoreCTLookup(BignumCoreTarget, test_data_generation.BaseTest):
|
||||
"""Test cases for mbedtls_mpi_core_ct_uint_table_lookup()."""
|
||||
test_function = "mpi_core_ct_uint_table_lookup"
|
||||
test_name = "Constant time MPI table lookup"
|
||||
|
||||
bitsizes = [
|
||||
(32, "One limb"),
|
||||
(192, "Smallest curve sized"),
|
||||
(512, "Largest curve sized"),
|
||||
(2048, "Small FF/RSA sized"),
|
||||
(4096, "Large FF/RSA sized"),
|
||||
]
|
||||
|
||||
window_sizes = [0, 1, 2, 3, 4, 5, 6]
|
||||
|
||||
def __init__(self,
|
||||
bitsize: int, descr: str, window_size: int) -> None:
|
||||
self.bitsize = bitsize
|
||||
self.bitsize_description = descr
|
||||
self.window_size = window_size
|
||||
|
||||
def arguments(self) -> List[str]:
|
||||
return [str(self.bitsize), str(self.window_size)]
|
||||
|
||||
def description(self) -> str:
|
||||
return '{} - {} MPI with {} bit window'.format(
|
||||
BignumCoreCTLookup.test_name,
|
||||
self.bitsize_description,
|
||||
self.window_size
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
|
||||
for bitsize, bitsize_description in cls.bitsizes:
|
||||
for window_size in cls.window_sizes:
|
||||
yield (cls(bitsize, bitsize_description, window_size)
|
||||
.create_test_case())
|
||||
|
||||
|
||||
class BignumCoreAddAndAddIf(BignumCoreTarget, bignum_common.OperationCommon):
|
||||
"""Test cases for bignum core add and add-if."""
|
||||
count = 0
|
||||
symbol = "+"
|
||||
test_function = "mpi_core_add_and_add_if"
|
||||
test_name = "mpi_core_add_and_add_if"
|
||||
input_style = "arch_split"
|
||||
input_values = ADD_SUB_DATA
|
||||
unique_combinations_only = True
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a + self.int_b
|
||||
|
||||
carry, result = divmod(result, self.limb_boundary)
|
||||
|
||||
return [
|
||||
self.format_result(result),
|
||||
str(carry)
|
||||
]
|
||||
|
||||
|
||||
class BignumCoreSub(BignumCoreTarget, bignum_common.OperationCommon):
|
||||
"""Test cases for bignum core sub."""
|
||||
count = 0
|
||||
input_style = "arch_split"
|
||||
symbol = "-"
|
||||
test_function = "mpi_core_sub"
|
||||
test_name = "mbedtls_mpi_core_sub"
|
||||
input_values = ADD_SUB_DATA
|
||||
|
||||
def result(self) -> List[str]:
|
||||
if self.int_a >= self.int_b:
|
||||
result = self.int_a - self.int_b
|
||||
carry = 0
|
||||
else:
|
||||
result = self.limb_boundary + self.int_a - self.int_b
|
||||
carry = 1
|
||||
return [
|
||||
self.format_result(result),
|
||||
str(carry)
|
||||
]
|
||||
|
||||
|
||||
class BignumCoreMLA(BignumCoreTarget, bignum_common.OperationCommon):
|
||||
"""Test cases for fixed-size multiply accumulate."""
|
||||
count = 0
|
||||
test_function = "mpi_core_mla"
|
||||
test_name = "mbedtls_mpi_core_mla"
|
||||
|
||||
input_values = [
|
||||
"0", "1", "fffe", "ffffffff", "100000000", "20000000000000",
|
||||
"ffffffffffffffff", "10000000000000000", "1234567890abcdef0",
|
||||
"fffffffffffffffffefefefefefefefe",
|
||||
"100000000000000000000000000000000",
|
||||
"1234567890abcdef01234567890abcdef0",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0",
|
||||
(
|
||||
"4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f"
|
||||
"34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf17"
|
||||
"9298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38"
|
||||
"edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec02507"
|
||||
"6b12b"
|
||||
)
|
||||
] # type: List[str]
|
||||
input_scalars = [
|
||||
"0", "3", "fe", "ff", "ffff", "10000", "ffffffff", "100000000",
|
||||
"7f7f7f7f7f7f7f7f", "8000000000000000", "fffffffffffffffe"
|
||||
] # type: List[str]
|
||||
|
||||
def __init__(self, val_a: str, val_b: str, val_s: str) -> None:
|
||||
super().__init__(val_a, val_b)
|
||||
self.arg_scalar = val_s
|
||||
self.int_scalar = bignum_common.hex_to_int(val_s)
|
||||
if bignum_common.limbs_mpi(self.int_scalar, 32) > 1:
|
||||
self.dependencies = ["MBEDTLS_HAVE_INT64"]
|
||||
|
||||
def arguments(self) -> List[str]:
|
||||
return [
|
||||
bignum_common.quote_str(self.arg_a),
|
||||
bignum_common.quote_str(self.arg_b),
|
||||
bignum_common.quote_str(self.arg_scalar)
|
||||
] + self.result()
|
||||
|
||||
def description(self) -> str:
|
||||
"""Override and add the additional scalar."""
|
||||
if not self.case_description:
|
||||
self.case_description = "0x{} + 0x{} * 0x{}".format(
|
||||
self.arg_a, self.arg_b, self.arg_scalar
|
||||
)
|
||||
return super().description()
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a + (self.int_b * self.int_scalar)
|
||||
bound_val = max(self.int_a, self.int_b)
|
||||
bound_4 = bignum_common.bound_mpi(bound_val, 32)
|
||||
bound_8 = bignum_common.bound_mpi(bound_val, 64)
|
||||
carry_4, remainder_4 = divmod(result, bound_4)
|
||||
carry_8, remainder_8 = divmod(result, bound_8)
|
||||
return [
|
||||
"\"{:x}\"".format(remainder_4),
|
||||
"\"{:x}\"".format(carry_4),
|
||||
"\"{:x}\"".format(remainder_8),
|
||||
"\"{:x}\"".format(carry_8)
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def get_value_pairs(cls) -> Iterator[Tuple[str, str]]:
|
||||
"""Generator to yield pairs of inputs.
|
||||
|
||||
Combinations are first generated from all input values, and then
|
||||
specific cases provided.
|
||||
"""
|
||||
yield from super().get_value_pairs()
|
||||
yield from cls.input_cases
|
||||
|
||||
@classmethod
|
||||
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
|
||||
"""Override for additional scalar input."""
|
||||
for a_value, b_value in cls.get_value_pairs():
|
||||
for s_value in cls.input_scalars:
|
||||
cur_op = cls(a_value, b_value, s_value)
|
||||
yield cur_op.create_test_case()
|
||||
|
||||
|
||||
class BignumCoreMul(BignumCoreTarget, bignum_common.OperationCommon):
|
||||
"""Test cases for bignum core multiplication."""
|
||||
count = 0
|
||||
input_style = "arch_split"
|
||||
symbol = "*"
|
||||
test_function = "mpi_core_mul"
|
||||
test_name = "mbedtls_mpi_core_mul"
|
||||
arity = 2
|
||||
unique_combinations_only = True
|
||||
|
||||
def format_arg(self, val: str) -> str:
|
||||
return val
|
||||
|
||||
def format_result(self, res: int) -> str:
|
||||
res_str = '{:x}'.format(res)
|
||||
a_limbs = bignum_common.limbs_mpi(self.int_a, self.bits_in_limb)
|
||||
b_limbs = bignum_common.limbs_mpi(self.int_b, self.bits_in_limb)
|
||||
hex_digits = bignum_common.hex_digits_for_limb(a_limbs + b_limbs, self.bits_in_limb)
|
||||
return bignum_common.quote_str(self.format_arg(res_str).zfill(hex_digits))
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a * self.int_b
|
||||
return [self.format_result(result)]
|
||||
|
||||
|
||||
class BignumCoreMontmul(BignumCoreTarget, test_data_generation.BaseTest):
|
||||
"""Test cases for Montgomery multiplication."""
|
||||
count = 0
|
||||
test_function = "mpi_core_montmul"
|
||||
test_name = "mbedtls_mpi_core_montmul"
|
||||
|
||||
start_2_mpi4 = False
|
||||
start_2_mpi8 = False
|
||||
|
||||
replay_test_cases = [
|
||||
(2, 1, 1, 1, "19", "1", "1D"), (2, 1, 1, 1, "7", "1", "9"),
|
||||
(2, 1, 1, 1, "4", "1", "9"),
|
||||
(
|
||||
12, 1, 6, 1, (
|
||||
"3C246D0E059A93A266288A7718419EC741661B474C58C032C5EDAF92709402"
|
||||
"B07CC8C7CE0B781C641A1EA8DB2F4343"
|
||||
), "1", (
|
||||
"66A198186C18C10B2F5ED9B522752A9830B69916E535C8F047518A889A43A5"
|
||||
"94B6BED27A168D31D4A52F88925AA8F5"
|
||||
)
|
||||
), (
|
||||
8, 1, 4, 1,
|
||||
"1E442976B0E63D64FCCE74B999E470CA9888165CB75BFA1F340E918CE03C6211",
|
||||
"1", "B3A119602EE213CDE28581ECD892E0F592A338655DCE4CA88054B3D124D0E561"
|
||||
), (
|
||||
22, 1, 11, 1, (
|
||||
"7CF5AC97304E0B63C65413F57249F59994B0FED1D2A8D3D83ED5FA38560FFB"
|
||||
"82392870D6D08F87D711917FD7537E13B7E125BE407E74157776839B0AC9DB"
|
||||
"23CBDFC696104353E4D2780B2B4968F8D8542306BCA7A2366E"
|
||||
), "1", (
|
||||
"284139EA19C139EBE09A8111926AAA39A2C2BE12ED487A809D3CB5BC558547"
|
||||
"25B4CDCB5734C58F90B2F60D99CC1950CDBC8D651793E93C9C6F0EAD752500"
|
||||
"A32C56C62082912B66132B2A6AA42ADA923E1AD22CEB7BA0123"
|
||||
)
|
||||
)
|
||||
] # type: List[Tuple[int, int, int, int, str, str, str]]
|
||||
|
||||
random_test_cases = [
|
||||
("2", "2", "3", ""), ("1", "2", "3", ""), ("2", "1", "3", ""),
|
||||
("6", "5", "7", ""), ("3", "4", "7", ""), ("1", "6", "7", ""), ("5", "6", "7", ""),
|
||||
("3", "4", "B", ""), ("7", "4", "B", ""), ("9", "7", "B", ""), ("2", "a", "B", ""),
|
||||
("25", "16", "29", "(0x29 is prime)"), ("8", "28", "29", ""),
|
||||
("18", "21", "29", ""), ("15", "f", "29", ""),
|
||||
("e2", "ea", "FF", ""), ("43", "72", "FF", ""),
|
||||
("d8", "70", "FF", ""), ("3c", "7c", "FF", ""),
|
||||
("99", "b9", "101", "(0x101 is prime)"), ("65", "b2", "101", ""),
|
||||
("81", "32", "101", ""), ("51", "dd", "101", ""),
|
||||
("d5", "143", "38B", "(0x38B is prime)"), ("3d", "387", "38B", ""),
|
||||
("160", "2e5", "38B", ""), ("10f", "137", "38B", ""),
|
||||
("7dac", "25a", "8003", "(0x8003 is prime)"), ("6f1c", "3286", "8003", ""),
|
||||
("59ed", "2f3f", "8003", ""), ("6893", "736d", "8003", ""),
|
||||
("d199", "2832", "10001", "(0x10001 is prime)"), ("c3b2", "3e5b", "10001", ""),
|
||||
("abe4", "214e", "10001", ""), ("4360", "a05d", "10001", ""),
|
||||
("3f5a1", "165b2", "7F7F7", ""), ("3bd29", "37863", "7F7F7", ""),
|
||||
("60c47", "64819", "7F7F7", ""), ("16584", "12c49", "7F7F7", ""),
|
||||
("1ff03f", "610347", "800009", "(0x800009 is prime)"), ("340fd5", "19812e", "800009", ""),
|
||||
("3fe2e8", "4d0dc7", "800009", ""), ("40356", "e6392", "800009", ""),
|
||||
("dd8a1d", "266c0e", "100002B", "(0x100002B is prime)"),
|
||||
("3fa1cb", "847fd6", "100002B", ""), ("5f439d", "5c3196", "100002B", ""),
|
||||
("18d645", "f72dc6", "100002B", ""),
|
||||
("20051ad", "37def6e", "37EEE9D", "(0x37EEE9D is prime)"),
|
||||
("2ec140b", "3580dbf", "37EEE9D", ""), ("1d91b46", "190d4fc", "37EEE9D", ""),
|
||||
("34e488d", "1224d24", "37EEE9D", ""),
|
||||
("2a4fe2cb", "263466a9", "8000000B", "(0x8000000B is prime)"),
|
||||
("5643fe94", "29a1aefa", "8000000B", ""), ("29633513", "7b007ac4", "8000000B", ""),
|
||||
("2439cef5", "5c9d5a47", "8000000B", ""),
|
||||
("4de3cfaa", "50dea178", "8CD626B9", "(0x8CD626B9 is prime)"),
|
||||
("b8b8563", "10dbbbac", "8CD626B9", ""), ("4e8a6151", "5574ec19", "8CD626B9", ""),
|
||||
("69224878", "309cfc23", "8CD626B9", ""),
|
||||
("fb6f7fb6", "afb05423", "10000000F", "(0x10000000F is prime)"),
|
||||
("8391a243", "26034dcd", "10000000F", ""), ("d26b98c", "14b2d6aa", "10000000F", ""),
|
||||
("6b9f1371", "a21daf1d", "10000000F", ""),
|
||||
(
|
||||
"9f49435ad", "c8264ade8", "174876E7E9",
|
||||
"0x174876E7E9 is prime (dec) 99999999977"
|
||||
),
|
||||
("c402da434", "1fb427acf", "174876E7E9", ""),
|
||||
("f6ebc2bb1", "1096d39f2a", "174876E7E9", ""),
|
||||
("153b7f7b6b", "878fda8ff", "174876E7E9", ""),
|
||||
("2c1adbb8d6", "4384d2d3c6", "8000000017", "(0x8000000017 is prime)"),
|
||||
("2e4f9cf5fb", "794f3443d9", "8000000017", ""),
|
||||
("149e495582", "3802b8f7b7", "8000000017", ""),
|
||||
("7b9d49df82", "69c68a442a", "8000000017", ""),
|
||||
("683a134600", "6dd80ea9f6", "864CB9076D", "(0x864CB9076D is prime)"),
|
||||
("13a870ff0d", "59b099694a", "864CB9076D", ""),
|
||||
("37d06b0e63", "4d2147e46f", "864CB9076D", ""),
|
||||
("661714f8f4", "22e55df507", "864CB9076D", ""),
|
||||
("2f0a96363", "52693307b4", "F7F7F7F7F7", ""),
|
||||
("3c85078e64", "f2275ecb6d", "F7F7F7F7F7", ""),
|
||||
("352dae68d1", "707775b4c6", "F7F7F7F7F7", ""),
|
||||
("37ae0f3e0b", "912113040f", "F7F7F7F7F7", ""),
|
||||
("6dada15e31", "f58ed9eff7", "1000000000F", "(0x1000000000F is prime)"),
|
||||
("69627a7c89", "cfb5ebd13d", "1000000000F", ""),
|
||||
("a5e1ad239b", "afc030c731", "1000000000F", ""),
|
||||
("f1cc45f4c5", "c64ad607c8", "1000000000F", ""),
|
||||
("2ebad87d2e31", "4c72d90bca78", "800000000005", "(0x800000000005 is prime)"),
|
||||
("a30b3cc50d", "29ac4fe59490", "800000000005", ""),
|
||||
("33674e9647b4", "5ec7ee7e72d3", "800000000005", ""),
|
||||
("3d956f474f61", "74070040257d", "800000000005", ""),
|
||||
("48348e3717d6", "43fcb4399571", "800795D9BA47", "(0x800795D9BA47 is prime)"),
|
||||
("5234c03cc99b", "2f3cccb87803", "800795D9BA47", ""),
|
||||
("3ed13db194ab", "44b8f4ba7030", "800795D9BA47", ""),
|
||||
("1c11e843bfdb", "95bd1b47b08", "800795D9BA47", ""),
|
||||
("a81d11cb81fd", "1e5753a3f33d", "1000000000015", "(0x1000000000015 is prime)"),
|
||||
("688c4db99232", "36fc0cf7ed", "1000000000015", ""),
|
||||
("f0720cc07e07", "fc76140ed903", "1000000000015", ""),
|
||||
("2ec61f8d17d1", "d270c85e36d2", "1000000000015", ""),
|
||||
(
|
||||
"6a24cd3ab63820", "ed4aad55e5e348", "100000000000051",
|
||||
"(0x100000000000051 is prime)"
|
||||
),
|
||||
("e680c160d3b248", "31e0d8840ed510", "100000000000051", ""),
|
||||
("a80637e9aebc38", "bb81decc4e1738", "100000000000051", ""),
|
||||
("9afa5a59e9d630", "be9e65a6d42938", "100000000000051", ""),
|
||||
("ab5e104eeb71c000", "2cffbd639e9fea00", "ABCDEF0123456789", ""),
|
||||
("197b867547f68a00", "44b796cf94654800", "ABCDEF0123456789", ""),
|
||||
("329f9483a04f2c00", "9892f76961d0f000", "ABCDEF0123456789", ""),
|
||||
("4a2e12dfb4545000", "1aa3e89a69794500", "ABCDEF0123456789", ""),
|
||||
(
|
||||
"8b9acdf013d140f000", "12e4ceaefabdf2b2f00", "25A55A46E5DA99C71C7",
|
||||
"0x25A55A46E5DA99C71C7 is the 3rd repunit prime(dec) 11111111111111111111111"
|
||||
),
|
||||
("1b8d960ea277e3f5500", "14418aa980e37dd000", "25A55A46E5DA99C71C7", ""),
|
||||
("7314524977e8075980", "8172fa45618ccd0d80", "25A55A46E5DA99C71C7", ""),
|
||||
("ca14f031769be63580", "147a2f3cf2964ca9400", "25A55A46E5DA99C71C7", ""),
|
||||
(
|
||||
"18532ba119d5cd0cf39735c0000", "25f9838e31634844924733000000",
|
||||
"314DC643FB763F2B8C0E2DE00879",
|
||||
"0x314DC643FB763F2B8C0E2DE00879 is (dec)99999999977^3"
|
||||
),
|
||||
(
|
||||
"a56e2d2517519e3970e70c40000", "ec27428d4bb380458588fa80000",
|
||||
"314DC643FB763F2B8C0E2DE00879", ""
|
||||
),
|
||||
(
|
||||
"1cb5e8257710e8653fff33a00000", "15fdd42fe440fd3a1d121380000",
|
||||
"314DC643FB763F2B8C0E2DE00879", ""
|
||||
),
|
||||
(
|
||||
"e50d07a65fc6f93e538ce040000", "1f4b059ca609f3ce597f61240000",
|
||||
"314DC643FB763F2B8C0E2DE00879", ""
|
||||
),
|
||||
(
|
||||
"1ea3ade786a095d978d387f30df9f20000000",
|
||||
"127c448575f04af5a367a7be06c7da0000000",
|
||||
"47BF19662275FA2F6845C74942ED1D852E521",
|
||||
"0x47BF19662275FA2F6845C74942ED1D852E521 is (dec) 99999999977^4"
|
||||
),
|
||||
(
|
||||
"16e15b0ca82764e72e38357b1f10a20000000",
|
||||
"43e2355d8514bbe22b0838fdc3983a0000000",
|
||||
"47BF19662275FA2F6845C74942ED1D852E521", ""
|
||||
),
|
||||
(
|
||||
"be39332529d93f25c3d116c004c620000000",
|
||||
"5cccec42370a0a2c89c6772da801a0000000",
|
||||
"47BF19662275FA2F6845C74942ED1D852E521", ""
|
||||
),
|
||||
(
|
||||
"ecaa468d90de0eeda474d39b3e1fc0000000",
|
||||
"1e714554018de6dc0fe576bfd3b5660000000",
|
||||
"47BF19662275FA2F6845C74942ED1D852E521", ""
|
||||
),
|
||||
(
|
||||
"32298816711c5dce46f9ba06e775c4bedfc770e6700000000000000",
|
||||
"8ee751fd5fb24f0b4a653cb3a0c8b7d9e724574d168000000000000",
|
||||
"97EDD86E4B5C4592C6D32064AC55C888A7245F07CA3CC455E07C931",
|
||||
(
|
||||
"0x97EDD86E4B5C4592C6D32064AC55C888A7245F07CA3CC455E07C931"
|
||||
" is (dec) 99999999977^6"
|
||||
)
|
||||
),
|
||||
(
|
||||
"29213b9df3cfd15f4b428645b67b677c29d1378d810000000000000",
|
||||
"6cbb732c65e10a28872394dfdd1936d5171c3c3aac0000000000000",
|
||||
"97EDD86E4B5C4592C6D32064AC55C888A7245F07CA3CC455E07C931", ""
|
||||
),
|
||||
(
|
||||
"6f18db06ad4abc52c0c50643dd13098abccd4a232f0000000000000",
|
||||
"7e6bf41f2a86098ad51f98dfc10490ba3e8081bc830000000000000",
|
||||
"97EDD86E4B5C4592C6D32064AC55C888A7245F07CA3CC455E07C931", ""
|
||||
),
|
||||
(
|
||||
"62d3286cd706ad9d73caff63f1722775d7e8c731208000000000000",
|
||||
"530f7ba02ae2b04c2fe3e3d27ec095925631a6c2528000000000000",
|
||||
"97EDD86E4B5C4592C6D32064AC55C888A7245F07CA3CC455E07C931", ""
|
||||
),
|
||||
(
|
||||
"a6c6503e3c031fdbf6009a89ed60582b7233c5a85de28b16000000000000000",
|
||||
"75c8ed18270b583f16d442a467d32bf95c5e491e9b8523798000000000000000",
|
||||
"DD15FE80B731872AC104DB37832F7E75A244AA2631BC87885B861E8F20375499",
|
||||
(
|
||||
"0xDD15FE80B731872AC104DB37832F7E75A244AA2631BC87885B861E8F20375499"
|
||||
" is (dec) 99999999977^7"
|
||||
)
|
||||
),
|
||||
(
|
||||
"bf84d1f85cf6b51e04d2c8f4ffd03532d852053cf99b387d4000000000000000",
|
||||
"397ba5a743c349f4f28bc583ecd5f06e0a25f9c6d98f09134000000000000000",
|
||||
"DD15FE80B731872AC104DB37832F7E75A244AA2631BC87885B861E8F20375499", ""
|
||||
),
|
||||
(
|
||||
"6db11c3a4152ed1a2aa6fa34b0903ec82ea1b88908dcb482000000000000000",
|
||||
"ac8ac576a74ad6ca48f201bf89f77350ce86e821358d85920000000000000000",
|
||||
"DD15FE80B731872AC104DB37832F7E75A244AA2631BC87885B861E8F20375499", ""
|
||||
),
|
||||
(
|
||||
"3001d96d7fe8b733f33687646fc3017e3ac417eb32e0ec708000000000000000",
|
||||
"925ddbdac4174e8321a48a32f79640e8cf7ec6f46ea235a80000000000000000",
|
||||
"DD15FE80B731872AC104DB37832F7E75A244AA2631BC87885B861E8F20375499", ""
|
||||
),
|
||||
(
|
||||
"1029048755f2e60dd98c8de6d9989226b6bb4f0db8e46bd1939de560000000000000000000",
|
||||
"51bb7270b2e25cec0301a03e8275213bb6c2f6e6ec93d4d46d36ca0000000000000000000",
|
||||
"141B8EBD9009F84C241879A1F680FACCED355DA36C498F73E96E880CF78EA5F96146380E41",
|
||||
(
|
||||
"0x141B8EBD9009F84C241879A1F680FACCED355DA36C498F73E96E880CF78EA5F96146"
|
||||
"380E41 is 99999999977^8"
|
||||
)
|
||||
),
|
||||
(
|
||||
"1c5337ff982b3ad6611257dbff5bbd7a9920ba2d4f5838a0cc681ce000000000000000000",
|
||||
"520c5d049ca4702031ba728591b665c4d4ccd3b2b86864d4c160fd2000000000000000000",
|
||||
"141B8EBD9009F84C241879A1F680FACCED355DA36C498F73E96E880CF78EA5F96146380E41",
|
||||
""
|
||||
),
|
||||
(
|
||||
"57074dfa00e42f6555bae624b7f0209f218adf57f73ed34ab0ff90c000000000000000000",
|
||||
"41eb14b6c07bfd3d1fe4f4a610c17cc44fcfcda695db040e011065000000000000000000",
|
||||
"141B8EBD9009F84C241879A1F680FACCED355DA36C498F73E96E880CF78EA5F96146380E41",
|
||||
""
|
||||
),
|
||||
(
|
||||
"d8ed7feed2fe855e6997ad6397f776158573d425031bf085a615784000000000000000000",
|
||||
"6f121dcd18c578ab5e229881006007bb6d319b179f11015fe958b9c000000000000000000",
|
||||
"141B8EBD9009F84C241879A1F680FACCED355DA36C498F73E96E880CF78EA5F96146380E41",
|
||||
""
|
||||
),
|
||||
(
|
||||
(
|
||||
"2a462b156180ea5fe550d3758c764e06fae54e626b5f503265a09df76edbdfbf"
|
||||
"a1e6000000000000000000000000"
|
||||
), (
|
||||
"1136f41d1879fd4fb9e49e0943a46b6704d77c068ee237c3121f9071cfd3e6a0"
|
||||
"0315800000000000000000000000"
|
||||
), (
|
||||
"2A94608DE88B6D5E9F8920F5ABB06B24CC35AE1FBACC87D075C621C3E2833EC90"
|
||||
"2713E40F51E3B3C214EDFABC451"
|
||||
), (
|
||||
"0x2A94608DE88B6D5E9F8920F5ABB06B24CC35AE1FBACC87D075C621C3E2833EC"
|
||||
"902713E40F51E3B3C214EDFABC451 is (dec) 99999999977^10"
|
||||
)
|
||||
),
|
||||
(
|
||||
(
|
||||
"c1ac3800dfb3c6954dea391d206200cf3c47f795bf4a5603b4cb88ae7e574de47"
|
||||
"40800000000000000000000000"
|
||||
), (
|
||||
"c0d16eda0549ede42fa0deb4635f7b7ce061fadea02ee4d85cba4c4f709603419"
|
||||
"3c800000000000000000000000"
|
||||
), (
|
||||
"2A94608DE88B6D5E9F8920F5ABB06B24CC35AE1FBACC87D075C621C3E2833EC90"
|
||||
"2713E40F51E3B3C214EDFABC451"
|
||||
), ""
|
||||
),
|
||||
(
|
||||
(
|
||||
"19e45bb7633094d272588ad2e43bcb3ee341991c6731b6fa9d47c4018d7ce7bba"
|
||||
"5ee800000000000000000000000"
|
||||
), (
|
||||
"1e4f83166ae59f6b9cc8fd3e7677ed8bfc01bb99c98bd3eb084246b64c1e18c33"
|
||||
"65b800000000000000000000000"
|
||||
), (
|
||||
"2A94608DE88B6D5E9F8920F5ABB06B24CC35AE1FBACC87D075C621C3E2833EC90"
|
||||
"2713E40F51E3B3C214EDFABC451"
|
||||
), ""
|
||||
),
|
||||
(
|
||||
(
|
||||
"1aa93395fad5f9b7f20b8f9028a054c0bb7c11bb8520e6a95e5a34f06cb70bcdd"
|
||||
"01a800000000000000000000000"
|
||||
), (
|
||||
"54b45afa5d4310192f8d224634242dd7dcfb342318df3d9bd37b4c614788ba13b"
|
||||
"8b000000000000000000000000"
|
||||
), (
|
||||
"2A94608DE88B6D5E9F8920F5ABB06B24CC35AE1FBACC87D075C621C3E2833EC90"
|
||||
"2713E40F51E3B3C214EDFABC451"
|
||||
), ""
|
||||
),
|
||||
(
|
||||
(
|
||||
"544f2628a28cfb5ce0a1b7180ee66b49716f1d9476c466c57f0c4b23089917843"
|
||||
"06d48f78686115ee19e25400000000000000000000000000000000"
|
||||
), (
|
||||
"677eb31ef8d66c120fa872a60cd47f6e10cbfdf94f90501bd7883cba03d185be0"
|
||||
"a0148d1625745e9c4c827300000000000000000000000000000000"
|
||||
), (
|
||||
"8335616AED761F1F7F44E6BD49E807B82E3BF2BF11BFA6AF813C808DBF33DBFA1"
|
||||
"1DABD6E6144BEF37C6800000000000000000000000000000000051"
|
||||
), (
|
||||
"0x8335616AED761F1F7F44E6BD49E807B82E3BF2BF11BFA6AF813C808DBF33DBF"
|
||||
"A11DABD6E6144BEF37C6800000000000000000000000000000000051 is prime,"
|
||||
" (dec) 10^143 + 3^4"
|
||||
)
|
||||
),
|
||||
(
|
||||
(
|
||||
"76bb3470985174915e9993522aec989666908f9e8cf5cb9f037bf4aee33d8865c"
|
||||
"b6464174795d07e30015b80000000000000000000000000000000"
|
||||
), (
|
||||
"6aaaf60d5784dcef612d133613b179a317532ecca0eed40b8ad0c01e6d4a6d8c7"
|
||||
"9a52af190abd51739009a900000000000000000000000000000000"
|
||||
), (
|
||||
"8335616AED761F1F7F44E6BD49E807B82E3BF2BF11BFA6AF813C808DBF33DBFA1"
|
||||
"1DABD6E6144BEF37C6800000000000000000000000000000000051"
|
||||
), ""
|
||||
),
|
||||
(
|
||||
(
|
||||
"6cfdd6e60912e441d2d1fc88f421b533f0103a5322ccd3f4db84861643ad63fd6"
|
||||
"3d1d8cfbc1d498162786ba00000000000000000000000000000000"
|
||||
), (
|
||||
"1177246ec5e93814816465e7f8f248b350d954439d35b2b5d75d917218e7fd5fb"
|
||||
"4c2f6d0667f9467fdcf33400000000000000000000000000000000"
|
||||
), (
|
||||
"8335616AED761F1F7F44E6BD49E807B82E3BF2BF11BFA6AF813C808DBF33DBFA1"
|
||||
"1DABD6E6144BEF37C6800000000000000000000000000000000051"
|
||||
), ""
|
||||
),
|
||||
(
|
||||
(
|
||||
"7a09a0b0f8bbf8057116fb0277a9bdf3a91b5eaa8830d448081510d8973888be5"
|
||||
"a9f0ad04facb69aa3715f00000000000000000000000000000000"
|
||||
), (
|
||||
"764dec6c05a1c0d87b649efa5fd94c91ea28bffb4725d4ab4b33f1a3e8e3b314d"
|
||||
"799020e244a835a145ec9800000000000000000000000000000000"
|
||||
), (
|
||||
"8335616AED761F1F7F44E6BD49E807B82E3BF2BF11BFA6AF813C808DBF33DBFA1"
|
||||
"1DABD6E6144BEF37C6800000000000000000000000000000000051"
|
||||
), ""
|
||||
)
|
||||
] # type: List[Tuple[str, str, str, str]]
|
||||
|
||||
def __init__(
|
||||
self, val_a: str, val_b: str, val_n: str, case_description: str = ""
|
||||
):
|
||||
self.case_description = case_description
|
||||
self.arg_a = val_a
|
||||
self.int_a = bignum_common.hex_to_int(val_a)
|
||||
self.arg_b = val_b
|
||||
self.int_b = bignum_common.hex_to_int(val_b)
|
||||
self.arg_n = val_n
|
||||
self.int_n = bignum_common.hex_to_int(val_n)
|
||||
|
||||
limbs_a4 = bignum_common.limbs_mpi(self.int_a, 32)
|
||||
limbs_a8 = bignum_common.limbs_mpi(self.int_a, 64)
|
||||
self.limbs_b4 = bignum_common.limbs_mpi(self.int_b, 32)
|
||||
self.limbs_b8 = bignum_common.limbs_mpi(self.int_b, 64)
|
||||
self.limbs_an4 = bignum_common.limbs_mpi(self.int_n, 32)
|
||||
self.limbs_an8 = bignum_common.limbs_mpi(self.int_n, 64)
|
||||
|
||||
if limbs_a4 > self.limbs_an4 or limbs_a8 > self.limbs_an8:
|
||||
raise Exception("Limbs of input A ({}) exceeds N ({})".format(
|
||||
self.arg_a, self.arg_n
|
||||
))
|
||||
|
||||
def arguments(self) -> List[str]:
|
||||
return [
|
||||
str(self.limbs_an4), str(self.limbs_b4),
|
||||
str(self.limbs_an8), str(self.limbs_b8),
|
||||
bignum_common.quote_str(self.arg_a),
|
||||
bignum_common.quote_str(self.arg_b),
|
||||
bignum_common.quote_str(self.arg_n)
|
||||
] + self.result()
|
||||
|
||||
def description(self) -> str:
|
||||
if self.case_description != "replay":
|
||||
if not self.start_2_mpi4 and self.limbs_an4 > 1:
|
||||
tmp = "(start of 2-MPI 4-byte bignums) "
|
||||
self.__class__.start_2_mpi4 = True
|
||||
elif not self.start_2_mpi8 and self.limbs_an8 > 1:
|
||||
tmp = "(start of 2-MPI 8-byte bignums) "
|
||||
self.__class__.start_2_mpi8 = True
|
||||
else:
|
||||
tmp = "(gen) "
|
||||
self.case_description = tmp + self.case_description
|
||||
return super().description()
|
||||
|
||||
def result(self) -> List[str]:
|
||||
"""Get the result of the operation."""
|
||||
r4 = bignum_common.bound_mpi_limbs(self.limbs_an4, 32)
|
||||
i4 = bignum_common.invmod(r4, self.int_n)
|
||||
x4 = self.int_a * self.int_b * i4
|
||||
x4 = x4 % self.int_n
|
||||
|
||||
r8 = bignum_common.bound_mpi_limbs(self.limbs_an8, 64)
|
||||
i8 = bignum_common.invmod(r8, self.int_n)
|
||||
x8 = self.int_a * self.int_b * i8
|
||||
x8 = x8 % self.int_n
|
||||
return [
|
||||
"\"{:x}\"".format(x4),
|
||||
"\"{:x}\"".format(x8)
|
||||
]
|
||||
|
||||
def set_limbs(
|
||||
self, limbs_an4: int, limbs_b4: int, limbs_an8: int, limbs_b8: int
|
||||
) -> None:
|
||||
"""Set number of limbs for each input.
|
||||
|
||||
Replaces default values set during initialization.
|
||||
"""
|
||||
self.limbs_an4 = limbs_an4
|
||||
self.limbs_b4 = limbs_b4
|
||||
self.limbs_an8 = limbs_an8
|
||||
self.limbs_b8 = limbs_b8
|
||||
|
||||
@classmethod
|
||||
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
|
||||
"""Generate replay and randomly generated test cases."""
|
||||
# Test cases which replay captured invocations during unit test runs.
|
||||
for limbs_an4, limbs_b4, limbs_an8, limbs_b8, a, b, n in cls.replay_test_cases:
|
||||
cur_op = cls(a, b, n, case_description="replay")
|
||||
cur_op.set_limbs(limbs_an4, limbs_b4, limbs_an8, limbs_b8)
|
||||
yield cur_op.create_test_case()
|
||||
# Random test cases can be generated using mpi_modmul_case_generate()
|
||||
# Uses a mixture of primes and odd numbers as N, with four randomly
|
||||
# generated cases for each N.
|
||||
for a, b, n, description in cls.random_test_cases:
|
||||
cur_op = cls(a, b, n, case_description=description)
|
||||
yield cur_op.create_test_case()
|
||||
|
||||
|
||||
def mpi_modmul_case_generate() -> None:
|
||||
"""Generate valid inputs for montmul tests using moduli.
|
||||
|
||||
For each modulus, generates random values for A and B and simple descriptions
|
||||
for the test case.
|
||||
"""
|
||||
moduli = [
|
||||
("3", ""), ("7", ""), ("B", ""), ("29", ""), ("FF", ""),
|
||||
("101", ""), ("38B", ""), ("8003", ""), ("10001", ""),
|
||||
("7F7F7", ""), ("800009", ""), ("100002B", ""), ("37EEE9D", ""),
|
||||
("8000000B", ""), ("8CD626B9", ""), ("10000000F", ""),
|
||||
("174876E7E9", "is prime (dec) 99999999977"),
|
||||
("8000000017", ""), ("864CB9076D", ""), ("F7F7F7F7F7", ""),
|
||||
("1000000000F", ""), ("800000000005", ""), ("800795D9BA47", ""),
|
||||
("1000000000015", ""), ("100000000000051", ""), ("ABCDEF0123456789", ""),
|
||||
(
|
||||
"25A55A46E5DA99C71C7",
|
||||
"is the 3rd repunit prime (dec) 11111111111111111111111"
|
||||
),
|
||||
("314DC643FB763F2B8C0E2DE00879", "is (dec)99999999977^3"),
|
||||
("47BF19662275FA2F6845C74942ED1D852E521", "is (dec) 99999999977^4"),
|
||||
(
|
||||
"97EDD86E4B5C4592C6D32064AC55C888A7245F07CA3CC455E07C931",
|
||||
"is (dec) 99999999977^6"
|
||||
),
|
||||
(
|
||||
"DD15FE80B731872AC104DB37832F7E75A244AA2631BC87885B861E8F20375499",
|
||||
"is (dec) 99999999977^7"
|
||||
),
|
||||
(
|
||||
"141B8EBD9009F84C241879A1F680FACCED355DA36C498F73E96E880CF78EA5F96146380E41",
|
||||
"is (dec) 99999999977^8"
|
||||
),
|
||||
(
|
||||
(
|
||||
"2A94608DE88B6D5E9F8920F5ABB06B24CC35AE1FBACC87D075C621C3E283"
|
||||
"3EC902713E40F51E3B3C214EDFABC451"
|
||||
),
|
||||
"is (dec) 99999999977^10"
|
||||
),
|
||||
(
|
||||
"8335616AED761F1F7F44E6BD49E807B82E3BF2BF11BFA6AF813C808DBF33DBFA11"
|
||||
"DABD6E6144BEF37C6800000000000000000000000000000000051",
|
||||
"is prime, (dec) 10^143 + 3^4"
|
||||
)
|
||||
] # type: List[Tuple[str, str]]
|
||||
primes = [
|
||||
"3", "7", "B", "29", "101", "38B", "8003", "10001", "800009",
|
||||
"100002B", "37EEE9D", "8000000B", "8CD626B9",
|
||||
# From here they require > 1 4-byte MPI
|
||||
"10000000F", "174876E7E9", "8000000017", "864CB9076D", "1000000000F",
|
||||
"800000000005", "800795D9BA47", "1000000000015", "100000000000051",
|
||||
# From here they require > 1 8-byte MPI
|
||||
"25A55A46E5DA99C71C7", # this is 11111111111111111111111 decimal
|
||||
# 10^143 + 3^4: (which is prime)
|
||||
# 100000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
# 000000000000000000000000000000000000000000000000000000000000000081
|
||||
(
|
||||
"8335616AED761F1F7F44E6BD49E807B82E3BF2BF11BFA6AF813C808DBF33DBFA11"
|
||||
"DABD6E6144BEF37C6800000000000000000000000000000000051"
|
||||
)
|
||||
] # type: List[str]
|
||||
generated_inputs = []
|
||||
for mod, description in moduli:
|
||||
n = bignum_common.hex_to_int(mod)
|
||||
mod_read = "{:x}".format(n)
|
||||
case_count = 3 if n < 5 else 4
|
||||
cases = {} # type: Dict[int, int]
|
||||
i = 0
|
||||
while i < case_count:
|
||||
a = random.randint(1, n)
|
||||
b = random.randint(1, n)
|
||||
if cases.get(a) == b:
|
||||
continue
|
||||
cases[a] = b
|
||||
if description:
|
||||
out_description = "0x{} {}".format(mod_read, description)
|
||||
elif i == 0 and len(mod) > 1 and mod in primes:
|
||||
out_description = "(0x{} is prime)"
|
||||
else:
|
||||
out_description = ""
|
||||
generated_inputs.append(
|
||||
("{:x}".format(a), "{:x}".format(b), mod, out_description)
|
||||
)
|
||||
i += 1
|
||||
print(generated_inputs)
|
||||
|
||||
|
||||
class BignumCoreExpMod(BignumCoreTarget, bignum_common.ModOperationCommon):
|
||||
"""Test cases for bignum core exponentiation."""
|
||||
symbol = "^"
|
||||
test_function = "mpi_core_exp_mod"
|
||||
test_name = "Core modular exponentiation (Mongtomery form only)"
|
||||
input_style = "fixed"
|
||||
montgomery_form_a = True
|
||||
|
||||
def result(self) -> List[str]:
|
||||
# Result has to be given in Montgomery form too
|
||||
result = pow(self.int_a, self.int_b, self.int_n)
|
||||
mont_result = self.to_montgomery(result)
|
||||
return [self.format_result(mont_result)]
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
# The base needs to be canonical, but the exponent can be larger than
|
||||
# the modulus (see for example exponent blinding)
|
||||
return bool(self.int_a < self.int_n)
|
||||
|
||||
|
||||
class BignumCoreSubInt(BignumCoreTarget, bignum_common.OperationCommon):
|
||||
"""Test cases for bignum core sub int."""
|
||||
count = 0
|
||||
symbol = "-"
|
||||
test_function = "mpi_core_sub_int"
|
||||
test_name = "mpi_core_sub_int"
|
||||
input_style = "arch_split"
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
# This is "sub int", so b is only one limb
|
||||
if bignum_common.limbs_mpi(self.int_b, self.bits_in_limb) > 1:
|
||||
return False
|
||||
return True
|
||||
|
||||
# Overriding because we don't want leading zeros on b
|
||||
@property
|
||||
def arg_b(self) -> str:
|
||||
return self.val_b
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a - self.int_b
|
||||
|
||||
borrow, result = divmod(result, self.limb_boundary)
|
||||
|
||||
# Borrow will be -1 if non-zero, but we want it to be 1 in the test data
|
||||
return [
|
||||
self.format_result(result),
|
||||
str(-borrow)
|
||||
]
|
||||
|
||||
class BignumCoreZeroCheckCT(BignumCoreTarget, bignum_common.OperationCommon):
|
||||
"""Test cases for bignum core zero check (constant flow)."""
|
||||
count = 0
|
||||
symbol = "== 0"
|
||||
test_function = "mpi_core_check_zero_ct"
|
||||
test_name = "mpi_core_check_zero_ct"
|
||||
input_style = "variable"
|
||||
arity = 1
|
||||
suffix = True
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = 1 if self.int_a == 0 else 0
|
||||
return [str(result)]
|
||||
159
externals/mbedtls/scripts/mbedtls_dev/bignum_data.py
vendored
159
externals/mbedtls/scripts/mbedtls_dev/bignum_data.py
vendored
@@ -1,159 +0,0 @@
|
||||
"""Base values and datasets for bignum generated tests and helper functions that
|
||||
produced them."""
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
import random
|
||||
|
||||
# Functions calling these were used to produce test data and are here only for
|
||||
# reproducibility, they are not used by the test generation framework/classes
|
||||
try:
|
||||
from Cryptodome.Util.number import isPrime, getPrime #type: ignore #pylint: disable=import-error
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Generated by bignum_common.gen_safe_prime(192,1)
|
||||
SAFE_PRIME_192_BIT_SEED_1 = "d1c127a667786703830500038ebaef20e5a3e2dc378fb75b"
|
||||
|
||||
# First number generated by random.getrandbits(192) - seed(2,2), not a prime
|
||||
RANDOM_192_BIT_SEED_2_NO1 = "177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"
|
||||
|
||||
# Second number generated by random.getrandbits(192) - seed(2,2), not a prime
|
||||
RANDOM_192_BIT_SEED_2_NO2 = "cf1822ffbc6887782b491044d5e341245c6e433715ba2bdd"
|
||||
|
||||
# Third number generated by random.getrandbits(192) - seed(2,2), not a prime
|
||||
RANDOM_192_BIT_SEED_2_NO3 = "3653f8dd9b1f282e4067c3584ee207f8da94e3e8ab73738f"
|
||||
|
||||
# Fourth number generated by random.getrandbits(192) - seed(2,2), not a prime
|
||||
RANDOM_192_BIT_SEED_2_NO4 = "ffed9235288bc781ae66267594c9c9500925e4749b575bd1"
|
||||
|
||||
# Ninth number generated by random.getrandbits(192) - seed(2,2), not a prime
|
||||
RANDOM_192_BIT_SEED_2_NO9 = "2a1be9cd8697bbd0e2520e33e44c50556c71c4a66148a86f"
|
||||
|
||||
# Generated by bignum_common.gen_safe_prime(1024,3)
|
||||
SAFE_PRIME_1024_BIT_SEED_3 = ("c93ba7ec74d96f411ba008bdb78e63ff11bb5df46a51e16b"
|
||||
"2c9d156f8e4e18abf5e052cb01f47d0d1925a77f60991577"
|
||||
"e128fb6f52f34a27950a594baadd3d8057abeb222cf3cca9"
|
||||
"62db16abf79f2ada5bd29ab2f51244bf295eff9f6aaba130"
|
||||
"2efc449b128be75eeaca04bc3c1a155d11d14e8be32a2c82"
|
||||
"87b3996cf6ad5223")
|
||||
|
||||
# First number generated by random.getrandbits(1024) - seed(4,2), not a prime
|
||||
RANDOM_1024_BIT_SEED_4_NO1 = ("6905269ed6f0b09f165c8ce36e2f24b43000de01b2ed40ed"
|
||||
"3addccb2c33be0ac79d679346d4ac7a5c3902b38963dc6e8"
|
||||
"534f45738d048ec0f1099c6c3e1b258fd724452ccea71ff4"
|
||||
"a14876aeaff1a098ca5996666ceab360512bd13110722311"
|
||||
"710cf5327ac435a7a97c643656412a9b8a1abcd1a6916c74"
|
||||
"da4f9fc3c6da5d7")
|
||||
|
||||
# Second number generated by random.getrandbits(1024) - seed(4,2), not a prime
|
||||
RANDOM_1024_BIT_SEED_4_NO2 = ("f1cfd99216df648647adec26793d0e453f5082492d83a823"
|
||||
"3fb62d2c81862fc9634f806fabf4a07c566002249b191bf4"
|
||||
"d8441b5616332aca5f552773e14b0190d93936e1daca3c06"
|
||||
"f5ff0c03bb5d7385de08caa1a08179104a25e4664f5253a0"
|
||||
"2a3187853184ff27459142deccea264542a00403ce80c4b0"
|
||||
"a4042bb3d4341aad")
|
||||
|
||||
# Third number generated by random.getrandbits(1024) - seed(4,2), not a prime
|
||||
RANDOM_1024_BIT_SEED_4_NO3 = ("14c15c910b11ad28cc21ce88d0060cc54278c2614e1bcb38"
|
||||
"3bb4a570294c4ea3738d243a6e58d5ca49c7b59b995253fd"
|
||||
"6c79a3de69f85e3131f3b9238224b122c3e4a892d9196ada"
|
||||
"4fcfa583e1df8af9b474c7e89286a1754abcb06ae8abb93f"
|
||||
"01d89a024cdce7a6d7288ff68c320f89f1347e0cdd905ecf"
|
||||
"d160c5d0ef412ed6")
|
||||
|
||||
# Fourth number generated by random.getrandbits(1024) - seed(4,2), not a prime
|
||||
RANDOM_1024_BIT_SEED_4_NO4 = ("32decd6b8efbc170a26a25c852175b7a96b98b5fbf37a2be"
|
||||
"6f98bca35b17b9662f0733c846bbe9e870ef55b1a1f65507"
|
||||
"a2909cb633e238b4e9dd38b869ace91311021c9e32111ac1"
|
||||
"ac7cc4a4ff4dab102522d53857c49391b36cc9aa78a330a1"
|
||||
"a5e333cb88dcf94384d4cd1f47ca7883ff5a52f1a05885ac"
|
||||
"7671863c0bdbc23a")
|
||||
|
||||
# Fifth number generated by random.getrandbits(1024) - seed(4,2), not a prime
|
||||
RANDOM_1024_BIT_SEED_4_NO5 = ("53be4721f5b9e1f5acdac615bc20f6264922b9ccf469aef8"
|
||||
"f6e7d078e55b85dd1525f363b281b8885b69dc230af5ac87"
|
||||
"0692b534758240df4a7a03052d733dcdef40af2e54c0ce68"
|
||||
"1f44ebd13cc75f3edcb285f89d8cf4d4950b16ffc3e1ac3b"
|
||||
"4708d9893a973000b54a23020fc5b043d6e4a51519d9c9cc"
|
||||
"52d32377e78131c1")
|
||||
|
||||
# Adding 192 bit and 1024 bit numbers because these are the shortest required
|
||||
# for ECC and RSA respectively.
|
||||
INPUTS_DEFAULT = [
|
||||
"0", "1", # corner cases
|
||||
"2", "3", # small primes
|
||||
"4", # non-prime even
|
||||
"38", # small random
|
||||
SAFE_PRIME_192_BIT_SEED_1, # prime
|
||||
RANDOM_192_BIT_SEED_2_NO1, # not a prime
|
||||
RANDOM_192_BIT_SEED_2_NO2, # not a prime
|
||||
SAFE_PRIME_1024_BIT_SEED_3, # prime
|
||||
RANDOM_1024_BIT_SEED_4_NO1, # not a prime
|
||||
RANDOM_1024_BIT_SEED_4_NO3, # not a prime
|
||||
RANDOM_1024_BIT_SEED_4_NO2, # largest (not a prime)
|
||||
]
|
||||
|
||||
ADD_SUB_DATA = [
|
||||
"0", "1", "3", "f", "fe", "ff", "100", "ff00",
|
||||
"fffe", "ffff", "10000", # 2^16 - 1, 2^16, 2^16 + 1
|
||||
"fffffffe", "ffffffff", "100000000", # 2^32 - 1, 2^32, 2^32 + 1
|
||||
"1f7f7f7f7f7f7f",
|
||||
"8000000000000000", "fefefefefefefefe",
|
||||
"fffffffffffffffe", "ffffffffffffffff", "10000000000000000", # 2^64 - 1, 2^64, 2^64 + 1
|
||||
"1234567890abcdef0",
|
||||
"fffffffffffffffffffffffe",
|
||||
"ffffffffffffffffffffffff",
|
||||
"1000000000000000000000000",
|
||||
"fffffffffffffffffefefefefefefefe",
|
||||
"fffffffffffffffffffffffffffffffe",
|
||||
"ffffffffffffffffffffffffffffffff",
|
||||
"100000000000000000000000000000000",
|
||||
"1234567890abcdef01234567890abcdef0",
|
||||
"fffffffffffffffffffffffffffffffffffffffffffffffffefefefefefefefe",
|
||||
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"10000000000000000000000000000000000000000000000000000000000000000",
|
||||
"1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0",
|
||||
]
|
||||
|
||||
# Only odd moduli are present as in the new bignum code only odd moduli are
|
||||
# supported for now.
|
||||
MODULI_DEFAULT = [
|
||||
"53", # safe prime
|
||||
"45", # non-prime
|
||||
SAFE_PRIME_192_BIT_SEED_1, # safe prime
|
||||
RANDOM_192_BIT_SEED_2_NO4, # not a prime
|
||||
SAFE_PRIME_1024_BIT_SEED_3, # safe prime
|
||||
RANDOM_1024_BIT_SEED_4_NO5, # not a prime
|
||||
]
|
||||
|
||||
# Some functions, e.g. mbedtls_mpi_mod_raw_inv_prime(), only support prime moduli.
|
||||
ONLY_PRIME_MODULI = [
|
||||
"53", # safe prime
|
||||
"8ac72304057392b5", # 9999999997777777333 (longer, not safe, prime)
|
||||
# The next prime has a different R in Montgomery form depending on
|
||||
# whether 32- or 64-bit MPIs are used.
|
||||
"152d02c7e14af67fe0bf", # 99999999999999999991999
|
||||
SAFE_PRIME_192_BIT_SEED_1, # safe prime
|
||||
SAFE_PRIME_1024_BIT_SEED_3, # safe prime
|
||||
]
|
||||
|
||||
def __gen_safe_prime(bits, seed):
|
||||
'''
|
||||
Generate a safe prime.
|
||||
|
||||
This function is intended for generating constants offline and shouldn't be
|
||||
used in test generation classes.
|
||||
|
||||
Requires pycryptodomex for getPrime and isPrime and python 3.9 or later for
|
||||
randbytes.
|
||||
'''
|
||||
rng = random.Random()
|
||||
# We want reproducibility across python versions
|
||||
rng.seed(seed, version=2)
|
||||
while True:
|
||||
prime = 2*getPrime(bits-1, rng.randbytes)+1 #pylint: disable=no-member
|
||||
if isPrime(prime, 1e-30):
|
||||
return prime
|
||||
102
externals/mbedtls/scripts/mbedtls_dev/bignum_mod.py
vendored
102
externals/mbedtls/scripts/mbedtls_dev/bignum_mod.py
vendored
@@ -1,102 +0,0 @@
|
||||
"""Framework classes for generation of bignum mod test cases."""
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
from typing import Dict, List
|
||||
|
||||
from . import test_data_generation
|
||||
from . import bignum_common
|
||||
from .bignum_data import ONLY_PRIME_MODULI
|
||||
|
||||
class BignumModTarget(test_data_generation.BaseTarget):
|
||||
#pylint: disable=abstract-method, too-few-public-methods
|
||||
"""Target for bignum mod test case generation."""
|
||||
target_basename = 'test_suite_bignum_mod.generated'
|
||||
|
||||
|
||||
class BignumModMul(bignum_common.ModOperationCommon,
|
||||
BignumModTarget):
|
||||
# pylint:disable=duplicate-code
|
||||
"""Test cases for bignum mpi_mod_mul()."""
|
||||
symbol = "*"
|
||||
test_function = "mpi_mod_mul"
|
||||
test_name = "mbedtls_mpi_mod_mul"
|
||||
input_style = "arch_split"
|
||||
arity = 2
|
||||
|
||||
def arguments(self) -> List[str]:
|
||||
return [self.format_result(self.to_montgomery(self.int_a)),
|
||||
self.format_result(self.to_montgomery(self.int_b)),
|
||||
bignum_common.quote_str(self.arg_n)
|
||||
] + self.result()
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = (self.int_a * self.int_b) % self.int_n
|
||||
return [self.format_result(self.to_montgomery(result))]
|
||||
|
||||
|
||||
class BignumModSub(bignum_common.ModOperationCommon, BignumModTarget):
|
||||
"""Test cases for bignum mpi_mod_sub()."""
|
||||
symbol = "-"
|
||||
test_function = "mpi_mod_sub"
|
||||
test_name = "mbedtls_mpi_mod_sub"
|
||||
input_style = "fixed"
|
||||
arity = 2
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = (self.int_a - self.int_b) % self.int_n
|
||||
# To make negative tests easier, append 0 for success to the
|
||||
# generated cases
|
||||
return [self.format_result(result), "0"]
|
||||
|
||||
class BignumModInvNonMont(bignum_common.ModOperationCommon, BignumModTarget):
|
||||
"""Test cases for bignum mpi_mod_inv() - not in Montgomery form."""
|
||||
moduli = ONLY_PRIME_MODULI # for now only prime moduli supported
|
||||
symbol = "^ -1"
|
||||
test_function = "mpi_mod_inv_non_mont"
|
||||
test_name = "mbedtls_mpi_mod_inv non-Mont. form"
|
||||
input_style = "fixed"
|
||||
arity = 1
|
||||
suffix = True
|
||||
disallow_zero_a = True
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = bignum_common.invmod_positive(self.int_a, self.int_n)
|
||||
# To make negative tests easier, append 0 for success to the
|
||||
# generated cases
|
||||
return [self.format_result(result), "0"]
|
||||
|
||||
class BignumModInvMont(bignum_common.ModOperationCommon, BignumModTarget):
|
||||
"""Test cases for bignum mpi_mod_inv() - Montgomery form."""
|
||||
moduli = ONLY_PRIME_MODULI # for now only prime moduli supported
|
||||
symbol = "^ -1"
|
||||
test_function = "mpi_mod_inv_mont"
|
||||
test_name = "mbedtls_mpi_mod_inv Mont. form"
|
||||
input_style = "arch_split" # Mont. form requires arch_split
|
||||
arity = 1
|
||||
suffix = True
|
||||
disallow_zero_a = True
|
||||
montgomery_form_a = True
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = bignum_common.invmod_positive(self.int_a, self.int_n)
|
||||
mont_result = self.to_montgomery(result)
|
||||
# To make negative tests easier, append 0 for success to the
|
||||
# generated cases
|
||||
return [self.format_result(mont_result), "0"]
|
||||
|
||||
|
||||
class BignumModAdd(bignum_common.ModOperationCommon, BignumModTarget):
|
||||
"""Test cases for bignum mpi_mod_add()."""
|
||||
count = 0
|
||||
symbol = "+"
|
||||
test_function = "mpi_mod_add"
|
||||
test_name = "mbedtls_mpi_mod_add"
|
||||
input_style = "fixed"
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = (self.int_a + self.int_b) % self.int_n
|
||||
# To make negative tests easier, append "0" for success to the
|
||||
# generated cases
|
||||
return [self.format_result(result), "0"]
|
||||
@@ -1,242 +0,0 @@
|
||||
"""Framework classes for generation of bignum mod_raw test cases."""
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
from typing import Iterator, List
|
||||
|
||||
from . import test_case
|
||||
from . import test_data_generation
|
||||
from . import bignum_common
|
||||
from .bignum_data import ONLY_PRIME_MODULI
|
||||
|
||||
class BignumModRawTarget(test_data_generation.BaseTarget):
|
||||
#pylint: disable=abstract-method, too-few-public-methods
|
||||
"""Target for bignum mod_raw test case generation."""
|
||||
target_basename = 'test_suite_bignum_mod_raw.generated'
|
||||
|
||||
|
||||
class BignumModRawSub(bignum_common.ModOperationCommon,
|
||||
BignumModRawTarget):
|
||||
"""Test cases for bignum mpi_mod_raw_sub()."""
|
||||
symbol = "-"
|
||||
test_function = "mpi_mod_raw_sub"
|
||||
test_name = "mbedtls_mpi_mod_raw_sub"
|
||||
input_style = "fixed"
|
||||
arity = 2
|
||||
|
||||
def arguments(self) -> List[str]:
|
||||
return [bignum_common.quote_str(n) for n in [self.arg_a,
|
||||
self.arg_b,
|
||||
self.arg_n]
|
||||
] + self.result()
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = (self.int_a - self.int_b) % self.int_n
|
||||
return [self.format_result(result)]
|
||||
|
||||
class BignumModRawFixQuasiReduction(bignum_common.ModOperationCommon,
|
||||
BignumModRawTarget):
|
||||
"""Test cases for ecp quasi_reduction()."""
|
||||
symbol = "-"
|
||||
test_function = "mpi_mod_raw_fix_quasi_reduction"
|
||||
test_name = "fix_quasi_reduction"
|
||||
input_style = "fixed"
|
||||
arity = 1
|
||||
|
||||
# Extend the default values with n < x < 2n
|
||||
input_values = bignum_common.ModOperationCommon.input_values + [
|
||||
"73",
|
||||
|
||||
# First number generated by random.getrandbits(1024) - seed(3,2)
|
||||
"ea7b5bf55eb561a4216363698b529b4a97b750923ceb3ffd",
|
||||
|
||||
# First number generated by random.getrandbits(1024) - seed(1,2)
|
||||
("cd447e35b8b6d8fe442e3d437204e52db2221a58008a05a6c4647159c324c985"
|
||||
"9b810e766ec9d28663ca828dd5f4b3b2e4b06ce60741c7a87ce42c8218072e8c"
|
||||
"35bf992dc9e9c616612e7696a6cecc1b78e510617311d8a3c2ce6f447ed4d57b"
|
||||
"1e2feb89414c343c1027c4d1c386bbc4cd613e30d8f16adf91b7584a2265b1f5")
|
||||
] # type: List[str]
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a % self.int_n
|
||||
return [self.format_result(result)]
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
return bool(self.int_a < 2 * self.int_n)
|
||||
|
||||
class BignumModRawMul(bignum_common.ModOperationCommon,
|
||||
BignumModRawTarget):
|
||||
"""Test cases for bignum mpi_mod_raw_mul()."""
|
||||
symbol = "*"
|
||||
test_function = "mpi_mod_raw_mul"
|
||||
test_name = "mbedtls_mpi_mod_raw_mul"
|
||||
input_style = "arch_split"
|
||||
arity = 2
|
||||
|
||||
def arguments(self) -> List[str]:
|
||||
return [self.format_result(self.to_montgomery(self.int_a)),
|
||||
self.format_result(self.to_montgomery(self.int_b)),
|
||||
bignum_common.quote_str(self.arg_n)
|
||||
] + self.result()
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = (self.int_a * self.int_b) % self.int_n
|
||||
return [self.format_result(self.to_montgomery(result))]
|
||||
|
||||
|
||||
class BignumModRawInvPrime(bignum_common.ModOperationCommon,
|
||||
BignumModRawTarget):
|
||||
"""Test cases for bignum mpi_mod_raw_inv_prime()."""
|
||||
moduli = ONLY_PRIME_MODULI
|
||||
symbol = "^ -1"
|
||||
test_function = "mpi_mod_raw_inv_prime"
|
||||
test_name = "mbedtls_mpi_mod_raw_inv_prime (Montgomery form only)"
|
||||
input_style = "arch_split"
|
||||
arity = 1
|
||||
suffix = True
|
||||
montgomery_form_a = True
|
||||
disallow_zero_a = True
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = bignum_common.invmod_positive(self.int_a, self.int_n)
|
||||
mont_result = self.to_montgomery(result)
|
||||
return [self.format_result(mont_result)]
|
||||
|
||||
|
||||
class BignumModRawAdd(bignum_common.ModOperationCommon,
|
||||
BignumModRawTarget):
|
||||
"""Test cases for bignum mpi_mod_raw_add()."""
|
||||
symbol = "+"
|
||||
test_function = "mpi_mod_raw_add"
|
||||
test_name = "mbedtls_mpi_mod_raw_add"
|
||||
input_style = "fixed"
|
||||
arity = 2
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = (self.int_a + self.int_b) % self.int_n
|
||||
return [self.format_result(result)]
|
||||
|
||||
|
||||
class BignumModRawConvertRep(bignum_common.ModOperationCommon,
|
||||
BignumModRawTarget):
|
||||
# This is an abstract class, it's ok to have unimplemented methods.
|
||||
#pylint: disable=abstract-method
|
||||
"""Test cases for representation conversion."""
|
||||
symbol = ""
|
||||
input_style = "arch_split"
|
||||
arity = 1
|
||||
rep = bignum_common.ModulusRepresentation.INVALID
|
||||
|
||||
def set_representation(self, r: bignum_common.ModulusRepresentation) -> None:
|
||||
self.rep = r
|
||||
|
||||
def arguments(self) -> List[str]:
|
||||
return ([bignum_common.quote_str(self.arg_n), self.rep.symbol(),
|
||||
bignum_common.quote_str(self.arg_a)] +
|
||||
self.result())
|
||||
|
||||
def description(self) -> str:
|
||||
base = super().description()
|
||||
mod_with_rep = 'mod({})'.format(self.rep.name)
|
||||
return base.replace('mod', mod_with_rep, 1)
|
||||
|
||||
@classmethod
|
||||
def test_cases_for_values(cls, rep: bignum_common.ModulusRepresentation,
|
||||
n: str, a: str) -> Iterator[test_case.TestCase]:
|
||||
"""Emit test cases for the given values (if any).
|
||||
|
||||
This may emit no test cases if a isn't valid for the modulus n,
|
||||
or multiple test cases if rep requires different data depending
|
||||
on the limb size.
|
||||
"""
|
||||
for bil in cls.limb_sizes:
|
||||
test_object = cls(n, a, bits_in_limb=bil)
|
||||
test_object.set_representation(rep)
|
||||
# The class is set to having separate test cases for each limb
|
||||
# size, because the Montgomery representation requires it.
|
||||
# But other representations don't require it. So for other
|
||||
# representations, emit a single test case with no dependency
|
||||
# on the limb size.
|
||||
if rep is not bignum_common.ModulusRepresentation.MONTGOMERY:
|
||||
test_object.dependencies = \
|
||||
[dep for dep in test_object.dependencies
|
||||
if not dep.startswith('MBEDTLS_HAVE_INT')]
|
||||
if test_object.is_valid:
|
||||
yield test_object.create_test_case()
|
||||
if rep is not bignum_common.ModulusRepresentation.MONTGOMERY:
|
||||
# A single test case (emitted, or skipped due to invalidity)
|
||||
# is enough, since this test case doesn't depend on the
|
||||
# limb size.
|
||||
break
|
||||
|
||||
# The parent class doesn't support non-bignum parameters. So we override
|
||||
# test generation, in order to have the representation as a parameter.
|
||||
@classmethod
|
||||
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
|
||||
|
||||
for rep in bignum_common.ModulusRepresentation.supported_representations():
|
||||
for n in cls.moduli:
|
||||
for a in cls.input_values:
|
||||
yield from cls.test_cases_for_values(rep, n, a)
|
||||
|
||||
class BignumModRawCanonicalToModulusRep(BignumModRawConvertRep):
|
||||
"""Test cases for mpi_mod_raw_canonical_to_modulus_rep."""
|
||||
test_function = "mpi_mod_raw_canonical_to_modulus_rep"
|
||||
test_name = "Rep canon->mod"
|
||||
|
||||
def result(self) -> List[str]:
|
||||
return [self.format_result(self.convert_from_canonical(self.int_a, self.rep))]
|
||||
|
||||
class BignumModRawModulusToCanonicalRep(BignumModRawConvertRep):
|
||||
"""Test cases for mpi_mod_raw_modulus_to_canonical_rep."""
|
||||
test_function = "mpi_mod_raw_modulus_to_canonical_rep"
|
||||
test_name = "Rep mod->canon"
|
||||
|
||||
@property
|
||||
def arg_a(self) -> str:
|
||||
return self.format_arg("{:x}".format(self.convert_from_canonical(self.int_a, self.rep)))
|
||||
|
||||
def result(self) -> List[str]:
|
||||
return [self.format_result(self.int_a)]
|
||||
|
||||
|
||||
class BignumModRawConvertToMont(bignum_common.ModOperationCommon,
|
||||
BignumModRawTarget):
|
||||
""" Test cases for mpi_mod_raw_to_mont_rep(). """
|
||||
test_function = "mpi_mod_raw_to_mont_rep"
|
||||
test_name = "Convert into Mont: "
|
||||
symbol = "R *"
|
||||
input_style = "arch_split"
|
||||
arity = 1
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.to_montgomery(self.int_a)
|
||||
return [self.format_result(result)]
|
||||
|
||||
class BignumModRawConvertFromMont(bignum_common.ModOperationCommon,
|
||||
BignumModRawTarget):
|
||||
""" Test cases for mpi_mod_raw_from_mont_rep(). """
|
||||
test_function = "mpi_mod_raw_from_mont_rep"
|
||||
test_name = "Convert from Mont: "
|
||||
symbol = "1/R *"
|
||||
input_style = "arch_split"
|
||||
arity = 1
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.from_montgomery(self.int_a)
|
||||
return [self.format_result(result)]
|
||||
|
||||
class BignumModRawModNegate(bignum_common.ModOperationCommon,
|
||||
BignumModRawTarget):
|
||||
""" Test cases for mpi_mod_raw_neg(). """
|
||||
test_function = "mpi_mod_raw_neg"
|
||||
test_name = "Modular negation: "
|
||||
symbol = "-"
|
||||
input_style = "arch_split"
|
||||
arity = 1
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = (self.int_n - self.int_a) % self.int_n
|
||||
return [self.format_result(result)]
|
||||
120
externals/mbedtls/scripts/mbedtls_dev/build_tree.py
vendored
120
externals/mbedtls/scripts/mbedtls_dev/build_tree.py
vendored
@@ -1,120 +0,0 @@
|
||||
"""Mbed TLS build tree information and manipulation.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
import os
|
||||
import inspect
|
||||
from typing import Optional
|
||||
|
||||
def looks_like_tf_psa_crypto_root(path: str) -> bool:
|
||||
"""Whether the given directory looks like the root of the PSA Crypto source tree."""
|
||||
return all(os.path.isdir(os.path.join(path, subdir))
|
||||
for subdir in ['include', 'core', 'drivers', 'programs', 'tests'])
|
||||
|
||||
def looks_like_mbedtls_root(path: str) -> bool:
|
||||
"""Whether the given directory looks like the root of the Mbed TLS source tree."""
|
||||
return all(os.path.isdir(os.path.join(path, subdir))
|
||||
for subdir in ['include', 'library', 'programs', 'tests'])
|
||||
|
||||
def looks_like_root(path: str) -> bool:
|
||||
return looks_like_tf_psa_crypto_root(path) or looks_like_mbedtls_root(path)
|
||||
|
||||
def crypto_core_directory(root: Optional[str] = None, relative: Optional[bool] = False) -> str:
|
||||
"""
|
||||
Return the path of the directory containing the PSA crypto core
|
||||
for either TF-PSA-Crypto or Mbed TLS.
|
||||
|
||||
Returns either the full path or relative path depending on the
|
||||
"relative" boolean argument.
|
||||
"""
|
||||
if root is None:
|
||||
root = guess_project_root()
|
||||
if looks_like_tf_psa_crypto_root(root):
|
||||
if relative:
|
||||
return "core"
|
||||
return os.path.join(root, "core")
|
||||
elif looks_like_mbedtls_root(root):
|
||||
if relative:
|
||||
return "library"
|
||||
return os.path.join(root, "library")
|
||||
else:
|
||||
raise Exception('Neither Mbed TLS nor TF-PSA-Crypto source tree found')
|
||||
|
||||
def crypto_library_filename(root: Optional[str] = None) -> str:
|
||||
"""Return the crypto library filename for either TF-PSA-Crypto or Mbed TLS."""
|
||||
if root is None:
|
||||
root = guess_project_root()
|
||||
if looks_like_tf_psa_crypto_root(root):
|
||||
return "tfpsacrypto"
|
||||
elif looks_like_mbedtls_root(root):
|
||||
return "mbedcrypto"
|
||||
else:
|
||||
raise Exception('Neither Mbed TLS nor TF-PSA-Crypto source tree found')
|
||||
|
||||
def check_repo_path():
|
||||
"""Check that the current working directory is the project root, and throw
|
||||
an exception if not.
|
||||
"""
|
||||
if not all(os.path.isdir(d) for d in ["include", "library", "tests"]):
|
||||
raise Exception("This script must be run from Mbed TLS root")
|
||||
|
||||
def chdir_to_root() -> None:
|
||||
"""Detect the root of the Mbed TLS source tree and change to it.
|
||||
|
||||
The current directory must be up to two levels deep inside an Mbed TLS
|
||||
source tree.
|
||||
"""
|
||||
for d in [os.path.curdir,
|
||||
os.path.pardir,
|
||||
os.path.join(os.path.pardir, os.path.pardir)]:
|
||||
if looks_like_root(d):
|
||||
os.chdir(d)
|
||||
return
|
||||
raise Exception('Mbed TLS source tree not found')
|
||||
|
||||
def guess_project_root():
|
||||
"""Guess project source code directory.
|
||||
|
||||
Return the first possible project root directory.
|
||||
"""
|
||||
dirs = set({})
|
||||
for frame in inspect.stack():
|
||||
path = os.path.dirname(frame.filename)
|
||||
for d in ['.', os.path.pardir] \
|
||||
+ [os.path.join(*([os.path.pardir]*i)) for i in range(2, 10)]:
|
||||
d = os.path.abspath(os.path.join(path, d))
|
||||
if d in dirs:
|
||||
continue
|
||||
dirs.add(d)
|
||||
if looks_like_root(d):
|
||||
return d
|
||||
raise Exception('Neither Mbed TLS nor TF-PSA-Crypto source tree found')
|
||||
|
||||
def guess_mbedtls_root(root: Optional[str] = None) -> str:
|
||||
"""Guess Mbed TLS source code directory.
|
||||
|
||||
Return the first possible Mbed TLS root directory.
|
||||
Raise an exception if we are not in Mbed TLS.
|
||||
"""
|
||||
if root is None:
|
||||
root = guess_project_root()
|
||||
if looks_like_mbedtls_root(root):
|
||||
return root
|
||||
else:
|
||||
raise Exception('Mbed TLS source tree not found')
|
||||
|
||||
def guess_tf_psa_crypto_root(root: Optional[str] = None) -> str:
|
||||
"""Guess TF-PSA-Crypto source code directory.
|
||||
|
||||
Return the first possible TF-PSA-Crypto root directory.
|
||||
Raise an exception if we are not in TF-PSA-Crypto.
|
||||
"""
|
||||
if root is None:
|
||||
root = guess_project_root()
|
||||
if looks_like_tf_psa_crypto_root(root):
|
||||
return root
|
||||
else:
|
||||
raise Exception('TF-PSA-Crypto source tree not found')
|
||||
@@ -1,162 +0,0 @@
|
||||
"""Generate and run C code.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
def remove_file_if_exists(filename):
|
||||
"""Remove the specified file, ignoring errors."""
|
||||
if not filename:
|
||||
return
|
||||
try:
|
||||
os.remove(filename)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def create_c_file(file_label):
|
||||
"""Create a temporary C file.
|
||||
|
||||
* ``file_label``: a string that will be included in the file name.
|
||||
|
||||
Return ```(c_file, c_name, exe_name)``` where ``c_file`` is a Python
|
||||
stream open for writing to the file, ``c_name`` is the name of the file
|
||||
and ``exe_name`` is the name of the executable that will be produced
|
||||
by compiling the file.
|
||||
"""
|
||||
c_fd, c_name = tempfile.mkstemp(prefix='tmp-{}-'.format(file_label),
|
||||
suffix='.c')
|
||||
exe_suffix = '.exe' if platform.system() == 'Windows' else ''
|
||||
exe_name = c_name[:-2] + exe_suffix
|
||||
remove_file_if_exists(exe_name)
|
||||
c_file = os.fdopen(c_fd, 'w', encoding='ascii')
|
||||
return c_file, c_name, exe_name
|
||||
|
||||
def generate_c_printf_expressions(c_file, cast_to, printf_format, expressions):
|
||||
"""Generate C instructions to print the value of ``expressions``.
|
||||
|
||||
Write the code with ``c_file``'s ``write`` method.
|
||||
|
||||
Each expression is cast to the type ``cast_to`` and printed with the
|
||||
printf format ``printf_format``.
|
||||
"""
|
||||
for expr in expressions:
|
||||
c_file.write(' printf("{}\\n", ({}) {});\n'
|
||||
.format(printf_format, cast_to, expr))
|
||||
|
||||
def generate_c_file(c_file,
|
||||
caller, header,
|
||||
main_generator):
|
||||
"""Generate a temporary C source file.
|
||||
|
||||
* ``c_file`` is an open stream on the C source file.
|
||||
* ``caller``: an informational string written in a comment at the top
|
||||
of the file.
|
||||
* ``header``: extra code to insert before any function in the generated
|
||||
C file.
|
||||
* ``main_generator``: a function called with ``c_file`` as its sole argument
|
||||
to generate the body of the ``main()`` function.
|
||||
"""
|
||||
c_file.write('/* Generated by {} */'
|
||||
.format(caller))
|
||||
c_file.write('''
|
||||
#include <stdio.h>
|
||||
''')
|
||||
c_file.write(header)
|
||||
c_file.write('''
|
||||
int main(void)
|
||||
{
|
||||
''')
|
||||
main_generator(c_file)
|
||||
c_file.write(''' return 0;
|
||||
}
|
||||
''')
|
||||
|
||||
def compile_c_file(c_filename, exe_filename, include_dirs):
|
||||
"""Compile a C source file with the host compiler.
|
||||
|
||||
* ``c_filename``: the name of the source file to compile.
|
||||
* ``exe_filename``: the name for the executable to be created.
|
||||
* ``include_dirs``: a list of paths to include directories to be passed
|
||||
with the -I switch.
|
||||
"""
|
||||
# Respect $HOSTCC if it is set
|
||||
cc = os.getenv('HOSTCC', None)
|
||||
if cc is None:
|
||||
cc = os.getenv('CC', 'cc')
|
||||
cmd = [cc]
|
||||
|
||||
proc = subprocess.Popen(cmd,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.PIPE,
|
||||
universal_newlines=True)
|
||||
cc_is_msvc = 'Microsoft (R) C/C++' in proc.communicate()[1]
|
||||
|
||||
cmd += ['-I' + dir for dir in include_dirs]
|
||||
if cc_is_msvc:
|
||||
# MSVC has deprecated using -o to specify the output file,
|
||||
# and produces an object file in the working directory by default.
|
||||
obj_filename = exe_filename[:-4] + '.obj'
|
||||
cmd += ['-Fe' + exe_filename, '-Fo' + obj_filename]
|
||||
else:
|
||||
cmd += ['-o' + exe_filename]
|
||||
|
||||
subprocess.check_call(cmd + [c_filename])
|
||||
|
||||
def get_c_expression_values(
|
||||
cast_to, printf_format,
|
||||
expressions,
|
||||
caller=__name__, file_label='',
|
||||
header='', include_path=None,
|
||||
keep_c=False,
|
||||
): # pylint: disable=too-many-arguments, too-many-locals
|
||||
"""Generate and run a program to print out numerical values for expressions.
|
||||
|
||||
* ``cast_to``: a C type.
|
||||
* ``printf_format``: a printf format suitable for the type ``cast_to``.
|
||||
* ``header``: extra code to insert before any function in the generated
|
||||
C file.
|
||||
* ``expressions``: a list of C language expressions that have the type
|
||||
``cast_to``.
|
||||
* ``include_path``: a list of directories containing header files.
|
||||
* ``keep_c``: if true, keep the temporary C file (presumably for debugging
|
||||
purposes).
|
||||
|
||||
Use the C compiler specified by the ``CC`` environment variable, defaulting
|
||||
to ``cc``. If ``CC`` looks like MSVC, use its command line syntax,
|
||||
otherwise assume the compiler supports Unix traditional ``-I`` and ``-o``.
|
||||
|
||||
Return the list of values of the ``expressions``.
|
||||
"""
|
||||
if include_path is None:
|
||||
include_path = []
|
||||
c_name = None
|
||||
exe_name = None
|
||||
obj_name = None
|
||||
try:
|
||||
c_file, c_name, exe_name = create_c_file(file_label)
|
||||
generate_c_file(
|
||||
c_file, caller, header,
|
||||
lambda c_file: generate_c_printf_expressions(c_file,
|
||||
cast_to, printf_format,
|
||||
expressions)
|
||||
)
|
||||
c_file.close()
|
||||
|
||||
compile_c_file(c_name, exe_name, include_path)
|
||||
if keep_c:
|
||||
sys.stderr.write('List of {} tests kept at {}\n'
|
||||
.format(caller, c_name))
|
||||
else:
|
||||
os.remove(c_name)
|
||||
output = subprocess.check_output([exe_name])
|
||||
return output.decode('ascii').strip().split('\n')
|
||||
finally:
|
||||
remove_file_if_exists(exe_name)
|
||||
remove_file_if_exists(obj_name)
|
||||
@@ -1,112 +0,0 @@
|
||||
"""Generate test data for cryptographic mechanisms.
|
||||
|
||||
This module is a work in progress, only implementing a few cases for now.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
import hashlib
|
||||
from typing import Callable, Dict, Iterator, List, Optional #pylint: disable=unused-import
|
||||
|
||||
from . import crypto_knowledge
|
||||
from . import psa_information
|
||||
from . import test_case
|
||||
|
||||
|
||||
def psa_low_level_dependencies(*expressions: str) -> List[str]:
|
||||
"""Infer dependencies of a PSA low-level test case by looking for PSA_xxx symbols.
|
||||
|
||||
This function generates MBEDTLS_PSA_BUILTIN_xxx symbols.
|
||||
"""
|
||||
high_level = psa_information.automatic_dependencies(*expressions)
|
||||
for dep in high_level:
|
||||
assert dep.startswith('PSA_WANT_')
|
||||
return ['MBEDTLS_PSA_BUILTIN_' + dep[9:] for dep in high_level]
|
||||
|
||||
|
||||
class HashPSALowLevel:
|
||||
"""Generate test cases for the PSA low-level hash interface."""
|
||||
|
||||
def __init__(self, info: psa_information.Information) -> None:
|
||||
self.info = info
|
||||
base_algorithms = sorted(info.constructors.algorithms)
|
||||
all_algorithms = \
|
||||
[crypto_knowledge.Algorithm(expr)
|
||||
for expr in info.constructors.generate_expressions(base_algorithms)]
|
||||
self.algorithms = \
|
||||
[alg
|
||||
for alg in all_algorithms
|
||||
if (not alg.is_wildcard and
|
||||
alg.can_do(crypto_knowledge.AlgorithmCategory.HASH))]
|
||||
|
||||
# CALCULATE[alg] = function to return the hash of its argument in hex
|
||||
# TO-DO: implement the None entries with a third-party library, because
|
||||
# hashlib might not have everything, depending on the Python version and
|
||||
# the underlying OpenSSL. On Ubuntu 16.04, truncated sha512 and sha3/shake
|
||||
# are not available. On Ubuntu 22.04, md2, md4 and ripemd160 are not
|
||||
# available.
|
||||
CALCULATE = {
|
||||
'PSA_ALG_MD5': lambda data: hashlib.md5(data).hexdigest(),
|
||||
'PSA_ALG_RIPEMD160': None, #lambda data: hashlib.new('ripdemd160').hexdigest()
|
||||
'PSA_ALG_SHA_1': lambda data: hashlib.sha1(data).hexdigest(),
|
||||
'PSA_ALG_SHA_224': lambda data: hashlib.sha224(data).hexdigest(),
|
||||
'PSA_ALG_SHA_256': lambda data: hashlib.sha256(data).hexdigest(),
|
||||
'PSA_ALG_SHA_384': lambda data: hashlib.sha384(data).hexdigest(),
|
||||
'PSA_ALG_SHA_512': lambda data: hashlib.sha512(data).hexdigest(),
|
||||
'PSA_ALG_SHA_512_224': None, #lambda data: hashlib.new('sha512_224').hexdigest()
|
||||
'PSA_ALG_SHA_512_256': None, #lambda data: hashlib.new('sha512_256').hexdigest()
|
||||
'PSA_ALG_SHA3_224': None, #lambda data: hashlib.sha3_224(data).hexdigest(),
|
||||
'PSA_ALG_SHA3_256': None, #lambda data: hashlib.sha3_256(data).hexdigest(),
|
||||
'PSA_ALG_SHA3_384': None, #lambda data: hashlib.sha3_384(data).hexdigest(),
|
||||
'PSA_ALG_SHA3_512': None, #lambda data: hashlib.sha3_512(data).hexdigest(),
|
||||
'PSA_ALG_SHAKE256_512': None, #lambda data: hashlib.shake_256(data).hexdigest(64),
|
||||
} #type: Dict[str, Optional[Callable[[bytes], str]]]
|
||||
|
||||
@staticmethod
|
||||
def one_test_case(alg: crypto_knowledge.Algorithm,
|
||||
function: str, note: str,
|
||||
arguments: List[str]) -> test_case.TestCase:
|
||||
"""Construct one test case involving a hash."""
|
||||
tc = test_case.TestCase()
|
||||
tc.set_description('{}{} {}'
|
||||
.format(function,
|
||||
' ' + note if note else '',
|
||||
alg.short_expression()))
|
||||
tc.set_dependencies(psa_low_level_dependencies(alg.expression))
|
||||
tc.set_function(function)
|
||||
tc.set_arguments([alg.expression] +
|
||||
['"{}"'.format(arg) for arg in arguments])
|
||||
return tc
|
||||
|
||||
def test_cases_for_hash(self,
|
||||
alg: crypto_knowledge.Algorithm
|
||||
) -> Iterator[test_case.TestCase]:
|
||||
"""Enumerate all test cases for one hash algorithm."""
|
||||
calc = self.CALCULATE[alg.expression]
|
||||
if calc is None:
|
||||
return # not implemented yet
|
||||
|
||||
short = b'abc'
|
||||
hash_short = calc(short)
|
||||
long = (b'Hello, world. Here are 16 unprintable bytes: ['
|
||||
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a'
|
||||
b'\x80\x81\x82\x83\xfe\xff]. '
|
||||
b' This message was brought to you by a natural intelligence. '
|
||||
b' If you can read this, good luck with your debugging!')
|
||||
hash_long = calc(long)
|
||||
|
||||
yield self.one_test_case(alg, 'hash_empty', '', [calc(b'')])
|
||||
yield self.one_test_case(alg, 'hash_valid_one_shot', '',
|
||||
[short.hex(), hash_short])
|
||||
for n in [0, 1, 64, len(long) - 1, len(long)]:
|
||||
yield self.one_test_case(alg, 'hash_valid_multipart',
|
||||
'{} + {}'.format(n, len(long) - n),
|
||||
[long[:n].hex(), calc(long[:n]),
|
||||
long[n:].hex(), hash_long])
|
||||
|
||||
def all_test_cases(self) -> Iterator[test_case.TestCase]:
|
||||
"""Enumerate all test cases for all hash algorithms."""
|
||||
for alg in self.algorithms:
|
||||
yield from self.test_cases_for_hash(alg)
|
||||
@@ -1,568 +0,0 @@
|
||||
"""Knowledge about cryptographic mechanisms implemented in Mbed TLS.
|
||||
|
||||
This module is entirely based on the PSA API.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
import enum
|
||||
import re
|
||||
from typing import FrozenSet, Iterable, List, Optional, Tuple, Dict
|
||||
|
||||
from .asymmetric_key_data import ASYMMETRIC_KEY_DATA
|
||||
|
||||
|
||||
def short_expression(original: str, level: int = 0) -> str:
|
||||
"""Abbreviate the expression, keeping it human-readable.
|
||||
|
||||
If `level` is 0, just remove parts that are implicit from context,
|
||||
such as a leading ``PSA_KEY_TYPE_``.
|
||||
For larger values of `level`, also abbreviate some names in an
|
||||
unambiguous, but ad hoc way.
|
||||
"""
|
||||
short = original
|
||||
short = re.sub(r'\bPSA_(?:ALG|DH_FAMILY|ECC_FAMILY|KEY_[A-Z]+)_', r'', short)
|
||||
short = re.sub(r' +', r'', short)
|
||||
if level >= 1:
|
||||
short = re.sub(r'PUBLIC_KEY\b', r'PUB', short)
|
||||
short = re.sub(r'KEY_PAIR\b', r'PAIR', short)
|
||||
short = re.sub(r'\bBRAINPOOL_P', r'BP', short)
|
||||
short = re.sub(r'\bMONTGOMERY\b', r'MGM', short)
|
||||
short = re.sub(r'AEAD_WITH_SHORTENED_TAG\b', r'AEAD_SHORT', short)
|
||||
short = re.sub(r'\bDETERMINISTIC_', r'DET_', short)
|
||||
short = re.sub(r'\bKEY_AGREEMENT\b', r'KA', short)
|
||||
short = re.sub(r'_PSK_TO_MS\b', r'_PSK2MS', short)
|
||||
return short
|
||||
|
||||
|
||||
BLOCK_CIPHERS = frozenset(['AES', 'ARIA', 'CAMELLIA', 'DES'])
|
||||
BLOCK_MAC_MODES = frozenset(['CBC_MAC', 'CMAC'])
|
||||
BLOCK_CIPHER_MODES = frozenset([
|
||||
'CTR', 'CFB', 'OFB', 'XTS', 'CCM_STAR_NO_TAG',
|
||||
'ECB_NO_PADDING', 'CBC_NO_PADDING', 'CBC_PKCS7',
|
||||
])
|
||||
BLOCK_AEAD_MODES = frozenset(['CCM', 'GCM'])
|
||||
|
||||
class EllipticCurveCategory(enum.Enum):
|
||||
"""Categorization of elliptic curve families.
|
||||
|
||||
The category of a curve determines what algorithms are defined over it.
|
||||
"""
|
||||
|
||||
SHORT_WEIERSTRASS = 0
|
||||
MONTGOMERY = 1
|
||||
TWISTED_EDWARDS = 2
|
||||
|
||||
@staticmethod
|
||||
def from_family(family: str) -> 'EllipticCurveCategory':
|
||||
if family == 'PSA_ECC_FAMILY_MONTGOMERY':
|
||||
return EllipticCurveCategory.MONTGOMERY
|
||||
if family == 'PSA_ECC_FAMILY_TWISTED_EDWARDS':
|
||||
return EllipticCurveCategory.TWISTED_EDWARDS
|
||||
# Default to SW, which most curves belong to.
|
||||
return EllipticCurveCategory.SHORT_WEIERSTRASS
|
||||
|
||||
|
||||
class KeyType:
|
||||
"""Knowledge about a PSA key type."""
|
||||
|
||||
def __init__(self, name: str, params: Optional[Iterable[str]] = None) -> None:
|
||||
"""Analyze a key type.
|
||||
|
||||
The key type must be specified in PSA syntax. In its simplest form,
|
||||
`name` is a string 'PSA_KEY_TYPE_xxx' which is the name of a PSA key
|
||||
type macro. For key types that take arguments, the arguments can
|
||||
be passed either through the optional argument `params` or by
|
||||
passing an expression of the form 'PSA_KEY_TYPE_xxx(param1, ...)'
|
||||
in `name` as a string.
|
||||
"""
|
||||
|
||||
self.name = name.strip()
|
||||
"""The key type macro name (``PSA_KEY_TYPE_xxx``).
|
||||
|
||||
For key types constructed from a macro with arguments, this is the
|
||||
name of the macro, and the arguments are in `self.params`.
|
||||
"""
|
||||
if params is None:
|
||||
if '(' in self.name:
|
||||
m = re.match(r'(\w+)\s*\((.*)\)\Z', self.name)
|
||||
assert m is not None
|
||||
self.name = m.group(1)
|
||||
params = m.group(2).split(',')
|
||||
self.params = (None if params is None else
|
||||
[param.strip() for param in params])
|
||||
"""The parameters of the key type, if there are any.
|
||||
|
||||
None if the key type is a macro without arguments.
|
||||
"""
|
||||
assert re.match(r'PSA_KEY_TYPE_\w+\Z', self.name)
|
||||
|
||||
self.expression = self.name
|
||||
"""A C expression whose value is the key type encoding."""
|
||||
if self.params is not None:
|
||||
self.expression += '(' + ', '.join(self.params) + ')'
|
||||
|
||||
m = re.match(r'PSA_KEY_TYPE_(\w+)', self.name)
|
||||
assert m
|
||||
self.head = re.sub(r'_(?:PUBLIC_KEY|KEY_PAIR)\Z', r'', m.group(1))
|
||||
"""The key type macro name, with common prefixes and suffixes stripped."""
|
||||
|
||||
self.private_type = re.sub(r'_PUBLIC_KEY\Z', r'_KEY_PAIR', self.name)
|
||||
"""The key type macro name for the corresponding key pair type.
|
||||
|
||||
For everything other than a public key type, this is the same as
|
||||
`self.name`.
|
||||
"""
|
||||
|
||||
def short_expression(self, level: int = 0) -> str:
|
||||
"""Abbreviate the expression, keeping it human-readable.
|
||||
|
||||
See `crypto_knowledge.short_expression`.
|
||||
"""
|
||||
return short_expression(self.expression, level=level)
|
||||
|
||||
def is_public(self) -> bool:
|
||||
"""Whether the key type is for public keys."""
|
||||
return self.name.endswith('_PUBLIC_KEY')
|
||||
|
||||
DH_KEY_SIZES = {
|
||||
'PSA_DH_FAMILY_RFC7919': (2048, 3072, 4096, 6144, 8192),
|
||||
} # type: Dict[str, Tuple[int, ...]]
|
||||
ECC_KEY_SIZES = {
|
||||
'PSA_ECC_FAMILY_SECP_K1': (192, 225, 256),
|
||||
'PSA_ECC_FAMILY_SECP_R1': (224, 256, 384, 521),
|
||||
'PSA_ECC_FAMILY_SECP_R2': (160,),
|
||||
'PSA_ECC_FAMILY_SECT_K1': (163, 233, 239, 283, 409, 571),
|
||||
'PSA_ECC_FAMILY_SECT_R1': (163, 233, 283, 409, 571),
|
||||
'PSA_ECC_FAMILY_SECT_R2': (163,),
|
||||
'PSA_ECC_FAMILY_BRAINPOOL_P_R1': (160, 192, 224, 256, 320, 384, 512),
|
||||
'PSA_ECC_FAMILY_MONTGOMERY': (255, 448),
|
||||
'PSA_ECC_FAMILY_TWISTED_EDWARDS': (255, 448),
|
||||
} # type: Dict[str, Tuple[int, ...]]
|
||||
KEY_TYPE_SIZES = {
|
||||
'PSA_KEY_TYPE_AES': (128, 192, 256), # exhaustive
|
||||
'PSA_KEY_TYPE_ARIA': (128, 192, 256), # exhaustive
|
||||
'PSA_KEY_TYPE_CAMELLIA': (128, 192, 256), # exhaustive
|
||||
'PSA_KEY_TYPE_CHACHA20': (256,), # exhaustive
|
||||
'PSA_KEY_TYPE_DERIVE': (120, 128), # sample
|
||||
'PSA_KEY_TYPE_DES': (64, 128, 192), # exhaustive
|
||||
'PSA_KEY_TYPE_HMAC': (128, 160, 224, 256, 384, 512), # standard size for each supported hash
|
||||
'PSA_KEY_TYPE_PASSWORD': (48, 168, 336), # sample
|
||||
'PSA_KEY_TYPE_PASSWORD_HASH': (128, 256), # sample
|
||||
'PSA_KEY_TYPE_PEPPER': (128, 256), # sample
|
||||
'PSA_KEY_TYPE_RAW_DATA': (8, 40, 128), # sample
|
||||
'PSA_KEY_TYPE_RSA_KEY_PAIR': (1024, 1536), # small sample
|
||||
} # type: Dict[str, Tuple[int, ...]]
|
||||
def sizes_to_test(self) -> Tuple[int, ...]:
|
||||
"""Return a tuple of key sizes to test.
|
||||
|
||||
For key types that only allow a single size, or only a small set of
|
||||
sizes, these are all the possible sizes. For key types that allow a
|
||||
wide range of sizes, these are a representative sample of sizes,
|
||||
excluding large sizes for which a typical resource-constrained platform
|
||||
may run out of memory.
|
||||
"""
|
||||
if self.private_type == 'PSA_KEY_TYPE_ECC_KEY_PAIR':
|
||||
assert self.params is not None
|
||||
return self.ECC_KEY_SIZES[self.params[0]]
|
||||
if self.private_type == 'PSA_KEY_TYPE_DH_KEY_PAIR':
|
||||
assert self.params is not None
|
||||
return self.DH_KEY_SIZES[self.params[0]]
|
||||
return self.KEY_TYPE_SIZES[self.private_type]
|
||||
|
||||
# "48657265006973206b6579a064617461"
|
||||
DATA_BLOCK = b'Here\000is key\240data'
|
||||
def key_material(self, bits: int) -> bytes:
|
||||
"""Return a byte string containing suitable key material with the given bit length.
|
||||
|
||||
Use the PSA export representation. The resulting byte string is one that
|
||||
can be obtained with the following code:
|
||||
```
|
||||
psa_set_key_type(&attributes, `self.expression`);
|
||||
psa_set_key_bits(&attributes, `bits`);
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
|
||||
psa_generate_key(&attributes, &id);
|
||||
psa_export_key(id, `material`, ...);
|
||||
```
|
||||
"""
|
||||
if self.expression in ASYMMETRIC_KEY_DATA:
|
||||
if bits not in ASYMMETRIC_KEY_DATA[self.expression]:
|
||||
raise ValueError('No key data for {}-bit {}'
|
||||
.format(bits, self.expression))
|
||||
return ASYMMETRIC_KEY_DATA[self.expression][bits]
|
||||
if bits % 8 != 0:
|
||||
raise ValueError('Non-integer number of bytes: {} bits for {}'
|
||||
.format(bits, self.expression))
|
||||
length = bits // 8
|
||||
if self.name == 'PSA_KEY_TYPE_DES':
|
||||
# "644573206b457901644573206b457902644573206b457904"
|
||||
des3 = b'dEs kEy\001dEs kEy\002dEs kEy\004'
|
||||
return des3[:length]
|
||||
return b''.join([self.DATA_BLOCK] * (length // len(self.DATA_BLOCK)) +
|
||||
[self.DATA_BLOCK[:length % len(self.DATA_BLOCK)]])
|
||||
|
||||
def can_do(self, alg: 'Algorithm') -> bool:
|
||||
"""Whether this key type can be used for operations with the given algorithm.
|
||||
|
||||
This function does not currently handle key derivation or PAKE.
|
||||
"""
|
||||
#pylint: disable=too-many-branches,too-many-return-statements
|
||||
if not alg.is_valid_for_operation():
|
||||
return False
|
||||
if self.head == 'HMAC' and alg.head == 'HMAC':
|
||||
return True
|
||||
if self.head == 'DES':
|
||||
# 64-bit block ciphers only allow a reduced set of modes.
|
||||
return alg.head in [
|
||||
'CBC_NO_PADDING', 'CBC_PKCS7',
|
||||
'ECB_NO_PADDING',
|
||||
]
|
||||
if self.head in BLOCK_CIPHERS and \
|
||||
alg.head in frozenset.union(BLOCK_MAC_MODES,
|
||||
BLOCK_CIPHER_MODES,
|
||||
BLOCK_AEAD_MODES):
|
||||
if alg.head in ['CMAC', 'OFB'] and \
|
||||
self.head in ['ARIA', 'CAMELLIA']:
|
||||
return False # not implemented in Mbed TLS
|
||||
return True
|
||||
if self.head == 'CHACHA20' and alg.head == 'CHACHA20_POLY1305':
|
||||
return True
|
||||
if self.head in {'ARC4', 'CHACHA20'} and \
|
||||
alg.head == 'STREAM_CIPHER':
|
||||
return True
|
||||
if self.head == 'RSA' and alg.head.startswith('RSA_'):
|
||||
return True
|
||||
if alg.category == AlgorithmCategory.KEY_AGREEMENT and \
|
||||
self.is_public():
|
||||
# The PSA API does not use public key objects in key agreement
|
||||
# operations: it imports the public key as a formatted byte string.
|
||||
# So a public key object with a key agreement algorithm is not
|
||||
# a valid combination.
|
||||
return False
|
||||
if alg.is_invalid_key_agreement_with_derivation():
|
||||
return False
|
||||
if self.head == 'ECC':
|
||||
assert self.params is not None
|
||||
eccc = EllipticCurveCategory.from_family(self.params[0])
|
||||
if alg.head == 'ECDH' and \
|
||||
eccc in {EllipticCurveCategory.SHORT_WEIERSTRASS,
|
||||
EllipticCurveCategory.MONTGOMERY}:
|
||||
return True
|
||||
if alg.head == 'ECDSA' and \
|
||||
eccc == EllipticCurveCategory.SHORT_WEIERSTRASS:
|
||||
return True
|
||||
if alg.head in {'PURE_EDDSA', 'EDDSA_PREHASH'} and \
|
||||
eccc == EllipticCurveCategory.TWISTED_EDWARDS:
|
||||
return True
|
||||
if self.head == 'DH' and alg.head == 'FFDH':
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class AlgorithmCategory(enum.Enum):
|
||||
"""PSA algorithm categories."""
|
||||
# The numbers are aligned with the category bits in numerical values of
|
||||
# algorithms.
|
||||
HASH = 2
|
||||
MAC = 3
|
||||
CIPHER = 4
|
||||
AEAD = 5
|
||||
SIGN = 6
|
||||
ASYMMETRIC_ENCRYPTION = 7
|
||||
KEY_DERIVATION = 8
|
||||
KEY_AGREEMENT = 9
|
||||
PAKE = 10
|
||||
|
||||
def requires_key(self) -> bool:
|
||||
"""Whether operations in this category are set up with a key."""
|
||||
return self not in {self.HASH, self.KEY_DERIVATION}
|
||||
|
||||
def is_asymmetric(self) -> bool:
|
||||
"""Whether operations in this category involve asymmetric keys."""
|
||||
return self in {
|
||||
self.SIGN,
|
||||
self.ASYMMETRIC_ENCRYPTION,
|
||||
self.KEY_AGREEMENT
|
||||
}
|
||||
|
||||
|
||||
class AlgorithmNotRecognized(Exception):
|
||||
def __init__(self, expr: str) -> None:
|
||||
super().__init__('Algorithm not recognized: ' + expr)
|
||||
self.expr = expr
|
||||
|
||||
|
||||
class Algorithm:
|
||||
"""Knowledge about a PSA algorithm."""
|
||||
|
||||
@staticmethod
|
||||
def determine_base(expr: str) -> str:
|
||||
"""Return an expression for the "base" of the algorithm.
|
||||
|
||||
This strips off variants of algorithms such as MAC truncation.
|
||||
|
||||
This function does not attempt to detect invalid inputs.
|
||||
"""
|
||||
m = re.match(r'PSA_ALG_(?:'
|
||||
r'(?:TRUNCATED|AT_LEAST_THIS_LENGTH)_MAC|'
|
||||
r'AEAD_WITH_(?:SHORTENED|AT_LEAST_THIS_LENGTH)_TAG'
|
||||
r')\((.*),[^,]+\)\Z', expr)
|
||||
if m:
|
||||
expr = m.group(1)
|
||||
return expr
|
||||
|
||||
@staticmethod
|
||||
def determine_head(expr: str) -> str:
|
||||
"""Return the head of an algorithm expression.
|
||||
|
||||
The head is the first (outermost) constructor, without its PSA_ALG_
|
||||
prefix, and with some normalization of similar algorithms.
|
||||
"""
|
||||
m = re.match(r'PSA_ALG_(?:DETERMINISTIC_)?(\w+)', expr)
|
||||
if not m:
|
||||
raise AlgorithmNotRecognized(expr)
|
||||
head = m.group(1)
|
||||
if head == 'KEY_AGREEMENT':
|
||||
m = re.match(r'PSA_ALG_KEY_AGREEMENT\s*\(\s*PSA_ALG_(\w+)', expr)
|
||||
if not m:
|
||||
raise AlgorithmNotRecognized(expr)
|
||||
head = m.group(1)
|
||||
head = re.sub(r'_ANY\Z', r'', head)
|
||||
if re.match(r'ED[0-9]+PH\Z', head):
|
||||
head = 'EDDSA_PREHASH'
|
||||
return head
|
||||
|
||||
CATEGORY_FROM_HEAD = {
|
||||
'SHA': AlgorithmCategory.HASH,
|
||||
'SHAKE256_512': AlgorithmCategory.HASH,
|
||||
'MD': AlgorithmCategory.HASH,
|
||||
'RIPEMD': AlgorithmCategory.HASH,
|
||||
'ANY_HASH': AlgorithmCategory.HASH,
|
||||
'HMAC': AlgorithmCategory.MAC,
|
||||
'STREAM_CIPHER': AlgorithmCategory.CIPHER,
|
||||
'CHACHA20_POLY1305': AlgorithmCategory.AEAD,
|
||||
'DSA': AlgorithmCategory.SIGN,
|
||||
'ECDSA': AlgorithmCategory.SIGN,
|
||||
'EDDSA': AlgorithmCategory.SIGN,
|
||||
'PURE_EDDSA': AlgorithmCategory.SIGN,
|
||||
'RSA_PSS': AlgorithmCategory.SIGN,
|
||||
'RSA_PKCS1V15_SIGN': AlgorithmCategory.SIGN,
|
||||
'RSA_PKCS1V15_CRYPT': AlgorithmCategory.ASYMMETRIC_ENCRYPTION,
|
||||
'RSA_OAEP': AlgorithmCategory.ASYMMETRIC_ENCRYPTION,
|
||||
'HKDF': AlgorithmCategory.KEY_DERIVATION,
|
||||
'TLS12_PRF': AlgorithmCategory.KEY_DERIVATION,
|
||||
'TLS12_PSK_TO_MS': AlgorithmCategory.KEY_DERIVATION,
|
||||
'TLS12_ECJPAKE_TO_PMS': AlgorithmCategory.KEY_DERIVATION,
|
||||
'PBKDF': AlgorithmCategory.KEY_DERIVATION,
|
||||
'ECDH': AlgorithmCategory.KEY_AGREEMENT,
|
||||
'FFDH': AlgorithmCategory.KEY_AGREEMENT,
|
||||
# KEY_AGREEMENT(...) is a key derivation with a key agreement component
|
||||
'KEY_AGREEMENT': AlgorithmCategory.KEY_DERIVATION,
|
||||
'JPAKE': AlgorithmCategory.PAKE,
|
||||
}
|
||||
for x in BLOCK_MAC_MODES:
|
||||
CATEGORY_FROM_HEAD[x] = AlgorithmCategory.MAC
|
||||
for x in BLOCK_CIPHER_MODES:
|
||||
CATEGORY_FROM_HEAD[x] = AlgorithmCategory.CIPHER
|
||||
for x in BLOCK_AEAD_MODES:
|
||||
CATEGORY_FROM_HEAD[x] = AlgorithmCategory.AEAD
|
||||
|
||||
def determine_category(self, expr: str, head: str) -> AlgorithmCategory:
|
||||
"""Return the category of the given algorithm expression.
|
||||
|
||||
This function does not attempt to detect invalid inputs.
|
||||
"""
|
||||
prefix = head
|
||||
while prefix:
|
||||
if prefix in self.CATEGORY_FROM_HEAD:
|
||||
return self.CATEGORY_FROM_HEAD[prefix]
|
||||
if re.match(r'.*[0-9]\Z', prefix):
|
||||
prefix = re.sub(r'_*[0-9]+\Z', r'', prefix)
|
||||
else:
|
||||
prefix = re.sub(r'_*[^_]*\Z', r'', prefix)
|
||||
raise AlgorithmNotRecognized(expr)
|
||||
|
||||
@staticmethod
|
||||
def determine_wildcard(expr) -> bool:
|
||||
"""Whether the given algorithm expression is a wildcard.
|
||||
|
||||
This function does not attempt to detect invalid inputs.
|
||||
"""
|
||||
if re.search(r'\bPSA_ALG_ANY_HASH\b', expr):
|
||||
return True
|
||||
if re.search(r'_AT_LEAST_', expr):
|
||||
return True
|
||||
return False
|
||||
|
||||
def __init__(self, expr: str) -> None:
|
||||
"""Analyze an algorithm value.
|
||||
|
||||
The algorithm must be expressed as a C expression containing only
|
||||
calls to PSA algorithm constructor macros and numeric literals.
|
||||
|
||||
This class is only programmed to handle valid expressions. Invalid
|
||||
expressions may result in exceptions or in nonsensical results.
|
||||
"""
|
||||
self.expression = re.sub(r'\s+', r'', expr)
|
||||
self.base_expression = self.determine_base(self.expression)
|
||||
self.head = self.determine_head(self.base_expression)
|
||||
self.category = self.determine_category(self.base_expression, self.head)
|
||||
self.is_wildcard = self.determine_wildcard(self.expression)
|
||||
|
||||
def get_key_agreement_derivation(self) -> Optional[str]:
|
||||
"""For a combined key agreement and key derivation algorithm, get the derivation part.
|
||||
|
||||
For anything else, return None.
|
||||
"""
|
||||
if self.category != AlgorithmCategory.KEY_AGREEMENT:
|
||||
return None
|
||||
m = re.match(r'PSA_ALG_KEY_AGREEMENT\(\w+,\s*(.*)\)\Z', self.expression)
|
||||
if not m:
|
||||
return None
|
||||
kdf_alg = m.group(1)
|
||||
# Assume kdf_alg is either a valid KDF or 0.
|
||||
if re.match(r'(?:0[Xx])?0+\s*\Z', kdf_alg):
|
||||
return None
|
||||
return kdf_alg
|
||||
|
||||
KEY_DERIVATIONS_INCOMPATIBLE_WITH_AGREEMENT = frozenset([
|
||||
'PSA_ALG_TLS12_ECJPAKE_TO_PMS', # secret input in specific format
|
||||
])
|
||||
def is_valid_key_agreement_with_derivation(self) -> bool:
|
||||
"""Whether this is a valid combined key agreement and key derivation algorithm."""
|
||||
kdf_alg = self.get_key_agreement_derivation()
|
||||
if kdf_alg is None:
|
||||
return False
|
||||
return kdf_alg not in self.KEY_DERIVATIONS_INCOMPATIBLE_WITH_AGREEMENT
|
||||
|
||||
def is_invalid_key_agreement_with_derivation(self) -> bool:
|
||||
"""Whether this is an invalid combined key agreement and key derivation algorithm."""
|
||||
kdf_alg = self.get_key_agreement_derivation()
|
||||
if kdf_alg is None:
|
||||
return False
|
||||
return kdf_alg in self.KEY_DERIVATIONS_INCOMPATIBLE_WITH_AGREEMENT
|
||||
|
||||
def short_expression(self, level: int = 0) -> str:
|
||||
"""Abbreviate the expression, keeping it human-readable.
|
||||
|
||||
See `crypto_knowledge.short_expression`.
|
||||
"""
|
||||
return short_expression(self.expression, level=level)
|
||||
|
||||
HASH_LENGTH = {
|
||||
'PSA_ALG_MD5': 16,
|
||||
'PSA_ALG_SHA_1': 20,
|
||||
}
|
||||
HASH_LENGTH_BITS_RE = re.compile(r'([0-9]+)\Z')
|
||||
@classmethod
|
||||
def hash_length(cls, alg: str) -> int:
|
||||
"""The length of the given hash algorithm, in bytes."""
|
||||
if alg in cls.HASH_LENGTH:
|
||||
return cls.HASH_LENGTH[alg]
|
||||
m = cls.HASH_LENGTH_BITS_RE.search(alg)
|
||||
if m:
|
||||
return int(m.group(1)) // 8
|
||||
raise ValueError('Unknown hash length for ' + alg)
|
||||
|
||||
PERMITTED_TAG_LENGTHS = {
|
||||
'PSA_ALG_CCM': frozenset([4, 6, 8, 10, 12, 14, 16]),
|
||||
'PSA_ALG_CHACHA20_POLY1305': frozenset([16]),
|
||||
'PSA_ALG_GCM': frozenset([4, 8, 12, 13, 14, 15, 16]),
|
||||
}
|
||||
MAC_LENGTH = {
|
||||
'PSA_ALG_CBC_MAC': 16, # actually the block cipher length
|
||||
'PSA_ALG_CMAC': 16, # actually the block cipher length
|
||||
}
|
||||
HMAC_RE = re.compile(r'PSA_ALG_HMAC\((.*)\)\Z')
|
||||
@classmethod
|
||||
def permitted_truncations(cls, base: str) -> FrozenSet[int]:
|
||||
"""Permitted output lengths for the given MAC or AEAD base algorithm.
|
||||
|
||||
For a MAC algorithm, this is the set of truncation lengths that
|
||||
Mbed TLS supports.
|
||||
For an AEAD algorithm, this is the set of truncation lengths that
|
||||
are permitted by the algorithm specification.
|
||||
"""
|
||||
if base in cls.PERMITTED_TAG_LENGTHS:
|
||||
return cls.PERMITTED_TAG_LENGTHS[base]
|
||||
max_length = cls.MAC_LENGTH.get(base, None)
|
||||
if max_length is None:
|
||||
m = cls.HMAC_RE.match(base)
|
||||
if m:
|
||||
max_length = cls.hash_length(m.group(1))
|
||||
if max_length is None:
|
||||
raise ValueError('Unknown permitted lengths for ' + base)
|
||||
return frozenset(range(4, max_length + 1))
|
||||
|
||||
TRUNCATED_ALG_RE = re.compile(
|
||||
r'(?P<face>PSA_ALG_(?:AEAD_WITH_SHORTENED_TAG|TRUNCATED_MAC))'
|
||||
r'\((?P<base>.*),'
|
||||
r'(?P<length>0[Xx][0-9A-Fa-f]+|[1-9][0-9]*|0[0-7]*)[LUlu]*\)\Z')
|
||||
def is_invalid_truncation(self) -> bool:
|
||||
"""False for a MAC or AEAD algorithm truncated to an invalid length.
|
||||
|
||||
True for a MAC or AEAD algorithm truncated to a valid length or to
|
||||
a length that cannot be determined. True for anything other than
|
||||
a truncated MAC or AEAD.
|
||||
"""
|
||||
m = self.TRUNCATED_ALG_RE.match(self.expression)
|
||||
if m:
|
||||
base = m.group('base')
|
||||
to_length = int(m.group('length'), 0)
|
||||
permitted_lengths = self.permitted_truncations(base)
|
||||
if to_length not in permitted_lengths:
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_valid_for_operation(self) -> bool:
|
||||
"""Whether this algorithm construction is valid for an operation.
|
||||
|
||||
This function assumes that the algorithm is constructed in a
|
||||
"grammatically" correct way, and only rejects semantically invalid
|
||||
combinations.
|
||||
"""
|
||||
if self.is_wildcard:
|
||||
return False
|
||||
if self.is_invalid_truncation():
|
||||
return False
|
||||
return True
|
||||
|
||||
def can_do(self, category: AlgorithmCategory) -> bool:
|
||||
"""Whether this algorithm can perform operations in the given category.
|
||||
"""
|
||||
if category == self.category:
|
||||
return True
|
||||
if category == AlgorithmCategory.KEY_DERIVATION and \
|
||||
self.is_valid_key_agreement_with_derivation():
|
||||
return True
|
||||
return False
|
||||
|
||||
def usage_flags(self, public: bool = False) -> List[str]:
|
||||
"""The list of usage flags describing operations that can perform this algorithm.
|
||||
|
||||
If public is true, only return public-key operations, not private-key operations.
|
||||
"""
|
||||
if self.category == AlgorithmCategory.HASH:
|
||||
flags = []
|
||||
elif self.category == AlgorithmCategory.MAC:
|
||||
flags = ['SIGN_HASH', 'SIGN_MESSAGE',
|
||||
'VERIFY_HASH', 'VERIFY_MESSAGE']
|
||||
elif self.category == AlgorithmCategory.CIPHER or \
|
||||
self.category == AlgorithmCategory.AEAD:
|
||||
flags = ['DECRYPT', 'ENCRYPT']
|
||||
elif self.category == AlgorithmCategory.SIGN:
|
||||
flags = ['VERIFY_HASH', 'VERIFY_MESSAGE']
|
||||
if not public:
|
||||
flags += ['SIGN_HASH', 'SIGN_MESSAGE']
|
||||
elif self.category == AlgorithmCategory.ASYMMETRIC_ENCRYPTION:
|
||||
flags = ['ENCRYPT']
|
||||
if not public:
|
||||
flags += ['DECRYPT']
|
||||
elif self.category == AlgorithmCategory.KEY_DERIVATION or \
|
||||
self.category == AlgorithmCategory.KEY_AGREEMENT:
|
||||
flags = ['DERIVE']
|
||||
else:
|
||||
raise AlgorithmNotRecognized(self.expression)
|
||||
return ['PSA_KEY_USAGE_' + flag for flag in flags]
|
||||
875
externals/mbedtls/scripts/mbedtls_dev/ecp.py
vendored
875
externals/mbedtls/scripts/mbedtls_dev/ecp.py
vendored
@@ -1,875 +0,0 @@
|
||||
"""Framework classes for generation of ecp test cases."""
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
from typing import List
|
||||
|
||||
from . import test_data_generation
|
||||
from . import bignum_common
|
||||
|
||||
|
||||
class EcpTarget(test_data_generation.BaseTarget):
|
||||
#pylint: disable=abstract-method, too-few-public-methods
|
||||
"""Target for ecp test case generation."""
|
||||
target_basename = 'test_suite_ecp.generated'
|
||||
|
||||
|
||||
class EcpP192R1Raw(bignum_common.ModOperationCommon,
|
||||
EcpTarget):
|
||||
"""Test cases for ECP P192 fast reduction."""
|
||||
symbol = "-"
|
||||
test_function = "ecp_mod_p_generic_raw"
|
||||
test_name = "ecp_mod_p192_raw"
|
||||
input_style = "fixed"
|
||||
arity = 1
|
||||
dependencies = ["MBEDTLS_ECP_DP_SECP192R1_ENABLED",
|
||||
"MBEDTLS_ECP_NIST_OPTIM"]
|
||||
|
||||
moduli = ["fffffffffffffffffffffffffffffffeffffffffffffffff"] # type: List[str]
|
||||
|
||||
input_values = [
|
||||
"0", "1",
|
||||
|
||||
# Modulus - 1
|
||||
"fffffffffffffffffffffffffffffffefffffffffffffffe",
|
||||
|
||||
# Modulus + 1
|
||||
"ffffffffffffffffffffffffffffffff0000000000000000",
|
||||
|
||||
# 2^192 - 1
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
|
||||
# Maximum canonical P192 multiplication result
|
||||
("fffffffffffffffffffffffffffffffdfffffffffffffffc"
|
||||
"000000000000000100000000000000040000000000000004"),
|
||||
|
||||
# Generate an overflow during reduction
|
||||
("00000000000000000000000000000001ffffffffffffffff"
|
||||
"ffffffffffffffffffffffffffffffff0000000000000000"),
|
||||
|
||||
# Generate an overflow during carry reduction
|
||||
("ffffffffffffffff00000000000000010000000000000000"
|
||||
"fffffffffffffffeffffffffffffffff0000000000000000"),
|
||||
|
||||
# First 8 number generated by random.getrandbits(384) - seed(2,2)
|
||||
("cf1822ffbc6887782b491044d5e341245c6e433715ba2bdd"
|
||||
"177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"),
|
||||
("ffed9235288bc781ae66267594c9c9500925e4749b575bd1"
|
||||
"3653f8dd9b1f282e4067c3584ee207f8da94e3e8ab73738f"),
|
||||
("ef8acd128b4f2fc15f3f57ebf30b94fa82523e86feac7eb7"
|
||||
"dc38f519b91751dacdbd47d364be8049a372db8f6e405d93"),
|
||||
("e8624fab5186ee32ee8d7ee9770348a05d300cb90706a045"
|
||||
"defc044a09325626e6b58de744ab6cce80877b6f71e1f6d2"),
|
||||
("2d3d854e061b90303b08c6e33c7295782d6c797f8f7d9b78"
|
||||
"2a1be9cd8697bbd0e2520e33e44c50556c71c4a66148a86f"),
|
||||
("fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f1"
|
||||
"5c14bc4a829e07b0829a48d422fe99a22c70501e533c9135"),
|
||||
("97eeab64ca2ce6bc5d3fd983c34c769fe89204e2e8168561"
|
||||
"867e5e15bc01bfce6a27e0dfcbf8754472154e76e4c11ab2"),
|
||||
("bd143fa9b714210c665d7435c1066932f4767f26294365b2"
|
||||
"721dea3bf63f23d0dbe53fcafb2147df5ca495fa5a91c89b"),
|
||||
|
||||
# Next 2 number generated by random.getrandbits(192)
|
||||
"47733e847d718d733ff98ff387c56473a7a83ee0761ebfd2",
|
||||
"cbd4d3e2d4dec9ef83f0be4e80371eb97f81375eecc1cb63"
|
||||
]
|
||||
|
||||
@property
|
||||
def arg_a(self) -> str:
|
||||
return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits)
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a % self.int_n
|
||||
return [self.format_result(result)]
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
return True
|
||||
|
||||
def arguments(self)-> List[str]:
|
||||
args = super().arguments()
|
||||
return ["MBEDTLS_ECP_DP_SECP192R1"] + args
|
||||
|
||||
|
||||
class EcpP224R1Raw(bignum_common.ModOperationCommon,
|
||||
EcpTarget):
|
||||
"""Test cases for ECP P224 fast reduction."""
|
||||
symbol = "-"
|
||||
test_function = "ecp_mod_p_generic_raw"
|
||||
test_name = "ecp_mod_p224_raw"
|
||||
input_style = "arch_split"
|
||||
arity = 1
|
||||
dependencies = ["MBEDTLS_ECP_DP_SECP224R1_ENABLED",
|
||||
"MBEDTLS_ECP_NIST_OPTIM"]
|
||||
|
||||
moduli = ["ffffffffffffffffffffffffffffffff000000000000000000000001"] # type: List[str]
|
||||
|
||||
input_values = [
|
||||
"0", "1",
|
||||
|
||||
# Modulus - 1
|
||||
"ffffffffffffffffffffffffffffffff000000000000000000000000",
|
||||
|
||||
# Modulus + 1
|
||||
"ffffffffffffffffffffffffffffffff000000000000000000000002",
|
||||
|
||||
# 2^224 - 1
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
|
||||
# Maximum canonical P224 multiplication result
|
||||
("fffffffffffffffffffffffffffffffe000000000000000000000000"
|
||||
"00000001000000000000000000000000000000000000000000000000"),
|
||||
|
||||
# Generate an overflow during reduction
|
||||
("00000000000000000000000000010000000070000000002000001000"
|
||||
"ffffffffffff9fffffffffe00000efff000070000000002000001003"),
|
||||
|
||||
# Generate an underflow during reduction
|
||||
("00000001000000000000000000000000000000000000000000000000"
|
||||
"00000000000dc0000000000000000001000000010000000100000003"),
|
||||
|
||||
# First 8 number generated by random.getrandbits(448) - seed(2,2)
|
||||
("da94e3e8ab73738fcf1822ffbc6887782b491044d5e341245c6e4337"
|
||||
"15ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"),
|
||||
("cdbd47d364be8049a372db8f6e405d93ffed9235288bc781ae662675"
|
||||
"94c9c9500925e4749b575bd13653f8dd9b1f282e4067c3584ee207f8"),
|
||||
("defc044a09325626e6b58de744ab6cce80877b6f71e1f6d2ef8acd12"
|
||||
"8b4f2fc15f3f57ebf30b94fa82523e86feac7eb7dc38f519b91751da"),
|
||||
("2d6c797f8f7d9b782a1be9cd8697bbd0e2520e33e44c50556c71c4a6"
|
||||
"6148a86fe8624fab5186ee32ee8d7ee9770348a05d300cb90706a045"),
|
||||
("8f54f8ceacaab39e83844b40ffa9b9f15c14bc4a829e07b0829a48d4"
|
||||
"22fe99a22c70501e533c91352d3d854e061b90303b08c6e33c729578"),
|
||||
("97eeab64ca2ce6bc5d3fd983c34c769fe89204e2e8168561867e5e15"
|
||||
"bc01bfce6a27e0dfcbf8754472154e76e4c11ab2fec3f6b32e8d4b8a"),
|
||||
("a7a83ee0761ebfd2bd143fa9b714210c665d7435c1066932f4767f26"
|
||||
"294365b2721dea3bf63f23d0dbe53fcafb2147df5ca495fa5a91c89b"),
|
||||
("74667bffe202849da9643a295a9ac6decbd4d3e2d4dec9ef83f0be4e"
|
||||
"80371eb97f81375eecc1cb6347733e847d718d733ff98ff387c56473"),
|
||||
|
||||
# Next 2 number generated by random.getrandbits(224)
|
||||
"eb9ac688b9d39cca91551e8259cc60b17604e4b4e73695c3e652c71a",
|
||||
"f0caeef038c89b38a8acb5137c9260dc74e088a9b9492f258ebdbfe3"
|
||||
]
|
||||
|
||||
@property
|
||||
def arg_a(self) -> str:
|
||||
limbs = 2 * bignum_common.bits_to_limbs(224, self.bits_in_limb)
|
||||
hex_digits = bignum_common.hex_digits_for_limb(limbs, self.bits_in_limb)
|
||||
return super().format_arg('{:x}'.format(self.int_a)).zfill(hex_digits)
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a % self.int_n
|
||||
return [self.format_result(result)]
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
return True
|
||||
|
||||
def arguments(self)-> List[str]:
|
||||
args = super().arguments()
|
||||
return ["MBEDTLS_ECP_DP_SECP224R1"] + args
|
||||
|
||||
|
||||
class EcpP256R1Raw(bignum_common.ModOperationCommon,
|
||||
EcpTarget):
|
||||
"""Test cases for ECP P256 fast reduction."""
|
||||
symbol = "-"
|
||||
test_function = "ecp_mod_p_generic_raw"
|
||||
test_name = "ecp_mod_p256_raw"
|
||||
input_style = "fixed"
|
||||
arity = 1
|
||||
dependencies = ["MBEDTLS_ECP_DP_SECP256R1_ENABLED",
|
||||
"MBEDTLS_ECP_NIST_OPTIM"]
|
||||
|
||||
moduli = ["ffffffff00000001000000000000000000000000ffffffffffffffffffffffff"] # type: List[str]
|
||||
|
||||
input_values = [
|
||||
"0", "1",
|
||||
|
||||
# Modulus - 1
|
||||
"ffffffff00000001000000000000000000000000fffffffffffffffffffffffe",
|
||||
|
||||
# Modulus + 1
|
||||
"ffffffff00000001000000000000000000000001000000000000000000000000",
|
||||
|
||||
# 2^256 - 1
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
|
||||
# Maximum canonical P256 multiplication result
|
||||
("fffffffe00000002fffffffe0000000100000001fffffffe00000001fffffffc"
|
||||
"00000003fffffffcfffffffffffffffffffffffc000000000000000000000004"),
|
||||
|
||||
# Generate an overflow during reduction
|
||||
("0000000000000000000000010000000000000000000000000000000000000000"
|
||||
"00000000000000000000000000000000000000000000000000000000ffffffff"),
|
||||
|
||||
# Generate an underflow during reduction
|
||||
("0000000000000000000000000000000000000000000000000000000000000010"
|
||||
"ffffffff00000000000000000000000000000000000000000000000000000000"),
|
||||
|
||||
# Generate an overflow during carry reduction
|
||||
("aaaaaaaa00000000000000000000000000000000000000000000000000000000"
|
||||
"00000000000000000000000000000000aaaaaaacaaaaaaaaaaaaaaaa00000000"),
|
||||
|
||||
# Generate an underflow during carry reduction
|
||||
("000000000000000000000001ffffffff00000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000002000000020000000100000002"),
|
||||
|
||||
# First 8 number generated by random.getrandbits(512) - seed(2,2)
|
||||
("4067c3584ee207f8da94e3e8ab73738fcf1822ffbc6887782b491044d5e34124"
|
||||
"5c6e433715ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"),
|
||||
("82523e86feac7eb7dc38f519b91751dacdbd47d364be8049a372db8f6e405d93"
|
||||
"ffed9235288bc781ae66267594c9c9500925e4749b575bd13653f8dd9b1f282e"),
|
||||
("e8624fab5186ee32ee8d7ee9770348a05d300cb90706a045defc044a09325626"
|
||||
"e6b58de744ab6cce80877b6f71e1f6d2ef8acd128b4f2fc15f3f57ebf30b94fa"),
|
||||
("829a48d422fe99a22c70501e533c91352d3d854e061b90303b08c6e33c729578"
|
||||
"2d6c797f8f7d9b782a1be9cd8697bbd0e2520e33e44c50556c71c4a66148a86f"),
|
||||
("e89204e2e8168561867e5e15bc01bfce6a27e0dfcbf8754472154e76e4c11ab2"
|
||||
"fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f15c14bc4a829e07b0"),
|
||||
("bd143fa9b714210c665d7435c1066932f4767f26294365b2721dea3bf63f23d0"
|
||||
"dbe53fcafb2147df5ca495fa5a91c89b97eeab64ca2ce6bc5d3fd983c34c769f"),
|
||||
("74667bffe202849da9643a295a9ac6decbd4d3e2d4dec9ef83f0be4e80371eb9"
|
||||
"7f81375eecc1cb6347733e847d718d733ff98ff387c56473a7a83ee0761ebfd2"),
|
||||
("d08f1bb2531d6460f0caeef038c89b38a8acb5137c9260dc74e088a9b9492f25"
|
||||
"8ebdbfe3eb9ac688b9d39cca91551e8259cc60b17604e4b4e73695c3e652c71a"),
|
||||
|
||||
# Next 2 number generated by random.getrandbits(256)
|
||||
"c5e2486c44a4a8f69dc8db48e86ec9c6e06f291b2a838af8d5c44a4eb3172062",
|
||||
"d4c0dca8b4c9e755cc9c3adcf515a8234da4daeb4f3f87777ad1f45ae9500ec9"
|
||||
]
|
||||
|
||||
@property
|
||||
def arg_a(self) -> str:
|
||||
return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits)
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a % self.int_n
|
||||
return [self.format_result(result)]
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
return True
|
||||
|
||||
def arguments(self)-> List[str]:
|
||||
args = super().arguments()
|
||||
return ["MBEDTLS_ECP_DP_SECP256R1"] + args
|
||||
|
||||
|
||||
class EcpP384R1Raw(bignum_common.ModOperationCommon,
|
||||
EcpTarget):
|
||||
"""Test cases for ECP P384 fast reduction."""
|
||||
test_function = "ecp_mod_p_generic_raw"
|
||||
test_name = "ecp_mod_p384_raw"
|
||||
input_style = "fixed"
|
||||
arity = 1
|
||||
dependencies = ["MBEDTLS_ECP_DP_SECP384R1_ENABLED",
|
||||
"MBEDTLS_ECP_NIST_OPTIM"]
|
||||
|
||||
moduli = [("ffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"fffffffffffffffeffffffff0000000000000000ffffffff")
|
||||
] # type: List[str]
|
||||
|
||||
input_values = [
|
||||
"0", "1",
|
||||
|
||||
# Modulus - 1
|
||||
("ffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"fffffffffffffffeffffffff0000000000000000fffffffe"),
|
||||
|
||||
# Modulus + 1
|
||||
("ffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"fffffffffffffffeffffffff000000000000000100000000"),
|
||||
|
||||
# 2^384 - 1
|
||||
("ffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffff"),
|
||||
|
||||
# Maximum canonical P384 multiplication result
|
||||
("ffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"fffffffffffffffdfffffffe0000000000000001fffffffc"
|
||||
"000000000000000000000000000000010000000200000000"
|
||||
"fffffffe000000020000000400000000fffffffc00000004"),
|
||||
|
||||
# Testing with overflow in A(12) + A(21) + A(20);
|
||||
("497811378624857a2c2af60d70583376545484cfae5c812f"
|
||||
"e2999fc1abb51d18b559e8ca3b50aaf263fdf8f24bdfb98f"
|
||||
"ffffffff20e65bf9099e4e73a5e8b517cf4fbeb8fd1750fd"
|
||||
"ae6d43f2e53f82d5ffffffffffffffffcc6f1e06111c62e0"),
|
||||
|
||||
# Testing with underflow in A(13) + A(22) + A(23) - A(12) - A(20);
|
||||
("dfdd25e96777406b3c04b8c7b406f5fcf287e1e576003a09"
|
||||
"2852a6fbe517f2712b68abef41dbd35183a0614fb7222606"
|
||||
"ffffffff84396eee542f18a9189d94396c784059c17a9f18"
|
||||
"f807214ef32f2f10ffffffff8a77fac20000000000000000"),
|
||||
|
||||
# Testing with overflow in A(23) + A(20) + A(19) - A(22);
|
||||
("783753f8a5afba6c1862eead1deb2fcdd907272be3ffd185"
|
||||
"42b24a71ee8b26cab0aa33513610ff973042bbe1637cc9fc"
|
||||
"99ad36c7f703514572cf4f5c3044469a8f5be6312c19e5d3"
|
||||
"f8fc1ac6ffffffffffffffff8c86252400000000ffffffff"),
|
||||
|
||||
# Testing with underflow in A(23) + A(20) + A(19) - A(22);
|
||||
("65e1d2362fce922663b7fd517586e88842a9b4bd092e93e6"
|
||||
"251c9c69f278cbf8285d99ae3b53da5ba36e56701e2b17c2"
|
||||
"25f1239556c5f00117fa140218b46ebd8e34f50d0018701f"
|
||||
"a8a0a5cc00000000000000004410bcb4ffffffff00000000"),
|
||||
|
||||
# Testing the second round of carry reduction
|
||||
("000000000000000000000000ffffffffffffffffffffffff"
|
||||
"ffffffffffffffffffffffffffffffff0000000000000000"
|
||||
"0000000000000000ffffffff000000000000000000000001"
|
||||
"00000000000000000000000000000000ffffffff00000001"),
|
||||
|
||||
# First 8 number generated by random.getrandbits(768) - seed(2,2)
|
||||
("ffed9235288bc781ae66267594c9c9500925e4749b575bd1"
|
||||
"3653f8dd9b1f282e4067c3584ee207f8da94e3e8ab73738f"
|
||||
"cf1822ffbc6887782b491044d5e341245c6e433715ba2bdd"
|
||||
"177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"),
|
||||
("e8624fab5186ee32ee8d7ee9770348a05d300cb90706a045"
|
||||
"defc044a09325626e6b58de744ab6cce80877b6f71e1f6d2"
|
||||
"ef8acd128b4f2fc15f3f57ebf30b94fa82523e86feac7eb7"
|
||||
"dc38f519b91751dacdbd47d364be8049a372db8f6e405d93"),
|
||||
("fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f1"
|
||||
"5c14bc4a829e07b0829a48d422fe99a22c70501e533c9135"
|
||||
"2d3d854e061b90303b08c6e33c7295782d6c797f8f7d9b78"
|
||||
"2a1be9cd8697bbd0e2520e33e44c50556c71c4a66148a86f"),
|
||||
("bd143fa9b714210c665d7435c1066932f4767f26294365b2"
|
||||
"721dea3bf63f23d0dbe53fcafb2147df5ca495fa5a91c89b"
|
||||
"97eeab64ca2ce6bc5d3fd983c34c769fe89204e2e8168561"
|
||||
"867e5e15bc01bfce6a27e0dfcbf8754472154e76e4c11ab2"),
|
||||
("8ebdbfe3eb9ac688b9d39cca91551e8259cc60b17604e4b4"
|
||||
"e73695c3e652c71a74667bffe202849da9643a295a9ac6de"
|
||||
"cbd4d3e2d4dec9ef83f0be4e80371eb97f81375eecc1cb63"
|
||||
"47733e847d718d733ff98ff387c56473a7a83ee0761ebfd2"),
|
||||
("d4c0dca8b4c9e755cc9c3adcf515a8234da4daeb4f3f8777"
|
||||
"7ad1f45ae9500ec9c5e2486c44a4a8f69dc8db48e86ec9c6"
|
||||
"e06f291b2a838af8d5c44a4eb3172062d08f1bb2531d6460"
|
||||
"f0caeef038c89b38a8acb5137c9260dc74e088a9b9492f25"),
|
||||
("0227eeb7b9d7d01f5769da05d205bbfcc8c69069134bccd3"
|
||||
"e1cf4f589f8e4ce0af29d115ef24bd625dd961e6830b54fa"
|
||||
"7d28f93435339774bb1e386c4fd5079e681b8f5896838b76"
|
||||
"9da59b74a6c3181c81e220df848b1df78feb994a81167346"),
|
||||
("d322a7353ead4efe440e2b4fda9c025a22f1a83185b98f5f"
|
||||
"c11e60de1b343f52ea748db9e020307aaeb6db2c3a038a70"
|
||||
"9779ac1f45e9dd320c855fdfa7251af0930cdbd30f0ad2a8"
|
||||
"1b2d19a2beaa14a7ff3fe32a30ffc4eed0a7bd04e85bfcdd"),
|
||||
|
||||
# Next 2 number generated by random.getrandbits(384)
|
||||
("5c3747465cc36c270e8a35b10828d569c268a20eb78ac332"
|
||||
"e5e138e26c4454b90f756132e16dce72f18e859835e1f291"),
|
||||
("eb2b5693babb7fbb0a76c196067cfdcb11457d9cf45e2fa0"
|
||||
"1d7f4275153924800600571fac3a5b263fdf57cd2c006497")
|
||||
]
|
||||
|
||||
@property
|
||||
def arg_a(self) -> str:
|
||||
return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits)
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a % self.int_n
|
||||
return [self.format_result(result)]
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
return True
|
||||
|
||||
def arguments(self)-> List[str]:
|
||||
args = super().arguments()
|
||||
return ["MBEDTLS_ECP_DP_SECP384R1"] + args
|
||||
|
||||
|
||||
class EcpP521R1Raw(bignum_common.ModOperationCommon,
|
||||
EcpTarget):
|
||||
"""Test cases for ECP P521 fast reduction."""
|
||||
test_function = "ecp_mod_p_generic_raw"
|
||||
test_name = "ecp_mod_p521_raw"
|
||||
input_style = "arch_split"
|
||||
arity = 1
|
||||
dependencies = ["MBEDTLS_ECP_DP_SECP521R1_ENABLED",
|
||||
"MBEDTLS_ECP_NIST_OPTIM"]
|
||||
|
||||
moduli = [("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
|
||||
] # type: List[str]
|
||||
|
||||
input_values = [
|
||||
"0", "1",
|
||||
|
||||
# Modulus - 1
|
||||
("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"),
|
||||
|
||||
# Modulus + 1
|
||||
("020000000000000000000000000000000000000000000000000000000000000000"
|
||||
"000000000000000000000000000000000000000000000000000000000000000000"),
|
||||
|
||||
# Maximum canonical P521 multiplication result
|
||||
("0003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"fffff800"
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000000000004"),
|
||||
|
||||
# Test case for overflow during addition
|
||||
("0001efffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"000001ef"
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
"000000000000000000000000000000000000000000000000000000000f000000"),
|
||||
|
||||
# First 8 number generated by random.getrandbits(1042) - seed(2,2)
|
||||
("0003cc2e82523e86feac7eb7dc38f519b91751dacdbd47d364be8049a372db8f"
|
||||
"6e405d93ffed9235288bc781ae66267594c9c9500925e4749b575bd13653f8dd"
|
||||
"9b1f282e"
|
||||
"4067c3584ee207f8da94e3e8ab73738fcf1822ffbc6887782b491044d5e34124"
|
||||
"5c6e433715ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"),
|
||||
("00017052829e07b0829a48d422fe99a22c70501e533c91352d3d854e061b9030"
|
||||
"3b08c6e33c7295782d6c797f8f7d9b782a1be9cd8697bbd0e2520e33e44c5055"
|
||||
"6c71c4a6"
|
||||
"6148a86fe8624fab5186ee32ee8d7ee9770348a05d300cb90706a045defc044a"
|
||||
"09325626e6b58de744ab6cce80877b6f71e1f6d2ef8acd128b4f2fc15f3f57eb"),
|
||||
("00021f15a7a83ee0761ebfd2bd143fa9b714210c665d7435c1066932f4767f26"
|
||||
"294365b2721dea3bf63f23d0dbe53fcafb2147df5ca495fa5a91c89b97eeab64"
|
||||
"ca2ce6bc"
|
||||
"5d3fd983c34c769fe89204e2e8168561867e5e15bc01bfce6a27e0dfcbf87544"
|
||||
"72154e76e4c11ab2fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f1"),
|
||||
("000381bc2a838af8d5c44a4eb3172062d08f1bb2531d6460f0caeef038c89b38"
|
||||
"a8acb5137c9260dc74e088a9b9492f258ebdbfe3eb9ac688b9d39cca91551e82"
|
||||
"59cc60b1"
|
||||
"7604e4b4e73695c3e652c71a74667bffe202849da9643a295a9ac6decbd4d3e2"
|
||||
"d4dec9ef83f0be4e80371eb97f81375eecc1cb6347733e847d718d733ff98ff3"),
|
||||
("00034816c8c69069134bccd3e1cf4f589f8e4ce0af29d115ef24bd625dd961e6"
|
||||
"830b54fa7d28f93435339774bb1e386c4fd5079e681b8f5896838b769da59b74"
|
||||
"a6c3181c"
|
||||
"81e220df848b1df78feb994a81167346d4c0dca8b4c9e755cc9c3adcf515a823"
|
||||
"4da4daeb4f3f87777ad1f45ae9500ec9c5e2486c44a4a8f69dc8db48e86ec9c6"),
|
||||
("000397846c4454b90f756132e16dce72f18e859835e1f291d322a7353ead4efe"
|
||||
"440e2b4fda9c025a22f1a83185b98f5fc11e60de1b343f52ea748db9e020307a"
|
||||
"aeb6db2c"
|
||||
"3a038a709779ac1f45e9dd320c855fdfa7251af0930cdbd30f0ad2a81b2d19a2"
|
||||
"beaa14a7ff3fe32a30ffc4eed0a7bd04e85bfcdd0227eeb7b9d7d01f5769da05"),
|
||||
("00002c3296e6bc4d62b47204007ee4fab105d83e85e951862f0981aebc1b00d9"
|
||||
"2838e766ef9b6bf2d037fe2e20b6a8464174e75a5f834da70569c018eb2b5693"
|
||||
"babb7fbb"
|
||||
"0a76c196067cfdcb11457d9cf45e2fa01d7f4275153924800600571fac3a5b26"
|
||||
"3fdf57cd2c0064975c3747465cc36c270e8a35b10828d569c268a20eb78ac332"),
|
||||
("00009d23b4917fc09f20dbb0dcc93f0e66dfe717c17313394391b6e2e6eacb0f"
|
||||
"0bb7be72bd6d25009aeb7fa0c4169b148d2f527e72daf0a54ef25c0707e33868"
|
||||
"7d1f7157"
|
||||
"5653a45c49390aa51cf5192bbf67da14be11d56ba0b4a2969d8055a9f03f2d71"
|
||||
"581d8e830112ff0f0948eccaf8877acf26c377c13f719726fd70bddacb4deeec"),
|
||||
|
||||
# Next 2 number generated by random.getrandbits(521)
|
||||
("12b84ae65e920a63ac1f2b64df6dff07870c9d531ae72a47403063238da1a1fe"
|
||||
"3f9d6a179fa50f96cd4aff9261aa92c0e6f17ec940639bc2ccdf572df00790813e3"),
|
||||
("166049dd332a73fa0b26b75196cf87eb8a09b27ec714307c68c425424a1574f1"
|
||||
"eedf5b0f16cdfdb839424d201e653f53d6883ca1c107ca6e706649889c0c7f38608")
|
||||
]
|
||||
|
||||
@property
|
||||
def arg_a(self) -> str:
|
||||
# Number of limbs: 2 * N
|
||||
return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits)
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a % self.int_n
|
||||
return [self.format_result(result)]
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
return True
|
||||
|
||||
def arguments(self)-> List[str]:
|
||||
args = super().arguments()
|
||||
return ["MBEDTLS_ECP_DP_SECP521R1"] + args
|
||||
|
||||
|
||||
class EcpP192K1Raw(bignum_common.ModOperationCommon,
|
||||
EcpTarget):
|
||||
"""Test cases for ECP P192K1 fast reduction."""
|
||||
symbol = "-"
|
||||
test_function = "ecp_mod_p_generic_raw"
|
||||
test_name = "ecp_mod_p192k1_raw"
|
||||
input_style = "fixed"
|
||||
arity = 1
|
||||
dependencies = ["MBEDTLS_ECP_DP_SECP192K1_ENABLED"]
|
||||
|
||||
moduli = ["fffffffffffffffffffffffffffffffffffffffeffffee37"] # type: List[str]
|
||||
|
||||
input_values = [
|
||||
"0", "1",
|
||||
|
||||
# Modulus - 1
|
||||
"fffffffffffffffffffffffffffffffffffffffeffffee36",
|
||||
|
||||
# Modulus + 1
|
||||
"fffffffffffffffffffffffffffffffffffffffeffffee38",
|
||||
|
||||
# 2^192 - 1
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
|
||||
# Maximum canonical P192K1 multiplication result
|
||||
("fffffffffffffffffffffffffffffffffffffffdffffdc6c"
|
||||
"0000000000000000000000000000000100002394013c7364"),
|
||||
|
||||
# Test case for overflow during addition
|
||||
("00000007ffff71b809e27dd832cfd5e04d9d2dbb9f8da217"
|
||||
"0000000000000000000000000000000000000000520834f0"),
|
||||
|
||||
# First 8 number generated by random.getrandbits(384) - seed(2,2)
|
||||
("cf1822ffbc6887782b491044d5e341245c6e433715ba2bdd"
|
||||
"177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"),
|
||||
("ffed9235288bc781ae66267594c9c9500925e4749b575bd1"
|
||||
"3653f8dd9b1f282e4067c3584ee207f8da94e3e8ab73738f"),
|
||||
("ef8acd128b4f2fc15f3f57ebf30b94fa82523e86feac7eb7"
|
||||
"dc38f519b91751dacdbd47d364be8049a372db8f6e405d93"),
|
||||
("e8624fab5186ee32ee8d7ee9770348a05d300cb90706a045"
|
||||
"defc044a09325626e6b58de744ab6cce80877b6f71e1f6d2"),
|
||||
("2d3d854e061b90303b08c6e33c7295782d6c797f8f7d9b78"
|
||||
"2a1be9cd8697bbd0e2520e33e44c50556c71c4a66148a86f"),
|
||||
("fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f1"
|
||||
"5c14bc4a829e07b0829a48d422fe99a22c70501e533c9135"),
|
||||
("97eeab64ca2ce6bc5d3fd983c34c769fe89204e2e8168561"
|
||||
"867e5e15bc01bfce6a27e0dfcbf8754472154e76e4c11ab2"),
|
||||
("bd143fa9b714210c665d7435c1066932f4767f26294365b2"
|
||||
"721dea3bf63f23d0dbe53fcafb2147df5ca495fa5a91c89b"),
|
||||
|
||||
# Next 2 number generated by random.getrandbits(192)
|
||||
"47733e847d718d733ff98ff387c56473a7a83ee0761ebfd2",
|
||||
"cbd4d3e2d4dec9ef83f0be4e80371eb97f81375eecc1cb63"
|
||||
]
|
||||
|
||||
@property
|
||||
def arg_a(self) -> str:
|
||||
return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits)
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a % self.int_n
|
||||
return [self.format_result(result)]
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
return True
|
||||
|
||||
def arguments(self):
|
||||
args = super().arguments()
|
||||
return ["MBEDTLS_ECP_DP_SECP192K1"] + args
|
||||
|
||||
|
||||
class EcpP224K1Raw(bignum_common.ModOperationCommon,
|
||||
EcpTarget):
|
||||
"""Test cases for ECP P224 fast reduction."""
|
||||
symbol = "-"
|
||||
test_function = "ecp_mod_p_generic_raw"
|
||||
test_name = "ecp_mod_p224k1_raw"
|
||||
input_style = "arch_split"
|
||||
arity = 1
|
||||
dependencies = ["MBEDTLS_ECP_DP_SECP224K1_ENABLED"]
|
||||
|
||||
moduli = ["fffffffffffffffffffffffffffffffffffffffffffffffeffffe56d"] # type: List[str]
|
||||
|
||||
input_values = [
|
||||
"0", "1",
|
||||
|
||||
# Modulus - 1
|
||||
"fffffffffffffffffffffffffffffffffffffffffffffffeffffe56c",
|
||||
|
||||
# Modulus + 1
|
||||
"fffffffffffffffffffffffffffffffffffffffffffffffeffffe56e",
|
||||
|
||||
# 2^224 - 1
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
|
||||
# Maximum canonical P224K1 multiplication result
|
||||
("fffffffffffffffffffffffffffffffffffffffffffffffdffffcad8"
|
||||
"00000000000000000000000000000000000000010000352802c26590"),
|
||||
|
||||
# Test case for overflow during addition
|
||||
("0000007ffff2b68161180fd8cd92e1a109be158a19a99b1809db8032"
|
||||
"0000000000000000000000000000000000000000000000000bf04f49"),
|
||||
|
||||
# First 8 number generated by random.getrandbits(448) - seed(2,2)
|
||||
("da94e3e8ab73738fcf1822ffbc6887782b491044d5e341245c6e4337"
|
||||
"15ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"),
|
||||
("cdbd47d364be8049a372db8f6e405d93ffed9235288bc781ae662675"
|
||||
"94c9c9500925e4749b575bd13653f8dd9b1f282e4067c3584ee207f8"),
|
||||
("defc044a09325626e6b58de744ab6cce80877b6f71e1f6d2ef8acd12"
|
||||
"8b4f2fc15f3f57ebf30b94fa82523e86feac7eb7dc38f519b91751da"),
|
||||
("2d6c797f8f7d9b782a1be9cd8697bbd0e2520e33e44c50556c71c4a6"
|
||||
"6148a86fe8624fab5186ee32ee8d7ee9770348a05d300cb90706a045"),
|
||||
("8f54f8ceacaab39e83844b40ffa9b9f15c14bc4a829e07b0829a48d4"
|
||||
"22fe99a22c70501e533c91352d3d854e061b90303b08c6e33c729578"),
|
||||
("97eeab64ca2ce6bc5d3fd983c34c769fe89204e2e8168561867e5e15"
|
||||
"bc01bfce6a27e0dfcbf8754472154e76e4c11ab2fec3f6b32e8d4b8a"),
|
||||
("a7a83ee0761ebfd2bd143fa9b714210c665d7435c1066932f4767f26"
|
||||
"294365b2721dea3bf63f23d0dbe53fcafb2147df5ca495fa5a91c89b"),
|
||||
("74667bffe202849da9643a295a9ac6decbd4d3e2d4dec9ef83f0be4e"
|
||||
"80371eb97f81375eecc1cb6347733e847d718d733ff98ff387c56473"),
|
||||
|
||||
# Next 2 number generated by random.getrandbits(224)
|
||||
("eb9ac688b9d39cca91551e8259cc60b17604e4b4e73695c3e652c71a"),
|
||||
("f0caeef038c89b38a8acb5137c9260dc74e088a9b9492f258ebdbfe3"),
|
||||
]
|
||||
|
||||
@property
|
||||
def arg_a(self) -> str:
|
||||
limbs = 2 * bignum_common.bits_to_limbs(224, self.bits_in_limb)
|
||||
hex_digits = bignum_common.hex_digits_for_limb(limbs, self.bits_in_limb)
|
||||
return super().format_arg('{:x}'.format(self.int_a)).zfill(hex_digits)
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a % self.int_n
|
||||
return [self.format_result(result)]
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
return True
|
||||
|
||||
def arguments(self):
|
||||
args = super().arguments()
|
||||
return ["MBEDTLS_ECP_DP_SECP224K1"] + args
|
||||
|
||||
|
||||
class EcpP256K1Raw(bignum_common.ModOperationCommon,
|
||||
EcpTarget):
|
||||
"""Test cases for ECP P256 fast reduction."""
|
||||
symbol = "-"
|
||||
test_function = "ecp_mod_p_generic_raw"
|
||||
test_name = "ecp_mod_p256k1_raw"
|
||||
input_style = "fixed"
|
||||
arity = 1
|
||||
dependencies = ["MBEDTLS_ECP_DP_SECP256K1_ENABLED"]
|
||||
|
||||
moduli = ["fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"] # type: List[str]
|
||||
|
||||
input_values = [
|
||||
"0", "1",
|
||||
|
||||
# Modulus - 1
|
||||
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
|
||||
|
||||
# Modulus + 1
|
||||
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
|
||||
|
||||
# 2^256 - 1
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
|
||||
# Maximum canonical P256K1 multiplication result
|
||||
("fffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffff85c"
|
||||
"000000000000000000000000000000000000000000000001000007a4000e9844"),
|
||||
|
||||
# Test case for overflow during addition
|
||||
("0000fffffc2f000e90a0c86a0a63234e5ba641f43a7e4aecc4040e67ec850562"
|
||||
"00000000000000000000000000000000000000000000000000000000585674fd"),
|
||||
|
||||
# Test case for overflow during addition
|
||||
("0000fffffc2f000e90a0c86a0a63234e5ba641f43a7e4aecc4040e67ec850562"
|
||||
"00000000000000000000000000000000000000000000000000000000585674fd"),
|
||||
|
||||
# First 8 number generated by random.getrandbits(512) - seed(2,2)
|
||||
("4067c3584ee207f8da94e3e8ab73738fcf1822ffbc6887782b491044d5e34124"
|
||||
"5c6e433715ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"),
|
||||
("82523e86feac7eb7dc38f519b91751dacdbd47d364be8049a372db8f6e405d93"
|
||||
"ffed9235288bc781ae66267594c9c9500925e4749b575bd13653f8dd9b1f282e"),
|
||||
("e8624fab5186ee32ee8d7ee9770348a05d300cb90706a045defc044a09325626"
|
||||
"e6b58de744ab6cce80877b6f71e1f6d2ef8acd128b4f2fc15f3f57ebf30b94fa"),
|
||||
("829a48d422fe99a22c70501e533c91352d3d854e061b90303b08c6e33c729578"
|
||||
"2d6c797f8f7d9b782a1be9cd8697bbd0e2520e33e44c50556c71c4a66148a86f"),
|
||||
("e89204e2e8168561867e5e15bc01bfce6a27e0dfcbf8754472154e76e4c11ab2"
|
||||
"fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f15c14bc4a829e07b0"),
|
||||
("bd143fa9b714210c665d7435c1066932f4767f26294365b2721dea3bf63f23d0"
|
||||
"dbe53fcafb2147df5ca495fa5a91c89b97eeab64ca2ce6bc5d3fd983c34c769f"),
|
||||
("74667bffe202849da9643a295a9ac6decbd4d3e2d4dec9ef83f0be4e80371eb9"
|
||||
"7f81375eecc1cb6347733e847d718d733ff98ff387c56473a7a83ee0761ebfd2"),
|
||||
("d08f1bb2531d6460f0caeef038c89b38a8acb5137c9260dc74e088a9b9492f25"
|
||||
"8ebdbfe3eb9ac688b9d39cca91551e8259cc60b17604e4b4e73695c3e652c71a"),
|
||||
|
||||
# Next 2 number generated by random.getrandbits(256)
|
||||
("c5e2486c44a4a8f69dc8db48e86ec9c6e06f291b2a838af8d5c44a4eb3172062"),
|
||||
("d4c0dca8b4c9e755cc9c3adcf515a8234da4daeb4f3f87777ad1f45ae9500ec9"),
|
||||
]
|
||||
|
||||
@property
|
||||
def arg_a(self) -> str:
|
||||
return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits)
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a % self.int_n
|
||||
return [self.format_result(result)]
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
return True
|
||||
|
||||
def arguments(self):
|
||||
args = super().arguments()
|
||||
return ["MBEDTLS_ECP_DP_SECP256K1"] + args
|
||||
|
||||
|
||||
class EcpP255Raw(bignum_common.ModOperationCommon,
|
||||
EcpTarget):
|
||||
"""Test cases for ECP 25519 fast reduction."""
|
||||
symbol = "-"
|
||||
test_function = "ecp_mod_p_generic_raw"
|
||||
test_name = "mbedtls_ecp_mod_p255_raw"
|
||||
input_style = "fixed"
|
||||
arity = 1
|
||||
dependencies = ["MBEDTLS_ECP_DP_CURVE25519_ENABLED"]
|
||||
|
||||
moduli = [("7fffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"ffffffffffffed")] # type: List[str]
|
||||
|
||||
input_values = [
|
||||
"0", "1",
|
||||
|
||||
# Modulus - 1
|
||||
("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec"),
|
||||
|
||||
# Modulus + 1
|
||||
("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee"),
|
||||
|
||||
# 2^255 - 1
|
||||
("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
||||
|
||||
# Maximum canonical P255 multiplication result
|
||||
("3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec"
|
||||
"0000000000000000000000000000000000000000000000000000000000000190"),
|
||||
|
||||
# First 8 number generated by random.getrandbits(510) - seed(2,2)
|
||||
("1019f0d64ee207f8da94e3e8ab73738fcf1822ffbc6887782b491044d5e34124"
|
||||
"5c6e433715ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"),
|
||||
("20948fa1feac7eb7dc38f519b91751dacdbd47d364be8049a372db8f6e405d93"
|
||||
"ffed9235288bc781ae66267594c9c9500925e4749b575bd13653f8dd9b1f282e"),
|
||||
("3a1893ea5186ee32ee8d7ee9770348a05d300cb90706a045defc044a09325626"
|
||||
"e6b58de744ab6cce80877b6f71e1f6d2ef8acd128b4f2fc15f3f57ebf30b94fa"),
|
||||
("20a6923522fe99a22c70501e533c91352d3d854e061b90303b08c6e33c729578"
|
||||
"2d6c797f8f7d9b782a1be9cd8697bbd0e2520e33e44c50556c71c4a66148a86f"),
|
||||
("3a248138e8168561867e5e15bc01bfce6a27e0dfcbf8754472154e76e4c11ab2"
|
||||
"fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f15c14bc4a829e07b0"),
|
||||
("2f450feab714210c665d7435c1066932f4767f26294365b2721dea3bf63f23d0"
|
||||
"dbe53fcafb2147df5ca495fa5a91c89b97eeab64ca2ce6bc5d3fd983c34c769f"),
|
||||
("1d199effe202849da9643a295a9ac6decbd4d3e2d4dec9ef83f0be4e80371eb9"
|
||||
"7f81375eecc1cb6347733e847d718d733ff98ff387c56473a7a83ee0761ebfd2"),
|
||||
("3423c6ec531d6460f0caeef038c89b38a8acb5137c9260dc74e088a9b9492f25"
|
||||
"8ebdbfe3eb9ac688b9d39cca91551e8259cc60b17604e4b4e73695c3e652c71a"),
|
||||
|
||||
# Next 2 number generated by random.getrandbits(255)
|
||||
("62f1243644a4a8f69dc8db48e86ec9c6e06f291b2a838af8d5c44a4eb3172062"),
|
||||
("6a606e54b4c9e755cc9c3adcf515a8234da4daeb4f3f87777ad1f45ae9500ec9"),
|
||||
]
|
||||
|
||||
@property
|
||||
def arg_a(self) -> str:
|
||||
return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits)
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a % self.int_n
|
||||
return [self.format_result(result)]
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
return True
|
||||
|
||||
def arguments(self)-> List[str]:
|
||||
args = super().arguments()
|
||||
return ["MBEDTLS_ECP_DP_CURVE25519"] + args
|
||||
|
||||
|
||||
class EcpP448Raw(bignum_common.ModOperationCommon,
|
||||
EcpTarget):
|
||||
"""Test cases for ECP P448 fast reduction."""
|
||||
symbol = "-"
|
||||
test_function = "ecp_mod_p_generic_raw"
|
||||
test_name = "ecp_mod_p448_raw"
|
||||
input_style = "fixed"
|
||||
arity = 1
|
||||
dependencies = ["MBEDTLS_ECP_DP_CURVE448_ENABLED"]
|
||||
|
||||
moduli = [("fffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffff")] # type: List[str]
|
||||
|
||||
input_values = [
|
||||
"0", "1",
|
||||
|
||||
# Modulus - 1
|
||||
("fffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
|
||||
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffe"),
|
||||
|
||||
# Modulus + 1
|
||||
("ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"00000000000000000000000000000000000000000000000000000000"),
|
||||
|
||||
# 2^448 - 1
|
||||
("ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
||||
|
||||
# Maximum canonical P448 multiplication result
|
||||
("fffffffffffffffffffffffffffffffffffffffffffffffffffffffd"
|
||||
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffd"
|
||||
"00000000000000000000000000000000000000000000000000000004"
|
||||
"00000000000000000000000000000000000000000000000000000004"),
|
||||
|
||||
# First 8 number generated by random.getrandbits(896) - seed(2,2)
|
||||
("74667bffe202849da9643a295a9ac6decbd4d3e2d4dec9ef83f0be4e"
|
||||
"80371eb97f81375eecc1cb6347733e847d718d733ff98ff387c56473"
|
||||
"a7a83ee0761ebfd2bd143fa9b714210c665d7435c1066932f4767f26"
|
||||
"294365b2721dea3bf63f23d0dbe53fcafb2147df5ca495fa5a91c89b"),
|
||||
("4da4daeb4f3f87777ad1f45ae9500ec9c5e2486c44a4a8f69dc8db48"
|
||||
"e86ec9c6e06f291b2a838af8d5c44a4eb3172062d08f1bb2531d6460"
|
||||
"f0caeef038c89b38a8acb5137c9260dc74e088a9b9492f258ebdbfe3"
|
||||
"eb9ac688b9d39cca91551e8259cc60b17604e4b4e73695c3e652c71a"),
|
||||
("bc1b00d92838e766ef9b6bf2d037fe2e20b6a8464174e75a5f834da7"
|
||||
"0569c018eb2b5693babb7fbb0a76c196067cfdcb11457d9cf45e2fa0"
|
||||
"1d7f4275153924800600571fac3a5b263fdf57cd2c0064975c374746"
|
||||
"5cc36c270e8a35b10828d569c268a20eb78ac332e5e138e26c4454b9"),
|
||||
("8d2f527e72daf0a54ef25c0707e338687d1f71575653a45c49390aa5"
|
||||
"1cf5192bbf67da14be11d56ba0b4a2969d8055a9f03f2d71581d8e83"
|
||||
"0112ff0f0948eccaf8877acf26c377c13f719726fd70bddacb4deeec"
|
||||
"0b0c995e96e6bc4d62b47204007ee4fab105d83e85e951862f0981ae"),
|
||||
("84ae65e920a63ac1f2b64df6dff07870c9d531ae72a47403063238da"
|
||||
"1a1fe3f9d6a179fa50f96cd4aff9261aa92c0e6f17ec940639bc2ccd"
|
||||
"f572df00790813e32748dd1db4917fc09f20dbb0dcc93f0e66dfe717"
|
||||
"c17313394391b6e2e6eacb0f0bb7be72bd6d25009aeb7fa0c4169b14"),
|
||||
("2bb3b36f29421c4021b7379f0897246a40c270b00e893302aba9e7b8"
|
||||
"23fc5ad2f58105748ed5d1b7b310b730049dd332a73fa0b26b75196c"
|
||||
"f87eb8a09b27ec714307c68c425424a1574f1eedf5b0f16cdfdb8394"
|
||||
"24d201e653f53d6883ca1c107ca6e706649889c0c7f3860895bfa813"),
|
||||
("af3f5d7841b1256d5c1dc12fb5a1ae519fb8883accda6559caa538a0"
|
||||
"9fc9370d3a6b86a7975b54a31497024640332b0612d4050771d7b14e"
|
||||
"b6c004cc3b8367dc3f2bb31efe9934ad0809eae3ef232a32b5459d83"
|
||||
"fbc46f1aea990e94821d46063b4dbf2ca294523d74115c86188b1044"),
|
||||
("7430051376e31f5aab63ad02854efa600641b4fa37a47ce41aeffafc"
|
||||
"3b45402ac02659fe2e87d4150511baeb198ababb1a16daff3da95cd2"
|
||||
"167b75dfb948f82a8317cba01c75f67e290535d868a24b7f627f2855"
|
||||
"09167d4126af8090013c3273c02c6b9586b4625b475b51096c4ad652"),
|
||||
|
||||
# Corner case which causes maximum overflow
|
||||
("f4ae65e920a63ac1f2b64df6dff07870c9d531ae72a47403063238da1"
|
||||
"a1fe3f9d6a179fa50f96cd4aff9261aa92c0e6f17ec940639bc2ccd0B"
|
||||
"519A16DF59C53E0D49B209200F878F362ACE518D5B8BFCF9CDC725E5E"
|
||||
"01C06295E8605AF06932B5006D9E556D3F190E8136BF9C643D332"),
|
||||
|
||||
# Next 2 number generated by random.getrandbits(448)
|
||||
("8f54f8ceacaab39e83844b40ffa9b9f15c14bc4a829e07b0829a48d4"
|
||||
"22fe99a22c70501e533c91352d3d854e061b90303b08c6e33c729578"),
|
||||
("97eeab64ca2ce6bc5d3fd983c34c769fe89204e2e8168561867e5e15"
|
||||
"bc01bfce6a27e0dfcbf8754472154e76e4c11ab2fec3f6b32e8d4b8a"),
|
||||
|
||||
]
|
||||
|
||||
@property
|
||||
def arg_a(self) -> str:
|
||||
return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits)
|
||||
|
||||
def result(self) -> List[str]:
|
||||
result = self.int_a % self.int_n
|
||||
return [self.format_result(result)]
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
return True
|
||||
|
||||
def arguments(self):
|
||||
args = super().arguments()
|
||||
return ["MBEDTLS_ECP_DP_CURVE448"] + args
|
||||
@@ -1,46 +0,0 @@
|
||||
"""Auxiliary functions used for logging module.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
import logging
|
||||
import sys
|
||||
|
||||
def configure_logger(
|
||||
logger: logging.Logger,
|
||||
log_format="[%(levelname)s]: %(message)s",
|
||||
split_level=logging.WARNING
|
||||
) -> None:
|
||||
"""
|
||||
Configure the logging.Logger instance so that:
|
||||
- Format is set to any log_format.
|
||||
Default: "[%(levelname)s]: %(message)s"
|
||||
- loglevel >= split_level are printed to stderr.
|
||||
- loglevel < split_level are printed to stdout.
|
||||
Default: logging.WARNING
|
||||
"""
|
||||
class MaxLevelFilter(logging.Filter):
|
||||
# pylint: disable=too-few-public-methods
|
||||
def __init__(self, max_level, name=''):
|
||||
super().__init__(name)
|
||||
self.max_level = max_level
|
||||
|
||||
def filter(self, record: logging.LogRecord) -> bool:
|
||||
return record.levelno <= self.max_level
|
||||
|
||||
log_formatter = logging.Formatter(log_format)
|
||||
|
||||
# set loglevel >= split_level to be printed to stderr
|
||||
stderr_hdlr = logging.StreamHandler(sys.stderr)
|
||||
stderr_hdlr.setLevel(split_level)
|
||||
stderr_hdlr.setFormatter(log_formatter)
|
||||
|
||||
# set loglevel < split_level to be printed to stdout
|
||||
stdout_hdlr = logging.StreamHandler(sys.stdout)
|
||||
stdout_hdlr.addFilter(MaxLevelFilter(split_level - 1))
|
||||
stdout_hdlr.setFormatter(log_formatter)
|
||||
|
||||
logger.addHandler(stderr_hdlr)
|
||||
logger.addHandler(stdout_hdlr)
|
||||
@@ -1,539 +0,0 @@
|
||||
"""Collect macro definitions from header files.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
import itertools
|
||||
import re
|
||||
from typing import Dict, IO, Iterable, Iterator, List, Optional, Pattern, Set, Tuple, Union
|
||||
|
||||
|
||||
class ReadFileLineException(Exception):
|
||||
def __init__(self, filename: str, line_number: Union[int, str]) -> None:
|
||||
message = 'in {} at {}'.format(filename, line_number)
|
||||
super(ReadFileLineException, self).__init__(message)
|
||||
self.filename = filename
|
||||
self.line_number = line_number
|
||||
|
||||
|
||||
class read_file_lines:
|
||||
# Dear Pylint, conventionally, a context manager class name is lowercase.
|
||||
# pylint: disable=invalid-name,too-few-public-methods
|
||||
"""Context manager to read a text file line by line.
|
||||
|
||||
```
|
||||
with read_file_lines(filename) as lines:
|
||||
for line in lines:
|
||||
process(line)
|
||||
```
|
||||
is equivalent to
|
||||
```
|
||||
with open(filename, 'r') as input_file:
|
||||
for line in input_file:
|
||||
process(line)
|
||||
```
|
||||
except that if process(line) raises an exception, then the read_file_lines
|
||||
snippet annotates the exception with the file name and line number.
|
||||
"""
|
||||
def __init__(self, filename: str, binary: bool = False) -> None:
|
||||
self.filename = filename
|
||||
self.file = None #type: Optional[IO[str]]
|
||||
self.line_number = 'entry' #type: Union[int, str]
|
||||
self.generator = None #type: Optional[Iterable[Tuple[int, str]]]
|
||||
self.binary = binary
|
||||
def __enter__(self) -> 'read_file_lines':
|
||||
self.file = open(self.filename, 'rb' if self.binary else 'r')
|
||||
self.generator = enumerate(self.file)
|
||||
return self
|
||||
def __iter__(self) -> Iterator[str]:
|
||||
assert self.generator is not None
|
||||
for line_number, content in self.generator:
|
||||
self.line_number = line_number
|
||||
yield content
|
||||
self.line_number = 'exit'
|
||||
def __exit__(self, exc_type, exc_value, exc_traceback) -> None:
|
||||
if self.file is not None:
|
||||
self.file.close()
|
||||
if exc_type is not None:
|
||||
raise ReadFileLineException(self.filename, self.line_number) \
|
||||
from exc_value
|
||||
|
||||
|
||||
class PSAMacroEnumerator:
|
||||
"""Information about constructors of various PSA Crypto types.
|
||||
|
||||
This includes macro names as well as information about their arguments
|
||||
when applicable.
|
||||
|
||||
This class only provides ways to enumerate expressions that evaluate to
|
||||
values of the covered types. Derived classes are expected to populate
|
||||
the set of known constructors of each kind, as well as populate
|
||||
`self.arguments_for` for arguments that are not of a kind that is
|
||||
enumerated here.
|
||||
"""
|
||||
#pylint: disable=too-many-instance-attributes
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Set up an empty set of known constructor macros.
|
||||
"""
|
||||
self.statuses = set() #type: Set[str]
|
||||
self.lifetimes = set() #type: Set[str]
|
||||
self.locations = set() #type: Set[str]
|
||||
self.persistence_levels = set() #type: Set[str]
|
||||
self.algorithms = set() #type: Set[str]
|
||||
self.ecc_curves = set() #type: Set[str]
|
||||
self.dh_groups = set() #type: Set[str]
|
||||
self.key_types = set() #type: Set[str]
|
||||
self.key_usage_flags = set() #type: Set[str]
|
||||
self.hash_algorithms = set() #type: Set[str]
|
||||
self.mac_algorithms = set() #type: Set[str]
|
||||
self.ka_algorithms = set() #type: Set[str]
|
||||
self.kdf_algorithms = set() #type: Set[str]
|
||||
self.pake_algorithms = set() #type: Set[str]
|
||||
self.aead_algorithms = set() #type: Set[str]
|
||||
self.sign_algorithms = set() #type: Set[str]
|
||||
# macro name -> list of argument names
|
||||
self.argspecs = {} #type: Dict[str, List[str]]
|
||||
# argument name -> list of values
|
||||
self.arguments_for = {
|
||||
'mac_length': [],
|
||||
'min_mac_length': [],
|
||||
'tag_length': [],
|
||||
'min_tag_length': [],
|
||||
} #type: Dict[str, List[str]]
|
||||
# Whether to include intermediate macros in enumerations. Intermediate
|
||||
# macros serve as category headers and are not valid values of their
|
||||
# type. See `is_internal_name`.
|
||||
# Always false in this class, may be set to true in derived classes.
|
||||
self.include_intermediate = False
|
||||
|
||||
def is_internal_name(self, name: str) -> bool:
|
||||
"""Whether this is an internal macro. Internal macros will be skipped."""
|
||||
if not self.include_intermediate:
|
||||
if name.endswith('_BASE') or name.endswith('_NONE'):
|
||||
return True
|
||||
if '_CATEGORY_' in name:
|
||||
return True
|
||||
return name.endswith('_FLAG') or name.endswith('_MASK')
|
||||
|
||||
def gather_arguments(self) -> None:
|
||||
"""Populate the list of values for macro arguments.
|
||||
|
||||
Call this after parsing all the inputs.
|
||||
"""
|
||||
self.arguments_for['hash_alg'] = sorted(self.hash_algorithms)
|
||||
self.arguments_for['mac_alg'] = sorted(self.mac_algorithms)
|
||||
self.arguments_for['ka_alg'] = sorted(self.ka_algorithms)
|
||||
self.arguments_for['kdf_alg'] = sorted(self.kdf_algorithms)
|
||||
self.arguments_for['aead_alg'] = sorted(self.aead_algorithms)
|
||||
self.arguments_for['sign_alg'] = sorted(self.sign_algorithms)
|
||||
self.arguments_for['curve'] = sorted(self.ecc_curves)
|
||||
self.arguments_for['group'] = sorted(self.dh_groups)
|
||||
self.arguments_for['persistence'] = sorted(self.persistence_levels)
|
||||
self.arguments_for['location'] = sorted(self.locations)
|
||||
self.arguments_for['lifetime'] = sorted(self.lifetimes)
|
||||
|
||||
@staticmethod
|
||||
def _format_arguments(name: str, arguments: Iterable[str]) -> str:
|
||||
"""Format a macro call with arguments.
|
||||
|
||||
The resulting format is consistent with
|
||||
`InputsForTest.normalize_argument`.
|
||||
"""
|
||||
return name + '(' + ', '.join(arguments) + ')'
|
||||
|
||||
_argument_split_re = re.compile(r' *, *')
|
||||
@classmethod
|
||||
def _argument_split(cls, arguments: str) -> List[str]:
|
||||
return re.split(cls._argument_split_re, arguments)
|
||||
|
||||
def distribute_arguments(self, name: str) -> Iterator[str]:
|
||||
"""Generate macro calls with each tested argument set.
|
||||
|
||||
If name is a macro without arguments, just yield "name".
|
||||
If name is a macro with arguments, yield a series of
|
||||
"name(arg1,...,argN)" where each argument takes each possible
|
||||
value at least once.
|
||||
"""
|
||||
try:
|
||||
if name not in self.argspecs:
|
||||
yield name
|
||||
return
|
||||
argspec = self.argspecs[name]
|
||||
if argspec == []:
|
||||
yield name + '()'
|
||||
return
|
||||
argument_lists = [self.arguments_for[arg] for arg in argspec]
|
||||
arguments = [values[0] for values in argument_lists]
|
||||
yield self._format_arguments(name, arguments)
|
||||
# Dear Pylint, enumerate won't work here since we're modifying
|
||||
# the array.
|
||||
# pylint: disable=consider-using-enumerate
|
||||
for i in range(len(arguments)):
|
||||
for value in argument_lists[i][1:]:
|
||||
arguments[i] = value
|
||||
yield self._format_arguments(name, arguments)
|
||||
arguments[i] = argument_lists[i][0]
|
||||
except BaseException as e:
|
||||
raise Exception('distribute_arguments({})'.format(name)) from e
|
||||
|
||||
def distribute_arguments_without_duplicates(
|
||||
self, seen: Set[str], name: str
|
||||
) -> Iterator[str]:
|
||||
"""Same as `distribute_arguments`, but don't repeat seen results."""
|
||||
for result in self.distribute_arguments(name):
|
||||
if result not in seen:
|
||||
seen.add(result)
|
||||
yield result
|
||||
|
||||
def generate_expressions(self, names: Iterable[str]) -> Iterator[str]:
|
||||
"""Generate expressions covering values constructed from the given names.
|
||||
|
||||
`names` can be any iterable collection of macro names.
|
||||
|
||||
For example:
|
||||
* ``generate_expressions(['PSA_ALG_CMAC', 'PSA_ALG_HMAC'])``
|
||||
generates ``'PSA_ALG_CMAC'`` as well as ``'PSA_ALG_HMAC(h)'`` for
|
||||
every known hash algorithm ``h``.
|
||||
* ``macros.generate_expressions(macros.key_types)`` generates all
|
||||
key types.
|
||||
"""
|
||||
seen = set() #type: Set[str]
|
||||
return itertools.chain(*(
|
||||
self.distribute_arguments_without_duplicates(seen, name)
|
||||
for name in names
|
||||
))
|
||||
|
||||
|
||||
class PSAMacroCollector(PSAMacroEnumerator):
|
||||
"""Collect PSA crypto macro definitions from C header files.
|
||||
"""
|
||||
|
||||
def __init__(self, include_intermediate: bool = False) -> None:
|
||||
"""Set up an object to collect PSA macro definitions.
|
||||
|
||||
Call the read_file method of the constructed object on each header file.
|
||||
|
||||
* include_intermediate: if true, include intermediate macros such as
|
||||
PSA_XXX_BASE that do not designate semantic values.
|
||||
"""
|
||||
super().__init__()
|
||||
self.include_intermediate = include_intermediate
|
||||
self.key_types_from_curve = {} #type: Dict[str, str]
|
||||
self.key_types_from_group = {} #type: Dict[str, str]
|
||||
self.algorithms_from_hash = {} #type: Dict[str, str]
|
||||
|
||||
@staticmethod
|
||||
def algorithm_tester(name: str) -> str:
|
||||
"""The predicate for whether an algorithm is built from the given constructor.
|
||||
|
||||
The given name must be the name of an algorithm constructor of the
|
||||
form ``PSA_ALG_xxx`` which is used as ``PSA_ALG_xxx(yyy)`` to build
|
||||
an algorithm value. Return the corresponding predicate macro which
|
||||
is used as ``predicate(alg)`` to test whether ``alg`` can be built
|
||||
as ``PSA_ALG_xxx(yyy)``. The predicate is usually called
|
||||
``PSA_ALG_IS_xxx``.
|
||||
"""
|
||||
prefix = 'PSA_ALG_'
|
||||
assert name.startswith(prefix)
|
||||
midfix = 'IS_'
|
||||
suffix = name[len(prefix):]
|
||||
if suffix in ['DSA', 'ECDSA']:
|
||||
midfix += 'RANDOMIZED_'
|
||||
elif suffix == 'RSA_PSS':
|
||||
suffix += '_STANDARD_SALT'
|
||||
return prefix + midfix + suffix
|
||||
|
||||
def record_algorithm_subtype(self, name: str, expansion: str) -> None:
|
||||
"""Record the subtype of an algorithm constructor.
|
||||
|
||||
Given a ``PSA_ALG_xxx`` macro name and its expansion, if the algorithm
|
||||
is of a subtype that is tracked in its own set, add it to the relevant
|
||||
set.
|
||||
"""
|
||||
# This code is very ad hoc and fragile. It should be replaced by
|
||||
# something more robust.
|
||||
if re.match(r'MAC(?:_|\Z)', name):
|
||||
self.mac_algorithms.add(name)
|
||||
elif re.match(r'KDF(?:_|\Z)', name):
|
||||
self.kdf_algorithms.add(name)
|
||||
elif re.search(r'0x020000[0-9A-Fa-f]{2}', expansion):
|
||||
self.hash_algorithms.add(name)
|
||||
elif re.search(r'0x03[0-9A-Fa-f]{6}', expansion):
|
||||
self.mac_algorithms.add(name)
|
||||
elif re.search(r'0x05[0-9A-Fa-f]{6}', expansion):
|
||||
self.aead_algorithms.add(name)
|
||||
elif re.search(r'0x09[0-9A-Fa-f]{2}0000', expansion):
|
||||
self.ka_algorithms.add(name)
|
||||
elif re.search(r'0x08[0-9A-Fa-f]{6}', expansion):
|
||||
self.kdf_algorithms.add(name)
|
||||
|
||||
# "#define" followed by a macro name with either no parameters
|
||||
# or a single parameter and a non-empty expansion.
|
||||
# Grab the macro name in group 1, the parameter name if any in group 2
|
||||
# and the expansion in group 3.
|
||||
_define_directive_re = re.compile(r'\s*#\s*define\s+(\w+)' +
|
||||
r'(?:\s+|\((\w+)\)\s*)' +
|
||||
r'(.+)')
|
||||
_deprecated_definition_re = re.compile(r'\s*MBEDTLS_DEPRECATED')
|
||||
|
||||
def read_line(self, line):
|
||||
"""Parse a C header line and record the PSA identifier it defines if any.
|
||||
This function analyzes lines that start with "#define PSA_"
|
||||
(up to non-significant whitespace) and skips all non-matching lines.
|
||||
"""
|
||||
# pylint: disable=too-many-branches
|
||||
m = re.match(self._define_directive_re, line)
|
||||
if not m:
|
||||
return
|
||||
name, parameter, expansion = m.groups()
|
||||
expansion = re.sub(r'/\*.*?\*/|//.*', r' ', expansion)
|
||||
if parameter:
|
||||
self.argspecs[name] = [parameter]
|
||||
if re.match(self._deprecated_definition_re, expansion):
|
||||
# Skip deprecated values, which are assumed to be
|
||||
# backward compatibility aliases that share
|
||||
# numerical values with non-deprecated values.
|
||||
return
|
||||
if self.is_internal_name(name):
|
||||
# Macro only to build actual values
|
||||
return
|
||||
elif (name.startswith('PSA_ERROR_') or name == 'PSA_SUCCESS') \
|
||||
and not parameter:
|
||||
self.statuses.add(name)
|
||||
elif name.startswith('PSA_KEY_TYPE_') and not parameter:
|
||||
self.key_types.add(name)
|
||||
elif name.startswith('PSA_KEY_TYPE_') and parameter == 'curve':
|
||||
self.key_types_from_curve[name] = name[:13] + 'IS_' + name[13:]
|
||||
elif name.startswith('PSA_KEY_TYPE_') and parameter == 'group':
|
||||
self.key_types_from_group[name] = name[:13] + 'IS_' + name[13:]
|
||||
elif name.startswith('PSA_ECC_FAMILY_') and not parameter:
|
||||
self.ecc_curves.add(name)
|
||||
elif name.startswith('PSA_DH_FAMILY_') and not parameter:
|
||||
self.dh_groups.add(name)
|
||||
elif name.startswith('PSA_ALG_') and not parameter:
|
||||
if name in ['PSA_ALG_ECDSA_BASE',
|
||||
'PSA_ALG_RSA_PKCS1V15_SIGN_BASE']:
|
||||
# Ad hoc skipping of duplicate names for some numerical values
|
||||
return
|
||||
self.algorithms.add(name)
|
||||
self.record_algorithm_subtype(name, expansion)
|
||||
elif name.startswith('PSA_ALG_') and parameter == 'hash_alg':
|
||||
self.algorithms_from_hash[name] = self.algorithm_tester(name)
|
||||
elif name.startswith('PSA_KEY_USAGE_') and not parameter:
|
||||
self.key_usage_flags.add(name)
|
||||
else:
|
||||
# Other macro without parameter
|
||||
return
|
||||
|
||||
_nonascii_re = re.compile(rb'[^\x00-\x7f]+')
|
||||
_continued_line_re = re.compile(rb'\\\r?\n\Z')
|
||||
def read_file(self, header_file):
|
||||
for line in header_file:
|
||||
m = re.search(self._continued_line_re, line)
|
||||
while m:
|
||||
cont = next(header_file)
|
||||
line = line[:m.start(0)] + cont
|
||||
m = re.search(self._continued_line_re, line)
|
||||
line = re.sub(self._nonascii_re, rb'', line).decode('ascii')
|
||||
self.read_line(line)
|
||||
|
||||
|
||||
class InputsForTest(PSAMacroEnumerator):
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
"""Accumulate information about macros to test.
|
||||
enumerate
|
||||
This includes macro names as well as information about their arguments
|
||||
when applicable.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.all_declared = set() #type: Set[str]
|
||||
# Identifier prefixes
|
||||
self.table_by_prefix = {
|
||||
'ERROR': self.statuses,
|
||||
'ALG': self.algorithms,
|
||||
'ECC_CURVE': self.ecc_curves,
|
||||
'DH_GROUP': self.dh_groups,
|
||||
'KEY_LIFETIME': self.lifetimes,
|
||||
'KEY_LOCATION': self.locations,
|
||||
'KEY_PERSISTENCE': self.persistence_levels,
|
||||
'KEY_TYPE': self.key_types,
|
||||
'KEY_USAGE': self.key_usage_flags,
|
||||
} #type: Dict[str, Set[str]]
|
||||
# Test functions
|
||||
self.table_by_test_function = {
|
||||
# Any function ending in _algorithm also gets added to
|
||||
# self.algorithms.
|
||||
'key_type': [self.key_types],
|
||||
'block_cipher_key_type': [self.key_types],
|
||||
'stream_cipher_key_type': [self.key_types],
|
||||
'ecc_key_family': [self.ecc_curves],
|
||||
'ecc_key_types': [self.ecc_curves],
|
||||
'dh_key_family': [self.dh_groups],
|
||||
'dh_key_types': [self.dh_groups],
|
||||
'hash_algorithm': [self.hash_algorithms],
|
||||
'mac_algorithm': [self.mac_algorithms],
|
||||
'cipher_algorithm': [],
|
||||
'hmac_algorithm': [self.mac_algorithms, self.sign_algorithms],
|
||||
'aead_algorithm': [self.aead_algorithms],
|
||||
'key_derivation_algorithm': [self.kdf_algorithms],
|
||||
'key_agreement_algorithm': [self.ka_algorithms],
|
||||
'asymmetric_signature_algorithm': [self.sign_algorithms],
|
||||
'asymmetric_signature_wildcard': [self.algorithms],
|
||||
'asymmetric_encryption_algorithm': [],
|
||||
'pake_algorithm': [self.pake_algorithms],
|
||||
'other_algorithm': [],
|
||||
'lifetime': [self.lifetimes],
|
||||
} #type: Dict[str, List[Set[str]]]
|
||||
mac_lengths = [str(n) for n in [
|
||||
1, # minimum expressible
|
||||
4, # minimum allowed by policy
|
||||
13, # an odd size in a plausible range
|
||||
14, # an even non-power-of-two size in a plausible range
|
||||
16, # same as full size for at least one algorithm
|
||||
63, # maximum expressible
|
||||
]]
|
||||
self.arguments_for['mac_length'] += mac_lengths
|
||||
self.arguments_for['min_mac_length'] += mac_lengths
|
||||
aead_lengths = [str(n) for n in [
|
||||
1, # minimum expressible
|
||||
4, # minimum allowed by policy
|
||||
13, # an odd size in a plausible range
|
||||
14, # an even non-power-of-two size in a plausible range
|
||||
16, # same as full size for at least one algorithm
|
||||
63, # maximum expressible
|
||||
]]
|
||||
self.arguments_for['tag_length'] += aead_lengths
|
||||
self.arguments_for['min_tag_length'] += aead_lengths
|
||||
|
||||
def add_numerical_values(self) -> None:
|
||||
"""Add numerical values that are not supported to the known identifiers."""
|
||||
# Sets of names per type
|
||||
self.algorithms.add('0xffffffff')
|
||||
self.ecc_curves.add('0xff')
|
||||
self.dh_groups.add('0xff')
|
||||
self.key_types.add('0xffff')
|
||||
self.key_usage_flags.add('0x80000000')
|
||||
|
||||
# Hard-coded values for unknown algorithms
|
||||
#
|
||||
# These have to have values that are correct for their respective
|
||||
# PSA_ALG_IS_xxx macros, but are also not currently assigned and are
|
||||
# not likely to be assigned in the near future.
|
||||
self.hash_algorithms.add('0x020000fe') # 0x020000ff is PSA_ALG_ANY_HASH
|
||||
self.mac_algorithms.add('0x03007fff')
|
||||
self.ka_algorithms.add('0x09fc0000')
|
||||
self.kdf_algorithms.add('0x080000ff')
|
||||
self.pake_algorithms.add('0x0a0000ff')
|
||||
# For AEAD algorithms, the only variability is over the tag length,
|
||||
# and this only applies to known algorithms, so don't test an
|
||||
# unknown algorithm.
|
||||
|
||||
def get_names(self, type_word: str) -> Set[str]:
|
||||
"""Return the set of known names of values of the given type."""
|
||||
return {
|
||||
'status': self.statuses,
|
||||
'algorithm': self.algorithms,
|
||||
'ecc_curve': self.ecc_curves,
|
||||
'dh_group': self.dh_groups,
|
||||
'key_type': self.key_types,
|
||||
'key_usage': self.key_usage_flags,
|
||||
}[type_word]
|
||||
|
||||
# Regex for interesting header lines.
|
||||
# Groups: 1=macro name, 2=type, 3=argument list (optional).
|
||||
_header_line_re = \
|
||||
re.compile(r'#define +' +
|
||||
r'(PSA_((?:(?:DH|ECC|KEY)_)?[A-Z]+)_\w+)' +
|
||||
r'(?:\(([^\n()]*)\))?')
|
||||
# Regex of macro names to exclude.
|
||||
_excluded_name_re = re.compile(r'_(?:GET|IS|OF)_|_(?:BASE|FLAG|MASK)\Z')
|
||||
# Additional excluded macros.
|
||||
_excluded_names = set([
|
||||
# Macros that provide an alternative way to build the same
|
||||
# algorithm as another macro.
|
||||
'PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG',
|
||||
'PSA_ALG_FULL_LENGTH_MAC',
|
||||
# Auxiliary macro whose name doesn't fit the usual patterns for
|
||||
# auxiliary macros.
|
||||
'PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE',
|
||||
])
|
||||
def parse_header_line(self, line: str) -> None:
|
||||
"""Parse a C header line, looking for "#define PSA_xxx"."""
|
||||
m = re.match(self._header_line_re, line)
|
||||
if not m:
|
||||
return
|
||||
name = m.group(1)
|
||||
self.all_declared.add(name)
|
||||
if re.search(self._excluded_name_re, name) or \
|
||||
name in self._excluded_names or \
|
||||
self.is_internal_name(name):
|
||||
return
|
||||
dest = self.table_by_prefix.get(m.group(2))
|
||||
if dest is None:
|
||||
return
|
||||
dest.add(name)
|
||||
if m.group(3):
|
||||
self.argspecs[name] = self._argument_split(m.group(3))
|
||||
|
||||
_nonascii_re = re.compile(rb'[^\x00-\x7f]+') #type: Pattern
|
||||
def parse_header(self, filename: str) -> None:
|
||||
"""Parse a C header file, looking for "#define PSA_xxx"."""
|
||||
with read_file_lines(filename, binary=True) as lines:
|
||||
for line in lines:
|
||||
line = re.sub(self._nonascii_re, rb'', line).decode('ascii')
|
||||
self.parse_header_line(line)
|
||||
|
||||
_macro_identifier_re = re.compile(r'[A-Z]\w+')
|
||||
def generate_undeclared_names(self, expr: str) -> Iterable[str]:
|
||||
for name in re.findall(self._macro_identifier_re, expr):
|
||||
if name not in self.all_declared:
|
||||
yield name
|
||||
|
||||
def accept_test_case_line(self, function: str, argument: str) -> bool:
|
||||
#pylint: disable=unused-argument
|
||||
undeclared = list(self.generate_undeclared_names(argument))
|
||||
if undeclared:
|
||||
raise Exception('Undeclared names in test case', undeclared)
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def normalize_argument(argument: str) -> str:
|
||||
"""Normalize whitespace in the given C expression.
|
||||
|
||||
The result uses the same whitespace as
|
||||
` PSAMacroEnumerator.distribute_arguments`.
|
||||
"""
|
||||
return re.sub(r',', r', ', re.sub(r' +', r'', argument))
|
||||
|
||||
def add_test_case_line(self, function: str, argument: str) -> None:
|
||||
"""Parse a test case data line, looking for algorithm metadata tests."""
|
||||
sets = []
|
||||
if function.endswith('_algorithm'):
|
||||
sets.append(self.algorithms)
|
||||
if function == 'key_agreement_algorithm' and \
|
||||
argument.startswith('PSA_ALG_KEY_AGREEMENT('):
|
||||
# We only want *raw* key agreement algorithms as such, so
|
||||
# exclude ones that are already chained with a KDF.
|
||||
# Keep the expression as one to test as an algorithm.
|
||||
function = 'other_algorithm'
|
||||
sets += self.table_by_test_function[function]
|
||||
if self.accept_test_case_line(function, argument):
|
||||
for s in sets:
|
||||
s.add(self.normalize_argument(argument))
|
||||
|
||||
# Regex matching a *.data line containing a test function call and
|
||||
# its arguments. The actual definition is partly positional, but this
|
||||
# regex is good enough in practice.
|
||||
_test_case_line_re = re.compile(r'(?!depends_on:)(\w+):([^\n :][^:\n]*)')
|
||||
def parse_test_cases(self, filename: str) -> None:
|
||||
"""Parse a test case file (*.data), looking for algorithm metadata tests."""
|
||||
with read_file_lines(filename) as lines:
|
||||
for line in lines:
|
||||
m = re.match(self._test_case_line_re, line)
|
||||
if m:
|
||||
self.add_test_case_line(m.group(1), m.group(2))
|
||||
@@ -1,161 +0,0 @@
|
||||
"""Collect information about PSA cryptographic mechanisms.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
import re
|
||||
from collections import OrderedDict
|
||||
from typing import FrozenSet, List, Optional
|
||||
|
||||
from . import macro_collector
|
||||
|
||||
|
||||
class Information:
|
||||
"""Gather information about PSA constructors."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.constructors = self.read_psa_interface()
|
||||
|
||||
@staticmethod
|
||||
def remove_unwanted_macros(
|
||||
constructors: macro_collector.PSAMacroEnumerator
|
||||
) -> None:
|
||||
# Mbed TLS does not support finite-field DSA.
|
||||
# Don't attempt to generate any related test case.
|
||||
constructors.key_types.discard('PSA_KEY_TYPE_DSA_KEY_PAIR')
|
||||
constructors.key_types.discard('PSA_KEY_TYPE_DSA_PUBLIC_KEY')
|
||||
|
||||
def read_psa_interface(self) -> macro_collector.PSAMacroEnumerator:
|
||||
"""Return the list of known key types, algorithms, etc."""
|
||||
constructors = macro_collector.InputsForTest()
|
||||
header_file_names = ['include/psa/crypto_values.h',
|
||||
'include/psa/crypto_extra.h']
|
||||
test_suites = ['tests/suites/test_suite_psa_crypto_metadata.data']
|
||||
for header_file_name in header_file_names:
|
||||
constructors.parse_header(header_file_name)
|
||||
for test_cases in test_suites:
|
||||
constructors.parse_test_cases(test_cases)
|
||||
self.remove_unwanted_macros(constructors)
|
||||
constructors.gather_arguments()
|
||||
return constructors
|
||||
|
||||
|
||||
def psa_want_symbol(name: str) -> str:
|
||||
"""Return the PSA_WANT_xxx symbol associated with a PSA crypto feature."""
|
||||
if name.startswith('PSA_'):
|
||||
return name[:4] + 'WANT_' + name[4:]
|
||||
else:
|
||||
raise ValueError('Unable to determine the PSA_WANT_ symbol for ' + name)
|
||||
|
||||
def finish_family_dependency(dep: str, bits: int) -> str:
|
||||
"""Finish dep if it's a family dependency symbol prefix.
|
||||
|
||||
A family dependency symbol prefix is a PSA_WANT_ symbol that needs to be
|
||||
qualified by the key size. If dep is such a symbol, finish it by adjusting
|
||||
the prefix and appending the key size. Other symbols are left unchanged.
|
||||
"""
|
||||
return re.sub(r'_FAMILY_(.*)', r'_\1_' + str(bits), dep)
|
||||
|
||||
def finish_family_dependencies(dependencies: List[str], bits: int) -> List[str]:
|
||||
"""Finish any family dependency symbol prefixes.
|
||||
|
||||
Apply `finish_family_dependency` to each element of `dependencies`.
|
||||
"""
|
||||
return [finish_family_dependency(dep, bits) for dep in dependencies]
|
||||
|
||||
SYMBOLS_WITHOUT_DEPENDENCY = frozenset([
|
||||
'PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG', # modifier, only in policies
|
||||
'PSA_ALG_AEAD_WITH_SHORTENED_TAG', # modifier
|
||||
'PSA_ALG_ANY_HASH', # only in policies
|
||||
'PSA_ALG_AT_LEAST_THIS_LENGTH_MAC', # modifier, only in policies
|
||||
'PSA_ALG_KEY_AGREEMENT', # chaining
|
||||
'PSA_ALG_TRUNCATED_MAC', # modifier
|
||||
])
|
||||
def automatic_dependencies(*expressions: str) -> List[str]:
|
||||
"""Infer dependencies of a test case by looking for PSA_xxx symbols.
|
||||
|
||||
The arguments are strings which should be C expressions. Do not use
|
||||
string literals or comments as this function is not smart enough to
|
||||
skip them.
|
||||
"""
|
||||
used = set()
|
||||
for expr in expressions:
|
||||
used.update(re.findall(r'PSA_(?:ALG|ECC_FAMILY|DH_FAMILY|KEY_TYPE)_\w+', expr))
|
||||
used.difference_update(SYMBOLS_WITHOUT_DEPENDENCY)
|
||||
return sorted(psa_want_symbol(name) for name in used)
|
||||
|
||||
# Define set of regular expressions and dependencies to optionally append
|
||||
# extra dependencies for test case based on key description.
|
||||
|
||||
# Skip AES test cases which require 192- or 256-bit key
|
||||
# if MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH defined
|
||||
AES_128BIT_ONLY_DEP_REGEX = re.compile(r'AES\s(192|256)')
|
||||
AES_128BIT_ONLY_DEP = ['!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH']
|
||||
# Skip AES/ARIA/CAMELLIA test cases which require decrypt operation in ECB mode
|
||||
# if MBEDTLS_BLOCK_CIPHER_NO_DECRYPT enabled.
|
||||
ECB_NO_PADDING_DEP_REGEX = re.compile(r'(AES|ARIA|CAMELLIA).*ECB_NO_PADDING')
|
||||
ECB_NO_PADDING_DEP = ['!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT']
|
||||
|
||||
DEPENDENCY_FROM_DESCRIPTION = OrderedDict()
|
||||
DEPENDENCY_FROM_DESCRIPTION[AES_128BIT_ONLY_DEP_REGEX] = AES_128BIT_ONLY_DEP
|
||||
DEPENDENCY_FROM_DESCRIPTION[ECB_NO_PADDING_DEP_REGEX] = ECB_NO_PADDING_DEP
|
||||
def generate_deps_from_description(
|
||||
description: str
|
||||
) -> List[str]:
|
||||
"""Return additional dependencies based on test case description and REGEX.
|
||||
"""
|
||||
dep_list = []
|
||||
for regex, deps in DEPENDENCY_FROM_DESCRIPTION.items():
|
||||
if re.search(regex, description):
|
||||
dep_list += deps
|
||||
|
||||
return dep_list
|
||||
|
||||
# A temporary hack: at the time of writing, not all dependency symbols
|
||||
# are implemented yet. Skip test cases for which the dependency symbols are
|
||||
# not available. Once all dependency symbols are available, this hack must
|
||||
# be removed so that a bug in the dependency symbols properly leads to a test
|
||||
# failure.
|
||||
def read_implemented_dependencies(filename: str) -> FrozenSet[str]:
|
||||
return frozenset(symbol
|
||||
for line in open(filename)
|
||||
for symbol in re.findall(r'\bPSA_WANT_\w+\b', line))
|
||||
_implemented_dependencies = None #type: Optional[FrozenSet[str]] #pylint: disable=invalid-name
|
||||
def hack_dependencies_not_implemented(dependencies: List[str]) -> None:
|
||||
global _implemented_dependencies #pylint: disable=global-statement,invalid-name
|
||||
if _implemented_dependencies is None:
|
||||
_implemented_dependencies = \
|
||||
read_implemented_dependencies('include/psa/crypto_config.h')
|
||||
if not all((dep.lstrip('!') in _implemented_dependencies or
|
||||
not dep.lstrip('!').startswith('PSA_WANT'))
|
||||
for dep in dependencies):
|
||||
dependencies.append('DEPENDENCY_NOT_IMPLEMENTED_YET')
|
||||
|
||||
def tweak_key_pair_dependency(dep: str, usage: str):
|
||||
"""
|
||||
This helper function add the proper suffix to PSA_WANT_KEY_TYPE_xxx_KEY_PAIR
|
||||
symbols according to the required usage.
|
||||
"""
|
||||
ret_list = list()
|
||||
if dep.endswith('KEY_PAIR'):
|
||||
if usage == "BASIC":
|
||||
# BASIC automatically includes IMPORT and EXPORT for test purposes (see
|
||||
# config_psa.h).
|
||||
ret_list.append(re.sub(r'KEY_PAIR', r'KEY_PAIR_BASIC', dep))
|
||||
ret_list.append(re.sub(r'KEY_PAIR', r'KEY_PAIR_IMPORT', dep))
|
||||
ret_list.append(re.sub(r'KEY_PAIR', r'KEY_PAIR_EXPORT', dep))
|
||||
elif usage == "GENERATE":
|
||||
ret_list.append(re.sub(r'KEY_PAIR', r'KEY_PAIR_GENERATE', dep))
|
||||
else:
|
||||
# No replacement to do in this case
|
||||
ret_list.append(dep)
|
||||
return ret_list
|
||||
|
||||
def fix_key_pair_dependencies(dep_list: List[str], usage: str):
|
||||
new_list = [new_deps
|
||||
for dep in dep_list
|
||||
for new_deps in tweak_key_pair_dependency(dep, usage)]
|
||||
|
||||
return new_list
|
||||
206
externals/mbedtls/scripts/mbedtls_dev/psa_storage.py
vendored
206
externals/mbedtls/scripts/mbedtls_dev/psa_storage.py
vendored
@@ -1,206 +0,0 @@
|
||||
"""Knowledge about the PSA key store as implemented in Mbed TLS.
|
||||
|
||||
Note that if you need to make a change that affects how keys are
|
||||
stored, this may indicate that the key store is changing in a
|
||||
backward-incompatible way! Think carefully about backward compatibility
|
||||
before changing how test data is constructed or validated.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
import re
|
||||
import struct
|
||||
from typing import Dict, List, Optional, Set, Union
|
||||
import unittest
|
||||
|
||||
from . import c_build_helper
|
||||
from . import build_tree
|
||||
|
||||
|
||||
class Expr:
|
||||
"""Representation of a C expression with a known or knowable numerical value."""
|
||||
|
||||
def __init__(self, content: Union[int, str]):
|
||||
if isinstance(content, int):
|
||||
digits = 8 if content > 0xffff else 4
|
||||
self.string = '{0:#0{1}x}'.format(content, digits + 2)
|
||||
self.value_if_known = content #type: Optional[int]
|
||||
else:
|
||||
self.string = content
|
||||
self.unknown_values.add(self.normalize(content))
|
||||
self.value_if_known = None
|
||||
|
||||
value_cache = {} #type: Dict[str, int]
|
||||
"""Cache of known values of expressions."""
|
||||
|
||||
unknown_values = set() #type: Set[str]
|
||||
"""Expressions whose values are not present in `value_cache` yet."""
|
||||
|
||||
def update_cache(self) -> None:
|
||||
"""Update `value_cache` for expressions registered in `unknown_values`."""
|
||||
expressions = sorted(self.unknown_values)
|
||||
includes = ['include']
|
||||
if build_tree.looks_like_tf_psa_crypto_root('.'):
|
||||
includes.append('drivers/builtin/include')
|
||||
values = c_build_helper.get_c_expression_values(
|
||||
'unsigned long', '%lu',
|
||||
expressions,
|
||||
header="""
|
||||
#include <psa/crypto.h>
|
||||
""",
|
||||
include_path=includes) #type: List[str]
|
||||
for e, v in zip(expressions, values):
|
||||
self.value_cache[e] = int(v, 0)
|
||||
self.unknown_values.clear()
|
||||
|
||||
@staticmethod
|
||||
def normalize(string: str) -> str:
|
||||
"""Put the given C expression in a canonical form.
|
||||
|
||||
This function is only intended to give correct results for the
|
||||
relatively simple kind of C expression typically used with this
|
||||
module.
|
||||
"""
|
||||
return re.sub(r'\s+', r'', string)
|
||||
|
||||
def value(self) -> int:
|
||||
"""Return the numerical value of the expression."""
|
||||
if self.value_if_known is None:
|
||||
if re.match(r'([0-9]+|0x[0-9a-f]+)\Z', self.string, re.I):
|
||||
return int(self.string, 0)
|
||||
normalized = self.normalize(self.string)
|
||||
if normalized not in self.value_cache:
|
||||
self.update_cache()
|
||||
self.value_if_known = self.value_cache[normalized]
|
||||
return self.value_if_known
|
||||
|
||||
Exprable = Union[str, int, Expr]
|
||||
"""Something that can be converted to a C expression with a known numerical value."""
|
||||
|
||||
def as_expr(thing: Exprable) -> Expr:
|
||||
"""Return an `Expr` object for `thing`.
|
||||
|
||||
If `thing` is already an `Expr` object, return it. Otherwise build a new
|
||||
`Expr` object from `thing`. `thing` can be an integer or a string that
|
||||
contains a C expression.
|
||||
"""
|
||||
if isinstance(thing, Expr):
|
||||
return thing
|
||||
else:
|
||||
return Expr(thing)
|
||||
|
||||
|
||||
class Key:
|
||||
"""Representation of a PSA crypto key object and its storage encoding.
|
||||
"""
|
||||
|
||||
LATEST_VERSION = 0
|
||||
"""The latest version of the storage format."""
|
||||
|
||||
def __init__(self, *,
|
||||
version: Optional[int] = None,
|
||||
id: Optional[int] = None, #pylint: disable=redefined-builtin
|
||||
lifetime: Exprable = 'PSA_KEY_LIFETIME_PERSISTENT',
|
||||
type: Exprable, #pylint: disable=redefined-builtin
|
||||
bits: int,
|
||||
usage: Exprable, alg: Exprable, alg2: Exprable,
|
||||
material: bytes #pylint: disable=used-before-assignment
|
||||
) -> None:
|
||||
self.version = self.LATEST_VERSION if version is None else version
|
||||
self.id = id #pylint: disable=invalid-name #type: Optional[int]
|
||||
self.lifetime = as_expr(lifetime) #type: Expr
|
||||
self.type = as_expr(type) #type: Expr
|
||||
self.bits = bits #type: int
|
||||
self.usage = as_expr(usage) #type: Expr
|
||||
self.alg = as_expr(alg) #type: Expr
|
||||
self.alg2 = as_expr(alg2) #type: Expr
|
||||
self.material = material #type: bytes
|
||||
|
||||
MAGIC = b'PSA\000KEY\000'
|
||||
|
||||
@staticmethod
|
||||
def pack(
|
||||
fmt: str,
|
||||
*args: Union[int, Expr]
|
||||
) -> bytes: #pylint: disable=used-before-assignment
|
||||
"""Pack the given arguments into a byte string according to the given format.
|
||||
|
||||
This function is similar to `struct.pack`, but with the following differences:
|
||||
* All integer values are encoded with standard sizes and in
|
||||
little-endian representation. `fmt` must not include an endianness
|
||||
prefix.
|
||||
* Arguments can be `Expr` objects instead of integers.
|
||||
* Only integer-valued elements are supported.
|
||||
"""
|
||||
return struct.pack('<' + fmt, # little-endian, standard sizes
|
||||
*[arg.value() if isinstance(arg, Expr) else arg
|
||||
for arg in args])
|
||||
|
||||
def bytes(self) -> bytes:
|
||||
"""Return the representation of the key in storage as a byte array.
|
||||
|
||||
This is the content of the PSA storage file. When PSA storage is
|
||||
implemented over stdio files, this does not include any wrapping made
|
||||
by the PSA-storage-over-stdio-file implementation.
|
||||
|
||||
Note that if you need to make a change in this function,
|
||||
this may indicate that the key store is changing in a
|
||||
backward-incompatible way! Think carefully about backward
|
||||
compatibility before making any change here.
|
||||
"""
|
||||
header = self.MAGIC + self.pack('L', self.version)
|
||||
if self.version == 0:
|
||||
attributes = self.pack('LHHLLL',
|
||||
self.lifetime, self.type, self.bits,
|
||||
self.usage, self.alg, self.alg2)
|
||||
material = self.pack('L', len(self.material)) + self.material
|
||||
else:
|
||||
raise NotImplementedError
|
||||
return header + attributes + material
|
||||
|
||||
def hex(self) -> str:
|
||||
"""Return the representation of the key as a hexadecimal string.
|
||||
|
||||
This is the hexadecimal representation of `self.bytes`.
|
||||
"""
|
||||
return self.bytes().hex()
|
||||
|
||||
def location_value(self) -> int:
|
||||
"""The numerical value of the location encoded in the key's lifetime."""
|
||||
return self.lifetime.value() >> 8
|
||||
|
||||
|
||||
class TestKey(unittest.TestCase):
|
||||
# pylint: disable=line-too-long
|
||||
"""A few smoke tests for the functionality of the `Key` class."""
|
||||
|
||||
def test_numerical(self):
|
||||
key = Key(version=0,
|
||||
id=1, lifetime=0x00000001,
|
||||
type=0x2400, bits=128,
|
||||
usage=0x00000300, alg=0x05500200, alg2=0x04c01000,
|
||||
material=b'@ABCDEFGHIJKLMNO')
|
||||
expected_hex = '505341004b45590000000000010000000024800000030000000250050010c00410000000404142434445464748494a4b4c4d4e4f'
|
||||
self.assertEqual(key.bytes(), bytes.fromhex(expected_hex))
|
||||
self.assertEqual(key.hex(), expected_hex)
|
||||
|
||||
def test_names(self):
|
||||
length = 0xfff8 // 8 # PSA_MAX_KEY_BITS in bytes
|
||||
key = Key(version=0,
|
||||
id=1, lifetime='PSA_KEY_LIFETIME_PERSISTENT',
|
||||
type='PSA_KEY_TYPE_RAW_DATA', bits=length*8,
|
||||
usage=0, alg=0, alg2=0,
|
||||
material=b'\x00' * length)
|
||||
expected_hex = '505341004b45590000000000010000000110f8ff000000000000000000000000ff1f0000' + '00' * length
|
||||
self.assertEqual(key.bytes(), bytes.fromhex(expected_hex))
|
||||
self.assertEqual(key.hex(), expected_hex)
|
||||
|
||||
def test_defaults(self):
|
||||
key = Key(type=0x1001, bits=8,
|
||||
usage=0, alg=0, alg2=0,
|
||||
material=b'\x2a')
|
||||
expected_hex = '505341004b455900000000000100000001100800000000000000000000000000010000002a'
|
||||
self.assertEqual(key.bytes(), bytes.fromhex(expected_hex))
|
||||
self.assertEqual(key.hex(), expected_hex)
|
||||
@@ -1,91 +0,0 @@
|
||||
"""Library for constructing an Mbed TLS test case.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
import binascii
|
||||
import os
|
||||
import sys
|
||||
from typing import Iterable, List, Optional
|
||||
|
||||
from . import typing_util
|
||||
|
||||
def hex_string(data: bytes) -> str:
|
||||
return '"' + binascii.hexlify(data).decode('ascii') + '"'
|
||||
|
||||
|
||||
class MissingDescription(Exception):
|
||||
pass
|
||||
|
||||
class MissingFunction(Exception):
|
||||
pass
|
||||
|
||||
class TestCase:
|
||||
"""An Mbed TLS test case."""
|
||||
|
||||
def __init__(self, description: Optional[str] = None):
|
||||
self.comments = [] #type: List[str]
|
||||
self.description = description #type: Optional[str]
|
||||
self.dependencies = [] #type: List[str]
|
||||
self.function = None #type: Optional[str]
|
||||
self.arguments = [] #type: List[str]
|
||||
|
||||
def add_comment(self, *lines: str) -> None:
|
||||
self.comments += lines
|
||||
|
||||
def set_description(self, description: str) -> None:
|
||||
self.description = description
|
||||
|
||||
def set_dependencies(self, dependencies: List[str]) -> None:
|
||||
self.dependencies = dependencies
|
||||
|
||||
def set_function(self, function: str) -> None:
|
||||
self.function = function
|
||||
|
||||
def set_arguments(self, arguments: List[str]) -> None:
|
||||
self.arguments = arguments
|
||||
|
||||
def check_completeness(self) -> None:
|
||||
if self.description is None:
|
||||
raise MissingDescription
|
||||
if self.function is None:
|
||||
raise MissingFunction
|
||||
|
||||
def write(self, out: typing_util.Writable) -> None:
|
||||
"""Write the .data file paragraph for this test case.
|
||||
|
||||
The output starts and ends with a single newline character. If the
|
||||
surrounding code writes lines (consisting of non-newline characters
|
||||
and a final newline), you will end up with a blank line before, but
|
||||
not after the test case.
|
||||
"""
|
||||
self.check_completeness()
|
||||
assert self.description is not None # guide mypy
|
||||
assert self.function is not None # guide mypy
|
||||
out.write('\n')
|
||||
for line in self.comments:
|
||||
out.write('# ' + line + '\n')
|
||||
out.write(self.description + '\n')
|
||||
if self.dependencies:
|
||||
out.write('depends_on:' + ':'.join(self.dependencies) + '\n')
|
||||
out.write(self.function + ':' + ':'.join(self.arguments) + '\n')
|
||||
|
||||
def write_data_file(filename: str,
|
||||
test_cases: Iterable[TestCase],
|
||||
caller: Optional[str] = None) -> None:
|
||||
"""Write the test cases to the specified file.
|
||||
|
||||
If the file already exists, it is overwritten.
|
||||
"""
|
||||
if caller is None:
|
||||
caller = os.path.basename(sys.argv[0])
|
||||
tempfile = filename + '.new'
|
||||
with open(tempfile, 'w') as out:
|
||||
out.write('# Automatically generated by {}. Do not edit!\n'
|
||||
.format(caller))
|
||||
for tc in test_cases:
|
||||
tc.write(out)
|
||||
out.write('\n# End of automatically generated file.\n')
|
||||
os.replace(tempfile, filename)
|
||||
@@ -1,224 +0,0 @@
|
||||
"""Common code for test data generation.
|
||||
|
||||
This module defines classes that are of general use to automatically
|
||||
generate .data files for unit tests, as well as a main function.
|
||||
|
||||
These are used both by generate_psa_tests.py and generate_bignum_tests.py.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import posixpath
|
||||
import re
|
||||
import inspect
|
||||
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from typing import Callable, Dict, Iterable, Iterator, List, Type, TypeVar
|
||||
|
||||
from . import build_tree
|
||||
from . import test_case
|
||||
|
||||
T = TypeVar('T') #pylint: disable=invalid-name
|
||||
|
||||
|
||||
class BaseTest(metaclass=ABCMeta):
|
||||
"""Base class for test case generation.
|
||||
|
||||
Attributes:
|
||||
count: Counter for test cases from this class.
|
||||
case_description: Short description of the test case. This may be
|
||||
automatically generated using the class, or manually set.
|
||||
dependencies: A list of dependencies required for the test case.
|
||||
show_test_count: Toggle for inclusion of `count` in the test description.
|
||||
test_function: Test function which the class generates cases for.
|
||||
test_name: A common name or description of the test function. This can
|
||||
be `test_function`, a clearer equivalent, or a short summary of the
|
||||
test function's purpose.
|
||||
"""
|
||||
count = 0
|
||||
case_description = ""
|
||||
dependencies = [] # type: List[str]
|
||||
show_test_count = True
|
||||
test_function = ""
|
||||
test_name = ""
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
# pylint: disable=unused-argument
|
||||
cls.count += 1
|
||||
return super().__new__(cls)
|
||||
|
||||
@abstractmethod
|
||||
def arguments(self) -> List[str]:
|
||||
"""Get the list of arguments for the test case.
|
||||
|
||||
Override this method to provide the list of arguments required for
|
||||
the `test_function`.
|
||||
|
||||
Returns:
|
||||
List of arguments required for the test function.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def description(self) -> str:
|
||||
"""Create a test case description.
|
||||
|
||||
Creates a description of the test case, including a name for the test
|
||||
function, an optional case count, and a description of the specific
|
||||
test case. This should inform a reader what is being tested, and
|
||||
provide context for the test case.
|
||||
|
||||
Returns:
|
||||
Description for the test case.
|
||||
"""
|
||||
if self.show_test_count:
|
||||
return "{} #{} {}".format(
|
||||
self.test_name, self.count, self.case_description
|
||||
).strip()
|
||||
else:
|
||||
return "{} {}".format(self.test_name, self.case_description).strip()
|
||||
|
||||
|
||||
def create_test_case(self) -> test_case.TestCase:
|
||||
"""Generate TestCase from the instance."""
|
||||
tc = test_case.TestCase()
|
||||
tc.set_description(self.description())
|
||||
tc.set_function(self.test_function)
|
||||
tc.set_arguments(self.arguments())
|
||||
tc.set_dependencies(self.dependencies)
|
||||
|
||||
return tc
|
||||
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
|
||||
"""Generate test cases for the class test function.
|
||||
|
||||
This will be called in classes where `test_function` is set.
|
||||
Implementations should yield TestCase objects, by creating instances
|
||||
of the class with appropriate input data, and then calling
|
||||
`create_test_case()` on each.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class BaseTarget:
|
||||
#pylint: disable=too-few-public-methods
|
||||
"""Base target for test case generation.
|
||||
|
||||
Child classes of this class represent an output file, and can be referred
|
||||
to as file targets. These indicate where test cases will be written to for
|
||||
all subclasses of the file target, which is set by `target_basename`.
|
||||
|
||||
Attributes:
|
||||
target_basename: Basename of file to write generated tests to. This
|
||||
should be specified in a child class of BaseTarget.
|
||||
"""
|
||||
target_basename = ""
|
||||
|
||||
@classmethod
|
||||
def generate_tests(cls) -> Iterator[test_case.TestCase]:
|
||||
"""Generate test cases for the class and its subclasses.
|
||||
|
||||
In classes with `test_function` set, `generate_function_tests()` is
|
||||
called to generate test cases first.
|
||||
|
||||
In all classes, this method will iterate over its subclasses, and
|
||||
yield from `generate_tests()` in each. Calling this method on a class X
|
||||
will yield test cases from all classes derived from X.
|
||||
"""
|
||||
if issubclass(cls, BaseTest) and not inspect.isabstract(cls):
|
||||
#pylint: disable=no-member
|
||||
yield from cls.generate_function_tests()
|
||||
for subclass in sorted(cls.__subclasses__(), key=lambda c: c.__name__):
|
||||
yield from subclass.generate_tests()
|
||||
|
||||
|
||||
class TestGenerator:
|
||||
"""Generate test cases and write to data files."""
|
||||
def __init__(self, options) -> None:
|
||||
self.test_suite_directory = options.directory
|
||||
# Update `targets` with an entry for each child class of BaseTarget.
|
||||
# Each entry represents a file generated by the BaseTarget framework,
|
||||
# and enables generating the .data files using the CLI.
|
||||
self.targets.update({
|
||||
subclass.target_basename: subclass.generate_tests
|
||||
for subclass in BaseTarget.__subclasses__()
|
||||
if subclass.target_basename
|
||||
})
|
||||
|
||||
def filename_for(self, basename: str) -> str:
|
||||
"""The location of the data file with the specified base name."""
|
||||
return posixpath.join(self.test_suite_directory, basename + '.data')
|
||||
|
||||
def write_test_data_file(self, basename: str,
|
||||
test_cases: Iterable[test_case.TestCase]) -> None:
|
||||
"""Write the test cases to a .data file.
|
||||
|
||||
The output file is ``basename + '.data'`` in the test suite directory.
|
||||
"""
|
||||
filename = self.filename_for(basename)
|
||||
test_case.write_data_file(filename, test_cases)
|
||||
|
||||
# Note that targets whose names contain 'test_format' have their content
|
||||
# validated by `abi_check.py`.
|
||||
targets = {} # type: Dict[str, Callable[..., Iterable[test_case.TestCase]]]
|
||||
|
||||
def generate_target(self, name: str, *target_args) -> None:
|
||||
"""Generate cases and write to data file for a target.
|
||||
|
||||
For target callables which require arguments, override this function
|
||||
and pass these arguments using super() (see PSATestGenerator).
|
||||
"""
|
||||
test_cases = self.targets[name](*target_args)
|
||||
self.write_test_data_file(name, test_cases)
|
||||
|
||||
def main(args, description: str, generator_class: Type[TestGenerator] = TestGenerator):
|
||||
"""Command line entry point."""
|
||||
parser = argparse.ArgumentParser(description=description)
|
||||
parser.add_argument('--list', action='store_true',
|
||||
help='List available targets and exit')
|
||||
parser.add_argument('--list-for-cmake', action='store_true',
|
||||
help='Print \';\'-separated list of available targets and exit')
|
||||
# If specified explicitly, this option may be a path relative to the
|
||||
# current directory when the script is invoked. The default value
|
||||
# is relative to the mbedtls root, which we don't know yet. So we
|
||||
# can't set a string as the default value here.
|
||||
parser.add_argument('--directory', metavar='DIR',
|
||||
help='Output directory (default: tests/suites)')
|
||||
parser.add_argument('targets', nargs='*', metavar='TARGET',
|
||||
help='Target file to generate (default: all; "-": none)')
|
||||
options = parser.parse_args(args)
|
||||
|
||||
# Change to the mbedtls root, to keep things simple. But first, adjust
|
||||
# command line options that might be relative paths.
|
||||
if options.directory is None:
|
||||
options.directory = 'tests/suites'
|
||||
else:
|
||||
options.directory = os.path.abspath(options.directory)
|
||||
build_tree.chdir_to_root()
|
||||
|
||||
generator = generator_class(options)
|
||||
if options.list:
|
||||
for name in sorted(generator.targets):
|
||||
print(generator.filename_for(name))
|
||||
return
|
||||
# List in a cmake list format (i.e. ';'-separated)
|
||||
if options.list_for_cmake:
|
||||
print(';'.join(generator.filename_for(name)
|
||||
for name in sorted(generator.targets)), end='')
|
||||
return
|
||||
if options.targets:
|
||||
# Allow "-" as a special case so you can run
|
||||
# ``generate_xxx_tests.py - $targets`` and it works uniformly whether
|
||||
# ``$targets`` is empty or not.
|
||||
options.targets = [os.path.basename(re.sub(r'\.data\Z', r'', target))
|
||||
for target in options.targets
|
||||
if target != '-']
|
||||
else:
|
||||
options.targets = sorted(generator.targets)
|
||||
for target in options.targets:
|
||||
generator.generate_target(target)
|
||||
@@ -1,28 +0,0 @@
|
||||
"""Auxiliary definitions used in type annotations.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
|
||||
from typing import Any
|
||||
|
||||
# The typing_extensions module is necessary for type annotations that are
|
||||
# checked with mypy. It is only used for type annotations or to define
|
||||
# things that are themselves only used for type annotations. It is not
|
||||
# available on a default Python installation. Therefore, try loading
|
||||
# what we need from it for the sake of mypy (which depends on, or comes
|
||||
# with, typing_extensions), and if not define substitutes that lack the
|
||||
# static type information but are good enough at runtime.
|
||||
try:
|
||||
from typing_extensions import Protocol #pylint: disable=import-error
|
||||
except ImportError:
|
||||
class Protocol: #type: ignore
|
||||
#pylint: disable=too-few-public-methods
|
||||
pass
|
||||
|
||||
class Writable(Protocol):
|
||||
"""Abstract class for typing hints."""
|
||||
# pylint: disable=no-self-use,too-few-public-methods,unused-argument
|
||||
def write(self, text: str) -> Any:
|
||||
...
|
||||
49
externals/mbedtls/scripts/memory.sh
vendored
49
externals/mbedtls/scripts/memory.sh
vendored
@@ -8,10 +8,49 @@
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
|
||||
set -eu
|
||||
|
||||
CONFIG_H='include/mbedtls/mbedtls_config.h'
|
||||
CONFIG_H='include/mbedtls/config.h'
|
||||
|
||||
CLIENT='mini_client'
|
||||
|
||||
@@ -34,7 +73,7 @@ if [ $( uname ) != Linux ]; then
|
||||
fi
|
||||
|
||||
if git status | grep -F $CONFIG_H >/dev/null 2>&1; then
|
||||
echo "mbedtls_config.h not clean" >&2
|
||||
echo "config.h not clean" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -49,10 +88,10 @@ do_config()
|
||||
echo ""
|
||||
echo "config-$NAME:"
|
||||
cp configs/config-$NAME.h $CONFIG_H
|
||||
scripts/config.py unset MBEDTLS_SSL_SRV_C
|
||||
scripts/config.pl unset MBEDTLS_SSL_SRV_C
|
||||
|
||||
for FLAG in $UNSET_LIST; do
|
||||
scripts/config.py unset $FLAG
|
||||
scripts/config.pl unset $FLAG
|
||||
done
|
||||
|
||||
grep -F SSL_MAX_CONTENT_LEN $CONFIG_H || echo 'SSL_MAX_CONTENT_LEN=16384'
|
||||
@@ -117,7 +156,7 @@ do_config "ccm-psk-tls1_2" \
|
||||
"psk=000102030405060708090A0B0C0D0E0F"
|
||||
|
||||
do_config "suite-b" \
|
||||
"MBEDTLS_BASE64_C MBEDTLS_PEM_PARSE_C" \
|
||||
"MBEDTLS_BASE64_C MBEDTLS_PEM_PARSE_C MBEDTLS_CERTS_C" \
|
||||
""
|
||||
|
||||
# cleanup
|
||||
|
||||
127
externals/mbedtls/scripts/min_requirements.py
vendored
127
externals/mbedtls/scripts/min_requirements.py
vendored
@@ -1,127 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Install all the required Python packages, with the minimum Python version.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import typing
|
||||
|
||||
from typing import List, Optional
|
||||
from mbedtls_dev import typing_util
|
||||
|
||||
def pylint_doesn_t_notice_that_certain_types_are_used_in_annotations(
|
||||
_list: List[typing.Any],
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
|
||||
class Requirements:
|
||||
"""Collect and massage Python requirements."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.requirements = [] #type: List[str]
|
||||
|
||||
def adjust_requirement(self, req: str) -> str:
|
||||
"""Adjust a requirement to the minimum specified version."""
|
||||
# allow inheritance #pylint: disable=no-self-use
|
||||
# If a requirement specifies a minimum version, impose that version.
|
||||
split_req = req.split(';', 1)
|
||||
split_req[0] = re.sub(r'>=|~=', r'==', split_req[0])
|
||||
return ';'.join(split_req)
|
||||
|
||||
def add_file(self, filename: str) -> None:
|
||||
"""Add requirements from the specified file.
|
||||
|
||||
This method supports a subset of pip's requirement file syntax:
|
||||
* One requirement specifier per line, which is passed to
|
||||
`adjust_requirement`.
|
||||
* Comments (``#`` at the beginning of the line or after whitespace).
|
||||
* ``-r FILENAME`` to include another file.
|
||||
"""
|
||||
for line in open(filename):
|
||||
line = line.strip()
|
||||
line = re.sub(r'(\A|\s+)#.*', r'', line)
|
||||
if not line:
|
||||
continue
|
||||
m = re.match(r'-r\s+', line)
|
||||
if m:
|
||||
nested_file = os.path.join(os.path.dirname(filename),
|
||||
line[m.end(0):])
|
||||
self.add_file(nested_file)
|
||||
continue
|
||||
self.requirements.append(self.adjust_requirement(line))
|
||||
|
||||
def write(self, out: typing_util.Writable) -> None:
|
||||
"""List the gathered requirements."""
|
||||
for req in self.requirements:
|
||||
out.write(req + '\n')
|
||||
|
||||
def install(
|
||||
self,
|
||||
pip_general_options: Optional[List[str]] = None,
|
||||
pip_install_options: Optional[List[str]] = None,
|
||||
) -> None:
|
||||
"""Call pip to install the requirements."""
|
||||
if pip_general_options is None:
|
||||
pip_general_options = []
|
||||
if pip_install_options is None:
|
||||
pip_install_options = []
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
# This is more complicated than it needs to be for the sake
|
||||
# of Windows. Use a temporary file rather than the command line
|
||||
# to avoid quoting issues. Use a temporary directory rather
|
||||
# than NamedTemporaryFile because with a NamedTemporaryFile on
|
||||
# Windows, the subprocess can't open the file because this process
|
||||
# has an exclusive lock on it.
|
||||
req_file_name = os.path.join(temp_dir, 'requirements.txt')
|
||||
with open(req_file_name, 'w') as req_file:
|
||||
self.write(req_file)
|
||||
subprocess.check_call([sys.executable, '-m', 'pip'] +
|
||||
pip_general_options +
|
||||
['install'] + pip_install_options +
|
||||
['-r', req_file_name])
|
||||
|
||||
DEFAULT_REQUIREMENTS_FILE = 'ci.requirements.txt'
|
||||
|
||||
def main() -> None:
|
||||
"""Command line entry point."""
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--no-act', '-n',
|
||||
action='store_true',
|
||||
help="Don't act, just print what will be done")
|
||||
parser.add_argument('--pip-install-option',
|
||||
action='append', dest='pip_install_options',
|
||||
help="Pass this option to pip install")
|
||||
parser.add_argument('--pip-option',
|
||||
action='append', dest='pip_general_options',
|
||||
help="Pass this general option to pip")
|
||||
parser.add_argument('--user',
|
||||
action='append_const', dest='pip_install_options',
|
||||
const='--user',
|
||||
help="Install to the Python user install directory"
|
||||
" (short for --pip-install-option --user)")
|
||||
parser.add_argument('files', nargs='*', metavar='FILE',
|
||||
help="Requirement files"
|
||||
" (default: {} in the script's directory)" \
|
||||
.format(DEFAULT_REQUIREMENTS_FILE))
|
||||
options = parser.parse_args()
|
||||
if not options.files:
|
||||
options.files = [os.path.join(os.path.dirname(__file__),
|
||||
DEFAULT_REQUIREMENTS_FILE)]
|
||||
reqs = Requirements()
|
||||
for filename in options.files:
|
||||
reqs.add_file(filename)
|
||||
reqs.write(sys.stdout)
|
||||
if not options.no_act:
|
||||
reqs.install(pip_general_options=options.pip_general_options,
|
||||
pip_install_options=options.pip_install_options)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
88
externals/mbedtls/scripts/output_env.sh
vendored
88
externals/mbedtls/scripts/output_env.sh
vendored
@@ -5,6 +5,45 @@
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# Purpose
|
||||
#
|
||||
# To print out all the relevant information about the development environment.
|
||||
@@ -93,37 +132,9 @@ echo
|
||||
print_version "gcc" "--version" "" "head -n 1"
|
||||
echo
|
||||
|
||||
if [ -n "${GCC_EARLIEST+set}" ]; then
|
||||
print_version "${GCC_EARLIEST}" "--version" "" "head -n 1"
|
||||
else
|
||||
echo " GCC_EARLIEST : Not configured."
|
||||
fi
|
||||
echo
|
||||
|
||||
if [ -n "${GCC_LATEST+set}" ]; then
|
||||
print_version "${GCC_LATEST}" "--version" "" "head -n 1"
|
||||
else
|
||||
echo " GCC_LATEST : Not configured."
|
||||
fi
|
||||
echo
|
||||
|
||||
print_version "clang" "--version" "" "head -n 2"
|
||||
echo
|
||||
|
||||
if [ -n "${CLANG_EARLIEST+set}" ]; then
|
||||
print_version "${CLANG_EARLIEST}" "--version" "" "head -n 2"
|
||||
else
|
||||
echo " CLANG_EARLIEST : Not configured."
|
||||
fi
|
||||
echo
|
||||
|
||||
if [ -n "${CLANG_LATEST+set}" ]; then
|
||||
print_version "${CLANG_LATEST}" "--version" "" "head -n 2"
|
||||
else
|
||||
echo " CLANG_LATEST : Not configured."
|
||||
fi
|
||||
echo
|
||||
|
||||
print_version "ldd" "--version" "" "head -n 1"
|
||||
echo
|
||||
|
||||
@@ -158,6 +169,13 @@ echo
|
||||
print_version "$OPENSSL" "version" "default"
|
||||
echo
|
||||
|
||||
if [ -n "${OPENSSL_LEGACY+set}" ]; then
|
||||
print_version "$OPENSSL_LEGACY" "version" "legacy"
|
||||
else
|
||||
echo " * openssl (legacy): Not configured."
|
||||
fi
|
||||
echo
|
||||
|
||||
if [ -n "${OPENSSL_NEXT+set}" ]; then
|
||||
print_version "$OPENSSL_NEXT" "version" "next"
|
||||
else
|
||||
@@ -173,6 +191,20 @@ echo
|
||||
print_version "$GNUTLS_SERV" "--version" "default" "head -n 1"
|
||||
echo
|
||||
|
||||
if [ -n "${GNUTLS_LEGACY_CLI+set}" ]; then
|
||||
print_version "$GNUTLS_LEGACY_CLI" "--version" "legacy" "head -n 1"
|
||||
else
|
||||
echo " * gnutls-cli (legacy): Not configured."
|
||||
fi
|
||||
echo
|
||||
|
||||
if [ -n "${GNUTLS_LEGACY_SERV+set}" ]; then
|
||||
print_version "$GNUTLS_LEGACY_SERV" "--version" "legacy" "head -n 1"
|
||||
else
|
||||
echo " * gnutls-serv (legacy): Not configured."
|
||||
fi
|
||||
echo
|
||||
|
||||
echo " * Installed asan versions:"
|
||||
if type dpkg-query >/dev/null 2>/dev/null; then
|
||||
if ! dpkg-query -f '${Status} ${Package}: ${Version}\n' -W 'libasan*' |
|
||||
|
||||
70
externals/mbedtls/scripts/prepare_release.sh
vendored
70
externals/mbedtls/scripts/prepare_release.sh
vendored
@@ -1,70 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
print_usage()
|
||||
{
|
||||
cat <<EOF
|
||||
Usage: $0 [OPTION]...
|
||||
Prepare the source tree for a release.
|
||||
|
||||
Options:
|
||||
-u Prepare for development (undo the release preparation)
|
||||
EOF
|
||||
}
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
|
||||
set -eu
|
||||
|
||||
if [ $# -ne 0 ] && [ "$1" = "--help" ]; then
|
||||
print_usage
|
||||
exit
|
||||
fi
|
||||
|
||||
unrelease= # if non-empty, we're in undo-release mode
|
||||
while getopts u OPTLET; do
|
||||
case $OPTLET in
|
||||
u) unrelease=1;;
|
||||
\?)
|
||||
echo 1>&2 "$0: unknown option: -$OPTLET"
|
||||
echo 1>&2 "Try '$0 --help' for more information."
|
||||
exit 3;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
|
||||
#### .gitignore processing ####
|
||||
|
||||
GITIGNORES=$(find . -name ".gitignore")
|
||||
for GITIGNORE in $GITIGNORES; do
|
||||
if [ -n "$unrelease" ]; then
|
||||
sed -i '/###START_COMMENTED_GENERATED_FILES###/,/###END_COMMENTED_GENERATED_FILES###/s/^#//' $GITIGNORE
|
||||
sed -i 's/###START_COMMENTED_GENERATED_FILES###/###START_GENERATED_FILES###/' $GITIGNORE
|
||||
sed -i 's/###END_COMMENTED_GENERATED_FILES###/###END_GENERATED_FILES###/' $GITIGNORE
|
||||
else
|
||||
sed -i '/###START_GENERATED_FILES###/,/###END_GENERATED_FILES###/s/^/#/' $GITIGNORE
|
||||
sed -i 's/###START_GENERATED_FILES###/###START_COMMENTED_GENERATED_FILES###/' $GITIGNORE
|
||||
sed -i 's/###END_GENERATED_FILES###/###END_COMMENTED_GENERATED_FILES###/' $GITIGNORE
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
|
||||
#### Build scripts ####
|
||||
|
||||
# GEN_FILES defaults on (non-empty) in development, off (empty) in releases
|
||||
if [ -n "$unrelease" ]; then
|
||||
r=' yes'
|
||||
else
|
||||
r=''
|
||||
fi
|
||||
sed -i 's/^\(GEN_FILES[ ?:]*=\)\([^#]*\)/\1'"$r/" Makefile */Makefile
|
||||
|
||||
# GEN_FILES defaults on in development, off in releases
|
||||
if [ -n "$unrelease" ]; then
|
||||
r='ON'
|
||||
else
|
||||
r='OFF'
|
||||
fi
|
||||
sed -i '/[Oo][Ff][Ff] in development/! s/^\( *option *( *GEN_FILES *"[^"]*" *\)\([A-Za-z0-9][A-Za-z0-9]*\)/\1'"$r/" CMakeLists.txt
|
||||
160
externals/mbedtls/scripts/rename.pl
vendored
Executable file
160
externals/mbedtls/scripts/rename.pl
vendored
Executable file
@@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env perl
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# Purpose
|
||||
#
|
||||
# This script migrates application source code from the mbed TLS 1.3 API to the
|
||||
# mbed TLS 2.0 API.
|
||||
#
|
||||
# The script processes the given source code and renames identifiers - functions
|
||||
# types, enums etc, as
|
||||
#
|
||||
# Usage: rename.pl [-f datafile] [-s] [--] [filenames...]
|
||||
#
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use utf8;
|
||||
use Path::Class;
|
||||
use open qw(:std utf8);
|
||||
|
||||
my $usage = "Usage: $0 [-f datafile] [-s] [--] [filenames...]\n";
|
||||
|
||||
(my $datafile = $0) =~ s/rename.pl$/data_files\/rename-1.3-2.0.txt/;
|
||||
my $do_strings = 0;
|
||||
|
||||
while( @ARGV && $ARGV[0] =~ /^-/ ) {
|
||||
my $opt = shift;
|
||||
if( $opt eq '--' ) {
|
||||
last;
|
||||
} elsif( $opt eq '-f' ) {
|
||||
$datafile = shift;
|
||||
} elsif( $opt eq '-s' ) {
|
||||
$do_strings = 1; shift;
|
||||
} else {
|
||||
die $usage;
|
||||
}
|
||||
}
|
||||
|
||||
my %subst;
|
||||
open my $nfh, '<', $datafile or die "Could not read $datafile\n";
|
||||
my $ident = qr/[_A-Za-z][_A-Za-z0-9]*/;
|
||||
while( my $line = <$nfh> ) {
|
||||
chomp $line;
|
||||
my ( $old, $new ) = ( $line =~ /^($ident)\s+($ident)$/ );
|
||||
if( ! $old || ! $new ) {
|
||||
die "$0: $datafile:$.: bad input '$line'\n";
|
||||
}
|
||||
$subst{$old} = $new;
|
||||
}
|
||||
close $nfh or die;
|
||||
|
||||
my $string = qr/"(?:\\.|[^\\"])*"/;
|
||||
my $space = qr/\s+/;
|
||||
my $idnum = qr/[a-zA-Z0-9_]+/;
|
||||
my $symbols = qr/[-!#\$%&'()*+,.\/:;<=>?@[\\\]^_`{|}~]+|"/;
|
||||
|
||||
my $lib_include_dir = dir($0)->parent->parent->subdir('include', 'mbedtls');
|
||||
my $lib_source_dir = dir($0)->parent->parent->subdir('library');
|
||||
|
||||
# if we replace inside strings, we don't consider them a token
|
||||
my $token = $do_strings ? qr/$space|$idnum|$symbols/
|
||||
: qr/$string|$space|$idnum|$symbols/;
|
||||
|
||||
my %warnings;
|
||||
|
||||
# If no files were passed, exit...
|
||||
if ( not defined($ARGV[0]) ){ die $usage; }
|
||||
|
||||
while( my $filename = shift )
|
||||
{
|
||||
print STDERR "$filename... ";
|
||||
|
||||
if( dir($filename)->parent eq $lib_include_dir ||
|
||||
dir($filename)->parent eq $lib_source_dir )
|
||||
{
|
||||
die "Script cannot be executed on the mbed TLS library itself.";
|
||||
}
|
||||
|
||||
if( -d $filename ) { print STDERR "skip (directory)\n"; next }
|
||||
|
||||
open my $rfh, '<', $filename or die;
|
||||
my @lines = <$rfh>;
|
||||
close $rfh or die;
|
||||
|
||||
my @out;
|
||||
for my $line (@lines) {
|
||||
if( $line =~ /#include/ ) {
|
||||
$line =~ s/polarssl/mbedtls/;
|
||||
$line =~ s/POLARSSL/MBEDTLS/;
|
||||
push( @out, $line );
|
||||
next;
|
||||
}
|
||||
|
||||
my @words = ($line =~ /$token/g);
|
||||
my $checkline = join '', @words;
|
||||
if( $checkline eq $line ) {
|
||||
my @new = map { exists $subst{$_} ? $subst{$_} : $_ } @words;
|
||||
push( @out, join '', @new );
|
||||
} else {
|
||||
$warnings{$filename} = [] unless $warnings{$filename};
|
||||
push @{ $warnings{$filename} }, $line;
|
||||
push( @out, $line );
|
||||
}
|
||||
}
|
||||
|
||||
open my $wfh, '>', $filename or die;
|
||||
print $wfh $_ for @out;
|
||||
close $wfh or die;
|
||||
print STDERR "done\n";
|
||||
}
|
||||
|
||||
if( %warnings ) {
|
||||
print "\nWarning: lines skipped due to unexpected characters:\n";
|
||||
for my $filename (sort keys %warnings) {
|
||||
print "in $filename:\n";
|
||||
print for @{ $warnings{$filename} };
|
||||
}
|
||||
}
|
||||
7
externals/mbedtls/scripts/rm-calloc-cast.cocci
vendored
Normal file
7
externals/mbedtls/scripts/rm-calloc-cast.cocci
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
@rm_calloc_cast@
|
||||
expression x, n, m;
|
||||
type T;
|
||||
@@
|
||||
x =
|
||||
- (T *)
|
||||
mbedtls_calloc(n, m)
|
||||
@@ -5,6 +5,45 @@
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
|
||||
IGNORE=""
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ if not "%~1"=="" set "retarget=,PlatformToolset=%1"
|
||||
@rem vcvarsall.bat will silently change the directory to that directory.
|
||||
@rem Setting the VSCMD_START_DIR environment variable causes it to change
|
||||
@rem to that directory instead.
|
||||
set "VSCMD_START_DIR=%~dp0\..\visualc\VS2013"
|
||||
set "VSCMD_START_DIR=%~dp0\..\visualc\VS2010"
|
||||
|
||||
"%vcvarsall%" x64 && ^
|
||||
msbuild /t:Rebuild /p:Configuration=%cfg%%retarget% /m mbedTLS.sln
|
||||
|
||||
Reference in New Issue
Block a user