本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

298 lines
8.4KB

  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.
  4. package rsa
  5. // This file implements the PSS signature scheme [1].
  6. //
  7. // [1] http://www.rsa.com/rsalabs/pkcs/files/h11300-wp-pkcs-1v2-2-rsa-cryptography-standard.pdf
  8. import (
  9. "bytes"
  10. "crypto"
  11. "errors"
  12. "hash"
  13. "io"
  14. "math/big"
  15. )
  16. func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byte, error) {
  17. // See [1], section 9.1.1
  18. hLen := hash.Size()
  19. sLen := len(salt)
  20. emLen := (emBits + 7) / 8
  21. // 1. If the length of M is greater than the input limitation for the
  22. // hash function (2^61 - 1 octets for SHA-1), output "message too
  23. // long" and stop.
  24. //
  25. // 2. Let mHash = Hash(M), an octet string of length hLen.
  26. if len(mHash) != hLen {
  27. return nil, errors.New("crypto/rsa: input must be hashed message")
  28. }
  29. // 3. If emLen < hLen + sLen + 2, output "encoding error" and stop.
  30. if emLen < hLen+sLen+2 {
  31. return nil, errors.New("crypto/rsa: encoding error")
  32. }
  33. em := make([]byte, emLen)
  34. db := em[:emLen-sLen-hLen-2+1+sLen]
  35. h := em[emLen-sLen-hLen-2+1+sLen : emLen-1]
  36. // 4. Generate a random octet string salt of length sLen; if sLen = 0,
  37. // then salt is the empty string.
  38. //
  39. // 5. Let
  40. // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt;
  41. //
  42. // M' is an octet string of length 8 + hLen + sLen with eight
  43. // initial zero octets.
  44. //
  45. // 6. Let H = Hash(M'), an octet string of length hLen.
  46. var prefix [8]byte
  47. hash.Write(prefix[:])
  48. hash.Write(mHash)
  49. hash.Write(salt)
  50. h = hash.Sum(h[:0])
  51. hash.Reset()
  52. // 7. Generate an octet string PS consisting of emLen - sLen - hLen - 2
  53. // zero octets. The length of PS may be 0.
  54. //
  55. // 8. Let DB = PS || 0x01 || salt; DB is an octet string of length
  56. // emLen - hLen - 1.
  57. db[emLen-sLen-hLen-2] = 0x01
  58. copy(db[emLen-sLen-hLen-1:], salt)
  59. // 9. Let dbMask = MGF(H, emLen - hLen - 1).
  60. //
  61. // 10. Let maskedDB = DB \xor dbMask.
  62. mgf1XOR(db, hash, h)
  63. // 11. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in
  64. // maskedDB to zero.
  65. db[0] &= (0xFF >> uint(8*emLen-emBits))
  66. // 12. Let EM = maskedDB || H || 0xbc.
  67. em[emLen-1] = 0xBC
  68. // 13. Output EM.
  69. return em, nil
  70. }
  71. func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error {
  72. // 1. If the length of M is greater than the input limitation for the
  73. // hash function (2^61 - 1 octets for SHA-1), output "inconsistent"
  74. // and stop.
  75. //
  76. // 2. Let mHash = Hash(M), an octet string of length hLen.
  77. hLen := hash.Size()
  78. if hLen != len(mHash) {
  79. return ErrVerification
  80. }
  81. // 3. If emLen < hLen + sLen + 2, output "inconsistent" and stop.
  82. emLen := (emBits + 7) / 8
  83. if emLen < hLen+sLen+2 {
  84. return ErrVerification
  85. }
  86. // 4. If the rightmost octet of EM does not have hexadecimal value
  87. // 0xbc, output "inconsistent" and stop.
  88. if em[len(em)-1] != 0xBC {
  89. return ErrVerification
  90. }
  91. // 5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and
  92. // let H be the next hLen octets.
  93. db := em[:emLen-hLen-1]
  94. h := em[emLen-hLen-1 : len(em)-1]
  95. // 6. If the leftmost 8 * emLen - emBits bits of the leftmost octet in
  96. // maskedDB are not all equal to zero, output "inconsistent" and
  97. // stop.
  98. if em[0]&(0xFF<<uint(8-(8*emLen-emBits))) != 0 {
  99. return ErrVerification
  100. }
  101. // 7. Let dbMask = MGF(H, emLen - hLen - 1).
  102. //
  103. // 8. Let DB = maskedDB \xor dbMask.
  104. mgf1XOR(db, hash, h)
  105. // 9. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in DB
  106. // to zero.
  107. db[0] &= (0xFF >> uint(8*emLen-emBits))
  108. if sLen == PSSSaltLengthAuto {
  109. FindSaltLength:
  110. for sLen = emLen - (hLen + 2); sLen >= 0; sLen-- {
  111. switch db[emLen-hLen-sLen-2] {
  112. case 1:
  113. break FindSaltLength
  114. case 0:
  115. continue
  116. default:
  117. return ErrVerification
  118. }
  119. }
  120. if sLen < 0 {
  121. return ErrVerification
  122. }
  123. } else {
  124. // 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero
  125. // or if the octet at position emLen - hLen - sLen - 1 (the leftmost
  126. // position is "position 1") does not have hexadecimal value 0x01,
  127. // output "inconsistent" and stop.
  128. for _, e := range db[:emLen-hLen-sLen-2] {
  129. if e != 0x00 {
  130. return ErrVerification
  131. }
  132. }
  133. if db[emLen-hLen-sLen-2] != 0x01 {
  134. return ErrVerification
  135. }
  136. }
  137. // 11. Let salt be the last sLen octets of DB.
  138. salt := db[len(db)-sLen:]
  139. // 12. Let
  140. // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ;
  141. // M' is an octet string of length 8 + hLen + sLen with eight
  142. // initial zero octets.
  143. //
  144. // 13. Let H' = Hash(M'), an octet string of length hLen.
  145. var prefix [8]byte
  146. hash.Write(prefix[:])
  147. hash.Write(mHash)
  148. hash.Write(salt)
  149. h0 := hash.Sum(nil)
  150. // 14. If H = H', output "consistent." Otherwise, output "inconsistent."
  151. if !bytes.Equal(h0, h) {
  152. return ErrVerification
  153. }
  154. return nil
  155. }
  156. // signPSSWithSalt calculates the signature of hashed using PSS [1] with specified salt.
  157. // Note that hashed must be the result of hashing the input message using the
  158. // given hash function. salt is a random sequence of bytes whose length will be
  159. // later used to verify the signature.
  160. func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) (s []byte, err error) {
  161. nBits := priv.N.BitLen()
  162. em, err := emsaPSSEncode(hashed, nBits-1, salt, hash.New())
  163. if err != nil {
  164. return
  165. }
  166. m := new(big.Int).SetBytes(em)
  167. c, err := decryptAndCheck(rand, priv, m)
  168. if err != nil {
  169. return
  170. }
  171. s = make([]byte, (nBits+7)/8)
  172. copyWithLeftPad(s, c.Bytes())
  173. return
  174. }
  175. const (
  176. // PSSSaltLengthAuto causes the salt in a PSS signature to be as large
  177. // as possible when signing, and to be auto-detected when verifying.
  178. PSSSaltLengthAuto = 0
  179. // PSSSaltLengthEqualsHash causes the salt length to equal the length
  180. // of the hash used in the signature.
  181. PSSSaltLengthEqualsHash = -1
  182. )
  183. // PSSOptions contains options for creating and verifying PSS signatures.
  184. type PSSOptions struct {
  185. // SaltLength controls the length of the salt used in the PSS
  186. // signature. It can either be a number of bytes, or one of the special
  187. // PSSSaltLength constants.
  188. SaltLength int
  189. // Hash, if not zero, overrides the hash function passed to SignPSS.
  190. // This is the only way to specify the hash function when using the
  191. // crypto.Signer interface.
  192. Hash crypto.Hash
  193. }
  194. // HashFunc returns pssOpts.Hash so that PSSOptions implements
  195. // crypto.SignerOpts.
  196. func (pssOpts *PSSOptions) HashFunc() crypto.Hash {
  197. return pssOpts.Hash
  198. }
  199. func (opts *PSSOptions) saltLength() int {
  200. if opts == nil {
  201. return PSSSaltLengthAuto
  202. }
  203. return opts.SaltLength
  204. }
  205. // SignPSS calculates the signature of hashed using RSASSA-PSS [1].
  206. // Note that hashed must be the result of hashing the input message using the
  207. // given hash function. The opts argument may be nil, in which case sensible
  208. // defaults are used.
  209. func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte, opts *PSSOptions) (s []byte, err error) {
  210. saltLength := opts.saltLength()
  211. switch saltLength {
  212. case PSSSaltLengthAuto:
  213. saltLength = (priv.N.BitLen()+7)/8 - 2 - hash.Size()
  214. case PSSSaltLengthEqualsHash:
  215. saltLength = hash.Size()
  216. }
  217. if opts != nil && opts.Hash != 0 {
  218. hash = opts.Hash
  219. }
  220. salt := make([]byte, saltLength)
  221. if _, err = io.ReadFull(rand, salt); err != nil {
  222. return
  223. }
  224. return signPSSWithSalt(rand, priv, hash, hashed, salt)
  225. }
  226. // VerifyPSS verifies a PSS signature.
  227. // hashed is the result of hashing the input message using the given hash
  228. // function and sig is the signature. A valid signature is indicated by
  229. // returning a nil error. The opts argument may be nil, in which case sensible
  230. // defaults are used.
  231. func VerifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, opts *PSSOptions) error {
  232. return verifyPSS(pub, hash, hashed, sig, opts.saltLength())
  233. }
  234. // verifyPSS verifies a PSS signature with the given salt length.
  235. func verifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, saltLen int) error {
  236. nBits := pub.N.BitLen()
  237. if len(sig) != (nBits+7)/8 {
  238. return ErrVerification
  239. }
  240. s := new(big.Int).SetBytes(sig)
  241. m := encrypt(new(big.Int), pub, s)
  242. emBits := nBits - 1
  243. emLen := (emBits + 7) / 8
  244. if emLen < len(m.Bytes()) {
  245. return ErrVerification
  246. }
  247. em := make([]byte, emLen)
  248. copyWithLeftPad(em, m.Bytes())
  249. if saltLen == PSSSaltLengthEqualsHash {
  250. saltLen = hash.Size()
  251. }
  252. return emsaPSSVerify(hashed, em, emBits, saltLen, hash.New())
  253. }
上海开阖软件有限公司 沪ICP备12045867号-1