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