pkcs1v15.mx raw

   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  // This file implements signing and verification using PKCS #1 v1.5 signatures.
   8  
   9  import (
  10  	"bytes"
  11  	"crypto/internal/fips140"
  12  	"errors"
  13  )
  14  
  15  // These are ASN1 DER structures:
  16  //
  17  //	DigestInfo ::= SEQUENCE {
  18  //	  digestAlgorithm AlgorithmIdentifier,
  19  //	  digest OCTET STRING
  20  //	}
  21  //
  22  // For performance, we don't use the generic ASN1 encoder. Rather, we
  23  // precompute a prefix of the digest value that makes a valid ASN1 DER string
  24  // with the correct contents.
  25  var hashPrefixes = map[string][]byte{
  26  	"MD5":         {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
  27  	"SHA-1":       {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},
  28  	"SHA-224":     {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
  29  	"SHA-256":     {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
  30  	"SHA-384":     {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
  31  	"SHA-512":     {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
  32  	"SHA-512/224": {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x05, 0x05, 0x00, 0x04, 0x1C},
  33  	"SHA-512/256": {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x06, 0x05, 0x00, 0x04, 0x20},
  34  	"SHA3-224":    {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x07, 0x05, 0x00, 0x04, 0x1C},
  35  	"SHA3-256":    {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08, 0x05, 0x00, 0x04, 0x20},
  36  	"SHA3-384":    {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x09, 0x05, 0x00, 0x04, 0x30},
  37  	"SHA3-512":    {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0a, 0x05, 0x00, 0x04, 0x40},
  38  	"MD5+SHA1":    {}, // A special TLS case which doesn't use an ASN1 prefix.
  39  	"RIPEMD-160":  {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
  40  }
  41  
  42  // SignPKCS1v15 calculates an RSASSA-PKCS1-v1.5 signature.
  43  //
  44  // hash is the name of the hash function as returned by [crypto.Hash.String]
  45  // or the empty string to indicate that the message is signed directly.
  46  func SignPKCS1v15(priv *PrivateKey, hash string, hashed []byte) ([]byte, error) {
  47  	fipsSelfTest()
  48  	fips140.RecordApproved()
  49  	checkApprovedHashName(hash)
  50  
  51  	return signPKCS1v15(priv, hash, hashed)
  52  }
  53  
  54  func signPKCS1v15(priv *PrivateKey, hash string, hashed []byte) ([]byte, error) {
  55  	em, err := pkcs1v15ConstructEM(&priv.pub, hash, hashed)
  56  	if err != nil {
  57  		return nil, err
  58  	}
  59  
  60  	return decrypt(priv, em, withCheck)
  61  }
  62  
  63  func pkcs1v15ConstructEM(pub *PublicKey, hash string, hashed []byte) ([]byte, error) {
  64  	// Special case: "" is used to indicate that the data is signed directly.
  65  	var prefix []byte
  66  	if hash != "" {
  67  		var ok bool
  68  		prefix, ok = hashPrefixes[hash]
  69  		if !ok {
  70  			return nil, errors.New("crypto/rsa: unsupported hash function")
  71  		}
  72  	}
  73  
  74  	// EM = 0x00 || 0x01 || PS || 0x00 || T
  75  	k := pub.Size()
  76  	if k < len(prefix)+len(hashed)+2+8+1 {
  77  		return nil, ErrMessageTooLong
  78  	}
  79  	em := []byte{:k}
  80  	em[1] = 1
  81  	for i := 2; i < k-len(prefix)-len(hashed)-1; i++ {
  82  		em[i] = 0xff
  83  	}
  84  	copy(em[k-len(prefix)-len(hashed):], prefix)
  85  	copy(em[k-len(hashed):], hashed)
  86  	return em, nil
  87  }
  88  
  89  // VerifyPKCS1v15 verifies an RSASSA-PKCS1-v1.5 signature.
  90  //
  91  // hash is the name of the hash function as returned by [crypto.Hash.String]
  92  // or the empty string to indicate that the message is signed directly.
  93  func VerifyPKCS1v15(pub *PublicKey, hash string, hashed []byte, sig []byte) error {
  94  	fipsSelfTest()
  95  	fips140.RecordApproved()
  96  	checkApprovedHashName(hash)
  97  
  98  	return verifyPKCS1v15(pub, hash, hashed, sig)
  99  }
 100  
 101  func verifyPKCS1v15(pub *PublicKey, hash string, hashed []byte, sig []byte) error {
 102  	if fipsApproved, err := checkPublicKey(pub); err != nil {
 103  		return err
 104  	} else if !fipsApproved {
 105  		fips140.RecordNonApproved()
 106  	}
 107  
 108  	// RFC 8017 Section 8.2.2: If the length of the signature S is not k
 109  	// octets (where k is the length in octets of the RSA modulus n), output
 110  	// "invalid signature" and stop.
 111  	if pub.Size() != len(sig) {
 112  		return ErrVerification
 113  	}
 114  
 115  	em, err := encrypt(pub, sig)
 116  	if err != nil {
 117  		return ErrVerification
 118  	}
 119  
 120  	expected, err := pkcs1v15ConstructEM(pub, hash, hashed)
 121  	if err != nil {
 122  		return ErrVerification
 123  	}
 124  	if !bytes.Equal(em, expected) {
 125  		return ErrVerification
 126  	}
 127  
 128  	return nil
 129  }
 130  
 131  func checkApprovedHashName(hash string) {
 132  	switch hash {
 133  	case "SHA-224", "SHA-256", "SHA-384", "SHA-512", "SHA-512/224", "SHA-512/256",
 134  		"SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512":
 135  	default:
 136  		fips140.RecordNonApproved()
 137  	}
 138  }
 139