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