-
Notifications
You must be signed in to change notification settings - Fork 28
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
[RFC] RSA lib integration #29
Conversation
Thank you for the PR! I did not have a closer look yet but I just want to give you a heads-up that we are already working on a solution for the test issue. |
@alt3r-3go Hey! I plan to take a look at it this week |
@alt3r-3go #31 refactors the client used for the tests and should allow you to execute them normally with |
Hey @alt3r-3go, great work, I will answer (hopefully all) of your TODOs here to have it in one place.
But again: keep it simple and stick to Sooo, hope this answers the questions. Rebasing on top of
This is really nice! Feels like nearly all of the heavy lifting stuff is done, despite the smaller changes described above (ok ignoring 3k, 4k - but that's totally fine for now). We anyways won't be able to upstream this until RSACrypto / RSA will have proper |
Signed-off-by: alt3r 3go <[email protected]>
Signed-off-by: alt3r 3go <[email protected]>
Signed-off-by: alt3r 3go <[email protected]>
Signed-off-by: alt3r 3go <[email protected]>
Signed-off-by: alt3r 3go <[email protected]>
Signed-off-by: alt3r 3go <[email protected]>
Signed-off-by: alt3r 3go <[email protected]>
Signed-off-by: alt3r 3go <[email protected]>
Signed-off-by: alt3r 3go <[email protected]>
ecc399e
to
16003b6
Compare
Thanks @daringer, that makes a lot of sense and is certainly helpful. I've rebased to the latest
Other existing ones seem to store pure bytes when using
As of ~6 months ago, when I actively tested this, it actually was running fine with |
In a separate commit for better visibility. Removed addressed TODOs, reworded those that should stay for later (magic numbers), rebased to the latest "main". Signed-off-by: alt3r 3go <[email protected]>
16003b6
to
c7cca84
Compare
I've rebased it on top of 8e347ab in sosthene-nitrokey:rsa-lib-integration-fmt |
Hey @alt3r-3go ! |
@szszszsz I probably could, but what exactly do you have in mind in terms of actions required? It seems to me it's ready to be merged into whatever place we'd designate for this, as per our past discussions, maybe based on the rebased branch that @sosthene-nitrokey mentioned. Are you maybe talking about namely that cargo-fmt commit and rebasing this PR specifically onto it? |
I mean't this PR should be reset to my https://github.com/sosthene-nitrokey/trussed/tree/rsa-lib-integration-fmt branch to resolve merge conflicts. Sorry it took me so much time to respond, I missed the notification |
I'm not sure what is the best way to serialize public keys. For example the OpenPGP smartcard specification uses it's own serialization format, and to build it we need both Maybe we could have two additional serialization formats |
Hey @sosthene-nitrokey @alt3r-3go ! Edit: @alt3r-3go : Sorry for the delay. Had hot month. I just thought something is still pending to do. Good to hear it's more or less finished! It works for my use case in Nitrokey WebCrypt as well. |
} | ||
|
||
#[cfg(feature = "rsa2k")] | ||
impl DeserializeKey for super::Rsa2kPkcs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DeserializeKey and SerializeKey should only work with public keys.
Private key import is done through UnsafeInjectKey, and private key export should never be an option.
I also think the serialization format should be Pkcs8, not Raw
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, good catch. Looking at the code now, I'm not sure why I used the Secret
one here. I was following the p256 and ed255 implementations, but apparently they don't do this either. Probably an artifact of working on this on and off for a longer time. I'll correct this. There's no Pkcs8 type though (that's why we settled on Raw with @daringer in his earlier comment). Do you mean we should add it?
// TODO: Consider using .sign_blinded(), which is supposed to protect the private key from timing side channels | ||
use rsa::padding::PaddingScheme; | ||
use rsa::hash::Hash; | ||
let native_signature = priv_key |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can panic il the length of the data is not 32
, it should return an error instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also we may want to use another hash than SHA-256. I'd be in favor of using None
for the hash. We need that for OpenPGP anyway, as all hashes can be used. it depends on the host.
It would require added documentation that the hash prefix needs to be added by the client though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, this was an outcome of our earlier discussion with @daringer, where we decided to just treat this as prehashed, by contract. As for the None
specifically, this is a bit error-prone, do we really have to provide that choice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree this is somewhat uncomfortable, but for OpenPGP: in § 7.2.10, it mentions the digest prefix added for each hash that come as part of the input (DigestInfo) "The card may not check the correctness of the DigestInfo.". So we need to accept any input and not attempt to parse it or add any prefix other than the Pkcs#1v15 padding.
I'll look into and address specific comments later, but overall it looks like this needs to be merged somewhere, as more and more further changes start to pile up on top. I will rebase this on top of @sosthene-nitrokey's cargo-fmt branch, but let's also define where we want to merge this. One option we discussed before was an NK-owned Trussed fork, at least until mechanisms are in place to address @nickray's concerns cleanly. @daringer (or whoever is the right person to decide?), do you maybe want to create one? If not, how do you folks think we should move forward? |
@sosthene-nitrokey @daringer @robin-nitrokey We should discuss this tomorrow |
|
||
let key_id = request.key; | ||
|
||
let priv_key_der = keystore.load_key(key::Secrecy::Secret, Some(key::Kind::Rsa2k), &key_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signature verification should probably load a public key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does derive it, a little below. Though it indeed could load it directly, instead of deriving. This is probably the same thing as in Serialize/Deserialize, it looks like for whatever reason I assumed that keystore only holds private keys, or some such.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The keystore can hold both public and private keys. It's a bit of a shame that it needs to be told what key is being loaded rather than returning an enum allowing to match against the key type, which would be more flexible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does derive it, a little below.
Yes, but the current implementation means you can't verify a signature unless you also have the private key.
Ok, so we talked about where we are going to go with this PR. We're going have a version off this PR on the Nitrokey repo here. I already added some fixes that I needed for the OpenPGP card implementation. With regard to serialization: Since both OpenPGP and the SE050 secure element use a similar BER-TLV format 1, we are going to use it for (de)serialization of RSA Key (with an added In case their is a need for Pkcs (de)serialization, we should keep it with an added Footnotes |
Good! I see you've already fixed in that new PR the comments posted in this PR. Let me know if you need any further action from me. I also think we can close this PR and continue in the NK repo one - let me know if there are any objections. |
Now that we've got the right place for this PR, let me close it. We can continue in that NK repo if/when needed, please just @-mention me, so that I don't miss the notification. |
This is an "request for comments"-type PR to invite a discussion and iron out the details of the RSA library integration.
Context
We've discussed this with the Nitrokey team a while ago (around the end of 2021) and I took a stab at it, then it got paused for several months after this discussion we additionally had with @nickray. Recently @daringer suggested we move ahead anyway, probably in a form of an NK-specific temporary fork, while those TIPs are getting written/implemented. AFAIU this is driven by the desire to have an RSA implementation for NK3, so at least some working solution is valued higher than the ideal one we discussed in that Matrix chat.
Implemented now
RSA2K-PKCS_v1.5 signing/verification and the whole necessary set of helper traits (
DeriveKey
, etc) + tests for them, that work on a PC. I separately was able to run Trussed and the RSA lib's full set of tests on my nRF52832, but haven't yet tried both of them at once.Caveats
The PR is still well WIP and has items to discuss (marked as
TODO:alt3r-3go
in the code). I've based the general approach on themiracl
one (#12) and that proved to be quite useful, so kudos to @nickray for such a nice example. Due to one of the TODOs related to the test infra, tests need to be run one by one for now, at the bottom of this description I'm showing a simple script that can be used for that. I haven't included it into the code, but let me know if it's helpful until I close the TODO.All comments, big and small, as well as suggestions on the TODOs are more than welcome.
Testing script