rsa/
pkcs1v15.rs

1//! PKCS#1 v1.5 support as described in [RFC8017 § 8.2].
2//!
3//! # Usage
4//!
5//! See [code example in the toplevel rustdoc](../index.html#pkcs1-v15-signatures).
6//!
7//! [RFC8017 § 8.2]: https://datatracker.ietf.org/doc/html/rfc8017#section-8.2
8
9use alloc::vec::Vec;
10use core::fmt::{Debug, Display, Formatter, LowerHex, UpperHex};
11use core::marker::PhantomData;
12use core::ops::Deref;
13use digest::Digest;
14use pkcs8::{AssociatedOid, Document, EncodePrivateKey, EncodePublicKey, SecretDocument};
15use rand_core::{CryptoRng, RngCore};
16#[cfg(feature = "hazmat")]
17use signature::hazmat::{PrehashSigner, PrehashVerifier};
18use signature::{
19    DigestSigner, DigestVerifier, RandomizedDigestSigner, RandomizedSigner,
20    Signature as SignSignature, Signer, Verifier,
21};
22use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
23use zeroize::Zeroizing;
24
25use crate::dummy_rng::DummyRng;
26use crate::errors::{Error, Result};
27use crate::key::{self, PrivateKey, PublicKey};
28use crate::{RsaPrivateKey, RsaPublicKey};
29
30/// PKCS#1 v1.5 signatures as described in [RFC8017 § 8.2].
31///
32/// [RFC8017 § 8.2]: https://datatracker.ietf.org/doc/html/rfc8017#section-8.2
33#[derive(Clone)]
34pub struct Signature {
35    bytes: Vec<u8>,
36}
37
38impl signature::Signature for Signature {
39    fn from_bytes(bytes: &[u8]) -> signature::Result<Self> {
40        Ok(Signature {
41            bytes: bytes.into(),
42        })
43    }
44
45    fn as_bytes(&self) -> &[u8] {
46        self.bytes.as_slice()
47    }
48}
49
50impl From<Vec<u8>> for Signature {
51    fn from(bytes: Vec<u8>) -> Self {
52        Self { bytes }
53    }
54}
55
56impl Deref for Signature {
57    type Target = [u8];
58
59    fn deref(&self) -> &Self::Target {
60        self.as_bytes()
61    }
62}
63
64impl PartialEq for Signature {
65    fn eq(&self, other: &Self) -> bool {
66        self.as_bytes() == other.as_bytes()
67    }
68}
69
70impl Eq for Signature {}
71
72impl Debug for Signature {
73    fn fmt(&self, fmt: &mut Formatter<'_>) -> core::result::Result<(), core::fmt::Error> {
74        fmt.debug_list().entries(self.as_bytes().iter()).finish()
75    }
76}
77
78impl AsRef<[u8]> for Signature {
79    fn as_ref(&self) -> &[u8] {
80        self.as_bytes()
81    }
82}
83
84impl LowerHex for Signature {
85    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
86        for byte in self.as_bytes() {
87            write!(f, "{:02x}", byte)?;
88        }
89        Ok(())
90    }
91}
92
93impl UpperHex for Signature {
94    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
95        for byte in self.as_bytes() {
96            write!(f, "{:02X}", byte)?;
97        }
98        Ok(())
99    }
100}
101
102impl Display for Signature {
103    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
104        write!(f, "{:X}", self)
105    }
106}
107
108/// Encrypts the given message with RSA and the padding
109/// scheme from PKCS#1 v1.5.  The message must be no longer than the
110/// length of the public modulus minus 11 bytes.
111#[inline]
112pub(crate) fn encrypt<R: RngCore + CryptoRng, PK: PublicKey>(
113    rng: &mut R,
114    pub_key: &PK,
115    msg: &[u8],
116) -> Result<Vec<u8>> {
117    key::check_public(pub_key)?;
118
119    let k = pub_key.size();
120    if msg.len() > k - 11 {
121        return Err(Error::MessageTooLong);
122    }
123
124    // EM = 0x00 || 0x02 || PS || 0x00 || M
125    let mut em = Zeroizing::new(vec![0u8; k]);
126    em[1] = 2;
127    non_zero_random_bytes(rng, &mut em[2..k - msg.len() - 1]);
128    em[k - msg.len() - 1] = 0;
129    em[k - msg.len()..].copy_from_slice(msg);
130
131    pub_key.raw_encryption_primitive(&em, pub_key.size())
132}
133
134/// Decrypts a plaintext using RSA and the padding scheme from PKCS#1 v1.5.
135///
136/// If an `rng` is passed, it uses RSA blinding to avoid timing side-channel attacks.
137///
138/// Note that whether this function returns an error or not discloses secret
139/// information. If an attacker can cause this function to run repeatedly and
140/// learn whether each instance returned an error then they can decrypt and
141/// forge signatures as if they had the private key. See
142/// `decrypt_session_key` for a way of solving this problem.
143#[inline]
144pub(crate) fn decrypt<R: RngCore + CryptoRng, SK: PrivateKey>(
145    rng: Option<&mut R>,
146    priv_key: &SK,
147    ciphertext: &[u8],
148) -> Result<Vec<u8>> {
149    key::check_public(priv_key)?;
150
151    let (valid, out, index) = decrypt_inner(rng, priv_key, ciphertext)?;
152    if valid == 0 {
153        return Err(Error::Decryption);
154    }
155
156    Ok(out[index as usize..].to_vec())
157}
158
159/// Calculates the signature of hashed using
160/// RSASSA-PKCS1-V1_5-SIGN from RSA PKCS#1 v1.5. Note that `hashed` must
161/// be the result of hashing the input message using the given hash
162/// function. If hash is `None`, hashed is signed directly. This isn't
163/// advisable except for interoperability.
164///
165/// If `rng` is not `None` then RSA blinding will be used to avoid timing
166/// side-channel attacks.
167///
168/// This function is deterministic. Thus, if the set of possible
169/// messages is small, an attacker may be able to build a map from
170/// messages to signatures and identify the signed messages. As ever,
171/// signatures provide authenticity, not confidentiality.
172#[inline]
173pub(crate) fn sign<R: RngCore + CryptoRng, SK: PrivateKey>(
174    rng: Option<&mut R>,
175    priv_key: &SK,
176    prefix: &[u8],
177    hashed: &[u8],
178) -> Result<Vec<u8>> {
179    let hash_len = hashed.len();
180    let t_len = prefix.len() + hashed.len();
181    let k = priv_key.size();
182    if k < t_len + 11 {
183        return Err(Error::MessageTooLong);
184    }
185
186    // EM = 0x00 || 0x01 || PS || 0x00 || T
187    let mut em = vec![0xff; k];
188    em[0] = 0;
189    em[1] = 1;
190    em[k - t_len - 1] = 0;
191    em[k - t_len..k - hash_len].copy_from_slice(prefix);
192    em[k - hash_len..k].copy_from_slice(hashed);
193
194    priv_key.raw_decryption_primitive(rng, &em, priv_key.size())
195}
196
197/// Verifies an RSA PKCS#1 v1.5 signature.
198#[inline]
199pub(crate) fn verify<PK: PublicKey>(
200    pub_key: &PK,
201    prefix: &[u8],
202    hashed: &[u8],
203    sig: &[u8],
204) -> Result<()> {
205    let hash_len = hashed.len();
206    let t_len = prefix.len() + hashed.len();
207    let k = pub_key.size();
208    if k < t_len + 11 {
209        return Err(Error::Verification);
210    }
211
212    let em = pub_key.raw_encryption_primitive(sig, pub_key.size())?;
213
214    // EM = 0x00 || 0x01 || PS || 0x00 || T
215    let mut ok = em[0].ct_eq(&0u8);
216    ok &= em[1].ct_eq(&1u8);
217    ok &= em[k - hash_len..k].ct_eq(hashed);
218    ok &= em[k - t_len..k - hash_len].ct_eq(prefix);
219    ok &= em[k - t_len - 1].ct_eq(&0u8);
220
221    for el in em.iter().skip(2).take(k - t_len - 3) {
222        ok &= el.ct_eq(&0xff)
223    }
224
225    if ok.unwrap_u8() != 1 {
226        return Err(Error::Verification);
227    }
228
229    Ok(())
230}
231
232/// prefix = 0x30 <oid_len + 8 + digest_len> 0x30 <oid_len + 4> 0x06 <oid_len> oid 0x05 0x00 0x04 <digest_len>
233#[inline]
234pub(crate) fn generate_prefix<D>() -> Vec<u8>
235where
236    D: Digest + AssociatedOid,
237{
238    let oid = D::OID.as_bytes();
239    let oid_len = oid.len() as u8;
240    let digest_len = <D as Digest>::output_size() as u8;
241    let mut v = vec![
242        0x30,
243        oid_len + 8 + digest_len,
244        0x30,
245        oid_len + 4,
246        0x6,
247        oid_len,
248    ];
249    v.extend_from_slice(oid);
250    v.extend_from_slice(&[0x05, 0x00, 0x04, digest_len]);
251    v
252}
253
254/// Decrypts ciphertext using `priv_key` and blinds the operation if
255/// `rng` is given. It returns one or zero in valid that indicates whether the
256/// plaintext was correctly structured. In either case, the plaintext is
257/// returned in em so that it may be read independently of whether it was valid
258/// in order to maintain constant memory access patterns. If the plaintext was
259/// valid then index contains the index of the original message in em.
260#[inline]
261fn decrypt_inner<R: RngCore + CryptoRng, SK: PrivateKey>(
262    rng: Option<&mut R>,
263    priv_key: &SK,
264    ciphertext: &[u8],
265) -> Result<(u8, Vec<u8>, u32)> {
266    let k = priv_key.size();
267    if k < 11 {
268        return Err(Error::Decryption);
269    }
270
271    let em = priv_key.raw_decryption_primitive(rng, ciphertext, priv_key.size())?;
272
273    let first_byte_is_zero = em[0].ct_eq(&0u8);
274    let second_byte_is_two = em[1].ct_eq(&2u8);
275
276    // The remainder of the plaintext must be a string of non-zero random
277    // octets, followed by a 0, followed by the message.
278    //   looking_for_index: 1 iff we are still looking for the zero.
279    //   index: the offset of the first zero byte.
280    let mut looking_for_index = 1u8;
281    let mut index = 0u32;
282
283    for (i, el) in em.iter().enumerate().skip(2) {
284        let equals0 = el.ct_eq(&0u8);
285        index.conditional_assign(&(i as u32), Choice::from(looking_for_index) & equals0);
286        looking_for_index.conditional_assign(&0u8, equals0);
287    }
288
289    // The PS padding must be at least 8 bytes long, and it starts two
290    // bytes into em.
291    // TODO: WARNING: THIS MUST BE CONSTANT TIME CHECK:
292    // Ref: https://github.com/dalek-cryptography/subtle/issues/20
293    // This is currently copy & paste from the constant time impl in
294    // go, but very likely not sufficient.
295    let valid_ps = Choice::from((((2i32 + 8i32 - index as i32 - 1i32) >> 31) & 1) as u8);
296    let valid =
297        first_byte_is_zero & second_byte_is_two & Choice::from(!looking_for_index & 1) & valid_ps;
298    index = u32::conditional_select(&0, &(index + 1), valid);
299
300    Ok((valid.unwrap_u8(), em, index))
301}
302
303/// Fills the provided slice with random values, which are guaranteed
304/// to not be zero.
305#[inline]
306fn non_zero_random_bytes<R: RngCore + CryptoRng>(rng: &mut R, data: &mut [u8]) {
307    rng.fill_bytes(data);
308
309    for el in data {
310        if *el == 0u8 {
311            // TODO: break after a certain amount of time
312            while *el == 0u8 {
313                rng.fill_bytes(core::slice::from_mut(el));
314            }
315        }
316    }
317}
318
319/// Signing key for PKCS#1 v1.5 signatures as described in [RFC8017 § 8.2].
320///
321/// [RFC8017 § 8.2]: https://datatracker.ietf.org/doc/html/rfc8017#section-8.2
322#[derive(Debug, Clone)]
323pub struct SigningKey<D>
324where
325    D: Digest,
326{
327    inner: RsaPrivateKey,
328    prefix: Vec<u8>,
329    phantom: PhantomData<D>,
330}
331
332impl<D> SigningKey<D>
333where
334    D: Digest,
335{
336    /// Create a new signing key from the give RSA private key.
337    pub fn new(key: RsaPrivateKey) -> Self {
338        Self {
339            inner: key,
340            prefix: Vec::new(),
341            phantom: Default::default(),
342        }
343    }
344
345    pub(crate) fn key(&self) -> &RsaPrivateKey {
346        &self.inner
347    }
348
349    pub(crate) fn prefix(&self) -> Vec<u8> {
350        self.prefix.clone()
351    }
352}
353
354impl<D> From<RsaPrivateKey> for SigningKey<D>
355where
356    D: Digest,
357{
358    fn from(key: RsaPrivateKey) -> Self {
359        Self::new(key)
360    }
361}
362
363impl<D> From<SigningKey<D>> for RsaPrivateKey
364where
365    D: Digest,
366{
367    fn from(key: SigningKey<D>) -> Self {
368        key.inner
369    }
370}
371
372impl<D> SigningKey<D>
373where
374    D: Digest + AssociatedOid,
375{
376    /// Create a new verifying key with a prefix for the digest `D`.
377    pub fn new_with_prefix(key: RsaPrivateKey) -> Self {
378        Self {
379            inner: key,
380            prefix: generate_prefix::<D>(),
381            phantom: Default::default(),
382        }
383    }
384}
385
386impl<D> AsRef<RsaPrivateKey> for SigningKey<D>
387where
388    D: Digest,
389{
390    fn as_ref(&self) -> &RsaPrivateKey {
391        &self.inner
392    }
393}
394
395impl<D> EncodePrivateKey for SigningKey<D>
396where
397    D: Digest,
398{
399    fn to_pkcs8_der(&self) -> pkcs8::Result<SecretDocument> {
400        self.inner.to_pkcs8_der()
401    }
402}
403
404impl<D> Signer<Signature> for SigningKey<D>
405where
406    D: Digest,
407{
408    fn try_sign(&self, msg: &[u8]) -> signature::Result<Signature> {
409        sign::<DummyRng, _>(None, &self.inner, &self.prefix, &D::digest(msg))
410            .map(|v| v.into())
411            .map_err(|e| e.into())
412    }
413}
414
415impl<D> RandomizedSigner<Signature> for SigningKey<D>
416where
417    D: Digest,
418{
419    fn try_sign_with_rng(
420        &self,
421        mut rng: impl CryptoRng + RngCore,
422        msg: &[u8],
423    ) -> signature::Result<Signature> {
424        sign(Some(&mut rng), &self.inner, &self.prefix, &D::digest(msg))
425            .map(|v| v.into())
426            .map_err(|e| e.into())
427    }
428}
429
430impl<D> DigestSigner<D, Signature> for SigningKey<D>
431where
432    D: Digest,
433{
434    fn try_sign_digest(&self, digest: D) -> signature::Result<Signature> {
435        sign::<DummyRng, _>(None, &self.inner, &self.prefix, &digest.finalize())
436            .map(|v| v.into())
437            .map_err(|e| e.into())
438    }
439}
440
441impl<D> RandomizedDigestSigner<D, Signature> for SigningKey<D>
442where
443    D: Digest,
444{
445    fn try_sign_digest_with_rng(
446        &self,
447        mut rng: impl CryptoRng + RngCore,
448        digest: D,
449    ) -> signature::Result<Signature> {
450        sign(
451            Some(&mut rng),
452            &self.inner,
453            &self.prefix,
454            &digest.finalize(),
455        )
456        .map(|v| v.into())
457        .map_err(|e| e.into())
458    }
459}
460
461#[cfg(feature = "hazmat")]
462impl<D> PrehashSigner<Signature> for SigningKey<D>
463where
464    D: Digest,
465{
466    fn sign_prehash(&self, prehash: &[u8]) -> signature::Result<Signature> {
467        sign::<DummyRng, _>(None, &self.inner, &self.prefix, prehash)
468            .map(|v| v.into())
469            .map_err(|e| e.into())
470    }
471}
472
473/// Verifying key for PKCS#1 v1.5 signatures as described in [RFC8017 § 8.2].
474///
475/// [RFC8017 § 8.2]: https://datatracker.ietf.org/doc/html/rfc8017#section-8.2
476#[derive(Debug, Clone)]
477pub struct VerifyingKey<D>
478where
479    D: Digest,
480{
481    inner: RsaPublicKey,
482    prefix: Vec<u8>,
483    phantom: PhantomData<D>,
484}
485
486impl<D> VerifyingKey<D>
487where
488    D: Digest,
489{
490    /// Create a new verifying key from an RSA public key.
491    pub fn new(key: RsaPublicKey) -> Self {
492        Self {
493            inner: key,
494            prefix: Vec::new(),
495            phantom: Default::default(),
496        }
497    }
498}
499
500impl<D> From<RsaPublicKey> for VerifyingKey<D>
501where
502    D: Digest,
503{
504    fn from(key: RsaPublicKey) -> Self {
505        Self::new(key)
506    }
507}
508
509impl<D> From<VerifyingKey<D>> for RsaPublicKey
510where
511    D: Digest,
512{
513    fn from(key: VerifyingKey<D>) -> Self {
514        key.inner
515    }
516}
517
518impl<D> VerifyingKey<D>
519where
520    D: Digest + AssociatedOid,
521{
522    /// Create a new verifying key with a prefix for the digest `D`.
523    pub fn new_with_prefix(key: RsaPublicKey) -> Self {
524        Self {
525            inner: key,
526            prefix: generate_prefix::<D>(),
527            phantom: Default::default(),
528        }
529    }
530}
531
532impl<D> AsRef<RsaPublicKey> for VerifyingKey<D>
533where
534    D: Digest,
535{
536    fn as_ref(&self) -> &RsaPublicKey {
537        &self.inner
538    }
539}
540
541impl<D> From<SigningKey<D>> for VerifyingKey<D>
542where
543    D: Digest,
544{
545    fn from(key: SigningKey<D>) -> Self {
546        Self {
547            inner: key.key().into(),
548            prefix: key.prefix(),
549            phantom: Default::default(),
550        }
551    }
552}
553
554impl<D> From<&SigningKey<D>> for VerifyingKey<D>
555where
556    D: Digest,
557{
558    fn from(key: &SigningKey<D>) -> Self {
559        Self {
560            inner: key.key().into(),
561            prefix: key.prefix(),
562            phantom: Default::default(),
563        }
564    }
565}
566
567impl<D> Verifier<Signature> for VerifyingKey<D>
568where
569    D: Digest,
570{
571    fn verify(&self, msg: &[u8], signature: &Signature) -> signature::Result<()> {
572        verify(
573            &self.inner,
574            &self.prefix,
575            &D::digest(msg),
576            signature.as_ref(),
577        )
578        .map_err(|e| e.into())
579    }
580}
581
582impl<D> DigestVerifier<D, Signature> for VerifyingKey<D>
583where
584    D: Digest,
585{
586    fn verify_digest(&self, digest: D, signature: &Signature) -> signature::Result<()> {
587        verify(
588            &self.inner,
589            &self.prefix,
590            &digest.finalize(),
591            signature.as_ref(),
592        )
593        .map_err(|e| e.into())
594    }
595}
596
597#[cfg(feature = "hazmat")]
598impl<D> PrehashVerifier<Signature> for VerifyingKey<D>
599where
600    D: Digest,
601{
602    fn verify_prehash(&self, prehash: &[u8], signature: &Signature) -> signature::Result<()> {
603        verify(&self.inner, &self.prefix, prehash, signature.as_ref()).map_err(|e| e.into())
604    }
605}
606
607impl<D> EncodePublicKey for VerifyingKey<D>
608where
609    D: Digest,
610{
611    fn to_public_key_der(&self) -> pkcs8::spki::Result<Document> {
612        self.inner.to_public_key_der()
613    }
614}
615
616#[cfg(test)]
617mod tests {
618    use super::*;
619    use base64ct::{Base64, Encoding};
620    use hex_literal::hex;
621    use num_bigint::BigUint;
622    use num_traits::FromPrimitive;
623    use num_traits::Num;
624    use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng};
625    use sha1::{Digest, Sha1};
626    use sha2::Sha256;
627    use sha3::Sha3_256;
628    use signature::{RandomizedSigner, Signature, Signer, Verifier};
629
630    use crate::{PaddingScheme, PublicKey, PublicKeyParts, RsaPrivateKey, RsaPublicKey};
631
632    #[test]
633    fn test_non_zero_bytes() {
634        for _ in 0..10 {
635            let mut rng = ChaCha8Rng::from_seed([42; 32]);
636            let mut b = vec![0u8; 512];
637            non_zero_random_bytes(&mut rng, &mut b);
638            for el in &b {
639                assert_ne!(*el, 0u8);
640            }
641        }
642    }
643
644    fn get_private_key() -> RsaPrivateKey {
645        // In order to generate new test vectors you'll need the PEM form of this key:
646        // -----BEGIN RSA PRIVATE KEY-----
647        // MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
648        // fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu
649        // /ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu
650        // RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/
651        // EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A
652        // IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS
653        // tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
654        // -----END RSA PRIVATE KEY-----
655
656        RsaPrivateKey::from_components(
657            BigUint::from_str_radix("9353930466774385905609975137998169297361893554149986716853295022578535724979677252958524466350471210367835187480748268864277464700638583474144061408845077", 10).unwrap(),
658            BigUint::from_u64(65537).unwrap(),
659            BigUint::from_str_radix("7266398431328116344057699379749222532279343923819063639497049039389899328538543087657733766554155839834519529439851673014800261285757759040931985506583861", 10).unwrap(),
660            vec![
661                BigUint::from_str_radix("98920366548084643601728869055592650835572950932266967461790948584315647051443",10).unwrap(),
662                BigUint::from_str_radix("94560208308847015747498523884063394671606671904944666360068158221458669711639", 10).unwrap()
663            ],
664        ).unwrap()
665    }
666
667    #[test]
668    fn test_decrypt_pkcs1v15() {
669        let priv_key = get_private_key();
670
671        let tests = [[
672	    "gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==",
673	    "x",
674	], [
675	    "Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==",
676	    "testing.",
677	], [
678	    "arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==",
679	    "testing.\n",
680	], [
681	"WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==",
682		"01234567890123456789012345678901234567890123456789012",
683	]];
684
685        for test in &tests {
686            let out = priv_key
687                .decrypt(
688                    PaddingScheme::new_pkcs1v15_encrypt(),
689                    &Base64::decode_vec(test[0]).unwrap(),
690                )
691                .unwrap();
692            assert_eq!(out, test[1].as_bytes());
693        }
694    }
695
696    #[test]
697    fn test_encrypt_decrypt_pkcs1v15() {
698        let mut rng = ChaCha8Rng::from_seed([42; 32]);
699        let priv_key = get_private_key();
700        let k = priv_key.size();
701
702        for i in 1..100 {
703            let mut input = vec![0u8; i * 8];
704            rng.fill_bytes(&mut input);
705            if input.len() > k - 11 {
706                input = input[0..k - 11].to_vec();
707            }
708
709            let pub_key: RsaPublicKey = priv_key.clone().into();
710            let ciphertext = encrypt(&mut rng, &pub_key, &input).unwrap();
711            assert_ne!(input, ciphertext);
712
713            let blind: bool = rng.next_u32() < (1u32 << 31);
714            let blinder = if blind { Some(&mut rng) } else { None };
715            let plaintext = decrypt(blinder, &priv_key, &ciphertext).unwrap();
716            assert_eq!(input, plaintext);
717        }
718    }
719
720    #[test]
721    fn test_sign_pkcs1v15() {
722        let priv_key = get_private_key();
723
724        let tests = [(
725            "Test.\n",
726            hex!(
727                "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
728                "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
729            ),
730        )];
731
732        for (text, expected) in &tests {
733            let digest = Sha1::digest(text.as_bytes()).to_vec();
734
735            let out = priv_key
736                .sign(PaddingScheme::new_pkcs1v15_sign::<Sha1>(), &digest)
737                .unwrap();
738            assert_ne!(out, digest);
739            assert_eq!(out, expected);
740
741            let mut rng = ChaCha8Rng::from_seed([42; 32]);
742            let out2 = priv_key
743                .sign_blinded(
744                    &mut rng,
745                    PaddingScheme::new_pkcs1v15_sign::<Sha1>(),
746                    &digest,
747                )
748                .unwrap();
749            assert_eq!(out2, expected);
750        }
751    }
752
753    #[test]
754    fn test_sign_pkcs1v15_signer() {
755        let priv_key = get_private_key();
756
757        let tests = [(
758            "Test.\n",
759            hex!(
760                "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
761                "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
762            ),
763        )];
764
765        let signing_key = SigningKey::<Sha1>::new_with_prefix(priv_key);
766
767        for (text, expected) in &tests {
768            let out = signing_key.sign(text.as_bytes());
769            assert_ne!(out.as_ref(), text.as_bytes());
770            assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec());
771            assert_eq!(out.as_ref(), expected);
772
773            let mut rng = ChaCha8Rng::from_seed([42; 32]);
774            let out2 = signing_key.sign_with_rng(&mut rng, text.as_bytes());
775            assert_eq!(out2.as_ref(), expected);
776        }
777    }
778
779    #[test]
780    fn test_sign_pkcs1v15_signer_sha2_256() {
781        let priv_key = get_private_key();
782
783        let tests = [(
784            "Test.\n",
785            hex!(
786                "2ffae3f3e130287b3a1dcb320e46f52e8f3f7969b646932273a7e3a6f2a182ea"
787                "02d42875a7ffa4a148aa311f9e4b562e4e13a2223fb15f4e5bf5f2b206d9451b"
788            ),
789        )];
790
791        let signing_key = SigningKey::<Sha256>::new_with_prefix(priv_key);
792
793        for (text, expected) in &tests {
794            let out = signing_key.sign(text.as_bytes());
795            assert_ne!(out.as_ref(), text.as_bytes());
796            assert_eq!(out.as_ref(), expected);
797
798            let mut rng = ChaCha8Rng::from_seed([42; 32]);
799            let out2 = signing_key.sign_with_rng(&mut rng, text.as_bytes());
800            assert_eq!(out2.as_ref(), expected);
801        }
802    }
803
804    #[test]
805    fn test_sign_pkcs1v15_signer_sha3_256() {
806        let priv_key = get_private_key();
807
808        let tests = [(
809            "Test.\n",
810            hex!(
811                "55e9fba3354dfb51d2c8111794ea552c86afc2cab154652c03324df8c2c51ba7"
812                "2ff7c14de59a6f9ba50d90c13a7537cc3011948369f1f0ec4a49d21eb7e723f9"
813            ),
814        )];
815
816        let signing_key = SigningKey::<Sha3_256>::new_with_prefix(priv_key);
817
818        for (text, expected) in &tests {
819            let out = signing_key.sign(text.as_bytes());
820            assert_ne!(out.as_ref(), text.as_bytes());
821            assert_eq!(out.as_ref(), expected);
822
823            let mut rng = ChaCha8Rng::from_seed([42; 32]);
824            let out2 = signing_key.sign_with_rng(&mut rng, text.as_bytes());
825            assert_eq!(out2.as_ref(), expected);
826        }
827    }
828
829    #[test]
830    fn test_sign_pkcs1v15_digest_signer() {
831        let priv_key = get_private_key();
832
833        let tests = [(
834            "Test.\n",
835            hex!(
836                "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
837                "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
838            ),
839        )];
840
841        let signing_key = SigningKey::new_with_prefix(priv_key);
842
843        for (text, expected) in &tests {
844            let mut digest = Sha1::new();
845            digest.update(text.as_bytes());
846            let out = signing_key.sign_digest(digest);
847            assert_ne!(out.as_ref(), text.as_bytes());
848            assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec());
849            assert_eq!(out.as_ref(), expected);
850
851            let mut rng = ChaCha8Rng::from_seed([42; 32]);
852            let mut digest = Sha1::new();
853            digest.update(text.as_bytes());
854            let out2 = signing_key.sign_digest_with_rng(&mut rng, digest);
855            assert_eq!(out2.as_ref(), expected);
856        }
857    }
858
859    #[test]
860    fn test_verify_pkcs1v15() {
861        let priv_key = get_private_key();
862
863        let tests = [
864            (
865                "Test.\n",
866                hex!(
867                    "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
868                    "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
869                ),
870                true,
871            ),
872            (
873                "Test.\n",
874                hex!(
875                    "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
876                    "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
877                ),
878                false,
879            ),
880        ];
881        let pub_key: RsaPublicKey = priv_key.into();
882
883        for (text, sig, expected) in &tests {
884            let digest = Sha1::digest(text.as_bytes()).to_vec();
885
886            let result = pub_key.verify(PaddingScheme::new_pkcs1v15_sign::<Sha1>(), &digest, sig);
887            match expected {
888                true => result.expect("failed to verify"),
889                false => {
890                    result.expect_err("expected verifying error");
891                }
892            }
893        }
894    }
895
896    #[test]
897    fn test_verify_pkcs1v15_signer() {
898        let priv_key = get_private_key();
899
900        let tests = [
901            (
902                "Test.\n",
903                hex!(
904                    "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
905                    "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
906                ),
907                true,
908            ),
909            (
910                "Test.\n",
911                hex!(
912                    "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
913                    "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
914                ),
915                false,
916            ),
917        ];
918        let pub_key: RsaPublicKey = priv_key.into();
919        let verifying_key = VerifyingKey::<Sha1>::new_with_prefix(pub_key);
920
921        for (text, sig, expected) in &tests {
922            let result =
923                verifying_key.verify(text.as_bytes(), &Signature::from_bytes(sig).unwrap());
924            match expected {
925                true => result.expect("failed to verify"),
926                false => {
927                    result.expect_err("expected verifying error");
928                }
929            }
930        }
931    }
932
933    #[test]
934    fn test_verify_pkcs1v15_digest_signer() {
935        let priv_key = get_private_key();
936
937        let tests = [
938            (
939                "Test.\n",
940                hex!(
941                    "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
942                    "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"
943                ),
944                true,
945            ),
946            (
947                "Test.\n",
948                hex!(
949                    "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33"
950                    "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af"
951                ),
952                false,
953            ),
954        ];
955        let pub_key: RsaPublicKey = priv_key.into();
956        let verifying_key = VerifyingKey::new_with_prefix(pub_key);
957
958        for (text, sig, expected) in &tests {
959            let mut digest = Sha1::new();
960            digest.update(text.as_bytes());
961            let result = verifying_key.verify_digest(digest, &Signature::from_bytes(sig).unwrap());
962            match expected {
963                true => result.expect("failed to verify"),
964                false => {
965                    result.expect_err("expected verifying error");
966                }
967            }
968        }
969    }
970    #[test]
971    fn test_unpadded_signature() {
972        let msg = b"Thu Dec 19 18:06:16 EST 2013\n";
973        let expected_sig = Base64::decode_vec("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==").unwrap();
974        let priv_key = get_private_key();
975
976        let sig = priv_key
977            .sign(PaddingScheme::new_pkcs1v15_sign_raw(), msg)
978            .unwrap();
979        assert_eq!(expected_sig, sig);
980
981        let pub_key: RsaPublicKey = priv_key.into();
982        pub_key
983            .verify(PaddingScheme::new_pkcs1v15_sign_raw(), msg, &sig)
984            .expect("failed to verify");
985    }
986
987    #[cfg(feature = "hazmat")]
988    #[test]
989    fn test_unpadded_signature_hazmat() {
990        let msg = b"Thu Dec 19 18:06:16 EST 2013\n";
991        let expected_sig = Base64::decode_vec("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==").unwrap();
992        let priv_key = get_private_key();
993
994        let signing_key = SigningKey::<Sha1>::new(priv_key);
995        let sig = signing_key.sign_prehash(msg).expect("Failure during sign");
996        assert_eq!(sig.as_ref(), expected_sig);
997
998        let verifying_key: VerifyingKey<_> = (&signing_key).into();
999        verifying_key
1000            .verify_prehash(msg, &Signature::from_bytes(&expected_sig).unwrap())
1001            .expect("failed to verify");
1002    }
1003}