1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
7 // This file implements the PSS signature scheme [1].
9 // [1] https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf
20 func emsaPSSEncode(mHash
[]byte, emBits
int, salt
[]byte, hash hash
.Hash
) ([]byte, error
) {
21 // See [1], section 9.1.1
24 emLen
:= (emBits
+ 7) / 8
26 // 1. If the length of M is greater than the input limitation for the
27 // hash function (2^61 - 1 octets for SHA-1), output "message too
30 // 2. Let mHash = Hash(M), an octet string of length hLen.
32 if len(mHash
) != hLen
{
33 return nil, errors
.New("crypto/rsa: input must be hashed message")
36 // 3. If emLen < hLen + sLen + 2, output "encoding error" and stop.
38 if emLen
< hLen
+sLen
+2 {
39 return nil, errors
.New("crypto/rsa: key size too small for PSS signature")
42 em
:= make([]byte, emLen
)
43 db
:= em
[:emLen
-sLen
-hLen
-2+1+sLen
]
44 h
:= em
[emLen
-sLen
-hLen
-2+1+sLen
: emLen
-1]
46 // 4. Generate a random octet string salt of length sLen; if sLen = 0,
47 // then salt is the empty string.
50 // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt;
52 // M' is an octet string of length 8 + hLen + sLen with eight
53 // initial zero octets.
55 // 6. Let H = Hash(M'), an octet string of length hLen.
66 // 7. Generate an octet string PS consisting of emLen - sLen - hLen - 2
67 // zero octets. The length of PS may be 0.
69 // 8. Let DB = PS || 0x01 || salt; DB is an octet string of length
72 db
[emLen
-sLen
-hLen
-2] = 0x01
73 copy(db
[emLen
-sLen
-hLen
-1:], salt
)
75 // 9. Let dbMask = MGF(H, emLen - hLen - 1).
77 // 10. Let maskedDB = DB \xor dbMask.
81 // 11. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in
84 db
[0] &= (0xFF >> uint(8*emLen
-emBits
))
86 // 12. Let EM = maskedDB || H || 0xbc.
93 func emsaPSSVerify(mHash
, em
[]byte, emBits
, sLen
int, hash hash
.Hash
) error
{
94 // 1. If the length of M is greater than the input limitation for the
95 // hash function (2^61 - 1 octets for SHA-1), output "inconsistent"
98 // 2. Let mHash = Hash(M), an octet string of length hLen.
100 if hLen
!= len(mHash
) {
101 return ErrVerification
104 // 3. If emLen < hLen + sLen + 2, output "inconsistent" and stop.
105 emLen
:= (emBits
+ 7) / 8
106 if emLen
< hLen
+sLen
+2 {
107 return ErrVerification
110 // 4. If the rightmost octet of EM does not have hexadecimal value
111 // 0xbc, output "inconsistent" and stop.
112 if em
[len(em
)-1] != 0xBC {
113 return ErrVerification
116 // 5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and
117 // let H be the next hLen octets.
118 db
:= em
[:emLen
-hLen
-1]
119 h
:= em
[emLen
-hLen
-1 : len(em
)-1]
121 // 6. If the leftmost 8 * emLen - emBits bits of the leftmost octet in
122 // maskedDB are not all equal to zero, output "inconsistent" and
124 if em
[0]&(0xFF<<uint(8-(8*emLen
-emBits
))) != 0 {
125 return ErrVerification
128 // 7. Let dbMask = MGF(H, emLen - hLen - 1).
130 // 8. Let DB = maskedDB \xor dbMask.
133 // 9. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in DB
135 db
[0] &= (0xFF >> uint(8*emLen
-emBits
))
137 if sLen
== PSSSaltLengthAuto
{
139 for sLen
= emLen
- (hLen
+ 2); sLen
>= 0; sLen
-- {
140 switch db
[emLen
-hLen
-sLen
-2] {
146 return ErrVerification
150 return ErrVerification
153 // 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero
154 // or if the octet at position emLen - hLen - sLen - 1 (the leftmost
155 // position is "position 1") does not have hexadecimal value 0x01,
156 // output "inconsistent" and stop.
157 for _
, e
:= range db
[:emLen
-hLen
-sLen
-2] {
159 return ErrVerification
162 if db
[emLen
-hLen
-sLen
-2] != 0x01 {
163 return ErrVerification
167 // 11. Let salt be the last sLen octets of DB.
168 salt
:= db
[len(db
)-sLen
:]
171 // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ;
172 // M' is an octet string of length 8 + hLen + sLen with eight
173 // initial zero octets.
175 // 13. Let H' = Hash(M'), an octet string of length hLen.
177 hash
.Write(prefix
[:])
183 // 14. If H = H', output "consistent." Otherwise, output "inconsistent."
184 if !bytes
.Equal(h0
, h
) {
185 return ErrVerification
190 // signPSSWithSalt calculates the signature of hashed using PSS [1] with specified salt.
191 // Note that hashed must be the result of hashing the input message using the
192 // given hash function. salt is a random sequence of bytes whose length will be
193 // later used to verify the signature.
194 func signPSSWithSalt(rand io
.Reader
, priv
*PrivateKey
, hash crypto
.Hash
, hashed
, salt
[]byte) (s
[]byte, err error
) {
195 nBits
:= priv
.N
.BitLen()
196 em
, err
:= emsaPSSEncode(hashed
, nBits
-1, salt
, hash
.New())
200 m
:= new(big
.Int
).SetBytes(em
)
201 c
, err
:= decryptAndCheck(rand
, priv
, m
)
205 s
= make([]byte, (nBits
+7)/8)
206 copyWithLeftPad(s
, c
.Bytes())
211 // PSSSaltLengthAuto causes the salt in a PSS signature to be as large
212 // as possible when signing, and to be auto-detected when verifying.
213 PSSSaltLengthAuto
= 0
214 // PSSSaltLengthEqualsHash causes the salt length to equal the length
215 // of the hash used in the signature.
216 PSSSaltLengthEqualsHash
= -1
219 // PSSOptions contains options for creating and verifying PSS signatures.
220 type PSSOptions
struct {
221 // SaltLength controls the length of the salt used in the PSS
222 // signature. It can either be a number of bytes, or one of the special
223 // PSSSaltLength constants.
226 // Hash, if not zero, overrides the hash function passed to SignPSS.
227 // This is the only way to specify the hash function when using the
228 // crypto.Signer interface.
232 // HashFunc returns pssOpts.Hash so that PSSOptions implements
233 // crypto.SignerOpts.
234 func (pssOpts
*PSSOptions
) HashFunc() crypto
.Hash
{
238 func (opts
*PSSOptions
) saltLength() int {
240 return PSSSaltLengthAuto
242 return opts
.SaltLength
245 // SignPSS calculates the signature of hashed using RSASSA-PSS [1].
246 // Note that hashed must be the result of hashing the input message using the
247 // given hash function. The opts argument may be nil, in which case sensible
248 // defaults are used.
249 func SignPSS(rand io
.Reader
, priv
*PrivateKey
, hash crypto
.Hash
, hashed
[]byte, opts
*PSSOptions
) ([]byte, error
) {
250 saltLength
:= opts
.saltLength()
252 case PSSSaltLengthAuto
:
253 saltLength
= (priv
.N
.BitLen()+7)/8 - 2 - hash
.Size()
254 case PSSSaltLengthEqualsHash
:
255 saltLength
= hash
.Size()
258 if opts
!= nil && opts
.Hash
!= 0 {
262 salt
:= make([]byte, saltLength
)
263 if _
, err
:= io
.ReadFull(rand
, salt
); err
!= nil {
266 return signPSSWithSalt(rand
, priv
, hash
, hashed
, salt
)
269 // VerifyPSS verifies a PSS signature.
270 // hashed is the result of hashing the input message using the given hash
271 // function and sig is the signature. A valid signature is indicated by
272 // returning a nil error. The opts argument may be nil, in which case sensible
273 // defaults are used.
274 func VerifyPSS(pub
*PublicKey
, hash crypto
.Hash
, hashed
[]byte, sig
[]byte, opts
*PSSOptions
) error
{
275 return verifyPSS(pub
, hash
, hashed
, sig
, opts
.saltLength())
278 // verifyPSS verifies a PSS signature with the given salt length.
279 func verifyPSS(pub
*PublicKey
, hash crypto
.Hash
, hashed
[]byte, sig
[]byte, saltLen
int) error
{
280 nBits
:= pub
.N
.BitLen()
281 if len(sig
) != (nBits
+7)/8 {
282 return ErrVerification
284 s
:= new(big
.Int
).SetBytes(sig
)
285 m
:= encrypt(new(big
.Int
), pub
, s
)
287 emLen
:= (emBits
+ 7) / 8
288 if emLen
< len(m
.Bytes()) {
289 return ErrVerification
291 em
:= make([]byte, emLen
)
292 copyWithLeftPad(em
, m
.Bytes())
293 if saltLen
== PSSSaltLengthEqualsHash
{
294 saltLen
= hash
.Size()
296 return emsaPSSVerify(hashed
, em
, emBits
, saltLen
, hash
.New())