Skip to main content

crypto/
rsa.rs

1//! RSA signature verification: PKCS#1 v1.5 and RSA-PSS (RFC 8017).
2//!
3//! Implements modular exponentiation and padding verification for
4//! rsa_pkcs1_sha256 / sha384 / sha512 and rsa_pss_* schemes.
5//!
6//! Only verification is supported; signing is not implemented.
7
8use big_number::Uint;
9
10use crate::{Hasher, RsaError};
11
12/// Minimum RSA modulus size accepted (2048 bits).
13const RSA_MIN_BITS: usize = 2048;
14/// Maximum RSA modulus size supported (8192 bits).
15const RSA_MAX_BITS: usize = 8192;
16/// Maximum accepted public exponent size (64 bits).
17///
18/// Real-world RSA exponents are `3` or `65537`. Verification cost grows with
19/// the number of exponent bits (one modular multiplication per bit), so an
20/// unbounded exponent taken from an untrusted key is a CPU denial-of-service
21/// vector. This matches OpenSSL's `OPENSSL_RSA_MAX_PUBEXP_BITS`.
22const RSA_MAX_PUBEXP_BITS: usize = 64;
23const RSA_MAX_LIMBS: usize = RSA_MAX_BITS / 64;
24const RSA_MAX_BYTES: usize = RSA_MAX_BITS / 8;
25
26/// SHA-256 DigestInfo prefix for RSA PKCS#1 v1.5.
27pub const DIGEST_INFO_SHA256_PREFIX: &[u8] = &[
28    0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20,
29];
30
31/// SHA-384 DigestInfo prefix for RSA PKCS#1 v1.5.
32pub const DIGEST_INFO_SHA384_PREFIX: &[u8] = &[
33    0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30,
34];
35
36/// SHA-512 DigestInfo prefix for RSA PKCS#1 v1.5.
37pub const DIGEST_INFO_SHA512_PREFIX: &[u8] = &[
38    0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40,
39];
40
41/// An RSA public key parsed from a PKCS#1 `SubjectPublicKeyInfo` DER blob.
42pub struct PublicKey {
43    /// Modulus `n` as a 8192-bit integer (zero-padded for smaller keys).
44    n: Uint<RSA_MAX_BITS, RSA_MAX_LIMBS>,
45    /// Public exponent `e`.
46    e: Uint<RSA_MAX_BITS, RSA_MAX_LIMBS>,
47    /// Byte length of the modulus (without padding).
48    n_len: usize,
49    /// Byte length of the public exponent (without leading zeros).
50    e_len: usize,
51    /// Barrett reduction precomputation for mod n.
52    mu: [u64; big_number::MAX_LIMBS],
53}
54
55impl PublicKey {
56    /// Build an RSA public key from raw modulus `n` and public exponent `e`
57    /// (both big-endian byte slices).
58    ///
59    /// This is useful when importing keys from formats like JWK where `n` and
60    /// `e` are available directly as bytes rather than inside an ASN.1 DER
61    /// wrapper.
62    ///
63    /// The parameters are validated before the key is accepted: `n` must be
64    /// odd and between 2048 and 8192 bits, and `e` must be odd, at least 3, at
65    /// most 64 bits, and strictly smaller than `n`. The 64-bit exponent bound
66    /// keeps verification cost independent of attacker-controlled key
67    /// parameters (each extra exponent bit costs one modular multiplication).
68    ///
69    /// # Errors
70    ///
71    /// Returns [`RsaError::InvalidKey`] if `n` or `e` fail the checks above
72    /// (including empty or even `n`, `e < 3`, even `e`, `e >= n`, or `e` wider
73    /// than 64 bits), and [`RsaError::NotSupported`] if the modulus exceeds
74    /// 8192 bits.
75    #[inline]
76    pub fn from_n_e(n_bytes: &[u8], e: &[u8]) -> Result<Self, RsaError> {
77        let n = uint_from_variable_be(n_bytes)?;
78        let e_uint = uint_from_variable_be(e)?;
79        if n.is_zero() || !n.is_odd() || n.bit_len() < RSA_MIN_BITS {
80            return Err(RsaError::InvalidKey);
81        }
82        if e_uint.bit_len() < 2 || e_uint.bit_len() > RSA_MAX_PUBEXP_BITS || !e_uint.is_odd() || e_uint.ct_ge(&n) {
83            return Err(RsaError::InvalidKey);
84        }
85        let e_len = {
86            let mut start: usize = 0;
87            while start < e.len().saturating_sub(1) && e[start] == 0 {
88                start += 1;
89            }
90            e.len() - start
91        };
92        Ok(PublicKey {
93            // `k` for PKCS#1 is the octet length of the modulus, independent of
94            // any leading zero bytes in the caller-provided encoding.
95            n_len: n.bit_len().div_ceil(8),
96            mu: n.compute_mu_for_barrett(),
97            e: e_uint,
98            e_len,
99            n,
100        })
101    }
102
103    /// Parse an RSA public key from the raw PKCS#1 bytes.
104    ///
105    /// The input is the content of the BIT STRING inside the SPKI —
106    /// a strict DER `SEQUENCE { INTEGER n, INTEGER e }`. Non-minimal length
107    /// encodings, negative or non-minimally-encoded INTEGERs, an oversized
108    /// outer SEQUENCE, and any trailing bytes inside or after the SEQUENCE are
109    /// rejected.
110    ///
111    /// The same parameter validation as [`PublicKey::from_n_e`] is applied.
112    ///
113    /// # Errors
114    ///
115    /// Returns [`RsaError::Unspecified`] if `data` is not the exact strict DER
116    /// encoding of `SEQUENCE { INTEGER n, INTEGER e }`, and
117    /// [`RsaError::InvalidKey`] or [`RsaError::NotSupported`] when the
118    /// modulus/exponent fail the [`PublicKey::from_n_e`] checks.
119    pub fn from_pkcs1_der(data: &[u8]) -> Result<Self, RsaError> {
120        if data.len() < 2 || data[0] != 0x30 {
121            return Err(RsaError::Unspecified);
122        }
123        let (seq_len, len_size) = read_length(&data[1..])?;
124        let header = 1 + len_size;
125        if data.len() != header + seq_len {
126            return Err(RsaError::Unspecified);
127        }
128        let mut body = &data[header..];
129
130        let mut n_buf = [0u8; RSA_MAX_BYTES];
131        let (n_len, consumed) = read_integer(body, &mut n_buf)?;
132        body = &body[consumed..];
133
134        let mut e_buf = [0u8; RSA_MAX_BYTES];
135        let (e_len, consumed) = read_integer(body, &mut e_buf)?;
136        body = &body[consumed..];
137
138        if !body.is_empty() {
139            return Err(RsaError::Unspecified);
140        }
141
142        Self::from_n_e(&n_buf[..n_len], &e_buf[..e_len])
143    }
144
145    /// Raises the (public) signature to the public exponent modulo `n`.
146    ///
147    /// Dispatches to a Barrett working width (`W`) sized from the modulus so
148    /// that only the effective limbs are used. `W = MAX_LIMBS` would work but
149    /// spends most of its time multiplying zero limbs for a 2048-bit key.
150    fn modpow_public(&self, base: &Uint<RSA_MAX_BITS, RSA_MAX_LIMBS>) -> Uint<RSA_MAX_BITS, RSA_MAX_LIMBS> {
151        let bits = self.n.bit_len();
152        // W = 2 * (ceil(bits / 64) + 1), rounded up to a size class.
153        if bits <= 2048 {
154            base.modpow_barrett_w::<66>(&self.e, &self.n, &self.mu)
155        } else if bits <= 4096 {
156            base.modpow_barrett_w::<130>(&self.e, &self.n, &self.mu)
157        } else if bits <= 6144 {
158            base.modpow_barrett_w::<194>(&self.e, &self.n, &self.mu)
159        } else {
160            base.modpow_barrett_w::<258>(&self.e, &self.n, &self.mu)
161        }
162    }
163
164    /// Verify a PKCS#1 v1.5 signature.
165    ///
166    /// `signature` is the raw signature bytes (eg., 256 bytes for RSA-2048).
167    /// `message_digest` is the hash of the message to verify.
168    /// `digest_info_prefix` is the ASN.1 DigestInfo prefix for the hash algorithm
169    /// (the constant-length portion before the hash value).
170    ///
171    /// The padding and DigestInfo encoding must be strict DER and the DigestInfo
172    /// must fill the modulus exactly (`EM = 00 01 PS 00 T`, RFC 8017 §9.2).
173    /// Non-canonical encodings, including trailing zero bytes after the
174    /// DigestInfo, are rejected.
175    ///
176    /// # Errors
177    ///
178    /// Returns [`RsaError::Unspecified`] if `signature` is not exactly `n_len`
179    /// bytes long, if the signature is not reduced modulo `n`, or if the padded
180    /// message does not match the canonical encoding for `digest_info_prefix`
181    /// and `message_digest`.
182    pub fn verify_pkcs1_v1_5(
183        &self,
184        signature: &[u8],
185        message_digest: &[u8],
186        digest_info_prefix: &[u8],
187    ) -> Result<(), RsaError> {
188        if signature.len() != self.n_len {
189            return Err(RsaError::Unspecified);
190        }
191
192        let s = uint_from_variable_be(signature)?;
193
194        // Reject signatures not reduced modulo n
195        if s.ct_ge(&self.n) {
196            return Err(RsaError::Unspecified);
197        }
198
199        let m = self.modpow_public(&s);
200
201        let mod_bytes = self.n_len;
202        let mut m_bytes = [0u8; RSA_MAX_BYTES];
203        write_uint_be(&m, &mut m_bytes, mod_bytes);
204
205        if !pkcs1_v1_5_em_matches(&m_bytes[..mod_bytes], digest_info_prefix, message_digest) {
206            return Err(RsaError::Unspecified);
207        }
208
209        Ok(())
210    }
211
212    /// Verify an RSA-PSS signature (RFC 8017 §9.1.2).
213    ///
214    /// `message` is hashed with `H`, whose digest length must equal `salt_len`
215    /// (Go's `PSSSaltLengthEqualsHash`).
216    ///
217    /// Per RFC 8017, the encoded-message bit length is `emBits = bitlen(n) - 1`
218    /// and `emLen = ceil(emBits / 8)`. This matters for moduli whose top bit is
219    /// not set: `emLen` can be one byte shorter than the modulus and the number
220    /// of leftmost bits cleared from `DB` is `8·emLen - emBits`, not always 1.
221    pub fn verify_pss<H: Hasher>(&self, signature: &[u8], message: &[u8], salt_len: usize) -> Result<(), RsaError> {
222        if signature.len() != self.n_len {
223            return Err(RsaError::Unspecified);
224        }
225
226        let s = uint_from_variable_be(signature)?;
227        if s.ct_ge(&self.n) {
228            return Err(RsaError::Unspecified);
229        }
230
231        let m = self.modpow_public(&s);
232        let hash_len = H::OUTPUT_SIZE;
233
234        // RFC 8017 §9.1.2: emBits = modBits - 1 and emLen = ceil(emBits / 8),
235        // where modBits = bitlen(n). This can differ from n_len when the top
236        // bit of the modulus is not set.
237        let em_bits = self.n.bit_len() - 1;
238        let em_len = em_bits.div_ceil(8);
239
240        // I2OSP(m, emLen) requires m < 256^emLen. Only reachable when emBits is
241        // a multiple of 8, in which case m may need emLen + 1 bytes.
242        if m.bit_len() > 8 * em_len {
243            return Err(RsaError::Unspecified);
244        }
245
246        let mut em = [0u8; RSA_MAX_BYTES];
247        write_uint_be(&m, &mut em, em_len);
248
249        let leftmost_bits = 8 * em_len - em_bits;
250        if leftmost_bits > 0 && leftmost_bits < 8 {
251            if em[0] >> (8 - leftmost_bits) != 0 {
252                return Err(RsaError::Unspecified);
253            }
254        }
255
256        if em_len < hash_len + salt_len + 2 {
257            return Err(RsaError::Unspecified);
258        }
259        if em[em_len - 1] != 0xBC {
260            return Err(RsaError::Unspecified);
261        }
262
263        let masked_db_len = em_len - hash_len - 1;
264        let masked_db = &em[..masked_db_len];
265        let h = &em[masked_db_len..masked_db_len + hash_len];
266
267        let mut db_mask = [0u8; RSA_MAX_BYTES];
268        mgf1::<H>(h, &mut db_mask[..masked_db_len]);
269
270        let mut db = [0u8; RSA_MAX_BYTES];
271        for (i, (a, b)) in masked_db.iter().zip(db_mask[..masked_db_len].iter()).enumerate() {
272            db[i] = a ^ b;
273        }
274
275        if leftmost_bits > 0 && leftmost_bits < 8 {
276            db[0] &= 0xff >> leftmost_bits;
277        }
278
279        let ps_len = em_len - hash_len - salt_len - 2;
280        if ps_len > 0 {
281            for i in 0..ps_len {
282                if db[i] != 0x00 {
283                    return Err(RsaError::Unspecified);
284                }
285            }
286        }
287        if db[ps_len] != 0x01 {
288            return Err(RsaError::Unspecified);
289        }
290
291        let salt = &db[ps_len + 1..ps_len + 1 + salt_len];
292
293        let m_hash = H::hash(message);
294        let mut mp = [0u8; 8 + 64 + RSA_MAX_BYTES];
295        let mp_len = 8 + hash_len + salt_len;
296        mp[8..8 + hash_len].copy_from_slice(m_hash.as_ref());
297        mp[8 + hash_len..mp_len].copy_from_slice(salt);
298
299        let hp = H::hash(&mp[..mp_len]);
300
301        let mut ok = 0u8;
302        for i in 0..hash_len {
303            ok |= h[i] ^ hp.as_ref()[i];
304        }
305        if ok != 0 {
306            return Err(RsaError::Unspecified);
307        }
308
309        Ok(())
310    }
311
312    /// Verify an RSA PKCS#1 v1.5 signature over `message` using SHA-256.
313    ///
314    /// The message is hashed internally, so callers do not need to hash it
315    /// themselves. Equivalent to hashing with [`Sha256`](crate::sha2::Sha256)
316    /// and calling [`Self::verify_pkcs1_v1_5`].
317    pub fn verify_pkcs1_sha256(&self, signature: &[u8], message: &[u8]) -> Result<(), RsaError> {
318        let digest = crate::sha2::Sha256::hash(message);
319        self.verify_pkcs1_v1_5(signature, digest.as_ref(), DIGEST_INFO_SHA256_PREFIX)
320    }
321
322    /// Verify an RSA PKCS#1 v1.5 signature over `message` using SHA-384.
323    ///
324    /// See [`Self::verify_pkcs1_sha256`] for the hashing contract.
325    pub fn verify_pkcs1_sha384(&self, signature: &[u8], message: &[u8]) -> Result<(), RsaError> {
326        let digest = crate::sha2::Sha384::hash(message);
327        self.verify_pkcs1_v1_5(signature, digest.as_ref(), DIGEST_INFO_SHA384_PREFIX)
328    }
329
330    /// Verify an RSA PKCS#1 v1.5 signature over `message` using SHA-512.
331    ///
332    /// See [`Self::verify_pkcs1_sha256`] for the hashing contract.
333    pub fn verify_pkcs1_sha512(&self, signature: &[u8], message: &[u8]) -> Result<(), RsaError> {
334        let digest = crate::sha2::Sha512::hash(message);
335        self.verify_pkcs1_v1_5(signature, digest.as_ref(), DIGEST_INFO_SHA512_PREFIX)
336    }
337
338    /// Verify an RSA-PSS signature over `message` using SHA-256.
339    ///
340    /// The message is hashed internally. The salt length is the hash length
341    /// (`PSSSaltLengthEqualsHash`, RFC 8017).
342    pub fn verify_pss_sha256(&self, signature: &[u8], message: &[u8]) -> Result<(), RsaError> {
343        self.verify_pss::<crate::sha2::Sha256>(signature, message, 32)
344    }
345
346    /// Verify an RSA-PSS signature over `message` using SHA-384.
347    ///
348    /// See [`Self::verify_pss_sha256`] for the salt-length contract.
349    pub fn verify_pss_sha384(&self, signature: &[u8], message: &[u8]) -> Result<(), RsaError> {
350        self.verify_pss::<crate::sha2::Sha384>(signature, message, 48)
351    }
352
353    /// Verify an RSA-PSS signature over `message` using SHA-512.
354    ///
355    /// See [`Self::verify_pss_sha256`] for the salt-length contract.
356    pub fn verify_pss_sha512(&self, signature: &[u8], message: &[u8]) -> Result<(), RsaError> {
357        self.verify_pss::<crate::sha2::Sha512>(signature, message, 64)
358    }
359
360    /// Number of bytes in the modulus `n`, trimmed of leading zeros
361    /// (256 for RSA-2048, 512 for RSA-4096, 1024 for RSA-8192).
362    pub fn modulus_len_bytes(&self) -> usize {
363        self.n_len
364    }
365
366    /// Returns the modulus `n` as big-endian bytes, trimmed to the actual key size.
367    /// (e.g. 256 bytes for RSA-2048, 512 bytes for RSA-4096, 1024 bytes for RSA-8192).
368    #[cfg(feature = "alloc")]
369    pub fn n_bytes(&self) -> alloc::vec::Vec<u8> {
370        let full = self.n.to_be_bytes_fixed::<{ RSA_MAX_BYTES }>();
371        full[full.len() - self.n_len..].to_vec()
372    }
373
374    /// Returns the public exponent `e` as big-endian bytes, trimmed of leading zeros.
375    /// (e.g. `[1, 0, 1]` for 65537).
376    #[cfg(feature = "alloc")]
377    pub fn e_bytes(&self) -> small_collections::SmallVec<u8, 4> {
378        let full = self.e.to_be_bytes_fixed::<{ RSA_MAX_BYTES }>();
379        full[full.len() - self.e_len..].into()
380    }
381}
382
383/// Validate a PKCS#1 v1.5 encoded message `EM = 00 01 PS 00 T`.
384///
385/// `em` is the full `k`-byte encoded message. Returns `true` only when the
386/// padding is canonical (`00 01`, at least 8 `0xFF` bytes, `0x00` separator),
387/// when `digest_info_prefix` and `message_digest` match the trailing bytes, and
388/// when that DigestInfo occupies the remainder of `em` exactly. The last rule
389/// is what rejects non-conforming encodings that merely append zero bytes after
390/// a valid DigestInfo (RFC 8017 §9.2 requires `T` to fill the modulus).
391fn pkcs1_v1_5_em_matches(em: &[u8], digest_info_prefix: &[u8], message_digest: &[u8]) -> bool {
392    let mod_bytes = em.len();
393    if mod_bytes < 2 || em[0] != 0x00 || em[1] != 0x01 {
394        return false;
395    }
396
397    // Find the 0x00 separator after the FF padding.
398    let mut sep = 2;
399    while sep < mod_bytes && em[sep] == 0xff {
400        sep += 1;
401    }
402    // Require the separator and at least 8 bytes of FF padding.
403    if sep >= mod_bytes || em[sep] != 0x00 || sep < 10 {
404        return false;
405    }
406
407    let di_start = sep + 1;
408    let expected_len = digest_info_prefix.len() + message_digest.len();
409    // `di_start <= mod_bytes` because `sep < mod_bytes`; the DigestInfo must end
410    // exactly at the modulus (no shortfall, no trailing bytes).
411    if mod_bytes - di_start != expected_len {
412        return false;
413    }
414
415    // Verify the canonical DigestInfo prefix and the hash value.
416    let mut ok = 0u8;
417    for i in 0..digest_info_prefix.len() {
418        ok |= em[di_start + i] ^ digest_info_prefix[i];
419    }
420    for i in 0..message_digest.len() {
421        ok |= em[di_start + digest_info_prefix.len() + i] ^ message_digest[i];
422    }
423    ok == 0
424}
425
426/// MGF1 (Mask Generation Function 1) per RFC 8017 Appendix B.2.1.
427fn mgf1<H: Hasher>(seed: &[u8], out: &mut [u8]) {
428    let out_len = out.len();
429    let hash_len = H::OUTPUT_SIZE;
430    let mut offset = 0;
431    let mut counter: u32 = 0;
432    let input_prefix = seed.len();
433    let mut input_buf = [0u8; RSA_MAX_BYTES + 4];
434    input_buf[..input_prefix].copy_from_slice(seed);
435    while offset < out_len {
436        input_buf[input_prefix..input_prefix + 4].copy_from_slice(&counter.to_be_bytes());
437        let hash = H::hash(&input_buf[..input_prefix + 4]);
438        let take = (out_len - offset).min(hash_len);
439        out[offset..offset + take].copy_from_slice(&hash.as_ref()[..take]);
440        offset += take;
441        counter += 1;
442    }
443}
444
445/// Read an ASN.1 length field. Returns (value, bytes_consumed_for_length).
446///
447/// The encoding must be the minimal DER form prescribed by X.690 §10.1:
448/// long form is accepted only when the length is at least 128 and its first
449/// content byte is non-zero. Indefinite lengths (`0x80`) and long forms wider
450/// than four bytes are rejected.
451fn read_length(data: &[u8]) -> Result<(usize, usize), RsaError> {
452    if data.is_empty() {
453        return Err(RsaError::Unspecified);
454    }
455    if data[0] & 0x80 == 0 {
456        Ok((data[0] as usize, 1))
457    } else {
458        let num_bytes = (data[0] & 0x7f) as usize;
459        if num_bytes == 0 || num_bytes > 4 || data.len() < 1 + num_bytes {
460            return Err(RsaError::Unspecified);
461        }
462        if data[1] == 0x00 {
463            return Err(RsaError::Unspecified);
464        }
465        let mut len = 0usize;
466        for i in 0..num_bytes {
467            len = (len << 8) | data[1 + i] as usize;
468        }
469        if len < 0x80 {
470            return Err(RsaError::Unspecified);
471        }
472        Ok((len, 1 + num_bytes))
473    }
474}
475
476/// Read an ASN.1 INTEGER, writing its magnitude into `out` and returning
477/// `(value_len, total_consumed)`.
478///
479/// The encoding must be strict DER: the contents may not be empty, may not be
480/// negative (top bit set), and any leading `0x00` is allowed only when needed to
481/// keep the following byte's top bit from being read as a sign bit. This is the
482/// canonical form required by RFC 8017 for RSA public key parameters.
483fn read_integer(data: &[u8], out: &mut [u8]) -> Result<(usize, usize), RsaError> {
484    if data.len() < 2 || data[0] != 0x02 {
485        return Err(RsaError::Unspecified);
486    }
487    let (len, len_size) = read_length(&data[1..])?;
488    let consumed = 1 + len_size + len;
489    if len == 0 || data.len() < consumed {
490        return Err(RsaError::Unspecified);
491    }
492    let bytes = &data[1 + len_size..consumed];
493    if bytes[0] & 0x80 != 0 {
494        return Err(RsaError::Unspecified);
495    }
496    let (value, val_len) = if bytes[0] == 0x00 {
497        if bytes.len() < 2 || bytes[1] & 0x80 == 0 {
498            return Err(RsaError::Unspecified);
499        }
500        (&bytes[1..], bytes.len() - 1)
501    } else {
502        (bytes, bytes.len())
503    };
504    if out.len() < val_len {
505        return Err(RsaError::Unspecified);
506    }
507    out[..val_len].copy_from_slice(value);
508    Ok((val_len, consumed))
509}
510
511/// Build a `Uint` from a variable-length big-endian byte slice
512/// (left-padded with zeros to the full bit width).
513fn uint_from_variable_be(bytes: &[u8]) -> Result<Uint<RSA_MAX_BITS, RSA_MAX_LIMBS>, RsaError> {
514    let max_bytes = RSA_MAX_BITS / 8;
515    if bytes.len() > max_bytes {
516        return Err(RsaError::NotSupported);
517    }
518    let mut limbs = [0u64; RSA_MAX_LIMBS];
519    let byte_count = bytes.len();
520    let mut i = 0;
521    while i < RSA_MAX_LIMBS {
522        let limb_start = byte_count.saturating_sub((i + 1) * 8);
523        let limb_end = byte_count.saturating_sub(i * 8);
524        let len = limb_end - limb_start;
525        let mut buf = [0u8; 8];
526        if len > 0 {
527            buf[8 - len..].copy_from_slice(&bytes[limb_start..limb_end]);
528        }
529        limbs[i] = u64::from_be_bytes(buf);
530        i += 1;
531    }
532    Ok(Uint::from_limbs(limbs))
533}
534
535/// Write a `Uint` as big-endian bytes into a buffer, right-aligned.
536/// Only converts the required limbs instead of the full 8192-bit representation.
537fn write_uint_be(value: &Uint<RSA_MAX_BITS, RSA_MAX_LIMBS>, out: &mut [u8], byte_len: usize) {
538    assert!(byte_len <= RSA_MAX_BYTES);
539    let full = value.to_be_bytes_fixed::<{ RSA_MAX_BYTES }>();
540    let start = full.len() - byte_len;
541    out[..byte_len].copy_from_slice(&full[start..]);
542}
543
544/// Convenience: verify RSA-PKCS1-SHA256.
545pub fn verify_pkcs1_sha256(pkcs1_der: &[u8], signature: &[u8], message: &[u8]) -> Result<(), RsaError> {
546    let key = PublicKey::from_pkcs1_der(pkcs1_der)?;
547    let digest = crate::sha2::Sha256::hash(message);
548    key.verify_pkcs1_v1_5(signature, digest.as_ref(), DIGEST_INFO_SHA256_PREFIX)
549}
550
551/// Convenience: verify RSA-PKCS1-SHA384.
552pub fn verify_pkcs1_sha384(pkcs1_der: &[u8], signature: &[u8], message: &[u8]) -> Result<(), RsaError> {
553    let key = PublicKey::from_pkcs1_der(pkcs1_der)?;
554    let digest = crate::sha2::Sha384::hash(message);
555    key.verify_pkcs1_v1_5(signature, digest.as_ref(), DIGEST_INFO_SHA384_PREFIX)
556}
557
558/// Convenience: verify RSA-PKCS1-SHA512.
559pub fn verify_pkcs1_sha512(pkcs1_der: &[u8], signature: &[u8], message: &[u8]) -> Result<(), RsaError> {
560    let key = PublicKey::from_pkcs1_der(pkcs1_der)?;
561    let digest = crate::sha2::Sha512::hash(message);
562    key.verify_pkcs1_v1_5(signature, digest.as_ref(), DIGEST_INFO_SHA512_PREFIX)
563}
564
565/// Convenience: verify RSA-PSS-SHA256.
566pub fn verify_pss_sha256(pkcs1_der: &[u8], signature: &[u8], message: &[u8]) -> Result<(), RsaError> {
567    let key = PublicKey::from_pkcs1_der(pkcs1_der)?;
568    key.verify_pss::<crate::sha2::Sha256>(signature, message, 32)
569}
570
571/// Convenience: verify RSA-PSS-SHA384.
572pub fn verify_pss_sha384(pkcs1_der: &[u8], signature: &[u8], message: &[u8]) -> Result<(), RsaError> {
573    let key = PublicKey::from_pkcs1_der(pkcs1_der)?;
574    key.verify_pss::<crate::sha2::Sha384>(signature, message, 48)
575}
576
577/// Convenience: verify RSA-PSS-SHA512.
578pub fn verify_pss_sha512(pkcs1_der: &[u8], signature: &[u8], message: &[u8]) -> Result<(), RsaError> {
579    let key = PublicKey::from_pkcs1_der(pkcs1_der)?;
580    key.verify_pss::<crate::sha2::Sha512>(signature, message, 64)
581}
582
583#[cfg(test)]
584mod tests {
585    use hex;
586
587    use super::*;
588
589    macro_rules! wycheproof_rsa_test {
590        ($path:expr, $hasher:ty, $di_prefix:expr) => {{
591            let data: serde_json::Value = serde_json::from_str(include_str!($path)).unwrap();
592            let mut valid_tested = 0u64;
593            let mut invalid_tested = 0u64;
594
595            for group in data["testGroups"].as_array().unwrap() {
596                let pkcs1_der = hex::decode(group["publicKeyAsn"].as_str().unwrap()).unwrap();
597                let key = super::PublicKey::from_pkcs1_der(&pkcs1_der).unwrap();
598
599                for test in group["tests"].as_array().unwrap() {
600                    let msg_hex = test["msg"].as_str().unwrap();
601                    let sig_hex = test["sig"].as_str().unwrap();
602                    let result = test["result"].as_str().unwrap();
603
604                    let msg = hex::decode(msg_hex).unwrap();
605                    let sig = hex::decode(sig_hex).unwrap();
606
607                    let digest = <$hasher as crate::Hasher>::hash(&msg);
608                    let verify_result = key.verify_pkcs1_v1_5(&sig, digest.as_ref(), $di_prefix);
609
610                    match result {
611                        "valid" => {
612                            assert!(
613                                verify_result.is_ok(),
614                                "{}: tcId {}: expected valid, got error",
615                                $path,
616                                test["tcId"]
617                            );
618                            valid_tested += 1;
619                        }
620                        "invalid" => {
621                            assert!(
622                                verify_result.is_err(),
623                                "{}: tcId {} ({:?}): expected invalid, got ok",
624                                $path,
625                                test["tcId"],
626                                test.get("flags"),
627                            );
628                            invalid_tested += 1;
629                        }
630                        "acceptable" => {}
631                        _ => panic!("unknown result: {result}"),
632                    }
633                }
634            }
635
636            assert!(valid_tested > 0, "no valid RSA tests were run");
637            assert!(invalid_tested > 0, "no invalid RSA tests were run");
638        }};
639    }
640
641    macro_rules! wycheproof_rsa_pss_test {
642        ($path:expr, $hasher:ty, $hash_len:expr) => {{
643            let data: serde_json::Value = serde_json::from_str(include_str!($path)).unwrap();
644            let mut valid_tested = 0u64;
645            let mut invalid_tested = 0u64;
646
647            for group in data["testGroups"].as_array().unwrap() {
648                let pkcs1_der = hex::decode(group["publicKeyAsn"].as_str().unwrap()).unwrap();
649                let key = super::PublicKey::from_pkcs1_der(&pkcs1_der).unwrap();
650
651                for test in group["tests"].as_array().unwrap() {
652                    let msg_hex = test["msg"].as_str().unwrap();
653                    let sig_hex = test["sig"].as_str().unwrap();
654                    let result = test["result"].as_str().unwrap();
655
656                    let msg = hex::decode(msg_hex).unwrap();
657                    let sig = hex::decode(sig_hex).unwrap();
658
659                    let verify_result = key.verify_pss::<$hasher>(&sig, &msg, $hash_len);
660
661                    match result {
662                        "valid" => {
663                            assert!(
664                                verify_result.is_ok(),
665                                "{}: tcId {}: expected valid, got error: {:?}",
666                                $path,
667                                test["tcId"],
668                                verify_result,
669                            );
670                            valid_tested += 1;
671                        }
672                        "invalid" => {
673                            assert!(
674                                verify_result.is_err(),
675                                "{}: tcId {} ({:?}): expected invalid, got ok",
676                                $path,
677                                test["tcId"],
678                                test.get("flags"),
679                            );
680                            invalid_tested += 1;
681                        }
682                        "acceptable" => {}
683                        _ => panic!("unknown result: {result}"),
684                    }
685                }
686            }
687
688            assert!(valid_tested > 0, "no valid RSA-PSS tests were run for {}", $path);
689            assert!(invalid_tested > 0, "no invalid RSA-PSS tests were run for {}", $path);
690        }};
691    }
692
693    #[test]
694    fn modpow_works() {
695        let base = uint_from_variable_be(&[3]).unwrap();
696        let exp = uint_from_variable_be(&[5]).unwrap();
697        let modulus = uint_from_variable_be(&[7]).unwrap();
698        let result = base.modpow(&exp, &modulus);
699        let bytes = result.to_be_bytes_fixed::<{ RSA_MAX_BYTES }>();
700        assert_eq!(
701            bytes[RSA_MAX_BYTES - 1],
702            5,
703            "3^5 mod 7 should be 5, got {}",
704            bytes[RSA_MAX_BYTES - 1]
705        );
706    }
707
708    #[test]
709    fn from_n_e_matches_der() {
710        let sig = hex::decode(
711            "9d00f18defaa95b474b06ac4674b1b9270e110c6f474ce29e3aa972eca09137c9a82267e634986ecd54734f2edb1b3d72b539b8608e23074898c56042f9f014bfff59abce81c57d606b60f80ae4e110fc6f9dea99ce2897ce1d90661ab3d3b3f1a5ddf258b920a51c8c8758ab2da3da20da99c84eb2f57859b36918447c4cdbfa16cc09523fd27d28d4e97fa9ff0ea4d633c937a904a196a64e934851ee02b7922a8f5a4534bb10b8e16b89c12ddc347d7b4317f8b9d3dfed07a442d47351b18db38f45cc92e5c577b866df21766094d1f737ea418852827be3aec10d3c5a65a40087d9647b91a4d9419ad784a31caf02254cfc01a682bb6f5a231307f0fc8d9",
712        ).unwrap();
713        let digest = hex::decode("41cb0773387b187c038b7015498534c11369f1cfd094a714f4f39cf63ebb42ba").unwrap();
714
715        // n and e extracted from the DER above
716        let n = hex::decode(
717            "b1d59f746650c6a4360d26dc2e05581e1bd12cddcfc459a75dd2ef6d38cb6e977c72cad72f5e8ad4795484211e71e9a292d25a3901fca4cd242649f56cce50ad6ba148658d71f3a9c8b39e92a7a49543243df8ca2688292d47ff2a92a6ee0c9151162936791f522afccd6a7508251934b909d62fa805bae0d79f83f3c981b39c15ea79ce7b4ec2ff82240ce2a9fb93ae49d7697d1248f73d4ad23461055f469a3936ab959a0c6a067aa19521650f3649a028e2ebe355909aae7c95d3fc988684478b2bb11b307cb58c6c14727e1b62103d400ac8eed0e0d6d7f7d7cfc1f4ae4cbd9759372f8408c52174abb05f134ca6788fb60ba3f35c57c07cd44011bb113b",
718        ).unwrap();
719        let e = hex::decode("010001").unwrap();
720
721        let key = PublicKey::from_n_e(&n, &e).unwrap();
722        key.verify_pkcs1_v1_5(&sig, &digest, DIGEST_INFO_SHA256_PREFIX).unwrap();
723    }
724
725    #[test]
726    fn pkcs1_v1_5_requires_digest_info_to_fill_modulus() {
727        let hash = [0xa5u8; 32];
728        let prefix = DIGEST_INFO_SHA256_PREFIX;
729        let expected_len = prefix.len() + hash.len();
730        let mod_bytes = 256usize;
731        // Canonical separator: the DigestInfo ends exactly at the modulus.
732        let sep = mod_bytes - 1 - expected_len;
733
734        let mut em = [0u8; 256];
735        em[0] = 0x00;
736        em[1] = 0x01;
737        for b in em[2..sep].iter_mut() {
738            *b = 0xff;
739        }
740        em[sep] = 0x00;
741        em[sep + 1..sep + 1 + prefix.len()].copy_from_slice(prefix);
742        em[sep + 1 + prefix.len()..sep + 1 + expected_len].copy_from_slice(&hash);
743        assert!(sep >= 10, "canonical padding must keep at least 8 FF bytes");
744        assert!(pkcs1_v1_5_em_matches(&em, prefix, &hash));
745
746        // Same modulus, but the DigestInfo is shifted one byte earlier and the
747        // final byte is a trailing 0x00: EM = 00 01 FF..FF 00 T || 00. This is
748        // accepted by a "trailing bytes must be zero" check but rejected because
749        // the DigestInfo does not fill the modulus (M-09).
750        let mut em_trailing = [0u8; 256];
751        em_trailing[0] = 0x00;
752        em_trailing[1] = 0x01;
753        for b in em_trailing[2..sep - 1].iter_mut() {
754            *b = 0xff;
755        }
756        em_trailing[sep - 1] = 0x00;
757        let di = sep;
758        em_trailing[di..di + prefix.len()].copy_from_slice(prefix);
759        em_trailing[di + prefix.len()..di + expected_len].copy_from_slice(&hash);
760        assert!(!pkcs1_v1_5_em_matches(&em_trailing, prefix, &hash));
761    }
762
763    #[test]
764    fn from_n_e_validates_parameters() {
765        // 2048-bit odd modulus.
766        let n = hex::decode(
767            "b1d59f746650c6a4360d26dc2e05581e1bd12cddcfc459a75dd2ef6d38cb6e977c72cad72f5e8ad4795484211e71e9a292d25a3901fca4cd242649f56cce50ad6ba148658d71f3a9c8b39e92a7a49543243df8ca2688292d47ff2a92a6ee0c9151162936791f522afccd6a7508251934b909d62fa805bae0d79f83f3c981b39c15ea79ce7b4ec2ff82240ce2a9fb93ae49d7697d1248f73d4ad23461055f469a3936ab959a0c6a067aa19521650f3649a028e2ebe355909aae7c95d3fc988684478b2bb11b307cb58c6c14727e1b62103d400ac8eed0e0d6d7f7d7cfc1f4ae4cbd9759372f8408c52174abb05f134ca6788fb60ba3f35c57c07cd44011bb113b",
768        ).unwrap();
769        let e = hex::decode("010001").unwrap();
770
771        // Valid odd exponents >= 3.
772        assert!(PublicKey::from_n_e(&n, &e).is_ok());
773        assert!(PublicKey::from_n_e(&n, &[3]).is_ok());
774
775        // Exponents zero, one, two, and even values are rejected.
776        assert!(PublicKey::from_n_e(&n, &[0]).is_err());
777        assert!(PublicKey::from_n_e(&n, &[1]).is_err());
778        assert!(PublicKey::from_n_e(&n, &[2]).is_err());
779        assert!(PublicKey::from_n_e(&n, &[4]).is_err());
780
781        // Empty, zero, even, and below-minimum moduli are rejected.
782        assert!(PublicKey::from_n_e(&[], &e).is_err());
783        assert!(PublicKey::from_n_e(&[0], &e).is_err());
784        assert!(PublicKey::from_n_e(&[2], &e).is_err());
785        let mut small = n[..128].to_vec();
786        small[127] |= 1;
787        assert!(PublicKey::from_n_e(&small, &e).is_err());
788
789        // Exponents wider than 64 bits are rejected; verification cost grows
790        // linearly with the exponent, so an attacker-chosen exponent must not
791        // be able to turn verification into a CPU denial of service.
792        let huge_e = vec![1u8, 0, 0, 0, 0, 0, 0, 0, 0]; // 2^64, 65 bits
793        assert!(PublicKey::from_n_e(&n, &huge_e).is_err());
794        // 2^64 - 1 (odd, exactly 64 bits) is the largest accepted exponent.
795        let max_e = hex::decode("ffffffffffffffff").unwrap();
796        assert!(PublicKey::from_n_e(&n, &max_e).is_ok());
797
798        // Leading zero bytes in `n` must not inflate the reported length.
799        let mut padded_n = vec![0u8];
800        padded_n.extend_from_slice(&n);
801        let padded_key = PublicKey::from_n_e(&padded_n, &e).unwrap();
802        assert_eq!(padded_key.modulus_len_bytes(), n.len());
803
804        // The exponent must be strictly smaller than the modulus.
805        assert!(PublicKey::from_n_e(&n, &n).is_err());
806    }
807
808    /// Encode a DER length using the minimal form (test helper).
809    fn der_length(len: usize) -> Vec<u8> {
810        if len < 0x80 {
811            vec![len as u8]
812        } else if len <= 0xff {
813            vec![0x81, len as u8]
814        } else {
815            vec![0x82, (len >> 8) as u8, (len & 0xff) as u8]
816        }
817    }
818
819    /// Encode a non-negative big-endian magnitude as a strict DER INTEGER
820    /// (test helper).
821    fn der_integer(value: &[u8]) -> Vec<u8> {
822        let mut start = 0;
823        while start + 1 < value.len() && value[start] == 0 {
824            start += 1;
825        }
826        let value = &value[start..];
827        let mut out = vec![0x02];
828        if value[0] & 0x80 != 0 {
829            out.extend(der_length(value.len() + 1));
830            out.push(0x00);
831        } else {
832            out.extend(der_length(value.len()));
833        }
834        out.extend_from_slice(value);
835        out
836    }
837
838    /// Wrap a body in a strict DER SEQUENCE (test helper).
839    fn der_sequence(body: &[u8]) -> Vec<u8> {
840        let mut out = vec![0x30];
841        out.extend(der_length(body.len()));
842        out.extend_from_slice(body);
843        out
844    }
845
846    #[test]
847    fn read_length_requires_minimal_der() {
848        assert_eq!(read_length(&[0x05]).unwrap(), (5, 1));
849        assert_eq!(read_length(&[0x81, 0x80]).unwrap(), (128, 2));
850        assert_eq!(read_length(&[0x82, 0x01, 0x00]).unwrap(), (256, 3));
851
852        // Indefinite length is forbidden in DER.
853        assert!(read_length(&[0x80, 0x00]).is_err());
854        // Long form with a leading zero byte.
855        assert!(read_length(&[0x82, 0x00, 0x80]).is_err());
856        // Long form used for a value that fits in the short form.
857        assert!(read_length(&[0x81, 0x05]).is_err());
858        assert!(read_length(&[0x81, 0x7f]).is_err());
859        // Truncated and empty inputs.
860        assert!(read_length(&[0x82, 0x01]).is_err());
861        assert!(read_length(&[]).is_err());
862    }
863
864    #[test]
865    fn read_integer_requires_minimal_der() {
866        let mut out = [0u8; 8];
867
868        // Minimal positive INTEGER, e = 65537.
869        assert_eq!(read_integer(&[0x02, 0x03, 0x01, 0x00, 0x01], &mut out).unwrap(), (3, 5));
870        assert_eq!(&out[..3], &[0x01, 0x00, 0x01]);
871
872        // A leading zero is required when the top bit of the value is set.
873        assert_eq!(read_integer(&[0x02, 0x02, 0x00, 0x80], &mut out).unwrap(), (1, 4));
874        assert_eq!(out[0], 0x80);
875
876        // Negative INTEGER (top bit set without a sign byte).
877        assert!(read_integer(&[0x02, 0x01, 0x80], &mut out).is_err());
878        // Superfluous leading zero.
879        assert!(read_integer(&[0x02, 0x02, 0x00, 0x7f], &mut out).is_err());
880        // Non-minimal length.
881        assert!(read_integer(&[0x02, 0x81, 0x01, 0x05], &mut out).is_err());
882        // Empty and truncated values, and the wrong tag.
883        assert!(read_integer(&[0x02, 0x00], &mut out).is_err());
884        assert!(read_integer(&[0x02, 0x02, 0x01], &mut out).is_err());
885        assert!(read_integer(&[0x04, 0x01, 0x01], &mut out).is_err());
886    }
887
888    #[cfg(feature = "alloc")]
889    #[test]
890    fn from_pkcs1_der_is_strict() {
891        // 2048-bit odd modulus (top bit set, so DER carries a 0x00 sign byte)
892        // with e = 65537.
893        let mut n = [0x80u8; 256];
894        n[255] |= 1;
895        let e = [0x01u8, 0x00, 0x01];
896
897        let mut body = der_integer(&n);
898        body.extend(der_integer(&e));
899        let der = der_sequence(&body);
900
901        let key = PublicKey::from_pkcs1_der(&der).unwrap();
902        assert_eq!(key.n_bytes(), n.to_vec());
903        assert_eq!(key.e_bytes().as_slice(), &e);
904
905        // Trailing byte inside the SEQUENCE after `e`.
906        let mut body_trailing = body.clone();
907        body_trailing.push(0x00);
908        assert!(PublicKey::from_pkcs1_der(&der_sequence(&body_trailing)).is_err());
909
910        // Trailing byte after the outer SEQUENCE.
911        let mut der_trailing = der.clone();
912        der_trailing.push(0x00);
913        assert!(PublicKey::from_pkcs1_der(&der_trailing).is_err());
914
915        // Non-minimal outer SEQUENCE length (`83 00 01 0A` instead of `82 01 0A`).
916        let mut non_minimal = vec![0x30, 0x83, 0x00];
917        non_minimal.extend_from_slice(&(body.len() as u16).to_be_bytes());
918        non_minimal.extend_from_slice(&body);
919        assert!(PublicKey::from_pkcs1_der(&non_minimal).is_err());
920
921        // Non-minimal INTEGER length for `e`.
922        let mut body_bad_e_len = der_integer(&n);
923        body_bad_e_len.extend_from_slice(&[0x02, 0x81, 0x03, 0x01, 0x00, 0x01]);
924        assert!(PublicKey::from_pkcs1_der(&der_sequence(&body_bad_e_len)).is_err());
925
926        // Negative `e` (top bit set without a sign byte).
927        let mut body_neg_e = der_integer(&n);
928        body_neg_e.extend_from_slice(&[0x02, 0x01, 0x80]);
929        assert!(PublicKey::from_pkcs1_der(&der_sequence(&body_neg_e)).is_err());
930    }
931
932    #[test]
933    fn pss_non_full_length_modulus() {
934        // Regression for L-03. This modulus is 2049 bits (top byte 0x01): it is
935        // 257 bytes long, but RFC 8017 sets emBits = bitlen(n) - 1 = 2048 and
936        // emLen = 256, with no leftmost bits cleared from DB. Deriving
937        // emBits/emLen from the byte length instead (emBits = 2055,
938        // emLen = 257) rejected this valid signature.
939        let n = hex::decode(
940            "0164172bd317d5b8c209ea97405faad6a4ddb71dcf1233600f52d902ce3194409fe87e3efb35ea5c3d3dad4b224112105fa999fa26a44b5ed8d1bd3a6db9f8661f5cdd519805cb188ae89883799a0f82ae0f024d6faacaae8eecce96a9963d776779dfce1f2b43a012be154f321edb881401e062b985f2c2f6c69a6d08492e648a4f8084ccac74d29088a0baad787dd14b307c02f545f50662e08de2f0a6a52b5d400bb0cb48b1dec3c33c84bfc40021ac760d9d3be5229796f2a676408774e7c4f27492bce1731d51d58f56fd86e4c0b90134f115c94a0ab42aef65fbce2e4ea92e0d11937f4f612142fc888d3b040c8052026293b89b2d718cf85cf881dfc603",
941        ).unwrap();
942        let e = hex::decode("010001").unwrap();
943        let sig = hex::decode(
944            "0100156ede19d636555868311341b128ce65ec53c27f3e7dbfd35319e4356d93e9b7b968dca073ecc6caa1c0519fa89ff0cab4e49a21b0a37311ddca42de06468827880a574b96d83a572a0867ca1bed49644275ae8c3a9860377135728a3d6ee2b07625be2f434ca63fa9341fefccfbe9d9a356da673e40dbb2e87efa2a8ef271bc1aaee7a7e4443e39e14ff3def38a7987d5fa2bf6453c6dedb3a376c58d259ffae0e337f6d6a447ada7db55dabb6208e38e0d86280eeb2802da551e15ad4b52cd18d4dbe146f87349ba52332a2e8baac6c3d1606b97b625d4fb2d958643c7bb57319869366b91900deb1e72df47e92a6e1bbd38c5dfe66d359d283dde248b27",
945        ).unwrap();
946        let msg = b"stdx RSA-PSS L-03 regression vector";
947
948        let key = PublicKey::from_n_e(&n, &e).unwrap();
949        assert_eq!(key.n.bit_len(), 2049);
950        key.verify_pss::<crate::sha2::Sha256>(&sig, msg, 32).unwrap();
951
952        // A modified message must not verify.
953        let mut tampered = msg.to_vec();
954        tampered[0] ^= 0x01;
955        assert!(key.verify_pss::<crate::sha2::Sha256>(&sig, &tampered, 32).is_err());
956    }
957
958    #[cfg(feature = "std")]
959    #[test]
960    fn wycheproof_rsa_pss_2048_sha256() {
961        wycheproof_rsa_pss_test!(
962            "../testdata/wycheproof/testvectors_v1/rsa_pss_2048_sha256_mgf1_32_test.json",
963            crate::sha2::Sha256,
964            32
965        );
966    }
967
968    #[cfg(feature = "std")]
969    #[test]
970    fn wycheproof_rsa_pss_2048_sha384() {
971        wycheproof_rsa_pss_test!(
972            "../testdata/wycheproof/testvectors_v1/rsa_pss_2048_sha384_mgf1_48_test.json",
973            crate::sha2::Sha384,
974            48
975        );
976    }
977
978    #[cfg(feature = "std")]
979    #[test]
980    fn wycheproof_rsa_pss_3072_sha256() {
981        wycheproof_rsa_pss_test!(
982            "../testdata/wycheproof/testvectors_v1/rsa_pss_3072_sha256_mgf1_32_test.json",
983            crate::sha2::Sha256,
984            32
985        );
986    }
987
988    #[cfg(feature = "std")]
989    #[test]
990    fn wycheproof_rsa_pss_4096_sha512() {
991        wycheproof_rsa_pss_test!(
992            "../testdata/wycheproof/testvectors_v1/rsa_pss_4096_sha512_mgf1_64_test.json",
993            crate::sha2::Sha512,
994            64
995        );
996    }
997
998    #[test]
999    fn rsa_pkcs1_sha256_verify_works() {
1000        let pkcs1_der = hex::decode(
1001            "3082010a0282010100b1d59f746650c6a4360d26dc2e05581e1bd12cddcfc459a75dd2ef6d38cb6e977c72cad72f5e8ad4795484211e71e9a292d25a3901fca4cd242649f56cce50ad6ba148658d71f3a9c8b39e92a7a49543243df8ca2688292d47ff2a92a6ee0c9151162936791f522afccd6a7508251934b909d62fa805bae0d79f83f3c981b39c15ea79ce7b4ec2ff82240ce2a9fb93ae49d7697d1248f73d4ad23461055f469a3936ab959a0c6a067aa19521650f3649a028e2ebe355909aae7c95d3fc988684478b2bb11b307cb58c6c14727e1b62103d400ac8eed0e0d6d7f7d7cfc1f4ae4cbd9759372f8408c52174abb05f134ca6788fb60ba3f35c57c07cd44011bb113b0203010001",
1002        ).unwrap();
1003        let sig = hex::decode(
1004            "9d00f18defaa95b474b06ac4674b1b9270e110c6f474ce29e3aa972eca09137c9a82267e634986ecd54734f2edb1b3d72b539b8608e23074898c56042f9f014bfff59abce81c57d606b60f80ae4e110fc6f9dea99ce2897ce1d90661ab3d3b3f1a5ddf258b920a51c8c8758ab2da3da20da99c84eb2f57859b36918447c4cdbfa16cc09523fd27d28d4e97fa9ff0ea4d633c937a904a196a64e934851ee02b7922a8f5a4534bb10b8e16b89c12ddc347d7b4317f8b9d3dfed07a442d47351b18db38f45cc92e5c577b866df21766094d1f737ea418852827be3aec10d3c5a65a40087d9647b91a4d9419ad784a31caf02254cfc01a682bb6f5a231307f0fc8d9",
1005        ).unwrap();
1006        let digest = hex::decode("41cb0773387b187c038b7015498534c11369f1cfd094a714f4f39cf63ebb42ba").unwrap();
1007
1008        let key = PublicKey::from_pkcs1_der(&pkcs1_der).unwrap();
1009        key.verify_pkcs1_v1_5(&sig, &digest, DIGEST_INFO_SHA256_PREFIX).unwrap();
1010    }
1011
1012    #[cfg(feature = "std")]
1013    #[test]
1014    fn wycheproof_rsa_pkcs1_2048_sha256() {
1015        use crate::sha2::Sha256;
1016        wycheproof_rsa_test!(
1017            "../testdata/wycheproof/testvectors_v1/rsa_signature_2048_sha256_test.json",
1018            Sha256,
1019            DIGEST_INFO_SHA256_PREFIX
1020        );
1021    }
1022
1023    #[cfg(feature = "std")]
1024    #[test]
1025    fn wycheproof_rsa_pkcs1_2048_sha384() {
1026        use crate::sha2::Sha384;
1027        wycheproof_rsa_test!(
1028            "../testdata/wycheproof/testvectors_v1/rsa_signature_2048_sha384_test.json",
1029            Sha384,
1030            DIGEST_INFO_SHA384_PREFIX
1031        );
1032    }
1033
1034    #[cfg(feature = "std")]
1035    #[test]
1036    fn wycheproof_rsa_pkcs1_2048_sha512() {
1037        use crate::sha2::Sha512;
1038        wycheproof_rsa_test!(
1039            "../testdata/wycheproof/testvectors_v1/rsa_signature_2048_sha512_test.json",
1040            Sha512,
1041            DIGEST_INFO_SHA512_PREFIX
1042        );
1043    }
1044
1045    #[cfg(feature = "std")]
1046    #[test]
1047    fn wycheproof_rsa_pkcs1_3072_sha256() {
1048        use crate::sha2::Sha256;
1049        wycheproof_rsa_test!(
1050            "../testdata/wycheproof/testvectors_v1/rsa_signature_3072_sha256_test.json",
1051            Sha256,
1052            DIGEST_INFO_SHA256_PREFIX
1053        );
1054    }
1055
1056    #[cfg(feature = "std")]
1057    #[test]
1058    fn wycheproof_rsa_pkcs1_3072_sha384() {
1059        use crate::sha2::Sha384;
1060        wycheproof_rsa_test!(
1061            "../testdata/wycheproof/testvectors_v1/rsa_signature_3072_sha384_test.json",
1062            Sha384,
1063            DIGEST_INFO_SHA384_PREFIX
1064        );
1065    }
1066
1067    #[cfg(feature = "std")]
1068    #[test]
1069    fn wycheproof_rsa_pkcs1_3072_sha512() {
1070        use crate::sha2::Sha512;
1071        wycheproof_rsa_test!(
1072            "../testdata/wycheproof/testvectors_v1/rsa_signature_3072_sha512_test.json",
1073            Sha512,
1074            DIGEST_INFO_SHA512_PREFIX
1075        );
1076    }
1077
1078    #[cfg(feature = "std")]
1079    #[test]
1080    fn wycheproof_rsa_pkcs1_4096_sha256() {
1081        use crate::sha2::Sha256;
1082        wycheproof_rsa_test!(
1083            "../testdata/wycheproof/testvectors_v1/rsa_signature_4096_sha256_test.json",
1084            Sha256,
1085            DIGEST_INFO_SHA256_PREFIX
1086        );
1087    }
1088
1089    #[cfg(feature = "std")]
1090    #[test]
1091    fn wycheproof_rsa_pkcs1_4096_sha384() {
1092        use crate::sha2::Sha384;
1093        wycheproof_rsa_test!(
1094            "../testdata/wycheproof/testvectors_v1/rsa_signature_4096_sha384_test.json",
1095            Sha384,
1096            DIGEST_INFO_SHA384_PREFIX
1097        );
1098    }
1099
1100    #[cfg(feature = "std")]
1101    #[test]
1102    fn wycheproof_rsa_pkcs1_4096_sha512() {
1103        use crate::sha2::Sha512;
1104        wycheproof_rsa_test!(
1105            "../testdata/wycheproof/testvectors_v1/rsa_signature_4096_sha512_test.json",
1106            Sha512,
1107            DIGEST_INFO_SHA512_PREFIX
1108        );
1109    }
1110
1111    #[cfg(feature = "std")]
1112    #[test]
1113    fn wycheproof_rsa_pkcs1_8192_sha256() {
1114        use crate::sha2::Sha256;
1115        wycheproof_rsa_test!(
1116            "../testdata/wycheproof/testvectors_v1/rsa_signature_8192_sha256_test.json",
1117            Sha256,
1118            DIGEST_INFO_SHA256_PREFIX
1119        );
1120    }
1121
1122    #[cfg(feature = "std")]
1123    #[test]
1124    fn wycheproof_rsa_pkcs1_8192_sha384() {
1125        use crate::sha2::Sha384;
1126        wycheproof_rsa_test!(
1127            "../testdata/wycheproof/testvectors_v1/rsa_signature_8192_sha384_test.json",
1128            Sha384,
1129            DIGEST_INFO_SHA384_PREFIX
1130        );
1131    }
1132
1133    #[cfg(feature = "std")]
1134    #[test]
1135    fn wycheproof_rsa_pkcs1_8192_sha512() {
1136        use crate::sha2::Sha512;
1137        wycheproof_rsa_test!(
1138            "../testdata/wycheproof/testvectors_v1/rsa_signature_8192_sha512_test.json",
1139            Sha512,
1140            DIGEST_INFO_SHA512_PREFIX
1141        );
1142    }
1143}