Skip to main content

rsa/pkcs1v15/
encrypting_key.rs

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