@@ -2,6 +2,7 @@ use alloc::vec::Vec;
22use core:: cmp:: Ordering ;
33use core:: fmt;
44use core:: hash:: { Hash , Hasher } ;
5+ use core:: ops:: Range ;
56
67use crypto_bigint:: modular:: { BoxedMontyForm , BoxedMontyParams } ;
78use crypto_bigint:: { BoxedUint , Integer , NonZero , Odd , Resize } ;
@@ -206,29 +207,37 @@ impl RsaPublicKey {
206207 pub fn verify < S : SignatureScheme > ( & self , scheme : S , hashed : & [ u8 ] , sig : & [ u8 ] ) -> Result < ( ) > {
207208 scheme. verify ( self , hashed, sig)
208209 }
209- }
210210
211- impl RsaPublicKey {
212211 /// Minimum value of the public exponent `e`.
213212 pub const MIN_PUB_EXPONENT : u64 = 2 ;
214213
215214 /// Maximum value of the public exponent `e`.
216215 pub const MAX_PUB_EXPONENT : u64 = ( 1 << 33 ) - 1 ;
217216
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 ;
220222
221223 /// Create a new public key from its components.
222224 ///
223225 /// This function accepts public keys with a modulus size up to 4096-bits,
224226 /// i.e. [`RsaPublicKey::MAX_SIZE`].
225227 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 )
227229 }
228230
229231 /// 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) ?;
232241
233242 let n_odd = Odd :: new ( n. clone ( ) )
234243 . into_option ( )
@@ -239,19 +248,30 @@ impl RsaPublicKey {
239248 Ok ( Self { n, e, n_params } )
240249 }
241250
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+
242257 /// Create a new public key, bypassing checks around the modulus and public
243258 /// exponent size.
244259 ///
245260 /// This method is not recommended, and only intended for unusual use cases.
246261 /// Most applications should use [`RsaPublicKey::new`] or
247- /// [`RsaPublicKey::new_with_max_size `] instead.
262+ /// [`RsaPublicKey::new_with_size_limits `] instead.
248263 pub fn new_unchecked ( n : BoxedUint , e : BoxedUint ) -> Self {
249264 let n_odd = Odd :: new ( n. clone ( ) ) . expect ( "n must be odd" ) ;
250265 let n_params = BoxedMontyParams :: new ( n_odd) ;
251266 let n = NonZero :: new ( n) . expect ( "odd numbers are non zero" ) ;
252267
253268 Self { n, e, n_params }
254269 }
270+
271+ /// Get the size of the modulus `n` in bits.
272+ pub fn bits ( & self ) -> u32 {
273+ self . n . bits_vartime ( )
274+ }
255275}
256276
257277impl PublicKeyParts for RsaPrivateKey {
@@ -309,6 +329,36 @@ impl RsaPrivateKey {
309329 ///
310330 /// [NIST SP 800-56B Revision 2]: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Br2.pdf
311331 pub fn from_components (
332+ n : BoxedUint ,
333+ e : BoxedUint ,
334+ d : BoxedUint ,
335+ primes : Vec < BoxedUint > ,
336+ ) -> Result < RsaPrivateKey > {
337+ // The primes may come in padded with zeros too, so we need to shorten them as well.
338+ let primes = primes
339+ . into_iter ( )
340+ . map ( |p| {
341+ let p_bits = p. bits ( ) ;
342+ p. resize_unchecked ( p_bits)
343+ } )
344+ . collect ( ) ;
345+
346+ let mut k = Self :: from_components_unchecked ( n, e, d, primes) ?;
347+
348+ // Always validate the key, to ensure precompute can't fail
349+ k. validate ( ) ?;
350+
351+ // Precompute when possible, ignore error otherwise.
352+ k. precompute ( ) . ok ( ) ;
353+
354+ Ok ( k)
355+ }
356+
357+ /// Constructs an RSA key pair from individual components. Bypasses checks on the key's
358+ /// validity like the modulus size.
359+ ///
360+ /// Please use [`RsaPrivateKey::from_components`] whenever possible.
361+ pub fn from_components_unchecked (
312362 n : BoxedUint ,
313363 e : BoxedUint ,
314364 d : BoxedUint ,
@@ -337,8 +387,8 @@ impl RsaPrivateKey {
337387 1 => return Err ( Error :: NprimesTooSmall ) ,
338388 _ => {
339389 // 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.
390+ // This also ensures that `bits_precision ` of each prime is <= that of the modulus,
391+ // and `bits_precision ` of their product is >= that of the modulus.
342392 if & primes. iter ( ) . fold ( BoxedUint :: one ( ) , |acc, p| acc * p) != n_c. as_ref ( ) {
343393 return Err ( Error :: InvalidModulus ) ;
344394 }
@@ -354,7 +404,7 @@ impl RsaPrivateKey {
354404 } )
355405 . collect ( ) ;
356406
357- let mut k = RsaPrivateKey {
407+ Ok ( RsaPrivateKey {
358408 pubkey_components : RsaPublicKey {
359409 n : n_c,
360410 e,
@@ -363,15 +413,7 @@ impl RsaPrivateKey {
363413 d,
364414 primes,
365415 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)
416+ } )
375417 }
376418
377419 /// Constructs an RSA key pair from its two primes p and q.
@@ -584,6 +626,11 @@ impl RsaPrivateKey {
584626 ) -> Result < Vec < u8 > > {
585627 padding. sign ( Some ( rng) , self , digest_in)
586628 }
629+
630+ /// Get the size of the modulus `n` in bits.
631+ pub fn bits ( & self ) -> u32 {
632+ self . pubkey_components . bits ( )
633+ }
587634}
588635
589636impl PrivateKeyParts for RsaPrivateKey {
@@ -620,16 +667,30 @@ impl PrivateKeyParts for RsaPrivateKey {
620667 }
621668}
622669
623- /// Check that the public key is well formed and has an exponent within acceptable bounds.
670+ /// Check that the public key is well- formed and has an exponent within acceptable bounds.
624671#[ inline]
625672pub fn check_public ( public_key : & impl PublicKeyParts ) -> Result < ( ) > {
626- check_public_with_max_size ( public_key. n ( ) , public_key. e ( ) , RsaPublicKey :: MAX_SIZE )
673+ check_public_with_size_limits (
674+ public_key. n ( ) ,
675+ public_key. e ( ) ,
676+ RsaPublicKey :: MIN_SIZE ..RsaPublicKey :: MAX_SIZE ,
677+ )
627678}
628679
629- /// Check that the public key is well formed and has an exponent within acceptable bounds.
680+ /// Check that the public key is well- formed and has an exponent within acceptable bounds.
630681#[ 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 {
682+ fn check_public_with_size_limits (
683+ n : & BoxedUint ,
684+ e : & BoxedUint ,
685+ size_range_bits : Range < u32 > ,
686+ ) -> Result < ( ) > {
687+ let modulus_bits = n. bits_vartime ( ) ;
688+
689+ if modulus_bits < size_range_bits. start {
690+ return Err ( Error :: ModulusTooSmall ) ;
691+ }
692+
693+ if modulus_bits > size_range_bits. end {
633694 return Err ( Error :: ModulusTooLarge ) ;
634695 }
635696
@@ -732,7 +793,10 @@ mod tests {
732793 }
733794
734795 fn test_key_basics ( private_key : & RsaPrivateKey ) {
735- private_key. validate ( ) . expect ( "invalid private key" ) ;
796+ // Some test keys have moduli which are smaller than 1024-bits
797+ if private_key. bits ( ) >= RsaPublicKey :: MIN_SIZE {
798+ private_key. validate ( ) . expect ( "invalid private key" ) ;
799+ }
736800
737801 assert ! (
738802 PrivateKeyParts :: d( private_key) < PublicKeyParts :: n( private_key) . as_ref( ) ,
@@ -778,29 +842,17 @@ mod tests {
778842 } ;
779843 }
780844
781- key_generation ! ( key_generation_128, 2 , 128 ) ;
782845 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 ) ;
790846 key_generation ! ( key_generation_multi_16_1024, 16 , 1024 ) ;
791847
792848 #[ test]
793849 fn test_negative_decryption_value ( ) {
794850 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 ( ) ,
851+ let private_key = RsaPrivateKey :: from_components_unchecked (
852+ BoxedUint :: from_le_slice_vartime ( & [
853+ 99 , 192 , 208 , 179 , 0 , 220 , 7 , 29 , 49 , 151 , 75 , 107 , 75 , 73 , 200 , 180 ,
854+ ] ) ,
855+ BoxedUint :: from_le_slice_vartime ( & [ 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 ] ) ,
804856 BoxedUint :: from_le_slice (
805857 & [
806858 81 , 163 , 254 , 144 , 171 , 159 , 144 , 42 , 244 , 133 , 51 , 249 , 28 , 12 , 63 , 65 ,
@@ -827,21 +879,43 @@ mod tests {
827879 use serde_test:: { assert_tokens, Configure , Token } ;
828880
829881 let mut rng = ChaCha8Rng :: from_seed ( [ 42 ; 32 ] ) ;
830- let priv_key = RsaPrivateKey :: new ( & mut rng, 64 ) . expect ( "failed to generate key" ) ;
882+ let priv_key = RsaPrivateKey :: new ( & mut rng, 1024 ) . expect ( "failed to generate key" ) ;
831883
832884 let priv_tokens = [ Token :: Str ( concat ! (
833- "3056020100300d06092a864886f70d010101050004423040020100020900a" ,
834- "b240c3361d02e370203010001020811e54a15259d22f9020500ceff5cf302" ,
835- "0500d3a7aaad020500ccaddf17020500cb529d3d020500bb526d6f"
885+ "30820278020100300d06092a864886f70d0101010500048202623082025e0" ,
886+ "2010002818100cd1419dc3771354bee0955a90489cce0c98aee6577851358" ,
887+ "afe386a68bc95287862a1157d5aba8847e8e57b6f2f94748ab7efda3f3c74" ,
888+ "a6702329397ffe0a8f83e2ef5297aa3d9d883cbeb94ee018fd68e986e08d5" ,
889+ "b044c15e8170217cd57501d42dd72ef691b2a95bcc090d9bca735bba3ecb8" ,
890+ "38650f13b1aa36d0f454e37ff020301000102818100935c4248cf3df5c21d" ,
891+ "c56f5c07faccd129813f5481d189d94c69fdb366f6beeacb2927552a2032f" ,
892+ "321cd3e92237da40f3fcbfc8df6f9d928b3978c1ec8aab23e857a3ba2db26" ,
893+ "941ace6ecda8dcb290866a80820b3aa9138179ca867d37825ebcdb48adbe7" ,
894+ "c397f1e77c4160f0fbf87cc0cd5dff195ac96fd333c0b38384c74c1024100" ,
895+ "e90ad93c4b19bb40807391b5a9404ce5ea359e7b0556ee25cb2e7455aeb5c" ,
896+ "af83fc26f34457cdbb173347962c66b6fe0c4686b54dbe0d2c913a7aa924e" ,
897+ "ff5d67024100e148067566a1fa3aabd0672361be62715516c9d62790b03f4" ,
898+ "326cc00b2f782e6b64a167689e5c9aebe6a4cf594f3083380fe2a0a7edf1f" ,
899+ "325e58c523b98199a9024100df15fc8924577892b1a4707b178faf4d751c6" ,
900+ "91ed928b387486eaafd0ee7866a8916c73fa1b979d1f037ee6fa904563033" ,
901+ "b4c5f2911e328a3c9f87c0d190d1c7024057461ce26c7141cc6af5608f6f7" ,
902+ "55f13c2c0024f49a29ef4d321fb9425c1076033ac7e094c20ce4239185b5a" ,
903+ "246b06795576a178d16fc4d9317db859bfaafa8902410084b2d64651b471b" ,
904+ "f805af14018db693cdab6059063a6aa4eb8f9ca99b319074b79d7dead3d05" ,
905+ "68c364978be262d3395aa60541d670f94367babebe7616dbc260"
836906 ) ) ] ;
837907 assert_tokens ( & priv_key. clone ( ) . readable ( ) , & priv_tokens) ;
838908
839- let priv_tokens = [ Token :: Str (
840- "3024300d06092a864886f70d01010105000313003010020900ab240c3361d02e370203010001" ,
841- ) ] ;
909+ let pub_tokens = [ Token :: Str ( concat ! (
910+ "30819f300d06092a864886f70d010101050003818d0030818902818100cd1419dc3771354bee" ,
911+ "0955a90489cce0c98aee6577851358afe386a68bc95287862a1157d5aba8847e8e57b6f2f947" ,
912+ "48ab7efda3f3c74a6702329397ffe0a8f83e2ef5297aa3d9d883cbeb94ee018fd68e986e08d5" ,
913+ "b044c15e8170217cd57501d42dd72ef691b2a95bcc090d9bca735bba3ecb838650f13b1aa36d" ,
914+ "0f454e37ff0203010001" ,
915+ ) ) ] ;
842916 assert_tokens (
843917 & RsaPublicKey :: from ( priv_key. clone ( ) ) . readable ( ) ,
844- & priv_tokens ,
918+ & pub_tokens ,
845919 ) ;
846920 }
847921
0 commit comments