1use big_number::Uint;
9
10use crate::{Hasher, RsaError};
11
12const RSA_MIN_BITS: usize = 2048;
14const RSA_MAX_BITS: usize = 8192;
16const 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
26pub 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
31pub 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
36pub 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
41pub struct PublicKey {
43 n: Uint<RSA_MAX_BITS, RSA_MAX_LIMBS>,
45 e: Uint<RSA_MAX_BITS, RSA_MAX_LIMBS>,
47 n_len: usize,
49 e_len: usize,
51 mu: [u64; big_number::MAX_LIMBS],
53}
54
55impl PublicKey {
56 #[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 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 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 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 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 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 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 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 let em_bits = self.n.bit_len() - 1;
238 let em_len = em_bits.div_ceil(8);
239
240 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 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 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 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 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 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 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 pub fn modulus_len_bytes(&self) -> usize {
363 self.n_len
364 }
365
366 #[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 #[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
383fn 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 let mut sep = 2;
399 while sep < mod_bytes && em[sep] == 0xff {
400 sep += 1;
401 }
402 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 if mod_bytes - di_start != expected_len {
412 return false;
413 }
414
415 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
426fn 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
445fn 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
476fn 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
511fn 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
535fn 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
544pub 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
551pub 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
558pub 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
565pub 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
571pub 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
577pub 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 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 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 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 let n = hex::decode(
767 "b1d59f746650c6a4360d26dc2e05581e1bd12cddcfc459a75dd2ef6d38cb6e977c72cad72f5e8ad4795484211e71e9a292d25a3901fca4cd242649f56cce50ad6ba148658d71f3a9c8b39e92a7a49543243df8ca2688292d47ff2a92a6ee0c9151162936791f522afccd6a7508251934b909d62fa805bae0d79f83f3c981b39c15ea79ce7b4ec2ff82240ce2a9fb93ae49d7697d1248f73d4ad23461055f469a3936ab959a0c6a067aa19521650f3649a028e2ebe355909aae7c95d3fc988684478b2bb11b307cb58c6c14727e1b62103d400ac8eed0e0d6d7f7d7cfc1f4ae4cbd9759372f8408c52174abb05f134ca6788fb60ba3f35c57c07cd44011bb113b",
768 ).unwrap();
769 let e = hex::decode("010001").unwrap();
770
771 assert!(PublicKey::from_n_e(&n, &e).is_ok());
773 assert!(PublicKey::from_n_e(&n, &[3]).is_ok());
774
775 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 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 let huge_e = vec![1u8, 0, 0, 0, 0, 0, 0, 0, 0]; assert!(PublicKey::from_n_e(&n, &huge_e).is_err());
794 let max_e = hex::decode("ffffffffffffffff").unwrap();
796 assert!(PublicKey::from_n_e(&n, &max_e).is_ok());
797
798 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 assert!(PublicKey::from_n_e(&n, &n).is_err());
806 }
807
808 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 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 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 assert!(read_length(&[0x80, 0x00]).is_err());
854 assert!(read_length(&[0x82, 0x00, 0x80]).is_err());
856 assert!(read_length(&[0x81, 0x05]).is_err());
858 assert!(read_length(&[0x81, 0x7f]).is_err());
859 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 assert_eq!(read_integer(&[0x02, 0x03, 0x01, 0x00, 0x01], &mut out).unwrap(), (3, 5));
870 assert_eq!(&out[..3], &[0x01, 0x00, 0x01]);
871
872 assert_eq!(read_integer(&[0x02, 0x02, 0x00, 0x80], &mut out).unwrap(), (1, 4));
874 assert_eq!(out[0], 0x80);
875
876 assert!(read_integer(&[0x02, 0x01, 0x80], &mut out).is_err());
878 assert!(read_integer(&[0x02, 0x02, 0x00, 0x7f], &mut out).is_err());
880 assert!(read_integer(&[0x02, 0x81, 0x01, 0x05], &mut out).is_err());
882 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 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 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 let mut der_trailing = der.clone();
912 der_trailing.push(0x00);
913 assert!(PublicKey::from_pkcs1_der(&der_trailing).is_err());
914
915 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 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 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 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 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}