1
2
3
4
5 package rsa
6
7
8
9 import (
10 "bytes"
11 "crypto/internal/fips140"
12 "errors"
13 )
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 var hashPrefixes = map[string][]byte{
29 "MD5": {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
30 "SHA-1": {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},
31 "SHA-224": {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
32 "SHA-256": {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
33 "SHA-384": {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
34 "SHA-512": {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
35 "SHA-512/224": {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x05, 0x05, 0x00, 0x04, 0x1C},
36 "SHA-512/256": {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x06, 0x05, 0x00, 0x04, 0x20},
37 "SHA3-224": {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x07, 0x05, 0x00, 0x04, 0x1C},
38 "SHA3-256": {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08, 0x05, 0x00, 0x04, 0x20},
39 "SHA3-384": {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x09, 0x05, 0x00, 0x04, 0x30},
40 "SHA3-512": {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0a, 0x05, 0x00, 0x04, 0x40},
41 "MD5+SHA1": {},
42 "RIPEMD-160": {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
43 }
44
45
46
47
48
49 func SignPKCS1v15(priv *PrivateKey, hash string, hashed []byte) ([]byte, error) {
50 fipsSelfTest()
51 fips140.RecordApproved()
52 checkApprovedHashName(hash)
53
54 return signPKCS1v15(priv, hash, hashed)
55 }
56
57 func signPKCS1v15(priv *PrivateKey, hash string, hashed []byte) ([]byte, error) {
58 em, err := pkcs1v15ConstructEM(&priv.pub, hash, hashed)
59 if err != nil {
60 return nil, err
61 }
62
63 return decrypt(priv, em, withCheck)
64 }
65
66 func pkcs1v15ConstructEM(pub *PublicKey, hash string, hashed []byte) ([]byte, error) {
67
68 var prefix []byte
69 if hash != "" {
70 var ok bool
71 prefix, ok = hashPrefixes[hash]
72 if !ok {
73 return nil, errors.New("crypto/rsa: unsupported hash function")
74 }
75 if len(hashed) != hashSize(hash) {
76 return nil, errors.New("crypto/rsa: hashed message length does not match hash function")
77 }
78 }
79
80
81 k := pub.Size()
82 if k < len(prefix)+len(hashed)+2+8+1 {
83 return nil, ErrMessageTooLong
84 }
85 em := make([]byte, k)
86 em[1] = 1
87 for i := 2; i < k-len(prefix)-len(hashed)-1; i++ {
88 em[i] = 0xff
89 }
90 copy(em[k-len(prefix)-len(hashed):], prefix)
91 copy(em[k-len(hashed):], hashed)
92 return em, nil
93 }
94
95
96
97
98
99 func VerifyPKCS1v15(pub *PublicKey, hash string, hashed []byte, sig []byte) error {
100 fipsSelfTest()
101 fips140.RecordApproved()
102 checkApprovedHashName(hash)
103
104 return verifyPKCS1v15(pub, hash, hashed, sig)
105 }
106
107 func verifyPKCS1v15(pub *PublicKey, hash string, hashed []byte, sig []byte) error {
108 if fipsApproved, err := checkPublicKey(pub); err != nil {
109 return err
110 } else if !fipsApproved {
111 fips140.RecordNonApproved()
112 }
113
114
115
116
117 if pub.Size() != len(sig) {
118 return ErrVerification
119 }
120
121 em, err := encrypt(pub, sig)
122 if err != nil {
123 return ErrVerification
124 }
125
126 expected, err := pkcs1v15ConstructEM(pub, hash, hashed)
127 if err != nil {
128 return ErrVerification
129 }
130 if !bytes.Equal(em, expected) {
131 return ErrVerification
132 }
133
134 return nil
135 }
136
137 func hashSize(hash string) int {
138 switch hash {
139 case "MD5":
140 return 16
141 case "SHA-1", "RIPEMD-160":
142 return 20
143 case "SHA-224", "SHA-512/224", "SHA3-224":
144 return 28
145 case "SHA-256", "SHA-512/256", "SHA3-256":
146 return 32
147 case "SHA-384", "SHA3-384":
148 return 48
149 case "SHA-512", "SHA3-512":
150 return 64
151 case "MD5+SHA1":
152 return 36
153 default:
154 return -1
155 }
156 }
157
158 func checkApprovedHashName(hash string) {
159 switch hash {
160 case "SHA-224", "SHA-256", "SHA-384", "SHA-512", "SHA-512/224", "SHA-512/256",
161 "SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512":
162 default:
163 fips140.RecordNonApproved()
164 }
165 }
166
View as plain text