Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TPM2: ECC Support (won't merge here) #14

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
1f584b2
Update fuzzing docs and configuration
Logix64 Jun 11, 2024
ba935a8
Update fuzzing signature
Logix64 Jun 26, 2024
ee41b6b
Add BOTAN_PUBLIC_API to TLS::Context class
atreiber94 Sep 6, 2024
f0ecad0
Move examples target to shared build in ci;
atreiber94 Sep 6, 2024
d8460eb
FIX: `ninja tests` fails to build for 'shared'
reneme Sep 6, 2024
89c74e9
Merge pull request #4336 from Rohde-Schwarz/fix/ninja_shared
reneme Sep 7, 2024
0639e82
Merge pull request #4335 from Rohde-Schwarz/fix/context_visibility
atreiber94 Sep 9, 2024
1912f57
Use more secure KEM combination in example
FAlbertDev Sep 20, 2024
b5df358
Deprecate 0xFE30 X25519/Kyber512 code point
reneme Sep 23, 2024
7f256a0
Merge pull request #4347 from reneme/chore/retire_0xFE30
reneme Oct 1, 2024
d9e12cc
use @response_files.txt for linking in ninja
reneme Oct 2, 2024
4890fc9
Allow using `secure_allocator` for enum types, like `std::byte`
Delta-dev-99 Oct 5, 2024
34d6b46
Reorder/rephrase output from X509_Certificate::to_string
randombit Aug 29, 2024
097f78a
Deprecate various aliases for the public key padding code
randombit Oct 7, 2024
4e2e9d5
Merge pull request #4350 from Rohde-Schwarz/chore/response_files_for_…
reneme Oct 7, 2024
278dc55
Merge pull request #4353 from Delta-dev-99/patch-1
randombit Oct 7, 2024
7e28dda
Merge pull request #4344 from Rohde-Schwarz/fix/hybrid_kem_example
randombit Oct 7, 2024
175b1f2
Merge pull request #4330 from randombit/jack/rephrase-x509-to-string
randombit Oct 7, 2024
bd89aa3
Merge pull request #4355 from randombit/jack/deprecate-sig-variants
randombit Oct 7, 2024
7624371
Merge pull request #4337 from Rohde-Schwarz/feature/tpm2_support
atreiber94 Oct 7, 2024
00eb2d2
Merge pull request #4114 from Logix64/update-fuzzing
randombit Oct 7, 2024
7800449
Generalize TPM2 RSA Adapter in preparation of ECC support
atreiber94 Oct 7, 2024
4d72781
Add TPM2 ECC Adapter to support ECDSA TPM2 keys
atreiber94 Oct 7, 2024
fa7f055
Add ECDH Support to TPM2 Crypto Backend
atreiber94 Oct 7, 2024
78205c6
Be defensive with the input parameters in the crypto backend
reneme Oct 7, 2024
6c9b503
CI and Test infrastructure for TPM2 ECC support
atreiber94 Oct 7, 2024
0596bb2
Add TPM2 ECC Documentation
atreiber94 Oct 7, 2024
3ac8985
Add attribution to funding provider LANCOM
atreiber94 Oct 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ def __init__(self, source_paths, options, modules):
self.handbook_output_dir = os.path.join(self.doc_output_dir, 'handbook')
self.doc_output_dir_doxygen = os.path.join(self.doc_output_dir, 'doxygen') if options.with_doxygen else None
self.doc_module_info = os.path.join(self.build_dir, 'module_info') if options.with_doxygen else None
self.response_file_dir = os.path.join(self.build_dir, 'response_files')

# We split the header include paths into 'public', 'internal' and 'external'
# to allow for better control over what is exposed to each compilation unit.
Expand Down Expand Up @@ -272,6 +273,7 @@ def build_dirs(self):
self.internal_include_dir,
self.external_include_dir,
self.handbook_output_dir,
self.response_file_dir
]
if self.doc_output_dir_doxygen:
out += [self.doc_output_dir_doxygen, self.doc_module_info]
Expand Down Expand Up @@ -1938,6 +1940,7 @@ def _build_info(sources, objects, target_type):

if target_type in ['fuzzer', 'examples']:
exe_basename = os.path.basename(obj_file).replace('.' + osinfo.obj_suffix, osinfo.program_suffix)
info['exe_basename'] = exe_basename

