Source file
src/crypto/rsa/pkcs1v15.go
1
2
3
4
5 package rsa
6
7 import (
8 "crypto"
9 "crypto/subtle"
10 "errors"
11 "io"
12 "math/big"
13
14 "crypto/internal/randutil"
15 )
16
17
18
19
20
21 type PKCS1v15DecryptOptions struct {
22
23
24
25
26 SessionKeyLen int
27 }
28
29
30
31
32
33
34
35
36
37
38
39 func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) ([]byte, error) {
40 randutil.MaybeReadByte(rand)
41
42 if err := checkPub(pub); err != nil {
43 return nil, err
44 }
45 k := pub.Size()
46 if len(msg) > k-11 {
47 return nil, ErrMessageTooLong
48 }
49
50
51 em := make([]byte, k)
52 em[1] = 2
53 ps, mm := em[2:len(em)-len(msg)-1], em[len(em)-len(msg):]
54 err := nonZeroRandomBytes(ps, rand)
55 if err != nil {
56 return nil, err
57 }
58 em[len(em)-len(msg)-1] = 0
59 copy(mm, msg)
60
61 m := new(big.Int).SetBytes(em)
62 c := encrypt(new(big.Int), pub, m)
63
64 return c.FillBytes(em), nil
65 }
66
67
68
69
70
71
72
73
74
75 func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error) {
76 if err := checkPub(&priv.PublicKey); err != nil {
77 return nil, err
78 }
79 valid, out, index, err := decryptPKCS1v15(rand, priv, ciphertext)
80 if err != nil {
81 return nil, err
82 }
83 if valid == 0 {
84 return nil, ErrDecryption
85 }
86 return out[index:], nil
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) error {
109 if err := checkPub(&priv.PublicKey); err != nil {
110 return err
111 }
112 k := priv.Size()
113 if k-(len(key)+3+8) < 0 {
114 return ErrDecryption
115 }
116
117 valid, em, index, err := decryptPKCS1v15(rand, priv, ciphertext)
118 if err != nil {
119 return err
120 }
121
122 if len(em) != k {
123
124
125 return ErrDecryption
126 }
127
128 valid &= subtle.ConstantTimeEq(int32(len(em)-index), int32(len(key)))
129 subtle.ConstantTimeCopy(valid, key, em[len(em)-len(key):])
130 return nil
131 }
132
133
134
135
136
137
138
139 func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid int, em []byte, index int, err error) {
140 k := priv.Size()
141 if k < 11 {
142 err = ErrDecryption
143 return
144 }
145
146 c := new(big.Int).SetBytes(ciphertext)
147 m, err := decrypt(rand, priv, c)
148 if err != nil {
149 return
150 }
151
152 em = m.FillBytes(make([]byte, k))
153 firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
154 secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2)
155
156
157
158
159
160 lookingForIndex := 1
161
162 for i := 2; i < len(em); i++ {
163 equals0 := subtle.ConstantTimeByteEq(em[i], 0)
164 index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
165 lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
166 }
167
168
169
170 validPS := subtle.ConstantTimeLessOrEq(2+8, index)
171
172 valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) & validPS
173 index = subtle.ConstantTimeSelect(valid, index+1, 0)
174 return valid, em, index, nil
175 }
176
177
178 func nonZeroRandomBytes(s []byte, rand io.Reader) (err error) {
179 _, err = io.ReadFull(rand, s)
180 if err != nil {
181 return
182 }
183
184 for i := 0; i < len(s); i++ {
185 for s[i] == 0 {
186 _, err = io.ReadFull(rand, s[i:i+1])
187 if err != nil {
188 return
189 }
190
191
192 s[i] ^= 0x42
193 }
194 }
195
196 return
197 }
198
199
200
201
202
203
204
205
206
207 var hashPrefixes = map[crypto.Hash][]byte{
208 crypto.MD5: {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
209 crypto.SHA1: {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},
210 crypto.SHA224: {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
211 crypto.SHA256: {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
212 crypto.SHA384: {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
213 crypto.SHA512: {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
214 crypto.MD5SHA1: {},
215 crypto.RIPEMD160: {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
216 }
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231 func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
232 hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
233 if err != nil {
234 return nil, err
235 }
236
237 tLen := len(prefix) + hashLen
238 k := priv.Size()
239 if k < tLen+11 {
240 return nil, ErrMessageTooLong
241 }
242
243
244 em := make([]byte, k)
245 em[1] = 1
246 for i := 2; i < k-tLen-1; i++ {
247 em[i] = 0xff
248 }
249 copy(em[k-tLen:k-hashLen], prefix)
250 copy(em[k-hashLen:k], hashed)
251
252 m := new(big.Int).SetBytes(em)
253 c, err := decryptAndCheck(rand, priv, m)
254 if err != nil {
255 return nil, err
256 }
257
258 return c.FillBytes(em), nil
259 }
260
261
262
263
264
265
266 func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error {
267 hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
268 if err != nil {
269 return err
270 }
271
272 tLen := len(prefix) + hashLen
273 k := pub.Size()
274 if k < tLen+11 {
275 return ErrVerification
276 }
277
278
279
280
281 if k != len(sig) {
282 return ErrVerification
283 }
284
285 c := new(big.Int).SetBytes(sig)
286 m := encrypt(new(big.Int), pub, c)
287 em := m.FillBytes(make([]byte, k))
288
289
290 ok := subtle.ConstantTimeByteEq(em[0], 0)
291 ok &= subtle.ConstantTimeByteEq(em[1], 1)
292 ok &= subtle.ConstantTimeCompare(em[k-hashLen:k], hashed)
293 ok &= subtle.ConstantTimeCompare(em[k-tLen:k-hashLen], prefix)
294 ok &= subtle.ConstantTimeByteEq(em[k-tLen-1], 0)
295
296 for i := 2; i < k-tLen-1; i++ {
297 ok &= subtle.ConstantTimeByteEq(em[i], 0xff)
298 }
299
300 if ok != 1 {
301 return ErrVerification
302 }
303
304 return nil
305 }
306
307 func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte, err error) {
308
309
310 if hash == 0 {
311 return inLen, nil, nil
312 }
313
314 hashLen = hash.Size()
315 if inLen != hashLen {
316 return 0, nil, errors.New("crypto/rsa: input must be hashed message")
317 }
318 prefix, ok := hashPrefixes[hash]
319 if !ok {
320 return 0, nil, errors.New("crypto/rsa: unsupported hash function")
321 }
322 return
323 }
324
View as plain text