rsa/oaep/
decrypting_key.rs1use super::decrypt_digest;
2use crate::{
3 dummy_rng::DummyRng,
4 traits::{Decryptor, RandomizedDecryptor},
5 Result, RsaPrivateKey,
6};
7use alloc::{boxed::Box, vec::Vec};
8use core::marker::PhantomData;
9use digest::{Digest, FixedOutputReset};
10use rand_core::CryptoRng;
11#[cfg(feature = "serde")]
12use serde::{Deserialize, Serialize};
13use zeroize::ZeroizeOnDrop;
14
15#[derive(Debug, Clone)]
19#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
20pub struct DecryptingKey<D, MGD = D>
21where
22 D: Digest,
23 MGD: Digest + FixedOutputReset,
24{
25 inner: RsaPrivateKey,
26 label: Option<Box<[u8]>>,
27 phantom: PhantomData<D>,
28 mg_phantom: PhantomData<MGD>,
29}
30
31impl<D, MGD> DecryptingKey<D, MGD>
32where
33 D: Digest,
34 MGD: Digest + FixedOutputReset,
35{
36 pub fn new(key: RsaPrivateKey) -> Self {
38 Self {
39 inner: key,
40 label: None,
41 phantom: Default::default(),
42 mg_phantom: Default::default(),
43 }
44 }
45
46 pub fn new_with_label<S: Into<Box<[u8]>>>(key: RsaPrivateKey, label: S) -> Self {
48 Self {
49 inner: key,
50 label: Some(label.into()),
51 phantom: Default::default(),
52 mg_phantom: Default::default(),
53 }
54 }
55}
56
57impl<D, MGD> Decryptor for DecryptingKey<D, MGD>
58where
59 D: Digest,
60 MGD: Digest + FixedOutputReset,
61{
62 fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>> {
63 decrypt_digest::<DummyRng, D, MGD>(None, &self.inner, ciphertext, self.label.clone())
64 }
65}
66
67impl<D, MGD> RandomizedDecryptor for DecryptingKey<D, MGD>
68where
69 D: Digest,
70 MGD: Digest + FixedOutputReset,
71{
72 fn decrypt_with_rng<R: CryptoRng + ?Sized>(
73 &self,
74 rng: &mut R,
75 ciphertext: &[u8],
76 ) -> Result<Vec<u8>> {
77 decrypt_digest::<_, D, MGD>(Some(rng), &self.inner, ciphertext, self.label.clone())
78 }
79}
80
81impl<D, MGD> ZeroizeOnDrop for DecryptingKey<D, MGD>
82where
83 D: Digest,
84 MGD: Digest + FixedOutputReset,
85{
86}
87
88impl<D, MGD> PartialEq for DecryptingKey<D, MGD>
89where
90 D: Digest,
91 MGD: Digest + FixedOutputReset,
92{
93 fn eq(&self, other: &Self) -> bool {
94 self.inner == other.inner && self.label == other.label
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 #[test]
101 #[cfg(all(feature = "hazmat", feature = "serde"))]
102 fn test_serde() {
103 use super::*;
104 use rand::rngs::ChaCha8Rng;
105 use rand_core::SeedableRng;
106 use serde_test::{assert_tokens, Configure, Token};
107 use sha2::Sha256;
108
109 let mut rng = ChaCha8Rng::from_seed([42; 32]);
110 let decrypting_key = DecryptingKey::<Sha256>::new(
111 RsaPrivateKey::new_unchecked(&mut rng, 64).expect("failed to generate key"),
112 );
113
114 let tokens = [
115 Token::Struct {
116 name: "DecryptingKey",
117 len: 4,
118 },
119 Token::Str("inner"),
120 Token::Str(concat!(
121 "3056020100300d06092a864886f70d010101050004423040020100020900ab",
122 "240c3361d02e370203010001020811e54a15259d22f9020500ceff5cf30205",
123 "00d3a7aaad020500ccaddf17020500cb529d3d020500bb526d6f"
124 )),
125 Token::Str("label"),
126 Token::None,
127 Token::Str("phantom"),
128 Token::UnitStruct {
129 name: "PhantomData",
130 },
131 Token::Str("mg_phantom"),
132 Token::UnitStruct {
133 name: "PhantomData",
134 },
135 Token::StructEnd,
136 ];
137 assert_tokens(&decrypting_key.readable(), &tokens);
138 }
139}