if target_type == 'fuzzer':
info['exe'] = os.path.join(build_paths.fuzzer_output_dir, exe_basename)
Expand Down Expand Up @@ -2210,6 +2213,7 @@ def test_exe_extra_ldflags():
'doc_output_dir': build_paths.doc_output_dir,
'handbook_output_dir': build_paths.handbook_output_dir,
'doc_output_dir_doxygen': build_paths.doc_output_dir_doxygen,
'response_file_dir': build_paths.response_file_dir,

'os': options.os,
'arch': options.arch,
Expand Down Expand Up @@ -3183,10 +3187,6 @@ def canonicalize_build_targets(options):
else:
options.build_static_lib = True

# Set default fuzzing lib
if options.build_fuzzers == 'libfuzzer' and options.fuzzer_lib is None:
options.fuzzer_lib = 'Fuzzer'

if options.ldflags is not None:
extra_libs = []
link_to_lib = re.compile('^-l(.*)')
Expand Down
2 changes: 1 addition & 1 deletion doc/api_ref/providers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ For example, the following code signs a message using an RSA key with the
Botan::AutoSeeded_RNG rng;
auto key = Botan::create_private_key("RSA", rng, "3072");

Botan::PK_Signer signer(key, rng, "EMSA3(SHA-256)", Botan::Signature_Format::Standard, "CommonCrypto");
Botan::PK_Signer signer(key, rng, "PKCS1v15(SHA-256)", Botan::Signature_Format::Standard, "CommonCrypto");

signer.update("Hello");
signer.update(" ");
Expand Down
28 changes: 17 additions & 11 deletions doc/api_ref/pubkey.rst
Original file line number Diff line number Diff line change
Expand Up @@ -633,20 +633,21 @@ OAEP
OAEP (called EME1 in IEEE 1363 and in earlier versions of the library)
as specified in PKCS#1 v2.0 (RFC 2437) or PKCS#1 v2.1 (RFC 3447).

- Names: ``OAEP`` / ``EME-OAEP`` / ``EME1``
- Name: ``OAEP``,
- Deprecated aliases: ``EME-OAEP``, ``EME1``
- Parameters specification:

- ``(<HashFunction>)``
- ``(<HashFunction>,MGF1)``
- ``(<HashFunction>,MGF1(<HashFunction>))``
- ``(<HashFunction>,MGF1(<HashFunction>),<optional label>)``

- The only Mask generation function available is MGF1
which is also the default.
- The only Mask generation function available is MGF1, which is also the default.
- By default the same hash function will be used for the label and MGF1.
- By default the OAEP label is the empty string
- Examples:
``OAEP(SHA-256)``,
``EME-OAEP(SHA-256,MGF1)``,
``OAEP(SHA-256,MGF1)``,
``OAEP(SHA-256,MGF1(SHA-512))``,
``OAEP(SHA-512,MGF1(SHA-512),TCPA)``

Expand All @@ -655,7 +656,8 @@ PKCS #1 v1.5 Type 2 (encryption)

PKCS #1 v1.5 Type 2 (encryption) padding.

Names: ``PKCS1v15`` / ``EME-PKCS1-v1_5``
Name: ``PKCS1v15``
Deprecated alias: ``EME-PKCS1-v1_5``

Raw EME
"""""""
Expand Down Expand Up @@ -837,9 +839,10 @@ Available signature padding schemes
PKCS #1 v1.5 Type 1 (signature)
"""""""""""""""""""""""""""""""

PKCS #1 v1.5 Type 1 (signature) padding or EMSA3 from IEEE 1363.
PKCS #1 v1.5 Type 1 (signature) padding, aka EMSA3 in IEEE 1363.

- Names: ``PKCS1v15`` / ``EMSA_PKCS1`` / ``EMSA-PKCS1-v1_5`` / ``EMSA3``
- Name: ``PKCS1v15``
- Deprecated aliases: ``EMSA_PKCS1``, ``EMSA-PKCS1-v1_5``, ``EMSA3``
- Parameters specification:

- ``(<HashFunction>)``
Expand All @@ -857,7 +860,8 @@ EMSA-PSS

Probabilistic signature scheme (PSS) (called EMSA4 in IEEE 1363).

