1 //! Functionality related to RSA.
2
3 use super::{KeyMaterial, KeySizeInBits, OpaqueOr, RsaExponent};
4 use crate::{km_err, tag, try_to_vec, Error, FallibleAllocExt};
5 use alloc::vec::Vec;
6 use der::{Decode, Encode};
7 use kmr_wire::keymint::{Digest, KeyParam, PaddingMode};
8 use pkcs1::RsaPrivateKey;
9 use spki::{AlgorithmIdentifier, SubjectPublicKeyInfo};
10 use zeroize::ZeroizeOnDrop;
11
12 /// Overhead for PKCS#1 v1.5 signature padding of undigested messages. Digested messages have
13 /// additional overhead, for the digest algorithmIdentifier required by PKCS#1.
14 pub const PKCS1_UNDIGESTED_SIGNATURE_PADDING_OVERHEAD: usize = 11;
15
16 /// OID value for PKCS#1-encoded RSA keys held in PKCS#8 and X.509; see RFC 3447 A.1.
17 pub const X509_OID: pkcs8::ObjectIdentifier =
18 pkcs8::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.1");
19
20 /// OID value for PKCS#1 signature with SHA-256 and RSA, see RFC 4055 s5.
21 pub const SHA256_PKCS1_SIGNATURE_OID: pkcs8::ObjectIdentifier =
22 pkcs8::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.11");
23
24 /// An RSA key, in the form of an ASN.1 DER encoding of an PKCS#1 `RSAPrivateKey` structure,
25 /// as specified by RFC 3447 sections A.1.2 and 3.2:
26 ///
27 /// ```asn1
28 /// RSAPrivateKey ::= SEQUENCE {
29 /// version Version,
30 /// modulus INTEGER, -- n
31 /// publicExponent INTEGER, -- e
32 /// privateExponent INTEGER, -- d
33 /// prime1 INTEGER, -- p
34 /// prime2 INTEGER, -- q
35 /// exponent1 INTEGER, -- d mod (p-1)
36 /// exponent2 INTEGER, -- d mod (q-1)
37 /// coefficient INTEGER, -- (inverse of q) mod p
38 /// otherPrimeInfos OtherPrimeInfos OPTIONAL
39 /// }
40 ///
41 /// OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
42 ///
43 /// OtherPrimeInfo ::= SEQUENCE {
44 /// prime INTEGER, -- ri
45 /// exponent INTEGER, -- di
46 /// coefficient INTEGER -- ti
47 /// }
48 /// ```
49 #[derive(Clone, PartialEq, Eq, ZeroizeOnDrop)]
50 pub struct Key(pub Vec<u8>);
51
52 impl Key {
53 /// Return the `subjectPublicKey` that holds an ASN.1 DER-encoded `SEQUENCE`
54 /// as per RFC 3279 section 2.3.1:
55 /// ```asn1
56 /// RSAPublicKey ::= SEQUENCE {
57 /// modulus INTEGER, -- n
58 /// publicExponent INTEGER } -- e
59 /// ```
subject_public_key(&self) -> Result<Vec<u8>, Error>60 pub fn subject_public_key(&self) -> Result<Vec<u8>, Error> {
61 let rsa_pvt_key = RsaPrivateKey::from_der(self.0.as_slice())?;
62 let rsa_pub_key = rsa_pvt_key.public_key();
63 let mut encoded_data = Vec::<u8>::new();
64 rsa_pub_key.encode_to_vec(&mut encoded_data)?;
65 Ok(encoded_data)
66 }
67
68 /// Size of the key in bytes.
size(&self) -> usize69 pub fn size(&self) -> usize {
70 let rsa_pvt_key = match RsaPrivateKey::from_der(self.0.as_slice()) {
71 Ok(k) => k,
72 Err(e) => {
73 log::error!("failed to determine RSA key length: {:?}", e);
74 return 0;
75 }
76 };
77 let len = u32::from(rsa_pvt_key.modulus.len());
78 len as usize
79 }
80 }
81
82 impl OpaqueOr<Key> {
83 /// Encode into `buf` the public key information as an ASN.1 DER encodable
84 /// `SubjectPublicKeyInfo`, as described in RFC 5280 section 4.1.
85 ///
86 /// ```asn1
87 /// SubjectPublicKeyInfo ::= SEQUENCE {
88 /// algorithm AlgorithmIdentifier,
89 /// subjectPublicKey BIT STRING }
90 ///
91 /// AlgorithmIdentifier ::= SEQUENCE {
92 /// algorithm OBJECT IDENTIFIER,
93 /// parameters ANY DEFINED BY algorithm OPTIONAL }
94 /// ```
95 ///
96 /// For RSA keys, the contents are described in RFC 3279 section 2.3.1.
97 ///
98 /// - The `AlgorithmIdentifier` has an algorithm OID of 1.2.840.113549.1.1.1.
99 /// - The `AlgorithmIdentifier` has `NULL` parameters.
100 /// - The `subjectPublicKey` bit string holds an ASN.1 DER-encoded `SEQUENCE`:
101 /// ```asn1
102 /// RSAPublicKey ::= SEQUENCE {
103 /// modulus INTEGER, -- n
104 /// publicExponent INTEGER } -- e
105 /// ```
subject_public_key_info<'a>( &'a self, buf: &'a mut Vec<u8>, rsa: &dyn super::Rsa, ) -> Result<SubjectPublicKeyInfo<'a>, Error>106 pub fn subject_public_key_info<'a>(
107 &'a self,
108 buf: &'a mut Vec<u8>,
109 rsa: &dyn super::Rsa,
110 ) -> Result<SubjectPublicKeyInfo<'a>, Error> {
111 let pub_key = rsa.subject_public_key(self)?;
112 buf.try_extend_from_slice(&pub_key)?;
113 Ok(SubjectPublicKeyInfo {
114 algorithm: AlgorithmIdentifier { oid: X509_OID, parameters: Some(der::AnyRef::NULL) },
115 subject_public_key: buf,
116 })
117 }
118 }
119
120 /// RSA decryption mode.
121 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
122 pub enum DecryptionMode {
123 NoPadding,
124 OaepPadding { msg_digest: Digest, mgf_digest: Digest },
125 Pkcs1_1_5Padding,
126 }
127
128 impl DecryptionMode {
129 /// Determine the [`DecryptionMode`] from parameters.
new(params: &[KeyParam]) -> Result<Self, Error>130 pub fn new(params: &[KeyParam]) -> Result<Self, Error> {
131 let padding = tag::get_padding_mode(params)?;
132 match padding {
133 PaddingMode::None => Ok(DecryptionMode::NoPadding),
134 PaddingMode::RsaOaep => {
135 let msg_digest = tag::get_digest(params)?;
136 let mgf_digest = tag::get_mgf_digest(params)?;
137 Ok(DecryptionMode::OaepPadding { msg_digest, mgf_digest })
138 }
139 PaddingMode::RsaPkcs115Encrypt => Ok(DecryptionMode::Pkcs1_1_5Padding),
140 _ => Err(km_err!(
141 UnsupportedPaddingMode,
142 "padding mode {:?} not supported for RSA decryption",
143 padding
144 )),
145 }
146 }
147 }
148
149 /// RSA signature mode.
150 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
151 pub enum SignMode {
152 NoPadding,
153 PssPadding(Digest),
154 Pkcs1_1_5Padding(Digest),
155 }
156
157 impl SignMode {
158 /// Determine the [`SignMode`] from parameters.
new(params: &[KeyParam]) -> Result<Self, Error>159 pub fn new(params: &[KeyParam]) -> Result<Self, Error> {
160 let padding = tag::get_padding_mode(params)?;
161 match padding {
162 PaddingMode::None => Ok(SignMode::NoPadding),
163 PaddingMode::RsaPss => {
164 let digest = tag::get_digest(params)?;
165 Ok(SignMode::PssPadding(digest))
166 }
167 PaddingMode::RsaPkcs115Sign => {
168 let digest = tag::get_digest(params)?;
169 Ok(SignMode::Pkcs1_1_5Padding(digest))
170 }
171 _ => Err(km_err!(
172 UnsupportedPaddingMode,
173 "padding mode {:?} not supported for RSA signing",
174 padding
175 )),
176 }
177 }
178 }
179
180 /// Import an RSA key in PKCS#8 format, also returning the key size in bits and public exponent.
import_pkcs8_key(data: &[u8]) -> Result<(KeyMaterial, KeySizeInBits, RsaExponent), Error>181 pub fn import_pkcs8_key(data: &[u8]) -> Result<(KeyMaterial, KeySizeInBits, RsaExponent), Error> {
182 let key_info = pkcs8::PrivateKeyInfo::try_from(data)
183 .map_err(|_| km_err!(InvalidArgument, "failed to parse PKCS#8 RSA key"))?;
184 if key_info.algorithm.oid != X509_OID {
185 return Err(km_err!(
186 InvalidArgument,
187 "unexpected OID {:?} for PKCS#1 RSA key import",
188 key_info.algorithm.oid
189 ));
190 }
191 // For RSA, the inner private key is an ASN.1 `RSAPrivateKey`, as per PKCS#1 (RFC 3447 A.1.2).
192 import_pkcs1_key(key_info.private_key)
193 }
194
195 /// Import an RSA key in PKCS#1 format, also returning the key size in bits and public exponent.
import_pkcs1_key( private_key: &[u8], ) -> Result<(KeyMaterial, KeySizeInBits, RsaExponent), Error>196 pub fn import_pkcs1_key(
197 private_key: &[u8],
198 ) -> Result<(KeyMaterial, KeySizeInBits, RsaExponent), Error> {
199 let key = Key(try_to_vec(private_key)?);
200
201 // Need to parse it to find size/exponent.
202 let parsed_key = pkcs1::RsaPrivateKey::try_from(private_key)
203 .map_err(|_| km_err!(InvalidArgument, "failed to parse inner PKCS#1 key"))?;
204 let key_size = parsed_key.modulus.as_bytes().len() as u32 * 8;
205
206 let pub_exponent_bytes = parsed_key.public_exponent.as_bytes();
207 if pub_exponent_bytes.len() > 8 {
208 return Err(km_err!(
209 InvalidArgument,
210 "public exponent of length {} too big",
211 pub_exponent_bytes.len()
212 ));
213 }
214 let offset = 8 - pub_exponent_bytes.len();
215 let mut pub_exponent_arr = [0u8; 8];
216 pub_exponent_arr[offset..].copy_from_slice(pub_exponent_bytes);
217 let pub_exponent = u64::from_be_bytes(pub_exponent_arr);
218
219 Ok((KeyMaterial::Rsa(key.into()), KeySizeInBits(key_size), RsaExponent(pub_exponent)))
220 }
221