While working on yubikey-piv I was testing the RSA logic by implementing OAEP around it. What I ended up doing was copying in all the logic from #18, and replacing:
letmut em = {letmut c = BigUint::from_bytes_be(ciphertext);letmut m = internals::decrypt(rng, priv_key,&c)?;let em = internals::left_pad(&m.to_bytes_be(), k);
c.zeroize();
m.zeroize();
em
};with
letmut em = {let m = yubikey.decrypt_data(&ciphertext, algorithm, slot).unwrap();// I forgot to check if the padding was actually necessaryleft_pad(&m, k)};It seems like the way to achieve this more generally (across all decryption schemes) would be with a trait of the form:
traitPrivateKey{/// Do NOT use directly! Only for implementors.fnraw_decryption_primitive<R:Rng>(&self,rng:Option<&mutR>,ciphertext:&[u8],) -> Result<Vec<u8>>;/// Decrypt the given message.fndecrypt(&self,padding:PaddingScheme,ciphertext:&[u8]) -> Result<Vec<u8>>{
...}/// Decrypt the given message./// Uses `rng` to blind the decryption process.pubfndecrypt_blinded<R:Rng>(&self,rng:&mutR,padding:PaddingScheme,ciphertext:&[u8],) -> Result<Vec<u8>>{
...}fn decrypt_oaep(...) -> Result<...> {
oaep::decrypt(...)}}implPrivateKey for RSAPrivateKey{fnraw_decryption_primitive<R:Rng>(&self,rng:Option<&mutR>,ciphertext:&[u8],) -> Result<Vec<u8>>{letmut c = BigUint::from_bytes_be(ciphertext);letmut m = internals::decrypt(rng, priv_key,&c)?;let em = internals::left_pad(&m.to_bytes_be(), k);
c.zeroize();
m.zeroize();
em
}}Then in yubikey-piv we could do something like:
structYubiKeyRsaPrivateKey{yubikey:&mutYubiKey,algorithm:AlgorithmId,slot:SlotId,}implPrivateKeyforYubiKeyRsaPrivateKey{fnraw_decryption_primitive<R:Rng>(&self,_rng:Option<&mutR>,ciphertext:&[u8],) -> Result<Vec<u8>>{self.yubikey.decrypt_data(&ciphertext,self.algorithm,self.slot).map_err(|e| e.into())}}Thoughts? The part I dislike about the above sketch is that the raw RSA decryption primitive is exposed in the API, but this needs to happen somewhere if this kind of interoperability and code de-duplication were to happen at all.
While working on
yubikey-pivI was testing the RSA logic by implementing OAEP around it. What I ended up doing was copying in all the logic from #18, and replacing:with
It seems like the way to achieve this more generally (across all decryption schemes) would be with a trait of the form:
Then in
yubikey-pivwe could do something like:Thoughts? The part I dislike about the above sketch is that the raw RSA decryption primitive is exposed in the API, but this needs to happen somewhere if this kind of interoperability and code de-duplication were to happen at all.