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