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

adds a signature::Signer interface #537

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

baloo
Copy link
Contributor

@baloo baloo commented Aug 3, 2024

This brings an implementation of a signature::Signer for keys stored on the TPM.

This is intend to make for easier re-use of this crate and to allow to:

Here is an implementation of an SSH agent making use of that infrastructure: wiktor-k/ssh-agent-lib#87

@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch from 85783cc to 6525f15 Compare August 3, 2024 23:17
@baloo baloo marked this pull request as draft August 3, 2024 23:20
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch 2 times, most recently from 336466d to 8145f8e Compare August 4, 2024 03:35
Copy link
Collaborator

@Superhepper Superhepper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for reviewing a WIP though I found it a little bit interesting so I couldn't help my self. Feel free to disregard anything I have commented on.

tss-esapi/src/abstraction/public.rs Outdated Show resolved Hide resolved
tss-esapi/src/abstraction/public.rs Outdated Show resolved Hide resolved
tss-esapi/src/abstraction/transient/signer.rs Outdated Show resolved Hide resolved
tss-esapi/src/interface_types/algorithm.rs Outdated Show resolved Hide resolved
tss-esapi/src/structures/signatures.rs Outdated Show resolved Hide resolved
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch 6 times, most recently from df740fd to eaf82d5 Compare August 4, 2024 16:28
@baloo
Copy link
Contributor Author

baloo commented Aug 4, 2024

Sorry for reviewing a WIP though I found it a little bit interesting so I couldn't help my self. Feel free to disregard anything I have commented on.

Oh, no, thanks for reviewing it!
I sent it a bit early as this is work I've been putting off for almost a year now. I'm doing it mostly to get a sense whether this is a direction the project could go or not.

Copy link
Member

@ionut-arm ionut-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for bringing the patch! The overall design looks good to me.

Comment on lines +44 to +45
// Note: this does not implement `TryFrom<RsaSignature>` because `RsaSignature` does not carry the
// information whether the signatures was generated using PKCS#1v1.5 or PSS.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fields of RsaSignature are private, so we can extend it to capture this detail as well. It's a deviation from the TPM spec, but I don't necessarily see a problem with it. Thoughts?

cc @Superhepper

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it is not really a problem as long as it does not causes any ambiguities in the conversions between TPMS_SIGNATURE_RSA and RsaSignature.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine like that, the comment was more for a future self why we would not have such a TryFrom

use signature::{DigestSigner, Error as SigError, KeypairRef};

#[derive(Debug)]
pub struct Ecdsa<'ctx, C>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I know this is a draft: ) Would be good to have some docs on these structs to make it clear what they're meant for.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to add some, and add a code sample in the doc as well.

Comment on lines 87 to 127
/// Key parameters for this curve
pub fn key_params<D>() -> KeyParams
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit mystified by the purpose of this function. Also by the use of "this curve" in the doc for it, given that Ecdsa is presumably not the description of a curve (?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C describes the curve (could be NistP256, NistP384, NistP521, ...) those are all supported here. When using the signer (through the Ecdsa struct) you would specify which curve you're using.

This would pick the correct parameters to specify to the TPM when signing, the size of the object that comes back from signature, how to verify them, ...

This function just creates the TPM parameters related to this curve and the selected digest.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I think I was mostly confused by the existence of two nearly-identical methods before, and that the struct they're tacked to doesn't represent (just) a specific curve.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The key_params_default just use the "default" hashing mechanism for a given curve (P256 would use sha256, P384 would use sha384, etc).

The hashing methods needs to line up otherwise the curve has a higher "security score" than the hashing mechanism it uses and it's a waste of space.

@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch 3 times, most recently from fe52b1c to fa8ff3a Compare August 6, 2024 23:16
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch 4 times, most recently from 7bcbb0c to b79e193 Compare August 7, 2024 03:33
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch from b79e193 to 9f760ad Compare August 7, 2024 05:29
const TPM_DIGEST: HashingAlgorithm;
}

#[cfg(feature = "sha1")]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... how does this work if I don't see the feature declared in Cargo.toml? 🤔

Copy link
Contributor Author

@baloo baloo Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeaaah, I learned this one recently too lol.
https://doc.rust-lang.org/cargo/reference/features.html#optional-dependencies

