111
|
1 // Copyright 2009 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
|
|
5 package rsa
|
|
6
|
|
7 import (
|
|
8 "crypto"
|
|
9 "crypto/subtle"
|
|
10 "errors"
|
|
11 "io"
|
|
12 "math/big"
|
131
|
13
|
|
14 "crypto/internal/randutil"
|
111
|
15 )
|
|
16
|
|
17 // This file implements encryption and decryption using PKCS#1 v1.5 padding.
|
|
18
|
|
19 // PKCS1v15DecrypterOpts is for passing options to PKCS#1 v1.5 decryption using
|
|
20 // the crypto.Decrypter interface.
|
|
21 type PKCS1v15DecryptOptions struct {
|
|
22 // SessionKeyLen is the length of the session key that is being
|
|
23 // decrypted. If not zero, then a padding error during decryption will
|
|
24 // cause a random plaintext of this length to be returned rather than
|
|
25 // an error. These alternatives happen in constant time.
|
|
26 SessionKeyLen int
|
|
27 }
|
|
28
|
|
29 // EncryptPKCS1v15 encrypts the given message with RSA and the padding
|
|
30 // scheme from PKCS#1 v1.5. The message must be no longer than the
|
|
31 // length of the public modulus minus 11 bytes.
|
|
32 //
|
|
33 // The rand parameter is used as a source of entropy to ensure that
|
|
34 // encrypting the same message twice doesn't result in the same
|
|
35 // ciphertext.
|
|
36 //
|
|
37 // WARNING: use of this function to encrypt plaintexts other than
|
|
38 // session keys is dangerous. Use RSA OAEP in new protocols.
|
|
39 func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) ([]byte, error) {
|
131
|
40 randutil.MaybeReadByte(rand)
|
|
41
|
111
|
42 if err := checkPub(pub); err != nil {
|
|
43 return nil, err
|
|
44 }
|
131
|
45 k := pub.Size()
|
111
|
46 if len(msg) > k-11 {
|
|
47 return nil, ErrMessageTooLong
|
|
48 }
|
|
49
|
|
50 // EM = 0x00 || 0x02 || PS || 0x00 || M
|
|
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 // DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS#1 v1.5.
|
|
69 // If rand != nil, it uses RSA blinding to avoid timing side-channel attacks.
|
|
70 //
|
|
71 // Note that whether this function returns an error or not discloses secret
|
|
72 // information. If an attacker can cause this function to run repeatedly and
|
|
73 // learn whether each instance returned an error then they can decrypt and
|
|
74 // forge signatures as if they had the private key. See
|
|
75 // DecryptPKCS1v15SessionKey for a way of solving this problem.
|
|
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 // DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding scheme from PKCS#1 v1.5.
|
|
91 // If rand != nil, it uses RSA blinding to avoid timing side-channel attacks.
|
|
92 // It returns an error if the ciphertext is the wrong length or if the
|
|
93 // ciphertext is greater than the public modulus. Otherwise, no error is
|
|
94 // returned. If the padding is valid, the resulting plaintext message is copied
|
|
95 // into key. Otherwise, key is unchanged. These alternatives occur in constant
|
|
96 // time. It is intended that the user of this function generate a random
|
|
97 // session key beforehand and continue the protocol with the resulting value.
|
|
98 // This will remove any possibility that an attacker can learn any information
|
|
99 // about the plaintext.
|
|
100 // See ``Chosen Ciphertext Attacks Against Protocols Based on the RSA
|
|
101 // Encryption Standard PKCS #1'', Daniel Bleichenbacher, Advances in Cryptology
|
|
102 // (Crypto '98).
|
|
103 //
|
|
104 // Note that if the session key is too small then it may be possible for an
|
|
105 // attacker to brute-force it. If they can do that then they can learn whether
|
|
106 // a random value was used (because it'll be different for the same ciphertext)
|
|
107 // and thus whether the padding was correct. This defeats the point of this
|
|
108 // function. Using at least a 16-byte key will protect against this attack.
|
|
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 }
|
131
|
113 k := priv.Size()
|
111
|
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 // This should be impossible because decryptPKCS1v15 always
|
|
125 // returns the full slice.
|
|
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 // decryptPKCS1v15 decrypts ciphertext using priv and blinds the operation if
|
|
135 // rand is not nil. It returns one or zero in valid that indicates whether the
|
|
136 // plaintext was correctly structured. In either case, the plaintext is
|
|
137 // returned in em so that it may be read independently of whether it was valid
|
|
138 // in order to maintain constant memory access patterns. If the plaintext was
|
|
139 // valid then index contains the index of the original message in em.
|
|
140 func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid int, em []byte, index int, err error) {
|
131
|
141 k := priv.Size()
|
111
|
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 // The remainder of the plaintext must be a string of non-zero random
|
|
158 // octets, followed by a 0, followed by the message.
|
|
159 // lookingForIndex: 1 iff we are still looking for the zero.
|
|
160 // index: the offset of the first zero byte.
|
|
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 // The PS padding must be at least 8 bytes long, and it starts two
|
|
170 // bytes into em.
|
|
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 // nonZeroRandomBytes fills the given slice with non-zero random octets.
|
|
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 // In tests, the PRNG may return all zeros so we do
|
|
192 // this to break the loop.
|
|
193 s[i] ^= 0x42
|
|
194 }
|
|
195 }
|
|
196
|
|
197 return
|
|
198 }
|
|
199
|
|
200 // These are ASN1 DER structures:
|
|
201 // DigestInfo ::= SEQUENCE {
|
|
202 // digestAlgorithm AlgorithmIdentifier,
|
|
203 // digest OCTET STRING
|
|
204 // }
|
|
205 // For performance, we don't use the generic ASN1 encoder. Rather, we
|
|
206 // precompute a prefix of the digest value that makes a valid ASN1 DER string
|
|
207 // with the correct contents.
|
|
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: {}, // A special TLS case which doesn't use an ASN1 prefix.
|
|
216 crypto.RIPEMD160: {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
|
|
217 }
|
|
218
|
|
219 // SignPKCS1v15 calculates the signature of hashed using
|
|
220 // RSASSA-PKCS1-V1_5-SIGN from RSA PKCS#1 v1.5. Note that hashed must
|
|
221 // be the result of hashing the input message using the given hash
|
|
222 // function. If hash is zero, hashed is signed directly. This isn't
|
|
223 // advisable except for interoperability.
|
|
224 //
|
|
225 // If rand is not nil then RSA blinding will be used to avoid timing
|
|
226 // side-channel attacks.
|
|
227 //
|
|
228 // This function is deterministic. Thus, if the set of possible
|
|
229 // messages is small, an attacker may be able to build a map from
|
|
230 // messages to signatures and identify the signed messages. As ever,
|
|
231 // signatures provide authenticity, not confidentiality.
|
|
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
|
131
|
239 k := priv.Size()
|
111
|
240 if k < tLen+11 {
|
|
241 return nil, ErrMessageTooLong
|
|
242 }
|
|
243
|
|
244 // EM = 0x00 || 0x01 || PS || 0x00 || T
|
|
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 // VerifyPKCS1v15 verifies an RSA PKCS#1 v1.5 signature.
|
|
264 // hashed is the result of hashing the input message using the given hash
|
|
265 // function and sig is the signature. A valid signature is indicated by
|
|
266 // returning a nil error. If hash is zero then hashed is used directly. This
|
|
267 // isn't advisable except for interoperability.
|
|
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
|
131
|
275 k := pub.Size()
|
111
|
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 // EM = 0x00 || 0x01 || PS || 0x00 || T
|
|
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 // Special case: crypto.Hash(0) is used to indicate that the data is
|
|
304 // signed directly.
|
|
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 // copyWithLeftPad copies src to the end of dest, padding with zero bytes as
|
|
321 // needed.
|
|
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 }
|