- Names: ``PSS`` / ``EMSA-PSS`` / ``PSSR`` / ``PSS-MGF1`` / ``EMSA4``
- Name: ``PSS``
- Deprecated aliases: ``EMSA-PSS``, ``PSSR``, ``PSS-MGF1``, ``EMSA4``
- Parameters specification:

- ``(<HashFunction>)``
Expand All @@ -871,7 +875,8 @@ There also exists a raw version,
which accepts a pre-hashed buffer instead of the message.
Don't use this unless you know what you are doing.

- Names: ``PSS_Raw`` / ``PSSR_Raw``
- Name: ``PSS_Raw``
- Deprecated alias: ``PSSR_Raw``
- Parameters specification:

- ``(<HashFunction>)``
Expand Down Expand Up @@ -912,10 +917,11 @@ X9.31

EMSA from X9.31 (EMSA2 in IEEE 1363).

- Names: ``EMSA2`` / ``EMSA_X931`` / ``X9.31``
- Name: ``X9.31``
- Deprecated aliases: ``EMSA2``, ``EMSA_X931``
- Parameters specification:
``(<HashFunction>)``
- Example: ``EMSA2(SHA-256)``
- Example: ``X9.31(SHA-256)``

Raw EMSA
""""""""
Expand Down
22 changes: 20 additions & 2 deletions doc/api_ref/tpm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,9 @@ Asymmetric Keys hosted by a TPM 2.0

The TPM v2.0 supports RSA and ECC keys. Botan provides the classed
``PrivateKey`` and ``PublicKey`` in the ``TPM2`` namespace, to manage and use
asymmetric keys on the TPM. Additionally there are derived classes for RSA. ECC
is not supported at this time, but could be added in the future.
asymmetric keys on the TPM. Additionally there are derived classes for RSA and ECC.
Currently, RSA keys can be used for signing and encryption, while ECC keys can only
be used for ECDSA signing (i.e., ECDH, ECSCHNORR, and SM2 are not supported).

Objects of these classes can be used throughout the Botan library to perform
cryptographic operations with TPM keys wherever an abstract
Expand Down Expand Up @@ -216,6 +217,23 @@ and manage RSA keys on the TPM.
stored in the TPM's NVRAM and must be loaded from their public and
private blobs after a reboot.

Similarly, Botan provides a set of derived classes for ECC keys.

.. cpp:class:: Botan::TPM2::EC_PrivateKey

.. cpp:function:: static std::unique_ptr<TPM2::PrivateKey> create_unrestricted_transient(const std::shared_ptr<Context>& ctx, const SessionBundle& sessions, std::span<const uint8_t> auth_value, const TPM2::PrivateKey& parent, const EC_Group& group);

Creates a new ECC key pair on the TPM with the given ``group``. The
group must be one of the supported curves by the TPM and currently
must be one of the NIST curves (secp192r1, secp224r1, secp256r1,
secp384r1, secp521r1).

Keys generated with this function are not restricted in their usage.
They may only be used for signing: Currently, Botan only supports creating
ECDSA keys. Furthermore, they are transient, i.e. they are not stored in
the TPM's NVRAM and must be loaded from their public and private blobs after
a reboot.

Once a transient key pair was created on the TPM, it can be persisted into the
TPM's NVRAM to make it available across reboots independently of the "private
blob". This is done by passing the key pair to the ``Context::persist`` method.
Expand Down
7 changes: 7 additions & 0 deletions doc/deprecated.rst
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@ release, or where a backwards incompatible change is expected.
- All support for loading, generating or using RSA keys with a public
exponent larger than 2**64-1

- Currently some public key padding mechanisms can be used with several
different names. This is deprecated.
"EMSA_PKCS1", "EMSA-PKCS1-v1_5", "EMSA3": Use "PKCS1v15"
"PSSR_Raw": Use "PSS_Raw"
"PSSR", "EMSA-PSS", "PSS-MGF1", "EMSA4": Use "PSS"
"EMSA_X931", "EMSA2": Use "X9.31"

Deprecated Headers
^^^^^^^^^^^^^^^^^^^^^^

Expand Down
55 changes: 31 additions & 24 deletions doc/dev_ref/fuzzing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,47 @@ the library.
Fuzzing with libFuzzer
------------------------

