libgo: update to Go 1.11
[official-gcc.git] / libgo / go / crypto / rsa / pss.go
blob3ff0c2f4d0076912c0144fd5e0befaccd9abf7ac
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.
5 package rsa
7 // This file implements the PSS signature scheme [1].
8 //
9 // [1] https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf
11 import (
12 "bytes"
13 "crypto"
14 "errors"
15 "hash"
16 "io"
17 "math/big"
20 func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byte, error) {
21 // See [1], section 9.1.1
22 hLen := hash.Size()
23 sLen := len(salt)
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
28 // long" and stop.
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.
49 // 5. Let
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.
57 var prefix [8]byte
59 hash.Write(prefix[:])
60 hash.Write(mHash)
61 hash.Write(salt)
63 h = hash.Sum(h[:0])
64 hash.Reset()
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
70 // emLen - hLen - 1.
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.
79 mgf1XOR(db, hash, h)
81 // 11. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in
82 // maskedDB to zero.
84 db[0] &= (0xFF >> uint(8*emLen-emBits))
86 // 12. Let EM = maskedDB || H || 0xbc.
87 em[emLen-1] = 0xBC
89 // 13. Output EM.
90 return em, nil
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"
96 // and stop.
98 // 2. Let mHash = Hash(M), an octet string of length hLen.
99 hLen := hash.Size()
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
123 // stop.
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.
131 mgf1XOR(db, hash, h)
133 // 9. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in DB
134 // to zero.
135 db[0] &= (0xFF >> uint(8*emLen-emBits))
137 if sLen == PSSSaltLengthAuto {
138 FindSaltLength:
139 for sLen = emLen - (hLen + 2); sLen >= 0; sLen-- {
140 switch db[emLen-hLen-sLen-2] {
141 case 1:
142 break FindSaltLength
143 case 0:
144 continue
145 default:
146 return ErrVerification
149 if sLen < 0 {
150 return ErrVerification
152 } else {
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] {
158 if e != 0x00 {
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:]
170 // 12. Let
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.
176 var prefix [8]byte
177 hash.Write(prefix[:])
178 hash.Write(mHash)
179 hash.Write(salt)
181 h0 := hash.Sum(nil)
183 // 14. If H = H', output "consistent." Otherwise, output "inconsistent."
184 if !bytes.Equal(h0, h) {
185 return ErrVerification
187 return nil
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())
197 if err != nil {
198 return
200 m := new(big.Int).SetBytes(em)
201 c, err := decryptAndCheck(rand, priv, m)
202 if err != nil {
203 return
205 s = make([]byte, (nBits+7)/8)
206 copyWithLeftPad(s, c.Bytes())
207 return
210 const (
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.
224 SaltLength int
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.
229 Hash crypto.Hash
232 // HashFunc returns pssOpts.Hash so that PSSOptions implements
233 // crypto.SignerOpts.
234 func (pssOpts *PSSOptions) HashFunc() crypto.Hash {
235 return pssOpts.Hash
238 func (opts *PSSOptions) saltLength() int {
239 if opts == nil {
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()
251 switch 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 {
259 hash = opts.Hash
262 salt := make([]byte, saltLength)
263 if _, err := io.ReadFull(rand, salt); err != nil {
264 return nil, err
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)
286 emBits := nBits - 1
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())