@@ -2,6 +2,7 @@ use alloc::vec::Vec;
2
2
use core:: cmp:: Ordering ;
3
3
use core:: fmt;
4
4
use core:: hash:: { Hash , Hasher } ;
5
+ use core:: ops:: Range ;
5
6
6
7
use crypto_bigint:: modular:: { BoxedMontyForm , BoxedMontyParams } ;
7
8
use crypto_bigint:: { BoxedUint , Integer , NonZero , Odd , Resize } ;
@@ -206,29 +207,37 @@ impl RsaPublicKey {
206
207
pub fn verify < S : SignatureScheme > ( & self , scheme : S , hashed : & [ u8 ] , sig : & [ u8 ] ) -> Result < ( ) > {
207
208
scheme. verify ( self , hashed, sig)
208
209
}
209
- }
210
210
211
- impl RsaPublicKey {
212
211
/// Minimum value of the public exponent `e`.
213
212
pub const MIN_PUB_EXPONENT : u64 = 2 ;
214
213
215
214
/// Maximum value of the public exponent `e`.
216
215
pub const MAX_PUB_EXPONENT : u64 = ( 1 << 33 ) - 1 ;
217
216
218
- /// Maximum size of the modulus `n` in bits.
219
- pub const MAX_SIZE : usize = 4096 ;
217
+ /// Default minimum size of the modulus `n` in bits.
218
+ pub const MIN_SIZE : u32 = 1024 ;
219
+
220
+ /// Default maximum size of the modulus `n` in bits.
221
+ pub const MAX_SIZE : u32 = 4096 ;
220
222
221
223
/// Create a new public key from its components.
222
224
///
223
225
/// This function accepts public keys with a modulus size up to 4096-bits,
224
226
/// i.e. [`RsaPublicKey::MAX_SIZE`].
225
227
pub fn new ( n : BoxedUint , e : BoxedUint ) -> Result < Self > {
226
- Self :: new_with_max_size ( n, e, Self :: MAX_SIZE )
228
+ Self :: new_with_size_limits ( n, e, Self :: MIN_SIZE .. Self :: MAX_SIZE )
227
229
}
228
230
229
231
/// Create a new public key from its components.
230
- pub fn new_with_max_size ( n : BoxedUint , e : BoxedUint , max_size : usize ) -> Result < Self > {
231
- check_public_with_max_size ( & n, & e, max_size) ?;
232
+ ///
233
+ /// Accepts a third argument which specifies a range of allowed sizes from minimum to maximum
234
+ /// in bits, which by default is `1024..4096`.
235
+ pub fn new_with_size_limits (
236
+ n : BoxedUint ,
237
+ e : BoxedUint ,
238
+ size_range_bits : Range < u32 > ,
239
+ ) -> Result < Self > {
240
+ check_public_with_size_limits ( & n, & e, size_range_bits) ?;
232
241
233
242
let n_odd = Odd :: new ( n. clone ( ) )
234
243
. into_option ( )
@@ -239,19 +248,30 @@ impl RsaPublicKey {
239
248
Ok ( Self { n, e, n_params } )
240
249
}
241
250
251
+ /// Deprecated: this has been replaced with [`RsaPublicKey::new_with_size_limits`].
252
+ #[ deprecated( since = "0.10.0" , note = "please use `new_with_size_limits` instead" ) ]
253
+ pub fn new_with_max_size ( n : BoxedUint , e : BoxedUint , max_size : usize ) -> Result < Self > {
254
+ Self :: new_with_size_limits ( n, e, Self :: MIN_SIZE ..( max_size as u32 ) )
255
+ }
256
+
242
257
/// Create a new public key, bypassing checks around the modulus and public
243
258
/// exponent size.
244
259
///
245
260
/// This method is not recommended, and only intended for unusual use cases.
246
261
/// Most applications should use [`RsaPublicKey::new`] or
247
- /// [`RsaPublicKey::new_with_max_size `] instead.
262
+ /// [`RsaPublicKey::new_with_size_limits `] instead.
248
263
pub fn new_unchecked ( n : BoxedUint , e : BoxedUint ) -> Self {
249
264
let n_odd = Odd :: new ( n. clone ( ) ) . expect ( "n must be odd" ) ;
250
265
let n_params = BoxedMontyParams :: new ( n_odd) ;
251
266
let n = NonZero :: new ( n) . expect ( "odd numbers are non zero" ) ;
252
267
253
268
Self { n, e, n_params }
254
269
}
270
+
271
+ /// Get the size of the modulus `n` in bits.
272
+ pub fn bits ( & self ) -> u32 {
273
+ self . n . bits_vartime ( )
274
+ }
255
275
}
256
276
257
277
impl PublicKeyParts for RsaPrivateKey {
@@ -277,6 +297,25 @@ impl RsaPrivateKey {
277
297
Self :: new_with_exp ( rng, bit_size, BoxedUint :: from ( Self :: EXP ) )
278
298
}
279
299
300
+ /// Generate a new Rsa key pair of the given bit size using the passed in `rng
301
+ /// and allowing hazardous insecure or weak constructions of `RsaPrivateKey
302
+ ///
303
+ /// Unless you have specific needs, you should use `RsaPrivateKey::new` instead
304
+ #[ cfg( feature = "hazmat" ) ]
305
+ pub fn new_unchecked < R : CryptoRng + ?Sized > (
306
+ rng : & mut R ,
307
+ bit_size : usize ,
308
+ ) -> Result < RsaPrivateKey > {
309
+ let components =
310
+ generate_multi_prime_key_with_exp ( rng, 2 , bit_size, BoxedUint :: from ( Self :: EXP ) ) ?;
311
+ RsaPrivateKey :: from_components_unchecked (
312
+ components. n . get ( ) ,
313
+ components. e ,
314
+ components. d ,
315
+ components. primes ,
316
+ )
317
+ }
318
+
280
319
/// Generate a new RSA key pair of the given bit size and the public exponent
281
320
/// using the passed in `rng`.
282
321
///
@@ -309,6 +348,36 @@ impl RsaPrivateKey {
309
348
///
310
349
/// [NIST SP 800-56B Revision 2]: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Br2.pdf
311
350
pub fn from_components (
351
+ n : BoxedUint ,
352
+ e : BoxedUint ,
353
+ d : BoxedUint ,
354
+ primes : Vec < BoxedUint > ,
355
+ ) -> Result < RsaPrivateKey > {
356
+ // The primes may come in padded with zeros too, so we need to shorten them as well.
357
+ let primes = primes
358
+ . into_iter ( )
359
+ . map ( |p| {
360
+ let p_bits = p. bits ( ) ;
361
+ p. resize_unchecked ( p_bits)
362
+ } )
363
+ . collect ( ) ;
364
+
365
+ let mut k = Self :: from_components_unchecked ( n, e, d, primes) ?;
366
+
367
+ // Always validate the key, to ensure precompute can't fail
368
+ k. validate ( ) ?;
369
+
370
+ // Precompute when possible, ignore error otherwise.
371
+ k. precompute ( ) . ok ( ) ;
372
+
373
+ Ok ( k)
374
+ }
375
+
376
+ /// Constructs an RSA key pair from individual components. Bypasses checks on the key's
377
+ /// validity like the modulus size.
378
+ ///
379
+ /// Please use [`RsaPrivateKey::from_components`] whenever possible.
380
+ pub fn from_components_unchecked (
312
381
n : BoxedUint ,
313
382
e : BoxedUint ,
314
383
d : BoxedUint ,
@@ -337,8 +406,8 @@ impl RsaPrivateKey {
337
406
1 => return Err ( Error :: NprimesTooSmall ) ,
338
407
_ => {
339
408
// Check that the product of primes matches the modulus.
340
- // This also ensures that `bit_precision ` of each prime is <= that of the modulus,
341
- // and `bit_precision ` of their product is >= that of the modulus.
409
+ // This also ensures that `bits_precision ` of each prime is <= that of the modulus,
410
+ // and `bits_precision ` of their product is >= that of the modulus.
342
411
if & primes. iter ( ) . fold ( BoxedUint :: one ( ) , |acc, p| acc * p) != n_c. as_ref ( ) {
343
412
return Err ( Error :: InvalidModulus ) ;
344
413
}
@@ -354,7 +423,7 @@ impl RsaPrivateKey {
354
423
} )
355
424
. collect ( ) ;
356
425
357
- let mut k = RsaPrivateKey {
426
+ Ok ( RsaPrivateKey {
358
427
pubkey_components : RsaPublicKey {
359
428
n : n_c,
360
429
e,
@@ -363,15 +432,7 @@ impl RsaPrivateKey {
363
432
d,
364
433
primes,
365
434
precomputed : None ,
366
- } ;
367
-
368
- // Always validate the key, to ensure precompute can't fail
369
- k. validate ( ) ?;
370
-
371
- // Precompute when possible, ignore error otherwise.
372
- k. precompute ( ) . ok ( ) ;
373
-
374
- Ok ( k)
435
+ } )
375
436
}
376
437
377
438
/// Constructs an RSA key pair from its two primes p and q.
@@ -584,6 +645,11 @@ impl RsaPrivateKey {
584
645
) -> Result < Vec < u8 > > {
585
646
padding. sign ( Some ( rng) , self , digest_in)
586
647
}
648
+
649
+ /// Get the size of the modulus `n` in bits.
650
+ pub fn bits ( & self ) -> u32 {
651
+ self . pubkey_components . bits ( )
652
+ }
587
653
}
588
654
589
655
impl PrivateKeyParts for RsaPrivateKey {
@@ -620,16 +686,30 @@ impl PrivateKeyParts for RsaPrivateKey {
620
686
}
621
687
}
622
688
623
- /// Check that the public key is well formed and has an exponent within acceptable bounds.
689
+ /// Check that the public key is well- formed and has an exponent within acceptable bounds.
624
690
#[ inline]
625
691
pub fn check_public ( public_key : & impl PublicKeyParts ) -> Result < ( ) > {
626
- check_public_with_max_size ( public_key. n ( ) , public_key. e ( ) , RsaPublicKey :: MAX_SIZE )
692
+ check_public_with_size_limits (
693
+ public_key. n ( ) ,
694
+ public_key. e ( ) ,
695
+ RsaPublicKey :: MIN_SIZE ..RsaPublicKey :: MAX_SIZE ,
696
+ )
627
697
}
628
698
629
- /// Check that the public key is well formed and has an exponent within acceptable bounds.
699
+ /// Check that the public key is well- formed and has an exponent within acceptable bounds.
630
700
#[ inline]
631
- fn check_public_with_max_size ( n : & BoxedUint , e : & BoxedUint , max_size : usize ) -> Result < ( ) > {
632
- if n. bits_vartime ( ) as usize > max_size {
701
+ fn check_public_with_size_limits (
702
+ n : & BoxedUint ,
703
+ e : & BoxedUint ,
704
+ size_range_bits : Range < u32 > ,
705
+ ) -> Result < ( ) > {
706
+ let modulus_bits = n. bits_vartime ( ) ;
707
+
708
+ if modulus_bits < size_range_bits. start {
709
+ return Err ( Error :: ModulusTooSmall ) ;
710
+ }
711
+
712
+ if modulus_bits > size_range_bits. end {
633
713
return Err ( Error :: ModulusTooLarge ) ;
634
714
}
635
715
@@ -732,7 +812,10 @@ mod tests {
732
812
}
733
813
734
814
fn test_key_basics ( private_key : & RsaPrivateKey ) {
735
- private_key. validate ( ) . expect ( "invalid private key" ) ;
815
+ // Some test keys have moduli which are smaller than 1024-bits
816
+ if private_key. bits ( ) >= RsaPublicKey :: MIN_SIZE {
817
+ private_key. validate ( ) . expect ( "invalid private key" ) ;
818
+ }
736
819
737
820
assert ! (
738
821
PrivateKeyParts :: d( private_key) < PublicKeyParts :: n( private_key) . as_ref( ) ,
@@ -778,29 +861,17 @@ mod tests {
778
861
} ;
779
862
}
780
863
781
- key_generation ! ( key_generation_128, 2 , 128 ) ;
782
864
key_generation ! ( key_generation_1024, 2 , 1024 ) ;
783
-
784
- key_generation ! ( key_generation_multi_3_256, 3 , 256 ) ;
785
-
786
- key_generation ! ( key_generation_multi_4_64, 4 , 64 ) ;
787
-
788
- key_generation ! ( key_generation_multi_5_64, 5 , 64 ) ;
789
- key_generation ! ( key_generation_multi_8_576, 8 , 576 ) ;
790
865
key_generation ! ( key_generation_multi_16_1024, 16 , 1024 ) ;
791
866
792
867
#[ test]
793
868
fn test_negative_decryption_value ( ) {
794
869
let bits = 128 ;
795
- let private_key = RsaPrivateKey :: from_components (
796
- BoxedUint :: from_le_slice (
797
- & [
798
- 99 , 192 , 208 , 179 , 0 , 220 , 7 , 29 , 49 , 151 , 75 , 107 , 75 , 73 , 200 , 180 ,
799
- ] ,
800
- bits,
801
- )
802
- . unwrap ( ) ,
803
- BoxedUint :: from_le_slice ( & [ 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 ] , 64 ) . unwrap ( ) ,
870
+ let private_key = RsaPrivateKey :: from_components_unchecked (
871
+ BoxedUint :: from_le_slice_vartime ( & [
872
+ 99 , 192 , 208 , 179 , 0 , 220 , 7 , 29 , 49 , 151 , 75 , 107 , 75 , 73 , 200 , 180 ,
873
+ ] ) ,
874
+ BoxedUint :: from_le_slice_vartime ( & [ 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 ] ) ,
804
875
BoxedUint :: from_le_slice (
805
876
& [
806
877
81 , 163 , 254 , 144 , 171 , 159 , 144 , 42 , 244 , 133 , 51 , 249 , 28 , 12 , 63 , 65 ,
@@ -827,21 +898,44 @@ mod tests {
827
898
use serde_test:: { assert_tokens, Configure , Token } ;
828
899
829
900
let mut rng = ChaCha8Rng :: from_seed ( [ 42 ; 32 ] ) ;
830
- let priv_key = RsaPrivateKey :: new ( & mut rng, 64 ) . expect ( "failed to generate key" ) ;
901
+ let priv_key = RsaPrivateKey :: new ( & mut rng, 1024 ) . expect ( "failed to generate key" ) ;
831
902
832
903
let priv_tokens = [ Token :: Str ( concat ! (
833
- "3056020100300d06092a864886f70d010101050004423040020100020900a" ,
834
- "b240c3361d02e370203010001020811e54a15259d22f9020500ceff5cf302" ,
835
- "0500d3a7aaad020500ccaddf17020500cb529d3d020500bb526d6f"
904
+ "30820278020100300d06092a864886f70d0101010500048202623082025e0" ,
905
+ "2010002818100cd1419dc3771354bee0955a90489cce0c98aee6577851358" ,
906
+ "afe386a68bc95287862a1157d5aba8847e8e57b6f2f94748ab7efda3f3c74" ,
907
+ "a6702329397ffe0b1d4f76e1b025d87d583e48b3cfce99d6a507d94eb46c5" ,
908
+ "242b3addb54d346ecf43eb0d7343bcb258a31d5fa51f47b9e0d7280623901" ,
909
+ "d1d29af1a986fec92ba5fe2430203010001028181009bb3203326d0c7b31f" ,
910
+ "456d08c6ce4c8379e10640792ecad271afe002406d184096a707c5d50ee00" ,
911
+ "1c00818266970c3233439551f0e2d879a8f7b90bd3d62fdffa3e661f14c8d" ,
912
+ "cce071f081966e25bb351289810c2f8a012f2fa3f001029d7f2e0cf24f6a4" ,
913
+ "b139292f8078fac24e7fc8185bab4f02f539267bd09b615e4e19fe1024100" ,
914
+ "e90ad93c4b19bb40807391b5a9404ce5ea359e7b0556ee25cb2e7455aeb5c" ,
915
+ "af83fc26f34457cdbb173347962c66b6fe0c4686b54dbe0d2c913a7aa924e" ,
916
+ "ff6031024100e148067566a1fa3aabd0672361be62715516c9d62790b03f4" ,
917
+ "326cc00b2f782e6b64a167689e5c9aebe6a4cf594f3083380fe2a0a7edf1f" ,
918
+ "325e58c523b981a0b3024100ab96e85323bd038a3fca588c58ddd681278d6" ,
919
+ "96e8d84ef7ef676f303afcb7d728287e897a55e84e8c8b9e772da447b3115" ,
920
+ "8d0912877fa7d4945b4d15c382f7d102400ddde317e2e36185af01baf7809" ,
921
+ "2b97884664cb233e9421002d0268a7c79a3c313c167b4903466bfacd4da3b" ,
922
+ "db99420df988ab89cdd96a102da2852ff7c134e5024100bafb0dac0fda53f" ,
923
+ "9c755c23483343922727b88a5256a6fb47242e1c99b8f8a2c914f39f7af30" ,
924
+ "1219245786a6bb15336231d6a9b57ee7e0b3dd75129f93f54ecf"
836
925
) ) ] ;
837
926
assert_tokens ( & priv_key. clone ( ) . readable ( ) , & priv_tokens) ;
838
927
839
- let priv_tokens = [ Token :: Str (
840
- "3024300d06092a864886f70d01010105000313003010020900ab240c3361d02e370203010001" ,
841
- ) ] ;
928
+ let pub_tokens = [ Token :: Str ( concat ! (
929
+ "30819f300d06092a864886f70d010101050003818d0030818902818100cd1" ,
930
+ "419dc3771354bee0955a90489cce0c98aee6577851358afe386a68bc95287" ,
931
+ "862a1157d5aba8847e8e57b6f2f94748ab7efda3f3c74a6702329397ffe0b" ,
932
+ "1d4f76e1b025d87d583e48b3cfce99d6a507d94eb46c5242b3addb54d346e" ,
933
+ "cf43eb0d7343bcb258a31d5fa51f47b9e0d7280623901d1d29af1a986fec9" ,
934
+ "2ba5fe2430203010001"
935
+ ) ) ] ;
842
936
assert_tokens (
843
937
& RsaPublicKey :: from ( priv_key. clone ( ) ) . readable ( ) ,
844
- & priv_tokens ,
938
+ & pub_tokens ,
845
939
) ;
846
940
}
847
941
0 commit comments