-
Notifications
You must be signed in to change notification settings - Fork 156
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
Interoperability with libtomcrypt / OpenSSL #186
Comments
It sounds like you're using a number of nonstandard combinations of primitives. From what I can tell, you're attempting to roll your own version of signcryption, which allows decryption by the public key and also authenticates the message ala a typical digital signature. There's a semi-standard RSA construction for this: Probabilistic Signature Scheme with Recovery (PSS-R) as described in Section 5 of: https://web.cs.ucdavis.edu/~rogaway/papers/exact.pdf This approach allows for "folding" part of the message into the signature in such a way that it is "recoverable" by the verifier. |
That does seem to be what is going on, thanks for the hint! Do you think the 2 mentioned issues will be addressed in this crate, or should I switch to OpenSSL / continue using the copied code pieces? |
We could potentially add PSS-R as a high-level construction. The low-level primitives you're describing are easily misused and I personally don't think it would be good to add them. |
While I agree that they are easily misused, I have been often enough in the situation where I needed to support specific legacy constructions, that I wouldn't mind exposing this with a big warning sign under the
👍 |
Closing in favor of #231 which discusses adding PSS-R support |
I am trying to migrate a libtomcrypt based C program, which performs the following operations:
It uses the following buffers:
der_pub_key[u8; ...]
enc_data[u8; ...]
enc_aes_key[u8; 128]
enc_rsa_sig[u8; 128]
label[u8; 4]
nonce[u8; 16]
tag[u8; 16]
It executes the following methods (+ their logical equivalents in RustCrypto):
rsa::RsaPublicKey::from_pkcs1_der
rsa::RsaPublicKey::raw_encryption_primitive
rsa::oaep::decrypt_inner
w/opriv_key.raw_decryption_primitive
eax::Eax::<aes::Aes128>::decrypt
rsa::RsaPublicKey::raw_encryption_primitive
rsa::pss::emsa_pss_verify
I replicated the decrypted data & signature verification by ripping out some of the RustCrypto/RSA crate code, because I could not figure out how to use it otherwise:
Issue 1: RustCrypto does not allow public RSA keys to decrypt data
Step 2 & 3 should be combinable into:
rsa::RsaPublicKey::decrypt(enc_aes_key, label, OAEP<SHA256>)
- step 2 is implemented inrsa::RsaPublicKey
, but step 3 is only implemented inrsa::RsaPrivateKey
.rsa::RsaPublicKey
does not expose adecrypt
method, which is possible with libtomcrypt, and OpenSSL seems to support that as well.I copied and combined the code of
rsa::RsaPublicKey::raw_encryption_primitive
andrsa::oaep::decrypt_inner
(without thepriv_key.raw_decryption_primitive
part), to mimic the C program behaviour.Issue 2: RustCrypto verification steps differ from libtomcrypt
Step 5 & 6 can be combined into:
rsa::RsaPublicKey::verify(tag, rsa_sig, PSS<SHA256>)
. But it fails at the first validation step inrsa::pss::emsa_pss_verify
:In my case it equates to
16 != 32
, asm_hash
is thetag[u8; 16]
buffer of the C program, which is used for both AES-128 and RSA with SHA2-256 (hash
is SHA2-256). Changing the condition toif m_hash.len() > h_len
, which could be a valid interpretation of the"1. If the length of M is greater than [..]"
RFC-8017 description, the check and all other subsequent checks pass and attest the validity of the data, like the C program does. Though that interpretation contradicts"2. [..] string of length hLen"
as far as I understand.I think OpenSSL does not provide a possibility to set an explicit length (like
16
) either, so I guess it assumes32
as well. The OpenSSL Python version explicitly mentions, that they have no way of checking the condition. libtomcrypt did not enforce this for the authors of the C program the way RustCrypto does for me, so I need to copy and modify thersa::RsaPublicKey::verify
code.I can not judge whether this is an issue with libtomcrypt checking too little, or RustCrypto checking too much.
Both issues would also affect the Golang code RustCrypto was inspired by.
The text was updated successfully, but these errors were encountered: