Coverage Report

Created: 2025-08-11 06:51

/rust/registry/src/index.crates.io-6f17d22bba15001f/aws-lc-rs-1.13.0/src/rsa/encryption.rs
Line
Count
Source (jump to first uncovered line)
1
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
// SPDX-License-Identifier: Apache-2.0 OR ISC
3
4
pub(super) mod oaep;
5
pub(super) mod pkcs1;
6
7
use super::key::{generate_rsa_key, is_rsa_key};
8
use super::{encoding, KeySize};
9
use crate::aws_lc::{EVP_PKEY, EVP_PKEY_RSA};
10
use crate::encoding::{AsDer, Pkcs8V1Der, PublicKeyX509Der};
11
use crate::error::{KeyRejected, Unspecified};
12
use crate::pkcs8::Version;
13
use crate::ptr::LcPtr;
14
use core::fmt::Debug;
15
16
/// RSA Encryption Algorithm Identifier
17
#[allow(clippy::module_name_repetitions)]
18
#[derive(Debug, Clone, Copy, PartialEq)]
19
#[non_exhaustive]
20
pub enum EncryptionAlgorithmId {
21
    /// RSA-OAEP with SHA1 Hash and SHA1 MGF1
22
    OaepSha1Mgf1sha1,
23
24
    /// RSA-OAEP with SHA256 Hash and SHA256 MGF1
25
    OaepSha256Mgf1sha256,
26
27
    /// RSA-OAEP with SHA384 Hash and SHA384 MGF1
28
    OaepSha384Mgf1sha384,
29
30
    /// RSA-OAEP with SHA512 Hash and SHA512 MGF1
31
    OaepSha512Mgf1sha512,
32
}
33
34
/// An RSA private key used for decrypting ciphertext encrypted by a [`PublicEncryptingKey`].
35
pub struct PrivateDecryptingKey(LcPtr<EVP_PKEY>);
36
37
impl PrivateDecryptingKey {
38
0
    fn new(evp_pkey: LcPtr<EVP_PKEY>) -> Result<Self, Unspecified> {
39
0
        Self::validate_key(&evp_pkey)?;
40
0
        Ok(Self(evp_pkey))
41
0
    }
42
43
0
    fn validate_key(key: &LcPtr<EVP_PKEY>) -> Result<(), Unspecified> {
44
0
        if !is_rsa_key(key) {
45
0
            return Err(Unspecified);
46
0
        }
47
0
        match key.key_size_bits() {
48
0
            2048..=8192 => Ok(()),
49
0
            _ => Err(Unspecified),
50
        }
51
0
    }
52
53
    /// Generate a new RSA private key pair for use with asymmetrical encryption.
54
    ///
55
    /// Supports the following key sizes:
56
    /// * `KeySize::Rsa2048`
57
    /// * `KeySize::Rsa3072`
58
    /// * `KeySize::Rsa4096`
59
    /// * `KeySize::Rsa8192`
60
    ///
61
    /// # Errors
62
    /// * `Unspecified` for any error that occurs during the generation of the RSA keypair.
63
0
    pub fn generate(size: KeySize) -> Result<Self, Unspecified> {
64
0
        let key = generate_rsa_key(size.bits())?;
65
0
        Self::new(key)
66
0
    }
67
68
    /// Generate a new RSA private key pair for use with asymmetrical encryption.
69
    ///
70
    /// Supports the following key sizes:
71
    /// * `KeySize::Rsa2048`
72
    /// * `KeySize::Rsa3072`
73
    /// * `KeySize::Rsa4096`
74
    /// * `KeySize::Rsa8192`
75
    ///
76
    /// ## Deprecated
77
    /// This is equivalent to `KeyPair::generate`.
78
    ///
79
    /// # Errors
80
    /// * `Unspecified` for any error that occurs during the generation of the RSA keypair.
81
    #[cfg(feature = "fips")]
82
    #[deprecated]
83
    pub fn generate_fips(size: KeySize) -> Result<Self, Unspecified> {
84
        Self::generate(size)
85
    }
86
87
    /// Construct a `PrivateDecryptingKey` from the provided PKCS#8 (v1) document.
88
    ///
89
    /// Supports RSA key sizes between 2048 and 8192 (inclusive).
90
    ///
91
    /// # Errors
92
    /// * `Unspecified` for any error that occurs during deserialization of this key from PKCS#8.
93
0
    pub fn from_pkcs8(pkcs8: &[u8]) -> Result<Self, KeyRejected> {
94
0
        let key = LcPtr::<EVP_PKEY>::parse_rfc5208_private_key(pkcs8, EVP_PKEY_RSA)?;
95
0
        Ok(Self::new(key)?)
96
0
    }
97
98
    /// Returns a boolean indicator if this RSA key is an approved FIPS 140-3 key.
99
    #[cfg(feature = "fips")]
100
    #[must_use]
101
    pub fn is_valid_fips_key(&self) -> bool {
102
        super::key::is_valid_fips_key(&self.0)
103
    }
104
105
    /// Returns the RSA signature size in bytes.
106
    #[must_use]
107
0
    pub fn key_size_bytes(&self) -> usize {
108
0
        self.0.signature_size_bytes()
109
0
    }
110
111
    /// Returns the RSA key size in bits.
112
    #[must_use]
113
0
    pub fn key_size_bits(&self) -> usize {
114
0
        self.0.key_size_bits()
115
0
    }
116
117
    /// Retrieves the `PublicEncryptingKey` corresponding with this `PrivateDecryptingKey`.
118
    #[must_use]
119
    #[allow(clippy::missing_panics_doc)]
120
0
    pub fn public_key(&self) -> PublicEncryptingKey {
121
0
        PublicEncryptingKey::new(self.0.clone()).expect(
122
0
            "PublicEncryptingKey key size to be supported by PrivateDecryptingKey key sizes",
123
0
        )
124
0
    }
125
}
126
127
impl Debug for PrivateDecryptingKey {
128
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
129
0
        f.debug_tuple("PrivateDecryptingKey").finish()
130
0
    }
131
}
132
133
impl AsDer<Pkcs8V1Der<'static>> for PrivateDecryptingKey {
134
0
    fn as_der(&self) -> Result<Pkcs8V1Der<'static>, Unspecified> {
135
0
        Ok(Pkcs8V1Der::new(
136
0
            self.0.marshal_rfc5208_private_key(Version::V1)?,
137
        ))
138
0
    }
139
}
140
141
impl Clone for PrivateDecryptingKey {
142
0
    fn clone(&self) -> Self {
143
0
        Self(self.0.clone())
144
0
    }
145
}
146
147
/// An RSA public key used for encrypting plaintext that is decrypted by a [`PrivateDecryptingKey`].
148
pub struct PublicEncryptingKey(LcPtr<EVP_PKEY>);
149
150
impl PublicEncryptingKey {
151
0
    pub(crate) fn new(evp_pkey: LcPtr<EVP_PKEY>) -> Result<Self, Unspecified> {
152
0
        Self::validate_key(&evp_pkey)?;
153
0
        Ok(Self(evp_pkey))
154
0
    }
155
156
0
    fn validate_key(key: &LcPtr<EVP_PKEY>) -> Result<(), Unspecified> {
157
0
        if !is_rsa_key(key) {
158
0
            return Err(Unspecified);
159
0
        }
160
0
        match key.key_size_bits() {
161
0
            2048..=8192 => Ok(()),
162
0
            _ => Err(Unspecified),
163
        }
164
0
    }
165
166
    /// Construct a `PublicEncryptingKey` from X.509 `SubjectPublicKeyInfo` DER encoded bytes.
167
    ///
168
    /// # Errors
169
    /// * `Unspecified` for any error that occurs deserializing from bytes.
170
0
    pub fn from_der(value: &[u8]) -> Result<Self, KeyRejected> {
171
0
        Ok(Self(encoding::rfc5280::decode_public_key_der(value)?))
172
0
    }
173
174
    /// Returns the RSA signature size in bytes.
175
    #[must_use]
176
0
    pub fn key_size_bytes(&self) -> usize {
177
0
        self.0.signature_size_bytes()
178
0
    }
179
180
    /// Returns the RSA key size in bits.
181
    #[must_use]
182
0
    pub fn key_size_bits(&self) -> usize {
183
0
        self.0.key_size_bits()
184
0
    }
185
}
186
187
impl Debug for PublicEncryptingKey {
188
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
189
0
        f.debug_tuple("PublicEncryptingKey").finish()
190
0
    }
191
}
192
193
impl Clone for PublicEncryptingKey {
194
0
    fn clone(&self) -> Self {
195
0
        Self(self.0.clone())
196
0
    }
197
}
198
199
impl AsDer<PublicKeyX509Der<'static>> for PublicEncryptingKey {
200
    /// Serialize this `PublicEncryptingKey` to a X.509 `SubjectPublicKeyInfo` structure as DER encoded bytes.
201
    ///
202
    /// # Errors
203
    /// * `Unspecified` for any error that occurs serializing to bytes.
204
0
    fn as_der(&self) -> Result<PublicKeyX509Der<'static>, Unspecified> {
205
0
        encoding::rfc5280::encode_public_key_der(&self.0)
206
0
    }
207
}