github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/crypto/rsa/pkcs1v15.go (about)

     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/internal/boring"
    10  	"crypto/internal/randutil"
    11  	"crypto/subtle"
    12  	"errors"
    13  	"io"
    14  )
    15  
    16  // This file implements encryption and decryption using PKCS #1 v1.5 padding.
    17  
    18  // PKCS1v15DecryptOptions is for passing options to PKCS #1 v1.5 decryption using
    19  // the crypto.Decrypter interface.
    20  type PKCS1v15DecryptOptions struct {
    21  	// SessionKeyLen is the length of the session key that is being
    22  	// decrypted. If not zero, then a padding error during decryption will
    23  	// cause a random plaintext of this length to be returned rather than
    24  	// an error. These alternatives happen in constant time.
    25  	SessionKeyLen int
    26  }
    27  
    28  // EncryptPKCS1v15 encrypts the given message with RSA and the padding
    29  // scheme from PKCS #1 v1.5.  The message must be no longer than the
    30  // length of the public modulus minus 11 bytes.
    31  //
    32  // The random parameter is used as a source of entropy to ensure that
    33  // encrypting the same message twice doesn't result in the same
    34  // ciphertext.
    35  //
    36  // WARNING: use of this function to encrypt plaintexts other than
    37  // session keys is dangerous. Use RSA OAEP in new protocols.
    38  func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, error) {
    39  	randutil.MaybeReadByte(random)
    40  
    41  	if err := checkPub(pub); err != nil {
    42  		return nil, err
    43  	}
    44  	k := pub.Size()
    45  	if len(msg) > k-11 {
    46  		return nil, ErrMessageTooLong
    47  	}
    48  
    49  	if boring.Enabled && random == boring.RandReader {
    50  		bkey, err := boringPublicKey(pub)
    51  		if err != nil {
    52  			return nil, err
    53  		}
    54  		return boring.EncryptRSAPKCS1(bkey, msg)
    55  	}
    56  	boring.UnreachableExceptTests()
    57  
    58  	// EM = 0x00 || 0x02 || PS || 0x00 || M
    59  	em := make([]byte, k)
    60  	em[1] = 2
    61  	ps, mm := em[2:len(em)-len(msg)-1], em[len(em)-len(msg):]
    62  	err := nonZeroRandomBytes(ps, random)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	em[len(em)-len(msg)-1] = 0
    67  	copy(mm, msg)
    68  
    69  	if boring.Enabled {
    70  		var bkey *boring.PublicKeyRSA
    71  		bkey, err = boringPublicKey(pub)
    72  		if err != nil {
    73  			return nil, err
    74  		}
    75  		return boring.EncryptRSANoPadding(bkey, em)
    76  	}
    77  
    78  	return encrypt(pub, em)
    79  }
    80  
    81  // DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS #1 v1.5.
    82  // The random parameter is legacy and ignored, and it can be as nil.
    83  //
    84  // Note that whether this function returns an error or not discloses secret
    85  // information. If an attacker can cause this function to run repeatedly and
    86  // learn whether each instance returned an error then they can decrypt and
    87  // forge signatures as if they had the private key. See
    88  // DecryptPKCS1v15SessionKey for a way of solving this problem.
    89  func DecryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error) {
    90  	if err := checkPub(&priv.PublicKey); err != nil {
    91  		return nil, err
    92  	}
    93  
    94  	if boring.Enabled {
    95  		bkey, err := boringPrivateKey(priv)
    96  		if err != nil {
    97  			return nil, err
    98  		}
    99  		out, err := boring.DecryptRSAPKCS1(bkey, ciphertext)
   100  		if err != nil {
   101  			return nil, ErrDecryption
   102  		}
   103  		return out, nil
   104  	}
   105  
   106  	valid, out, index, err := decryptPKCS1v15(priv, ciphertext)
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  	if valid == 0 {
   111  		return nil, ErrDecryption
   112  	}
   113  	return out[index:], nil
   114  }
   115  
   116  // DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding scheme from PKCS #1 v1.5.
   117  // The random parameter is legacy and ignored, and it can be as nil.
   118  // It returns an error if the ciphertext is the wrong length or if the
   119  // ciphertext is greater than the public modulus. Otherwise, no error is
   120  // returned. If the padding is valid, the resulting plaintext message is copied
   121  // into key. Otherwise, key is unchanged. These alternatives occur in constant
   122  // time. It is intended that the user of this function generate a random
   123  // session key beforehand and continue the protocol with the resulting value.
   124  // This will remove any possibility that an attacker can learn any information
   125  // about the plaintext.
   126  // See “Chosen Ciphertext Attacks Against Protocols Based on the RSA
   127  // Encryption Standard PKCS #1”, Daniel Bleichenbacher, Advances in Cryptology
   128  // (Crypto '98).
   129  //
   130  // Note that if the session key is too small then it may be possible for an
   131  // attacker to brute-force it. If they can do that then they can learn whether
   132  // a random value was used (because it'll be different for the same ciphertext)
   133  // and thus whether the padding was correct. This defeats the point of this
   134  // function. Using at least a 16-byte key will protect against this attack.
   135  func DecryptPKCS1v15SessionKey(random io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) error {
   136  	if err := checkPub(&priv.PublicKey); err != nil {
   137  		return err
   138  	}
   139  	k := priv.Size()
   140  	if k-(len(key)+3+8) < 0 {
   141  		return ErrDecryption
   142  	}
   143  
   144  	valid, em, index, err := decryptPKCS1v15(priv, ciphertext)
   145  	if err != nil {
   146  		return err
   147  	}
   148  
   149  	if len(em) != k {
   150  		// This should be impossible because decryptPKCS1v15 always
   151  		// returns the full slice.
   152  		return ErrDecryption
   153  	}
   154  
   155  	valid &= subtle.ConstantTimeEq(int32(len(em)-index), int32(len(key)))
   156  	subtle.ConstantTimeCopy(valid, key, em[len(em)-len(key):])
   157  	return nil
   158  }
   159  
   160  // decryptPKCS1v15 decrypts ciphertext using priv. It returns one or zero in
   161  // valid that indicates whether the plaintext was correctly structured.
   162  // In either case, the plaintext is returned in em so that it may be read
   163  // independently of whether it was valid in order to maintain constant memory
   164  // access patterns. If the plaintext was valid then index contains the index of
   165  // the original message in em, to allow constant time padding removal.
   166  func decryptPKCS1v15(priv *PrivateKey, ciphertext []byte) (valid int, em []byte, index int, err error) {
   167  	k := priv.Size()
   168  	if k < 11 {
   169  		err = ErrDecryption
   170  		return
   171  	}
   172  
   173  	if boring.Enabled {
   174  		var bkey *boring.PrivateKeyRSA
   175  		bkey, err = boringPrivateKey(priv)
   176  		if err != nil {
   177  			return
   178  		}
   179  		em, err = boring.DecryptRSANoPadding(bkey, ciphertext)
   180  		if err != nil {
   181  			return
   182  		}
   183  	} else {
   184  		em, err = decrypt(priv, ciphertext, noCheck)
   185  		if err != nil {
   186  			return
   187  		}
   188  	}
   189  
   190  	firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
   191  	secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2)
   192  
   193  	// The remainder of the plaintext must be a string of non-zero random
   194  	// octets, followed by a 0, followed by the message.
   195  	//   lookingForIndex: 1 iff we are still looking for the zero.
   196  	//   index: the offset of the first zero byte.
   197  	lookingForIndex := 1
   198  
   199  	for i := 2; i < len(em); i++ {
   200  		equals0 := subtle.ConstantTimeByteEq(em[i], 0)
   201  		index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
   202  		lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
   203  	}
   204  
   205  	// The PS padding must be at least 8 bytes long, and it starts two
   206  	// bytes into em.
   207  	validPS := subtle.ConstantTimeLessOrEq(2+8, index)
   208  
   209  	valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) & validPS
   210  	index = subtle.ConstantTimeSelect(valid, index+1, 0)
   211  	return valid, em, index, nil
   212  }
   213  
   214  // nonZeroRandomBytes fills the given slice with non-zero random octets.
   215  func nonZeroRandomBytes(s []byte, random io.Reader) (err error) {
   216  	_, err = io.ReadFull(random, s)
   217  	if err != nil {
   218  		return
   219  	}
   220  
   221  	for i := 0; i < len(s); i++ {
   222  		for s[i] == 0 {
   223  			_, err = io.ReadFull(random, s[i:i+1])
   224  			if err != nil {
   225  				return
   226  			}
   227  			// In tests, the PRNG may return all zeros so we do
   228  			// this to break the loop.
   229  			s[i] ^= 0x42
   230  		}
   231  	}
   232  
   233  	return
   234  }
   235  
   236  // These are ASN1 DER structures:
   237  //
   238  //	DigestInfo ::= SEQUENCE {
   239  //	  digestAlgorithm AlgorithmIdentifier,
   240  //	  digest OCTET STRING
   241  //	}
   242  //
   243  // For performance, we don't use the generic ASN1 encoder. Rather, we
   244  // precompute a prefix of the digest value that makes a valid ASN1 DER string
   245  // with the correct contents.
   246  var hashPrefixes = map[crypto.Hash][]byte{
   247  	crypto.MD5:       {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
   248  	crypto.SHA1:      {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},
   249  	crypto.SHA224:    {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
   250  	crypto.SHA256:    {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
   251  	crypto.SHA384:    {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
   252  	crypto.SHA512:    {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
   253  	crypto.MD5SHA1:   {}, // A special TLS case which doesn't use an ASN1 prefix.
   254  	crypto.RIPEMD160: {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
   255  }
   256  
   257  // SignPKCS1v15 calculates the signature of hashed using
   258  // RSASSA-PKCS1-V1_5-SIGN from RSA PKCS #1 v1.5.  Note that hashed must
   259  // be the result of hashing the input message using the given hash
   260  // function. If hash is zero, hashed is signed directly. This isn't
   261  // advisable except for interoperability.
   262  //
   263  // The random parameter is legacy and ignored, and it can be as nil.
   264  //
   265  // This function is deterministic. Thus, if the set of possible
   266  // messages is small, an attacker may be able to build a map from
   267  // messages to signatures and identify the signed messages. As ever,
   268  // signatures provide authenticity, not confidentiality.
   269  func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
   270  	hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
   271  	if err != nil {
   272  		return nil, err
   273  	}
   274  
   275  	tLen := len(prefix) + hashLen
   276  	k := priv.Size()
   277  	if k < tLen+11 {
   278  		return nil, ErrMessageTooLong
   279  	}
   280  
   281  	if boring.Enabled {
   282  		bkey, err := boringPrivateKey(priv)
   283  		if err != nil {
   284  			return nil, err
   285  		}
   286  		return boring.SignRSAPKCS1v15(bkey, hash, hashed)
   287  	}
   288  
   289  	// EM = 0x00 || 0x01 || PS || 0x00 || T
   290  	em := make([]byte, k)
   291  	em[1] = 1
   292  	for i := 2; i < k-tLen-1; i++ {
   293  		em[i] = 0xff
   294  	}
   295  	copy(em[k-tLen:k-hashLen], prefix)
   296  	copy(em[k-hashLen:k], hashed)
   297  
   298  	return decrypt(priv, em, withCheck)
   299  }
   300  
   301  // VerifyPKCS1v15 verifies an RSA PKCS #1 v1.5 signature.
   302  // hashed is the result of hashing the input message using the given hash
   303  // function and sig is the signature. A valid signature is indicated by
   304  // returning a nil error. If hash is zero then hashed is used directly. This
   305  // isn't advisable except for interoperability.
   306  func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error {
   307  	if boring.Enabled {
   308  		bkey, err := boringPublicKey(pub)
   309  		if err != nil {
   310  			return err
   311  		}
   312  		if err := boring.VerifyRSAPKCS1v15(bkey, hash, hashed, sig); err != nil {
   313  			return ErrVerification
   314  		}
   315  		return nil
   316  	}
   317  
   318  	hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
   319  	if err != nil {
   320  		return err
   321  	}
   322  
   323  	tLen := len(prefix) + hashLen
   324  	k := pub.Size()
   325  	if k < tLen+11 {
   326  		return ErrVerification
   327  	}
   328  
   329  	// RFC 8017 Section 8.2.2: If the length of the signature S is not k
   330  	// octets (where k is the length in octets of the RSA modulus n), output
   331  	// "invalid signature" and stop.
   332  	if k != len(sig) {
   333  		return ErrVerification
   334  	}
   335  
   336  	em, err := encrypt(pub, sig)
   337  	if err != nil {
   338  		return ErrVerification
   339  	}
   340  	// EM = 0x00 || 0x01 || PS || 0x00 || T
   341  
   342  	ok := subtle.ConstantTimeByteEq(em[0], 0)
   343  	ok &= subtle.ConstantTimeByteEq(em[1], 1)
   344  	ok &= subtle.ConstantTimeCompare(em[k-hashLen:k], hashed)
   345  	ok &= subtle.ConstantTimeCompare(em[k-tLen:k-hashLen], prefix)
   346  	ok &= subtle.ConstantTimeByteEq(em[k-tLen-1], 0)
   347  
   348  	for i := 2; i < k-tLen-1; i++ {
   349  		ok &= subtle.ConstantTimeByteEq(em[i], 0xff)
   350  	}
   351  
   352  	if ok != 1 {
   353  		return ErrVerification
   354  	}
   355  
   356  	return nil
   357  }
   358  
   359  func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte, err error) {
   360  	// Special case: crypto.Hash(0) is used to indicate that the data is
   361  	// signed directly.
   362  	if hash == 0 {
   363  		return inLen, nil, nil
   364  	}
   365  
   366  	hashLen = hash.Size()
   367  	if inLen != hashLen {
   368  		return 0, nil, errors.New("crypto/rsa: input must be hashed message")
   369  	}
   370  	prefix, ok := hashPrefixes[hash]
   371  	if !ok {
   372  		return 0, nil, errors.New("crypto/rsa: unsupported hash function")
   373  	}
   374  	return
   375  }