Skip to main content

rsa/pkcs1v15/
encrypting_key.rs

1use super::encrypt_into;
2use crate::{
3    key::GenericRsaPublicKey,
4    traits::{
5        modular::{CtModulusParams, ModulusParams},
6        PublicKeyParts, RandomizedEncryptor, UnsignedModularInt,
7    },
8    Result,
9};
10#[cfg(feature = "alloc")]
11use alloc::vec::Vec;
12#[cfg(feature = "alloc")]
13use crypto_bigint::{modular::BoxedMontyParams, BoxedUint};
14use rand_core::CryptoRng;
15#[cfg(feature = "serde")]
16use serde::{Deserialize, Serialize};
17
18/// Encryption key for PKCS#1 v1.5 encryption as described in [RFC8017 § 7.2].
19///
20/// [RFC8017 § 7.2]: https://datatracker.ietf.org/doc/html/rfc8017#section-7.2
21#[derive(Debug, Clone, PartialEq)]
22#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
23#[cfg_attr(
24    feature = "serde",
25    serde(bound(
26        serialize = "GenericRsaPublicKey<T, M>: Serialize",
27        deserialize = "GenericRsaPublicKey<T, M>: serde::de::DeserializeOwned"
28    ))
29)]
30pub struct GenericEncryptingKey<T, M>
31where
32    T: UnsignedModularInt,
33    M: ModulusParams<Modulus = T>,
34{
35    pub(super) inner: GenericRsaPublicKey<T, M>,
36}
37
38/// Boxed PKCS#1 v1.5 encrypting key alias.
39#[cfg(feature = "alloc")]
40pub type EncryptingKey = GenericEncryptingKey<BoxedUint, BoxedMontyParams>;
41
42impl<T, M> GenericEncryptingKey<T, M>
43where
44    T: UnsignedModularInt,
45    M: ModulusParams<Modulus = T>,
46{
47    /// Create a new encrypting key from an RSA public key.
48    pub fn new(key: GenericRsaPublicKey<T, M>) -> Self {
49        Self { inner: key }
50    }
51}
52
53impl<T, M> RandomizedEncryptor for GenericEncryptingKey<T, M>
54where
55    T: UnsignedModularInt,
56    M: CtModulusParams<Modulus = T>,
57{
58    fn encrypt_with_rng_into<'a, R: rand_core::TryCryptoRng + ?Sized>(
59        &self,
60        rng: &mut R,
61        msg: &[u8],
62        storage: &'a mut [u8],
63    ) -> Result<&'a [u8]> {
64        encrypt_into(rng, &self.inner, msg, storage)
65    }
66
67    #[cfg(feature = "alloc")]
68    fn encrypt_with_rng<R: CryptoRng + ?Sized>(&self, rng: &mut R, msg: &[u8]) -> Result<Vec<u8>> {
69        let mut storage = vec![0u8; self.inner.size()];
70        let ciphertext = encrypt_into(rng, &self.inner, msg, &mut storage)?;
71        Ok(ciphertext.to_vec())
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    #[test]
78    #[cfg(all(feature = "hazmat", feature = "serde", feature = "keygen"))]
79    fn test_serde() {
80        use super::*;
81        use crate::RsaPrivateKey;
82        use rand::rngs::ChaCha8Rng;
83        use rand_core::SeedableRng;
84        use serde_test::{assert_tokens, Configure, Token};
85
86        let mut rng = ChaCha8Rng::from_seed([42; 32]);
87        let priv_key = RsaPrivateKey::new_unchecked(&mut rng, 64).expect("failed to generate key");
88        let encrypting_key = GenericEncryptingKey::new(priv_key.to_public_key());
89
90        let tokens = [
91            Token::Struct {
92                name: "GenericEncryptingKey",
93                len: 1,
94            },
95            Token::Str("inner"),
96            Token::Str(
97                "3024300d06092a864886f70d01010105000313003010020900ab240c3361d02e370203010001",
98            ),
99            Token::StructEnd,
100        ];
101        assert_tokens(&encrypting_key.clone().readable(), &tokens);
102    }
103}