Source file src/crypto/rsa/pkcs1v15.go
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/internal/boring" 9 "crypto/internal/fips140/rsa" 10 "crypto/internal/fips140only" 11 "crypto/internal/rand" 12 "crypto/subtle" 13 "errors" 14 "io" 15 ) 16 17 // This file implements encryption and decryption using PKCS #1 v1.5 padding. 18 19 // PKCS1v15DecryptOptions is for passing options to PKCS #1 v1.5 decryption using 20 // the [crypto.Decrypter] interface. 21 // 22 // Deprecated: PKCS #1 v1.5 encryption is dangerous and should not be used. 23 // See [draft-irtf-cfrg-rsa-guidance-05] for more information. Use 24 // [EncryptOAEP] and [DecryptOAEP] instead. 25 // 26 // [draft-irtf-cfrg-rsa-guidance-05]: https://www.ietf.org/archive/id/draft-irtf-cfrg-rsa-guidance-05.html#name-rationale 27 type PKCS1v15DecryptOptions struct { 28 // SessionKeyLen is the length of the session key that is being 29 // decrypted. If not zero, then a padding error during decryption will 30 // cause a random plaintext of this length to be returned rather than 31 // an error. These alternatives happen in constant time. 32 SessionKeyLen int 33 } 34 35 // EncryptPKCS1v15 encrypts the given message with RSA and the padding 36 // scheme from PKCS #1 v1.5. The message must be no longer than the 37 // length of the public modulus minus 11 bytes. 38 // 39 // The random parameter is used as a source of entropy to ensure that encrypting 40 // the same message twice doesn't result in the same ciphertext. Since Go 1.26, 41 // a secure source of random bytes is always used, and the Reader is ignored 42 // unless GODEBUG=cryptocustomrand=1 is set. This setting will be removed in a 43 // future Go release. Instead, use [testing/cryptotest.SetGlobalRandom]. 44 // 45 // Deprecated: PKCS #1 v1.5 encryption is dangerous and should not be used. 46 // See [draft-irtf-cfrg-rsa-guidance-05] for more information. Use 47 // [EncryptOAEP] and [DecryptOAEP] instead. 48 // 49 // [draft-irtf-cfrg-rsa-guidance-05]: https://www.ietf.org/archive/id/draft-irtf-cfrg-rsa-guidance-05.html#name-rationale 50 func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, error) { 51 if fips140only.Enforced() { 52 return nil, errors.New("crypto/rsa: use of PKCS#1 v1.5 encryption is not allowed in FIPS 140-only mode") 53 } 54 55 if err := checkPublicKeySize(pub); err != nil { 56 return nil, err 57 } 58 59 k := pub.Size() 60 if len(msg) > k-11 { 61 return nil, ErrMessageTooLong 62 } 63 64 if boring.Enabled && rand.IsDefaultReader(random) { 65 bkey, err := boringPublicKey(pub) 66 if err != nil { 67 return nil, err 68 } 69 return boring.EncryptRSAPKCS1(bkey, msg) 70 } 71 boring.UnreachableExceptTests() 72 73 random = rand.CustomReader(random) 74 75 // EM = 0x00 || 0x02 || PS || 0x00 || M 76 em := make([]byte, k) 77 em[1] = 2 78 ps, mm := em[2:len(em)-len(msg)-1], em[len(em)-len(msg):] 79 err := nonZeroRandomBytes(ps, random) 80 if err != nil { 81 return nil, err 82 } 83 em[len(em)-len(msg)-1] = 0 84 copy(mm, msg) 85 86 if boring.Enabled { 87 var bkey *boring.PublicKeyRSA 88 bkey, err = boringPublicKey(pub) 89 if err != nil { 90 return nil, err 91 } 92 return boring.EncryptRSANoPadding(bkey, em) 93 } 94 95 fk, err := fipsPublicKey(pub) 96 if err != nil { 97 return nil, err 98 } 99 return rsa.Encrypt(fk, em) 100 } 101 102 // DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from 103 // PKCS #1 v1.5. The random parameter is legacy and ignored, and it can be nil. 104 // 105 // Deprecated: PKCS #1 v1.5 encryption is dangerous and should not be used. 106 // Whether this function returns an error or not discloses secret information. 107 // If an attacker can cause this function to run repeatedly and learn whether 108 // each instance returned an error then they can decrypt and forge signatures as 109 // if they had the private key. See [draft-irtf-cfrg-rsa-guidance-05] for more 110 // information. Use [EncryptOAEP] and [DecryptOAEP] instead. 111 // 112 // [draft-irtf-cfrg-rsa-guidance-05]: https://www.ietf.org/archive/id/draft-irtf-cfrg-rsa-guidance-05.html#name-rationale 113 func DecryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error) { 114 if err := checkPublicKeySize(&priv.PublicKey); err != nil { 115 return nil, err 116 } 117 118 if boring.Enabled { 119 bkey, err := boringPrivateKey(priv) 120 if err != nil { 121 return nil, err 122 } 123 out, err := boring.DecryptRSAPKCS1(bkey, ciphertext) 124 if err != nil { 125 return nil, ErrDecryption 126 } 127 return out, nil 128 } 129 130 valid, out, index, err := decryptPKCS1v15(priv, ciphertext) 131 if err != nil { 132 return nil, err 133 } 134 if valid == 0 { 135 return nil, ErrDecryption 136 } 137 return out[index:], nil 138 } 139 140 // DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding 141 // scheme from PKCS #1 v1.5. The random parameter is legacy and ignored, and it 142 // can be nil. 143 // 144 // DecryptPKCS1v15SessionKey returns an error if the ciphertext is the wrong 145 // length or if the ciphertext is greater than the public modulus. Otherwise, no 146 // error is returned. If the padding is valid, the resulting plaintext message 147 // is copied into key. Otherwise, key is unchanged. These alternatives occur in 148 // constant time. It is intended that the user of this function generate a 149 // random session key beforehand and continue the protocol with the resulting 150 // value. 151 // 152 // Note that if the session key is too small then it may be possible for an 153 // attacker to brute-force it. If they can do that then they can learn whether a 154 // random value was used (because it'll be different for the same ciphertext) 155 // and thus whether the padding was correct. This also defeats the point of this 156 // function. Using at least a 16-byte key will protect against this attack. 157 // 158 // This method implements protections against Bleichenbacher chosen ciphertext 159 // attacks [0] described in RFC 3218 Section 2.3.2 [1]. While these protections 160 // make a Bleichenbacher attack significantly more difficult, the protections 161 // are only effective if the rest of the protocol which uses 162 // DecryptPKCS1v15SessionKey is designed with these considerations in mind. In 163 // particular, if any subsequent operations which use the decrypted session key 164 // leak any information about the key (e.g. whether it is a static or random 165 // key) then the mitigations are defeated. This method must be used extremely 166 // carefully, and typically should only be used when absolutely necessary for 167 // compatibility with an existing protocol (such as TLS) that is designed with 168 // these properties in mind. 169 // 170 // - [0] “Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption 171 // Standard PKCS #1”, Daniel Bleichenbacher, Advances in Cryptology (Crypto '98) 172 // - [1] RFC 3218, Preventing the Million Message Attack on CMS, 173 // https://www.rfc-editor.org/rfc/rfc3218.html 174 // 175 // Deprecated: PKCS #1 v1.5 encryption is dangerous and should not be used. The 176 // protections implemented by this function are limited and fragile, as 177 // explained above. See [draft-irtf-cfrg-rsa-guidance-05] for more information. 178 // Use [EncryptOAEP] and [DecryptOAEP] instead. 179 // 180 // [draft-irtf-cfrg-rsa-guidance-05]: https://www.ietf.org/archive/id/draft-irtf-cfrg-rsa-guidance-05.html#name-rationale 181 func DecryptPKCS1v15SessionKey(random io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) error { 182 if err := checkPublicKeySize(&priv.PublicKey); err != nil { 183 return err 184 } 185 186 k := priv.Size() 187 if k-(len(key)+3+8) < 0 { 188 return ErrDecryption 189 } 190 191 valid, em, index, err := decryptPKCS1v15(priv, ciphertext) 192 if err != nil { 193 return err 194 } 195 196 if len(em) != k { 197 // This should be impossible because decryptPKCS1v15 always 198 // returns the full slice. 199 return ErrDecryption 200 } 201 202 valid &= subtle.ConstantTimeEq(int32(len(em)-index), int32(len(key))) 203 subtle.ConstantTimeCopy(valid, key, em[len(em)-len(key):]) 204 return nil 205 } 206 207 // decryptPKCS1v15 decrypts ciphertext using priv. It returns one or zero in 208 // valid that indicates whether the plaintext was correctly structured. 209 // In either case, the plaintext is returned in em so that it may be read 210 // independently of whether it was valid in order to maintain constant memory 211 // access patterns. If the plaintext was valid then index contains the index of 212 // the original message in em, to allow constant time padding removal. 213 func decryptPKCS1v15(priv *PrivateKey, ciphertext []byte) (valid int, em []byte, index int, err error) { 214 if fips140only.Enforced() { 215 return 0, nil, 0, errors.New("crypto/rsa: use of PKCS#1 v1.5 encryption is not allowed in FIPS 140-only mode") 216 } 217 218 k := priv.Size() 219 if k < 11 { 220 err = ErrDecryption 221 return 0, nil, 0, err 222 } 223 224 if boring.Enabled { 225 var bkey *boring.PrivateKeyRSA 226 bkey, err = boringPrivateKey(priv) 227 if err != nil { 228 return 0, nil, 0, err 229 } 230 em, err = boring.DecryptRSANoPadding(bkey, ciphertext) 231 if err != nil { 232 return 0, nil, 0, ErrDecryption 233 } 234 } else { 235 fk, err := fipsPrivateKey(priv) 236 if err != nil { 237 return 0, nil, 0, err 238 } 239 em, err = rsa.DecryptWithoutCheck(fk, ciphertext) 240 if err != nil { 241 return 0, nil, 0, ErrDecryption 242 } 243 } 244 245 firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0) 246 secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2) 247 248 // The remainder of the plaintext must be a string of non-zero random 249 // octets, followed by a 0, followed by the message. 250 // lookingForIndex: 1 iff we are still looking for the zero. 251 // index: the offset of the first zero byte. 252 lookingForIndex := 1 253 254 for i := 2; i < len(em); i++ { 255 equals0 := subtle.ConstantTimeByteEq(em[i], 0) 256 index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index) 257 lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex) 258 } 259 260 // The PS padding must be at least 8 bytes long, and it starts two 261 // bytes into em. 262 validPS := subtle.ConstantTimeLessOrEq(2+8, index) 263 264 valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) & validPS 265 index = subtle.ConstantTimeSelect(valid, index+1, 0) 266 return valid, em, index, nil 267 } 268 269 // nonZeroRandomBytes fills the given slice with non-zero random octets. 270 func nonZeroRandomBytes(s []byte, random io.Reader) (err error) { 271 _, err = io.ReadFull(random, s) 272 if err != nil { 273 return 274 } 275 276 for i := 0; i < len(s); i++ { 277 for s[i] == 0 { 278 _, err = io.ReadFull(random, s[i:i+1]) 279 if err != nil { 280 return 281 } 282 // In tests, the PRNG may return all zeros so we do 283 // this to break the loop. 284 s[i] ^= 0x42 285 } 286 } 287 288 return 289 } 290