1 // Copyright 2015-2016 Brian Smith. 2 // 3 // Permission to use, copy, modify, and/or distribute this software for any 4 // purpose with or without fee is hereby granted, provided that the above 5 // copyright notice and this permission notice appear in all copies. 6 // 7 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES 8 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 10 // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12 // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13 // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 15 use super::super::{keypair, padding::RsaEncoding, public}; 16 17 /// RSA PKCS#1 1.5 signatures. 18 use crate::{ 19 digest, 20 error::{self, KeyRejected}, 21 io::{self, der, der_writer}, 22 rand, signature, 23 }; 24 use alloc::boxed::Box; 25 use core::convert::TryFrom; 26 27 /// An RSA key pair, used for signing. 28 pub struct RsaKeyPair { 29 inner: keypair::RsaKeyPair, 30 public_key: RsaSubjectPublicKey, 31 } 32 33 impl core::fmt::Debug for RsaKeyPair { fmt(&self, fmt: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error>34 fn fmt(&self, fmt: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { 35 self.inner.fmt(fmt) 36 } 37 } 38 39 impl RsaKeyPair { 40 /// Parses an unencrypted PKCS#8-encoded RSA private key. 41 /// 42 /// Only two-prime (not multi-prime) keys are supported. The public modulus 43 /// (n) must be at least 2047 bits. The public modulus must be no larger 44 /// than 4096 bits. It is recommended that the public modulus be exactly 45 /// 2048 or 3072 bits. The public exponent must be at least 65537. 46 /// 47 /// This will generate a 2048-bit RSA private key of the correct form using 48 /// OpenSSL's command line tool: 49 /// 50 /// ```sh 51 /// openssl genpkey -algorithm RSA \ 52 /// -pkeyopt rsa_keygen_bits:2048 \ 53 /// -pkeyopt rsa_keygen_pubexp:65537 | \ 54 /// openssl pkcs8 -topk8 -nocrypt -outform der > rsa-2048-private-key.pk8 55 /// ``` 56 /// 57 /// This will generate a 3072-bit RSA private key of the correct form: 58 /// 59 /// ```sh 60 /// openssl genpkey -algorithm RSA \ 61 /// -pkeyopt rsa_keygen_bits:3072 \ 62 /// -pkeyopt rsa_keygen_pubexp:65537 | \ 63 /// openssl pkcs8 -topk8 -nocrypt -outform der > rsa-3072-private-key.pk8 64 /// ``` 65 /// 66 /// Often, keys generated for use in OpenSSL-based software are stored in 67 /// the Base64 “PEM” format without the PKCS#8 wrapper. Such keys can be 68 /// converted to binary PKCS#8 form using the OpenSSL command line tool like 69 /// this: 70 /// 71 /// ```sh 72 /// openssl pkcs8 -topk8 -nocrypt -outform der \ 73 /// -in rsa-2048-private-key.pem > rsa-2048-private-key.pk8 74 /// ``` 75 /// 76 /// Base64 (“PEM”) PKCS#8-encoded keys can be converted to the binary PKCS#8 77 /// form like this: 78 /// 79 /// ```sh 80 /// openssl pkcs8 -nocrypt -outform der \ 81 /// -in rsa-2048-private-key.pem > rsa-2048-private-key.pk8 82 /// ``` 83 /// 84 /// The private key is validated according to [NIST SP-800-56B rev. 1] 85 /// section 6.4.1.4.3, crt_pkv (Intended Exponent-Creation Method Unknown), 86 /// with the following exceptions: 87 /// 88 /// * Section 6.4.1.2.1, Step 1: Neither a target security level nor an 89 /// expected modulus length is provided as a parameter, so checks 90 /// regarding these expectations are not done. 91 /// * Section 6.4.1.2.1, Step 3: Since neither the public key nor the 92 /// expected modulus length is provided as a parameter, the consistency 93 /// check between these values and the private key's value of n isn't 94 /// done. 95 /// * Section 6.4.1.2.1, Step 5: No primality tests are done, both for 96 /// performance reasons and to avoid any side channels that such tests 97 /// would provide. 98 /// * Section 6.4.1.2.1, Step 6, and 6.4.1.4.3, Step 7: 99 /// * *ring* has a slightly looser lower bound for the values of `p` 100 /// and `q` than what the NIST document specifies. This looser lower 101 /// bound matches what most other crypto libraries do. The check might 102 /// be tightened to meet NIST's requirements in the future. Similarly, 103 /// the check that `p` and `q` are not too close together is skipped 104 /// currently, but may be added in the future. 105 /// - The validity of the mathematical relationship of `dP`, `dQ`, `e` 106 /// and `n` is verified only during signing. Some size checks of `d`, 107 /// `dP` and `dQ` are performed at construction, but some NIST checks 108 /// are skipped because they would be expensive and/or they would leak 109 /// information through side channels. If a preemptive check of the 110 /// consistency of `dP`, `dQ`, `e` and `n` with each other is 111 /// necessary, that can be done by signing any message with the key 112 /// pair. 113 /// 114 /// * `d` is not fully validated, neither at construction nor during 115 /// signing. This is OK as far as *ring*'s usage of the key is 116 /// concerned because *ring* never uses the value of `d` (*ring* always 117 /// uses `p`, `q`, `dP` and `dQ` via the Chinese Remainder Theorem, 118 /// instead). However, *ring*'s checks would not be sufficient for 119 /// validating a key pair for use by some other system; that other 120 /// system must check the value of `d` itself if `d` is to be used. 121 /// 122 /// In addition to the NIST requirements, *ring* requires that `p > q` and 123 /// that `e` must be no more than 33 bits. 124 /// 125 /// See [RFC 5958] and [RFC 3447 Appendix A.1.2] for more details of the 126 /// encoding of the key. 127 /// 128 /// [NIST SP-800-56B rev. 1]: 129 /// http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Br1.pdf 130 /// 131 /// [RFC 3447 Appendix A.1.2]: 132 /// https://tools.ietf.org/html/rfc3447#appendix-A.1.2 133 /// 134 /// [RFC 5958]: 135 /// https://tools.ietf.org/html/rfc5958 from_pkcs8(pkcs8: &[u8]) -> Result<Self, KeyRejected>136 pub fn from_pkcs8(pkcs8: &[u8]) -> Result<Self, KeyRejected> { 137 keypair::RsaKeyPair::from_pkcs8(pkcs8).map(From::from) 138 } 139 140 /// Parses an RSA private key that is not inside a PKCS#8 wrapper. 141 /// 142 /// The private key must be encoded as a binary DER-encoded ASN.1 143 /// `RSAPrivateKey` as described in [RFC 3447 Appendix A.1.2]). In all other 144 /// respects, this is just like `from_pkcs8()`. See the documentation for 145 /// `from_pkcs8()` for more details. 146 /// 147 /// It is recommended to use `from_pkcs8()` (with a PKCS#8-encoded key) 148 /// instead. 149 /// 150 /// [RFC 3447 Appendix A.1.2]: 151 /// https://tools.ietf.org/html/rfc3447#appendix-A.1.2 152 /// 153 /// [NIST SP-800-56B rev. 1]: 154 /// http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Br1.pdf from_der(input: &[u8]) -> Result<Self, KeyRejected>155 pub fn from_der(input: &[u8]) -> Result<Self, KeyRejected> { 156 keypair::RsaKeyPair::from_der(input).map(From::from) 157 } 158 159 /// Returns a reference to the public key. 160 #[inline] public(&self) -> &public::Key161 pub fn public(&self) -> &public::Key { 162 self.inner.public() 163 } 164 165 /// Returns the length in bytes of the key pair's public modulus. 166 /// 167 /// A signature has the same length as the public modulus. 168 #[inline] public_modulus_len(&self) -> usize169 pub fn public_modulus_len(&self) -> usize { 170 self.public().n().len() 171 } 172 } 173 174 impl From<keypair::RsaKeyPair> for RsaKeyPair { from(inner: keypair::RsaKeyPair) -> Self175 fn from(inner: keypair::RsaKeyPair) -> Self { 176 let public_key = RsaSubjectPublicKey::from(inner.public()); 177 Self { inner, public_key } 178 } 179 } 180 181 impl<Public, Private> TryFrom<&keypair::Components<Public, Private>> for RsaKeyPair 182 where 183 Public: AsRef<[u8]> + core::fmt::Debug, 184 Private: AsRef<[u8]>, 185 { 186 type Error = KeyRejected; 187 try_from(components: &keypair::Components<Public, Private>) -> Result<Self, Self::Error>188 fn try_from(components: &keypair::Components<Public, Private>) -> Result<Self, Self::Error> { 189 keypair::RsaKeyPair::try_from(components).map(From::from) 190 } 191 } 192 193 impl signature::KeyPair for RsaKeyPair { 194 type PublicKey = RsaSubjectPublicKey; 195 196 #[inline] public_key(&self) -> &Self::PublicKey197 fn public_key(&self) -> &Self::PublicKey { 198 &self.public_key 199 } 200 } 201 202 /// A serialized RSA public key. 203 #[derive(Clone)] 204 pub struct RsaSubjectPublicKey(Box<[u8]>); 205 206 impl AsRef<[u8]> for RsaSubjectPublicKey { as_ref(&self) -> &[u8]207 fn as_ref(&self) -> &[u8] { 208 self.0.as_ref() 209 } 210 } 211 212 derive_debug_self_as_ref_hex_bytes!(RsaSubjectPublicKey); 213 214 impl From<&public::Key> for RsaSubjectPublicKey { from(key: &public::Key) -> Self215 fn from(key: &public::Key) -> Self { 216 // The public key `n` and `e` are always positive. 217 fn positive(bytes: &[u8]) -> io::Positive { 218 io::Positive::new_non_empty_without_leading_zeros(untrusted::Input::from(bytes)) 219 .unwrap() 220 } 221 222 let n = key.n().to_be_bytes(); 223 let e = key.e().to_be_bytes(); 224 225 let bytes = der_writer::write_all(der::Tag::Sequence, &|output| { 226 der_writer::write_positive_integer(output, &positive(&n)); 227 der_writer::write_positive_integer(output, &positive(&e)); 228 }); 229 RsaSubjectPublicKey(bytes) 230 } 231 } 232 233 impl RsaSubjectPublicKey { 234 /// The public modulus (n). modulus(&self) -> io::Positive235 pub fn modulus(&self) -> io::Positive { 236 // Parsing won't fail because we serialized it ourselves. 237 let (public_key, _exponent) = 238 super::super::parse_public_key(untrusted::Input::from(self.as_ref())).unwrap(); 239 public_key 240 } 241 242 /// The public exponent (e). exponent(&self) -> io::Positive243 pub fn exponent(&self) -> io::Positive { 244 // Parsing won't fail because we serialized it ourselves. 245 let (_public_key, exponent) = 246 super::super::parse_public_key(untrusted::Input::from(self.as_ref())).unwrap(); 247 exponent 248 } 249 } 250 251 impl RsaKeyPair { 252 /// Sign `msg`. `msg` is digested using the digest algorithm from 253 /// `padding_alg` and the digest is then padded using the padding algorithm 254 /// from `padding_alg`. The signature it written into `signature`; 255 /// `signature`'s length must be exactly the length returned by 256 /// `public_modulus_len()`. `rng` may be used to randomize the padding 257 /// (e.g. for PSS). 258 /// 259 /// Many other crypto libraries have signing functions that takes a 260 /// precomputed digest as input, instead of the message to digest. This 261 /// function does *not* take a precomputed digest; instead, `sign` 262 /// calculates the digest itself. 263 /// 264 /// Lots of effort has been made to make the signing operations close to 265 /// constant time to protect the private key from side channel attacks. On 266 /// x86-64, this is done pretty well, but not perfectly. On other 267 /// platforms, it is done less perfectly. sign( &self, padding_alg: &'static dyn RsaEncoding, rng: &dyn rand::SecureRandom, msg: &[u8], signature: &mut [u8], ) -> Result<(), error::Unspecified>268 pub fn sign( 269 &self, 270 padding_alg: &'static dyn RsaEncoding, 271 rng: &dyn rand::SecureRandom, 272 msg: &[u8], 273 signature: &mut [u8], 274 ) -> Result<(), error::Unspecified> { 275 let m_hash = digest::digest(padding_alg.digest_alg(), msg); 276 padding_alg.encode(m_hash, signature, self.public().n().len_bits(), rng)?; 277 self.inner.rsa_private_in_place(signature) 278 } 279 } 280 281 #[cfg(test)] 282 mod tests { 283 // We intentionally avoid `use super::*` so that we are sure to use only 284 // the public API; this ensures that enough of the API is public. 285 use crate::{rand, signature}; 286 use alloc::vec; 287 288 // `KeyPair::sign` requires that the output buffer is the same length as 289 // the public key modulus. Test what happens when it isn't the same length. 290 #[test] test_signature_rsa_pkcs1_sign_output_buffer_len()291 fn test_signature_rsa_pkcs1_sign_output_buffer_len() { 292 // Sign the message "hello, world", using PKCS#1 v1.5 padding and the 293 // SHA256 digest algorithm. 294 const MESSAGE: &[u8] = b"hello, world"; 295 let rng = rand::SystemRandom::new(); 296 297 const PRIVATE_KEY_DER: &[u8] = include_bytes!("signature_rsa_example_private_key.der"); 298 let key_pair = signature::RsaKeyPair::from_der(PRIVATE_KEY_DER).unwrap(); 299 300 // The output buffer is one byte too short. 301 let mut signature = vec![0; key_pair.public().n().len() - 1]; 302 303 assert!(key_pair 304 .sign(&signature::RSA_PKCS1_SHA256, &rng, MESSAGE, &mut signature) 305 .is_err()); 306 307 // The output buffer is the right length. 308 signature.push(0); 309 assert!(key_pair 310 .sign(&signature::RSA_PKCS1_SHA256, &rng, MESSAGE, &mut signature) 311 .is_ok()); 312 313 // The output buffer is one byte too long. 314 signature.push(0); 315 assert!(key_pair 316 .sign(&signature::RSA_PKCS1_SHA256, &rng, MESSAGE, &mut signature) 317 .is_err()); 318 } 319 } 320