To fuzz with libFuzzer (https://llvm.org/docs/LibFuzzer.html), you'll first
need to compile libFuzzer::
As of Clang Version 6.0 libFuzzer is automatically included in the compiler. Therefore you don't need to install any new software.
You can build the fuzzers by running ::

$ svn co https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/fuzzer libFuzzer
$ cd libFuzzer && clang -c -g -O2 -std=c++11 *.cpp
$ ar cr libFuzzer.a libFuzzer/*.o

Then build the fuzzers::

$ ./configure.py --cc=clang --build-fuzzer=libfuzzer --unsafe-fuzzer-mode \
--with-debug-info --enable-sanitizers=coverage,address,undefined
$ ./configure.py --cc=clang --build-fuzzer=libfuzzer --enable-sanitizers=fuzzer
$ make fuzzers

Enabling 'coverage' sanitizer flags is required for libFuzzer to work.
Address sanitizer and undefined sanitizer are optional.
The option `--enable-sanitizers=fuzzer` compiles the library for coverage-guided fuzzing.
You can add additional sanitizers like `address`, `undefined` and `memory` or with/without
additional information during building by either adding `--unsafe-fuzzer-mode` or `--with-debug-info`.
The `coverage` sanitizer is not compatible with this configuration.

If you want to link additional libraries you can use the `--with-fuzzer-lib` option
while configuring the build with configure.py.
The fuzzer binaries will be in `build/fuzzer`. Simply pick one and run it, optionally
also passing a directory containing corpus inputs.
also passing a directory containing corpus inputs. Running

$ make fuzzer_corpus

downloads a specific corpus from https://github.com/randombit/crypto-corpus.git. Together
with

Using `libfuzzer` build mode implicitly assumes the fuzzers need to
link with `libFuzzer`; if another library is needed (for example in
OSS-Fuzz, which uses `libFuzzingEngine`), use the flag
`--with-fuzzer-lib` to specify the desired name.
$ ./src/scripts/test_fuzzers.py fuzzer_corpus build/fuzzer

Fuzzing with AFL
you can test the Fuzzers.

Fuzzing with AFL++
--------------------

To fuzz with AFL (http://lcamtuf.coredump.cx/afl/)::
Please make sure that you have installed AFL++ according to https://aflplus.plus/building/.
The version of Clang should match the version of `afl-clang-fast++`/ `afl-clang-fast`.
You can fuzz with AFL++ in LLVM mode (https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.llvm.md) by running ::

$ ./configure.py --with-sanitizers --build-fuzzer=afl --unsafe-fuzzer-mode --cc-bin=afl-g++
$ ./configure.py --cc=clang --with-sanitizers --build-fuzzer=afl --unsafe-fuzzer-mode --cc-bin=afl-clang-fast++
$ make fuzzers

For AFL sanitizers are optional. You can also use `afl-clang-fast++`
or `afl-clang++`, be sure to set `--cc=clang` also.
For AFL++ in GCC mode make sure that you have `afl-g++-fast` installed.
Otherwise follow https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.gcc_plugin.md to build and install it.
You can configure the build by running ::

$ ./configure.py --cc=gcc --with-sanitizers --build-fuzzer=afl --unsafe-fuzzer-mode --cc-bin=afl-g++-fast
$ make fuzzers

The fuzzer binaries will be in `build/fuzzer`. To run them you need to
run under `afl-fuzz`::
Expand Down Expand Up @@ -73,7 +80,7 @@ Input Corpus
AFL requires an input corpus, and libFuzzer can certainly make good
use of it.

Some crypto corpus repositories include
Some other crypto corpus repositories include

* https://github.com/randombit/crypto-corpus
* https://github.com/mozilla/nss-fuzzing-corpus
Expand All @@ -86,6 +93,6 @@ Adding new fuzzers
New fuzzers are created by adding a source file to `src/fuzzers` which
have the signature:

``void fuzz(const uint8_t in[], size_t len)``
``void fuzz(std::span<const uint8_t> in)``

After adding your fuzzer, rerun ``./configure.py`` and build.
1 change: 1 addition & 0 deletions src/build-data/cc/clang.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ address -> "-fsanitize=address"
undefined -> "-fsanitize=undefined -fno-sanitize-recover=undefined"
coverage -> "-fsanitize=fuzzer-no-link"
memory -> "-fsanitize=memory"
fuzzer -> "-fsanitize=fuzzer"
</sanitizers>

shared_flags "-fPIC"
Expand Down
33 changes: 22 additions & 11 deletions src/build-data/ninja.in
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,19 @@ default all
%{if build_static_lib}

rule link_static
command = %{ar_command} %{ar_options} %{ar_output_to}$out $in
rspfile = %{response_file_dir}/static.txt
rspfile_content = $in
command = %{ar_command} %{ar_options} %{ar_output_to}$out @%{response_file_dir}/static.txt

build %{out_dir}/%{static_lib_name}: link_static %{join lib_objs}

%{endif}
%{if build_shared_lib}

rule link_shared
command = %{lib_link_cmd} ${ABI_FLAGS} ${LDFLAGS} $in ${LIB_LINKS_TO} %{output_to_exe}$out
rspfile = %{response_file_dir}/shared.txt
rspfile_content = $in
command = %{lib_link_cmd} ${ABI_FLAGS} ${LDFLAGS} @%{response_file_dir}/shared.txt ${LIB_LINKS_TO} %{output_to_exe}$out

build %{out_dir}/%{shared_lib_name}: link_shared %{join lib_objs}
%{endif}
Expand All @@ -80,17 +84,21 @@ build %{out_dir}/%{soname_patch}: symlink %{out_dir}/%{shared_lib_name}
%{endif}

rule link_cli
command = ${EXE_LINK_CMD} ${ABI_FLAGS} $in ${BUILD_DIR_LINK_PATH} ${LANG_EXE_FLAGS} ${LDFLAGS} ${EXE_LINKS_TO} %{output_to_exe}$out
rspfile = %{response_file_dir}/cli_${cli_name}.txt
rspfile_content = $in
command = ${EXE_LINK_CMD} ${ABI_FLAGS} @%{response_file_dir}/cli_${cli_name}.txt ${BUILD_DIR_LINK_PATH} ${LANG_EXE_FLAGS} ${LDFLAGS} ${EXE_LINKS_TO} %{output_to_exe}$out

rule link_tests
command = ${EXE_LINK_CMD} ${ABI_FLAGS} $in ${BUILD_DIR_LINK_PATH} ${LANG_EXE_FLAGS} ${LDFLAGS} %{test_exe_extra_ldflags} ${EXE_LINKS_TO} %{output_to_exe}$out

rspfile = %{response_file_dir}/tests.txt
rspfile_content = $in
command = ${EXE_LINK_CMD} ${ABI_FLAGS} @%{response_file_dir}/tests.txt ${BUILD_DIR_LINK_PATH} ${LANG_EXE_FLAGS} ${LDFLAGS} %{test_exe_extra_ldflags} ${EXE_LINKS_TO} %{output_to_exe}$out

# Executable targets

build %{cli_exe}: link_cli %{join cli_objs} | %{library_targets}
build %{cli_exe}: link_cli %{join cli_objs} | libs
cli_name = cli

build %{test_exe}: link_tests %{join test_objs} | %{library_targets}
build %{test_exe}: link_tests %{join test_objs} | libs

%{if build_fuzzers}

Expand Down Expand Up @@ -120,7 +128,8 @@ build examples: phony | %{example_bin}

%{if build_bogo_shim}

build botan_bogo_shim: link_cli bogo_shim_object | %{library_targets}
build botan_bogo_shim: link_cli bogo_shim_object | libs
cli_name = bogo

# BoGo shim
build %{out_dir}/bogo_shim_object: compile_exe %{bogo_shim_src}
Expand All @@ -129,7 +138,8 @@ build %{out_dir}/bogo_shim_object: compile_exe %{bogo_shim_src}

%{if build_ct_selftest}

build botan_ct_selftest: link_cli ct_selftest_object | %{library_targets}
build botan_ct_selftest: link_cli ct_selftest_object | libs
cli_name = ct_selftest

build %{out_dir}/ct_selftest_object: compile_exe %{ct_selftest_src}

Expand Down Expand Up @@ -208,10 +218,11 @@ build %{obj}: compile_exe %{src}
%{for fuzzer_build_info}
build %{obj}: compile_exe %{src}

build %{exe}: link_fuzzer %{obj} | %{library_targets}
build %{exe}: link_fuzzer %{obj} | libs
%{endfor}

%{for examples_build_info}
build %{obj}: compile_example_exe %{src}
build %{exe}: link_cli %{obj} | %{library_targets}
build %{exe}: link_cli %{obj} | libs
cli_name = example_%{exe_basename}
%{endfor}
Loading