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

Feature: ECC Support in TPM2 #4357

Merged
merged 8 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
1 change: 1 addition & 0 deletions src/lib/prov/tpm2/info.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pubkey
tpm2_algo_mappings.h
tpm2_hash.h
tpm2_util.h
tpm2_pkops.h
</header:internal>

<header:public>
Expand Down
68 changes: 66 additions & 2 deletions src/lib/prov/tpm2/tpm2_algo_mappings.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
/*
* TPM 2 algorithm mappings
* (C) 2024 Jack Lloyd
* (C) 2024 René Meusel, Amos Treiber - Rohde & Schwarz Cybersecurity GmbH
* (C) 2024 René Meusel, Amos Treiber - Rohde & Schwarz Cybersecurity GmbH, financed by LANCOM Systems GmbH
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#ifndef BOTAN_TPM2_ALGORITHM_MAPPINGS_H_
#define BOTAN_TPM2_ALGORITHM_MAPPINGS_H_

#include <botan/asn1_obj.h>
#include <botan/exceptn.h>

#include <botan/internal/fmt.h>
Expand All @@ -29,7 +30,7 @@ namespace Botan::TPM2 {
} else if(algo_name == "ECC") {
return TPM2_ALG_ECC;
} else if(algo_name == "ECDSA") {
return TPM2_ALG_ECC;
return TPM2_ALG_ECDSA;
} else if(algo_name == "ECDH") {
return TPM2_ALG_ECDH;
} else if(algo_name == "ECDAA") {
Expand Down Expand Up @@ -195,6 +196,69 @@ namespace Botan::TPM2 {
}
}

[[nodiscard]] inline std::optional<std::string> curve_id_tss2_to_botan(TPMI_ECC_CURVE mode_id) {
// Currently, tpm2-tss does not include support for Brainpool curves or 25519/448.
// Once the corresponding PR (https://github.com/tpm2-software/tpm2-tss/pull/2897) is merged and released,
// this function should be updated.
switch(mode_id) {
case TPM2_ECC_NIST_P192:
return "secp192r1";
case TPM2_ECC_NIST_P224:
return "secp224r1";
case TPM2_ECC_NIST_P256:
return "secp256r1";
case TPM2_ECC_NIST_P384:
return "secp384r1";
case TPM2_ECC_NIST_P521:
return "secp521r1";
case TPM2_ECC_SM2_P256:
return "sm2p256v1";
default:
return std::nullopt;
}
}

[[nodiscard]] inline std::optional<size_t> curve_id_order_byte_size(TPMI_ECC_CURVE curve_id) {
switch(curve_id) {
case TPM2_ECC_NIST_P192:
return 24;
case TPM2_ECC_NIST_P224:
return 28;
case TPM2_ECC_NIST_P256:
return 32;
case TPM2_ECC_NIST_P384:
return 48;
case TPM2_ECC_NIST_P521:
return 66; // Rounded up to the next full byte
case TPM2_ECC_SM2_P256:
return 32;
default:
return std::nullopt;
}
}

[[nodiscard]] inline std::optional<TPM2_ECC_CURVE> get_tpm2_curve_id(const OID& curve_oid) {
// Currently, tpm2-tss does not include support for Brainpool curves or 25519/448.
// Once the corresponding PR (https://github.com/tpm2-software/tpm2-tss/pull/2897) is merged and released,
// this function should be updated.
const std::string curve_name = curve_oid.to_formatted_string();
if(curve_name == "secp192r1") {
return TPM2_ECC_NIST_P192;
} else if(curve_name == "secp224r1") {
return TPM2_ECC_NIST_P224;
} else if(curve_name == "secp256r1") {
return TPM2_ECC_NIST_P256;
} else if(curve_name == "secp384r1") {
return TPM2_ECC_NIST_P384;
} else if(curve_name == "secp521r1") {
return TPM2_ECC_NIST_P521;
} else if(curve_name == "sm2p256v1") {
return TPM2_ECC_SM2_P256;
} else {
return std::nullopt;
}
}

[[nodiscard]] inline std::optional<TPMI_ALG_SYM_MODE> cipher_mode_botan_to_tss2(std::string_view mode_name) noexcept {
if(mode_name == "CFB") {
return TPM2_ALG_CFB;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/prov/tpm2/tpm2_context.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* TPM 2 interface
* (C) 2024 Jack Lloyd
* (C) 2024 René Meusel, Amos Treiber - Rohde & Schwarz Cybersecurity GmbH
* (C) 2024 René Meusel, Amos Treiber - Rohde & Schwarz Cybersecurity GmbH, financed by LANCOM Systems GmbH
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
Expand Down
2 changes: 1 addition & 1 deletion src/lib/prov/tpm2/tpm2_context.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* TPM 2 interface
* (C) 2024 Jack Lloyd
* (C) 2024 René Meusel, Amos Treiber - Rohde & Schwarz Cybersecurity GmbH
* (C) 2024 René Meusel, Amos Treiber - Rohde & Schwarz Cybersecurity GmbH, financed by LANCOM Systems GmbH
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
Expand Down
Loading
Loading