By default, this optional dependency implicitly defines a feature that looks like this:

[features]
gif = ["dep:gif"]

I'm abusing that mechanism here.

I actually need to split the features in the Cargo.toml to look more like:

rustcrypto = ["ecdsa", "elliptic-curve", "signature", "x509-cert"]
rustcrypto-full = ["rustcrypto", "p192", "p224", "p256", "p384", "p521", "rsa", "sha1", "sha2", "sha3", "sm2", "sm3"]

That way you can bring in rustcrypto + "p256" + "sha2" if you only care about those.

While I'm at it: I don't know how to name that feature, is rustcrypto good enough?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rustcrypto and rustcrypto-full are fine for me.

Would you be so kind to adjust all of these to use the rustcrypto-full feature name? (maybe this stuff only bothers me 😅

@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch from 9f760ad to edf67ed Compare August 7, 2024 16:37
@rucoder rucoder mentioned this pull request Jan 23, 2025
5 tasks
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch from edf67ed to 73e0b9c Compare January 24, 2025 20:05
@baloo baloo marked this pull request as ready for review January 24, 2025 20:05
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch from 01d0df7 to af146ef Compare January 27, 2025 20:50
@baloo baloo mentioned this pull request Jan 27, 2025
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch from af146ef to e21adf0 Compare January 28, 2025 08:04
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch from e21adf0 to ad664c0 Compare January 30, 2025 17:11
tss-esapi/src/abstraction/public.rs Outdated Show resolved Hide resolved
tss-esapi/src/abstraction/public.rs Show resolved Hide resolved
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch from ad664c0 to a699a3e Compare February 2, 2025 05:24
@rucoder
Copy link

rucoder commented Feb 2, 2025

@baloo why EcSigner depends on TransientKeyContext? The only method is used there is sign(). Besides TransientKeyContext is limited to RSA key as a primary. it would be better IMO either

  1. to have a constructor that that accepts Context and KeyHandle in TransientKeyContext/Builder. Currently fields are private
  2. Or maybe turn (partially) TransientKeyContext into a trait since EcSigner uses its methods (actually only sign() so far).

I should probably explain the use case: I'm loading a key that is stored on TPM as Persistent and currently there is no way to use EcSigner with such keys. TransientTpmContext is transient for reasons but then it limits usage of EcSigner

Sure, I can implement my own signer but if we can make EcSigner more versatile it would be very cool

@baloo
Copy link
Contributor Author

baloo commented Feb 3, 2025

This is a good point. I think I like the idea of making a trait but I'm not sure how to do it yet, TransientKeyContext and Context::sign are pretty dissimilar.

@baloo
Copy link
Contributor Author

baloo commented Feb 3, 2025

I have a rough follow-up PR for the trait option: baloo#1

@baloo
Copy link
Contributor Author

baloo commented Feb 5, 2025

It was also missing the implementation for an RSA signer: baloo#2

tss-esapi/Cargo.toml Outdated Show resolved Hide resolved
Copy link
Member

@ionut-arm ionut-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good overall!

Are you intending to add signing support for RSA too?

tss-esapi/src/abstraction/public.rs Show resolved Hide resolved
@ionut-arm
Copy link
Member

Ah, one thing that I keep forgetting - could you please document the new feature (in the README)?

@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch 2 times, most recently from 0135af5 to ff812e9 Compare February 9, 2025 06:27
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch from ff812e9 to a37e0ec Compare February 9, 2025 06:47
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch from a37e0ec to e8c25df Compare February 9, 2025 06:52
Copy link
Collaborator

@wiktor-k wiktor-k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks good. While I'm no expert in rust crypto I'm of the opinion that this is ready to be shipped to folks to try out in the wild.

const TPM_DIGEST: HashingAlgorithm;
}

#[cfg(feature = "sha1")]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rustcrypto and rustcrypto-full are fine for me.

Would you be so kind to adjust all of these to use the rustcrypto-full feature name? (maybe this stuff only bothers me 😅

#[allow(unused)]
Public::Ecc { parameters, .. } => {
macro_rules! read_key {
($curve:expr, $key_type:ty) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need $curve if it's not used anywhere? (also the allow(unused) lint)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants