@@ -35,13 +35,8 @@ package blindrsa
35
35
// This file implements the RSASSA-PSS signature scheme according to RFC 8017.
36
36
37
37
import (
38
- "bytes"
39
- "crypto"
40
- "crypto/rsa"
41
38
"errors"
42
39
"hash"
43
- "io"
44
- "math/big"
45
40
)
46
41
47
42
// Per RFC 8017, Section 9.1
@@ -131,202 +126,3 @@ func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byt
131
126
// 13. Output EM.
132
127
return em , nil
133
128
}
134
-
135
- func emsaPSSVerify (mHash , em []byte , emBits , sLen int , hash hash.Hash ) error {
136
- // See RFC 8017, Section 9.1.2.
137
-
138
- hLen := hash .Size ()
139
- if sLen == PSSSaltLengthEqualsHash {
140
- sLen = hLen
141
- }
142
- emLen := (emBits + 7 ) / 8
143
- if emLen != len (em ) {
144
- return errors .New ("rsa: internal error: inconsistent length" )
145
- }
146
-
147
- // 1. If the length of M is greater than the input limitation for the
148
- // hash function (2^61 - 1 octets for SHA-1), output "inconsistent"
149
- // and stop.
150
- //
151
- // 2. Let mHash = Hash(M), an octet string of length hLen.
152
- if hLen != len (mHash ) {
153
- return ErrVerification
154
- }
155
-
156
- // 3. If emLen < hLen + sLen + 2, output "inconsistent" and stop.
157
- if emLen < hLen + sLen + 2 {
158
- return ErrVerification
159
- }
160
-
161
- // 4. If the rightmost octet of EM does not have hexadecimal value
162
- // 0xbc, output "inconsistent" and stop.
163
- if em [emLen - 1 ] != 0xbc {
164
- return ErrVerification
165
- }
166
-
167
- // 5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and
168
- // let H be the next hLen octets.
169
- db := em [:emLen - hLen - 1 ]
170
- h := em [emLen - hLen - 1 : emLen - 1 ]
171
-
172
- // 6. If the leftmost 8 * emLen - emBits bits of the leftmost octet in
173
- // maskedDB are not all equal to zero, output "inconsistent" and
174
- // stop.
175
- var bitMask byte = 0xff >> (8 * emLen - emBits )
176
- if em [0 ] & ^ bitMask != 0 {
177
- return ErrVerification
178
- }
179
-
180
- // 7. Let dbMask = MGF(H, emLen - hLen - 1).
181
- //
182
- // 8. Let DB = maskedDB \xor dbMask.
183
- mgf1XOR (db , hash , h )
184
-
185
- // 9. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in DB
186
- // to zero.
187
- db [0 ] &= bitMask
188
-
189
- // If we don't know the salt length, look for the 0x01 delimiter.
190
- if sLen == PSSSaltLengthAuto {
191
- psLen := bytes .IndexByte (db , 0x01 )
192
- if psLen < 0 {
193
- return ErrVerification
194
- }
195
- sLen = len (db ) - psLen - 1
196
- }
197
-
198
- // 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero
199
- // or if the octet at position emLen - hLen - sLen - 1 (the leftmost
200
- // position is "position 1") does not have hexadecimal value 0x01,
201
- // output "inconsistent" and stop.
202
- psLen := emLen - hLen - sLen - 2
203
- for _ , e := range db [:psLen ] {
204
- if e != 0x00 {
205
- return ErrVerification
206
- }
207
- }
208
- if db [psLen ] != 0x01 {
209
- return ErrVerification
210
- }
211
-
212
- // 11. Let salt be the last sLen octets of DB.
213
- salt := db [len (db )- sLen :]
214
-
215
- // 12. Let
216
- // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ;
217
- // M' is an octet string of length 8 + hLen + sLen with eight
218
- // initial zero octets.
219
- //
220
- // 13. Let H' = Hash(M'), an octet string of length hLen.
221
- var prefix [8 ]byte
222
- hash .Write (prefix [:])
223
- hash .Write (mHash )
224
- hash .Write (salt )
225
-
226
- h0 := hash .Sum (nil )
227
-
228
- // 14. If H = H', output "consistent." Otherwise, output "inconsistent."
229
- if ! bytes .Equal (h0 , h ) { // TODO: constant time?
230
- return ErrVerification
231
- }
232
- return nil
233
- }
234
-
235
- // signPSSWithSalt calculates the signature of hashed using PSS with specified salt.
236
- // Note that hashed must be the result of hashing the input message using the
237
- // given hash function. salt is a random sequence of bytes whose length will be
238
- // later used to verify the signature.
239
- func signPSSWithSalt (rand io.Reader , priv * rsa.PrivateKey , hash crypto.Hash , hashed , salt []byte ) ([]byte , error ) {
240
- emBits := priv .N .BitLen () - 1
241
- em , err := emsaPSSEncode (hashed , emBits , salt , hash .New ())
242
- if err != nil {
243
- return nil , err
244
- }
245
- m := new (big.Int ).SetBytes (em )
246
- c , err := decryptAndCheck (rand , priv , m )
247
- if err != nil {
248
- return nil , err
249
- }
250
- s := make ([]byte , priv .Size ())
251
- return c .FillBytes (s ), nil
252
- }
253
-
254
- const (
255
- // PSSSaltLengthAuto causes the salt in a PSS signature to be as large
256
- // as possible when signing, and to be auto-detected when verifying.
257
- PSSSaltLengthAuto = 0
258
- // PSSSaltLengthEqualsHash causes the salt length to equal the length
259
- // of the hash used in the signature.
260
- PSSSaltLengthEqualsHash = - 1
261
- )
262
-
263
- // PSSOptions contains options for creating and verifying PSS signatures.
264
- type PSSOptions struct {
265
- // SaltLength controls the length of the salt used in the PSS
266
- // signature. It can either be a number of bytes, or one of the special
267
- // PSSSaltLength constants.
268
- SaltLength int
269
-
270
- // Hash is the hash function used to generate the message digest. If not
271
- // zero, it overrides the hash function passed to SignPSS. It's required
272
- // when using PrivateKey.Sign.
273
- Hash crypto.Hash
274
- }
275
-
276
- // HashFunc returns opts.Hash so that PSSOptions implements crypto.SignerOpts.
277
- func (opts * PSSOptions ) HashFunc () crypto.Hash {
278
- return opts .Hash
279
- }
280
-
281
- func (opts * PSSOptions ) saltLength () int {
282
- if opts == nil {
283
- return PSSSaltLengthAuto
284
- }
285
- return opts .SaltLength
286
- }
287
-
288
- // SignPSS calculates the signature of digest using PSS.
289
- //
290
- // digest must be the result of hashing the input message using the given hash
291
- // function. The opts argument may be nil, in which case sensible defaults are
292
- // used. If opts.Hash is set, it overrides hash.
293
- func SignPSS (rand io.Reader , priv * rsa.PrivateKey , hash crypto.Hash , digest []byte , opts * PSSOptions ) ([]byte , error ) {
294
- if opts != nil && opts .Hash != 0 {
295
- hash = opts .Hash
296
- }
297
-
298
- saltLength := opts .saltLength ()
299
- switch saltLength {
300
- case PSSSaltLengthAuto :
301
- saltLength = (priv .N .BitLen ()- 1 + 7 )/ 8 - 2 - hash .Size ()
302
- case PSSSaltLengthEqualsHash :
303
- saltLength = hash .Size ()
304
- }
305
-
306
- salt := make ([]byte , saltLength )
307
- if _ , err := io .ReadFull (rand , salt ); err != nil {
308
- return nil , err
309
- }
310
- return signPSSWithSalt (rand , priv , hash , digest , salt )
311
- }
312
-
313
- // VerifyPSS verifies a PSS signature.
314
- //
315
- // A valid signature is indicated by returning a nil error. digest must be the
316
- // result of hashing the input message using the given hash function. The opts
317
- // argument may be nil, in which case sensible defaults are used. opts.Hash is
318
- // ignored.
319
- func VerifyPSS (pub * rsa.PublicKey , hash crypto.Hash , digest []byte , sig []byte , opts * PSSOptions ) error {
320
- if len (sig ) != pub .Size () {
321
- return ErrVerification
322
- }
323
- s := new (big.Int ).SetBytes (sig )
324
- m := encrypt (new (big.Int ), pub , s )
325
- emBits := pub .N .BitLen () - 1
326
- emLen := (emBits + 7 ) / 8
327
- if m .BitLen () > emLen * 8 {
328
- return ErrVerification
329
- }
330
- em := m .FillBytes (make ([]byte , emLen ))
331
- return emsaPSSVerify (digest , em , emBits , opts .saltLength (), hash .New ())
332
- }
0 commit comments