@@ -53,81 +53,56 @@ impl ::private::Private for PKCS1 { }
53
53
54
54
#[ cfg( feature ="rsa_signing" ) ]
55
55
impl RSAEncoding for PKCS1 {
56
- // Implement padding procedure per EMSA-PKCS1-v1_5,
57
- // https://tools.ietf.org/html/rfc3447#section-9.2.
58
56
fn encode ( & self , msg : & [ u8 ] , m_out : & mut [ u8 ] , _mod_bits : bits:: BitLength ,
59
57
_rng : & rand:: SecureRandom ) -> Result < ( ) , error:: Unspecified > {
60
- let em = m_out;
61
-
62
- let digest_len = self . digestinfo_prefix . len ( ) +
63
- self . digest_alg . output_len ;
64
-
65
- // Require at least 8 bytes of padding. Since we disallow keys smaller
66
- // than 2048 bits, this should never happen anyway.
67
- debug_assert ! ( em. len( ) >= digest_len + 11 ) ;
68
- let pad_len = em. len ( ) - digest_len - 3 ;
69
- em[ 0 ] = 0 ;
70
- em[ 1 ] = 1 ;
71
- for i in 0 ..pad_len {
72
- em[ 2 + i] = 0xff ;
73
- }
74
- em[ 2 + pad_len] = 0 ;
75
-
76
- let ( digest_prefix, digest_dst) = em[ 3 + pad_len..]
77
- . split_at_mut ( self . digestinfo_prefix . len ( ) ) ;
78
- digest_prefix. copy_from_slice ( self . digestinfo_prefix ) ;
79
- digest_dst. copy_from_slice (
80
- digest:: digest ( self . digest_alg , msg) . as_ref ( ) ) ;
58
+ pkcs1_encode ( & self , msg, m_out) ;
81
59
Ok ( ( ) )
82
60
}
83
61
}
84
62
85
63
impl RSAVerification for PKCS1 {
86
64
fn verify ( & self , msg : untrusted:: Input , m : & mut untrusted:: Reader ,
87
- _mod_bits : bits:: BitLength ) -> Result < ( ) , error:: Unspecified > {
88
- let em = m;
89
-
90
- if try!( em. read_byte ( ) ) != 0 ||
91
- try!( em. read_byte ( ) ) != 1 {
92
- return Err ( error:: Unspecified ) ;
93
- }
94
-
95
- let mut ps_len = 0 ;
96
- loop {
97
- match try!( em. read_byte ( ) ) {
98
- 0xff => {
99
- ps_len += 1 ;
100
- } ,
101
- 0x00 => {
102
- break ;
103
- } ,
104
- _ => {
105
- return Err ( error:: Unspecified ) ;
106
- } ,
107
- }
108
- }
109
- if ps_len < 8 {
110
- return Err ( error:: Unspecified ) ;
111
- }
112
-
113
- let em_digestinfo_prefix = try!( em. skip_and_get_input (
114
- self . digestinfo_prefix . len ( ) ) ) ;
115
- if em_digestinfo_prefix != self . digestinfo_prefix {
116
- return Err ( error:: Unspecified ) ;
117
- }
118
-
119
- let digest_alg = self . digest_alg ;
120
- let decoded_digest =
121
- try!( em. skip_and_get_input ( digest_alg. output_len ) ) ;
122
- let digest = digest:: digest ( digest_alg, msg. as_slice_less_safe ( ) ) ;
123
- if decoded_digest != digest. as_ref ( ) {
65
+ mod_bits : bits:: BitLength ) -> Result < ( ) , error:: Unspecified > {
66
+ // `mod_bits.as_usize_bytes_rounded_up() <=
67
+ // PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN` is ensured by `verify_rsa()`.
68
+ let mut calculated = [ 0u8 ; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN ] ;
69
+ let calculated =
70
+ & mut calculated[ ..mod_bits. as_usize_bytes_rounded_up ( ) ] ;
71
+ pkcs1_encode ( & self , msg. as_slice_less_safe ( ) , calculated) ;
72
+ if m. skip_to_end ( ) != polyfill:: ref_from_mut_ref ( calculated) {
124
73
return Err ( error:: Unspecified ) ;
125
74
}
126
-
127
75
Ok ( ( ) )
128
76
}
129
77
}
130
78
79
+ // Implement padding procedure per EMSA-PKCS1-v1_5,
80
+ // https://tools.ietf.org/html/rfc3447#section-9.2. This is used by both
81
+ // verification and signing so it needs to be able to handle moduli of the
82
+ // minimum and maximum sizes for both operations.
83
+ fn pkcs1_encode ( pkcs1 : & PKCS1 , msg : & [ u8 ] , m_out : & mut [ u8 ] ) {
84
+ let em = m_out;
85
+
86
+ let digest_len =
87
+ pkcs1. digestinfo_prefix . len ( ) + pkcs1. digest_alg . output_len ;
88
+
89
+ // The specification requires at least 8 bytes of padding. Since we
90
+ // disallow keys smaller than 2048 bits, this should always be true.
91
+ assert ! ( em. len( ) >= digest_len + 11 ) ;
92
+ let pad_len = em. len ( ) - digest_len - 3 ;
93
+ em[ 0 ] = 0 ;
94
+ em[ 1 ] = 1 ;
95
+ for i in 0 ..pad_len {
96
+ em[ 2 + i] = 0xff ;
97
+ }
98
+ em[ 2 + pad_len] = 0 ;
99
+
100
+ let ( digest_prefix, digest_dst) = em[ 3 + pad_len..]
101
+ . split_at_mut ( pkcs1. digestinfo_prefix . len ( ) ) ;
102
+ digest_prefix. copy_from_slice ( pkcs1. digestinfo_prefix ) ;
103
+ digest_dst. copy_from_slice ( digest:: digest ( pkcs1. digest_alg , msg) . as_ref ( ) ) ;
104
+ }
105
+
131
106
macro_rules! rsa_pkcs1_padding {
132
107
( $PADDING_ALGORITHM: ident, $digest_alg: expr, $digestinfo_prefix: expr,
133
108
$doc_str: expr ) => {
0 commit comments