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

WIP: adds a signature::Signer interface #537

Draft
wants to merge 6 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 2 times, most recently from 7331b83 to 18ee544 Compare August 4, 2024 13:51
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch from 18ee544 to 55ea1cc Compare August 4, 2024 13:56
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch 2 times, most recently from dda6694 to df740fd Compare August 4, 2024 14:17
@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch 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.

I did bring back the two nearly-identical methods btw.

@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
Comment on lines +904 to +908
let builder = RequestBuilder::new(subject, &signer).expect("Create certificate request");

let cert_req = builder
.build::<p256::ecdsa::DerSignature>()
.expect("Sign a CSR");
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 added proper examples of what this interface is used for.

// I can't find where in the TPM spec this would be an illegal pair, we'll ignore for now.
#[ignore]
#[test]
fn sign_p256_sha3_256() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This one is a bit puzzling to me. I can't find where in the spec the the P-256/SHA3-256 pair would be illegal. If anyone has an idea, I'd love to know.

Copy link
Member

Choose a reason for hiding this comment

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

Could it be a limitation of the TPM you're using? From the Structures spec, table 8, it seems SHA3-256 is classified as Assigned rather than TCG standard. I assume this might mean that manufacturers are not required to implement it (?)

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'm using swtpm (0.8.2) with libtpms (0.9.6) I expected it to play nicely. I haven't took time to look in libtpms yet.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, from this it seems libtpms can block SHA3 at compile-time, perhaps that's what is going on here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, turns out it's more complicated than that.
stefanberger/libtpms#206

No sha3 support for now.

@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?

@baloo baloo force-pushed the baloo/rust-crypto/signer-interface branch from 9f760ad to edf67ed Compare August 7, 2024 16:37
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.

4 participants