...

Source file src/crypto/crypto.go

Documentation: crypto

     1  // Copyright 2011 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 crypto collects common cryptographic constants.
     6  package crypto
     7  
     8  import (
     9  	"hash"
    10  	"io"
    11  	"strconv"
    12  )
    13  
    14  // Hash identifies a cryptographic hash function that is implemented in another
    15  // package.
    16  type Hash uint
    17  
    18  // HashFunc simply returns the value of h so that [Hash] implements [SignerOpts].
    19  func (h Hash) HashFunc() Hash {
    20  	return h
    21  }
    22  
    23  func (h Hash) String() string {
    24  	switch h {
    25  	case MD4:
    26  		return "MD4"
    27  	case MD5:
    28  		return "MD5"
    29  	case SHA1:
    30  		return "SHA-1"
    31  	case SHA224:
    32  		return "SHA-224"
    33  	case SHA256:
    34  		return "SHA-256"
    35  	case SHA384:
    36  		return "SHA-384"
    37  	case SHA512:
    38  		return "SHA-512"
    39  	case MD5SHA1:
    40  		return "MD5+SHA1"
    41  	case RIPEMD160:
    42  		return "RIPEMD-160"
    43  	case SHA3_224:
    44  		return "SHA3-224"
    45  	case SHA3_256:
    46  		return "SHA3-256"
    47  	case SHA3_384:
    48  		return "SHA3-384"
    49  	case SHA3_512:
    50  		return "SHA3-512"
    51  	case SHA512_224:
    52  		return "SHA-512/224"
    53  	case SHA512_256:
    54  		return "SHA-512/256"
    55  	case BLAKE2s_256:
    56  		return "BLAKE2s-256"
    57  	case BLAKE2b_256:
    58  		return "BLAKE2b-256"
    59  	case BLAKE2b_384:
    60  		return "BLAKE2b-384"
    61  	case BLAKE2b_512:
    62  		return "BLAKE2b-512"
    63  	case MLDSAMu:
    64  		return "ML-DSA μ message representative"
    65  	default:
    66  		return "unknown hash value " + strconv.Itoa(int(h))
    67  	}
    68  }
    69  
    70  const (
    71  	MD4         Hash = 1 + iota // import golang.org/x/crypto/md4
    72  	MD5                         // import crypto/md5
    73  	SHA1                        // import crypto/sha1
    74  	SHA224                      // import crypto/sha256
    75  	SHA256                      // import crypto/sha256
    76  	SHA384                      // import crypto/sha512
    77  	SHA512                      // import crypto/sha512
    78  	MD5SHA1                     // no implementation; MD5+SHA1 used for TLS RSA
    79  	RIPEMD160                   // import golang.org/x/crypto/ripemd160
    80  	SHA3_224                    // import crypto/sha3
    81  	SHA3_256                    // import crypto/sha3
    82  	SHA3_384                    // import crypto/sha3
    83  	SHA3_512                    // import crypto/sha3
    84  	SHA512_224                  // import crypto/sha512
    85  	SHA512_256                  // import crypto/sha512
    86  	BLAKE2s_256                 // import golang.org/x/crypto/blake2s
    87  	BLAKE2b_256                 // import golang.org/x/crypto/blake2b
    88  	BLAKE2b_384                 // import golang.org/x/crypto/blake2b
    89  	BLAKE2b_512                 // import golang.org/x/crypto/blake2b
    90  
    91  	// MLDSAMu is a sentinel value for a [pre-hashed μ message representative].
    92  	// It has no implementation, but is used as a [SignerOpts.HashFunc] return
    93  	// value for [crypto/mldsa.PrivateKey.Sign].
    94  	//
    95  	// [pre-hashed μ message representative]: https://www.rfc-editor.org/rfc/rfc9881.html#externalmu
    96  	MLDSAMu
    97  
    98  	maxHash
    99  )
   100  
   101  var digestSizes = []uint8{
   102  	MD4:         16,
   103  	MD5:         16,
   104  	SHA1:        20,
   105  	SHA224:      28,
   106  	SHA256:      32,
   107  	SHA384:      48,
   108  	SHA512:      64,
   109  	SHA512_224:  28,
   110  	SHA512_256:  32,
   111  	SHA3_224:    28,
   112  	SHA3_256:    32,
   113  	SHA3_384:    48,
   114  	SHA3_512:    64,
   115  	MD5SHA1:     36,
   116  	RIPEMD160:   20,
   117  	BLAKE2s_256: 32,
   118  	BLAKE2b_256: 32,
   119  	BLAKE2b_384: 48,
   120  	BLAKE2b_512: 64,
   121  	MLDSAMu:     64,
   122  }
   123  
   124  // Size returns the length, in bytes, of a digest resulting from the given hash
   125  // function. It doesn't require that the hash function in question be linked
   126  // into the program.
   127  func (h Hash) Size() int {
   128  	if h > 0 && h < maxHash {
   129  		return int(digestSizes[h])
   130  	}
   131  	panic("crypto: Size of unknown hash function")
   132  }
   133  
   134  var hashes = make([]func() hash.Hash, maxHash)
   135  
   136  // New returns a new hash.Hash calculating the given hash function. New panics
   137  // if the hash function is not linked into the binary.
   138  func (h Hash) New() hash.Hash {
   139  	if h > 0 && h < maxHash {
   140  		f := hashes[h]
   141  		if f != nil {
   142  			return f()
   143  		}
   144  	}
   145  	panic("crypto: requested hash function unavailable: " + h.String())
   146  }
   147  
   148  // Available reports whether the given hash function is linked into the binary.
   149  func (h Hash) Available() bool {
   150  	return h < maxHash && hashes[h] != nil
   151  }
   152  
   153  // RegisterHash registers a function that returns a new instance of the given
   154  // hash function. This is intended to be called from the init function in
   155  // packages that implement hash functions.
   156  func RegisterHash(h Hash, f func() hash.Hash) {
   157  	if h == 0 || h >= maxHash {
   158  		panic("crypto: RegisterHash of unknown hash function")
   159  	}
   160  	if h == MLDSAMu {
   161  		panic("crypto: cannot RegisterHash for MLDSAMu")
   162  	}
   163  	hashes[h] = f
   164  }
   165  
   166  // PublicKey represents a public key using an unspecified algorithm.
   167  //
   168  // Although this type is an empty interface for backwards compatibility reasons,
   169  // all public key types in the standard library implement the following interface
   170  //
   171  //	interface{
   172  //	    Equal(x crypto.PublicKey) bool
   173  //	}
   174  //
   175  // which can be used for increased type safety within applications.
   176  type PublicKey any
   177  
   178  // PrivateKey represents a private key using an unspecified algorithm.
   179  //
   180  // Although this type is an empty interface for backwards compatibility reasons,
   181  // all private key types in the standard library implement the following interface
   182  //
   183  //	interface{
   184  //	    Public() crypto.PublicKey
   185  //	    Equal(x crypto.PrivateKey) bool
   186  //	}
   187  //
   188  // as well as purpose-specific interfaces such as [Signer] and [Decrypter], which
   189  // can be used for increased type safety within applications.
   190  type PrivateKey any
   191  
   192  // Signer is an interface for an opaque private key that can be used for
   193  // signing operations. For example, an RSA key kept in a hardware module.
   194  type Signer interface {
   195  	// Public returns the public key corresponding to the opaque,
   196  	// private key.
   197  	Public() PublicKey
   198  
   199  	// Sign signs digest with the private key, possibly using entropy from
   200  	// rand. For an RSA key, the resulting signature should be either a
   201  	// PKCS #1 v1.5 or PSS signature (as indicated by opts). For an (EC)DSA
   202  	// key, it should be a DER-serialised, ASN.1 signature structure.
   203  	//
   204  	// Hash implements the SignerOpts interface and, in most cases, one can
   205  	// simply pass in the hash function used as opts. Sign may also attempt
   206  	// to type assert opts to other types in order to obtain algorithm
   207  	// specific values. See the documentation in each package for details.
   208  	//
   209  	// Note that when a signature of a hash of a larger message is needed,
   210  	// the caller is responsible for hashing the larger message and passing
   211  	// the hash (as digest) and the hash function (as opts) to Sign.
   212  	Sign(rand io.Reader, digest []byte, opts SignerOpts) (signature []byte, err error)
   213  }
   214  
   215  // MessageSigner is an interface for an opaque private key that can be used for
   216  // signing operations where the message is not pre-hashed by the caller.
   217  // It is a superset of the Signer interface so that it can be passed to APIs
   218  // which accept Signer, which may try to do an interface upgrade.
   219  //
   220  // MessageSigner.SignMessage and MessageSigner.Sign should produce the same
   221  // result given the same opts. In particular, MessageSigner.SignMessage should
   222  // only accept a zero opts.HashFunc if the Signer would also accept messages
   223  // which are not pre-hashed.
   224  //
   225  // Implementations which do not provide the pre-hashed Sign API should implement
   226  // Signer.Sign by always returning an error.
   227  type MessageSigner interface {
   228  	Signer
   229  	SignMessage(rand io.Reader, msg []byte, opts SignerOpts) (signature []byte, err error)
   230  }
   231  
   232  // SignerOpts contains options for signing with a [Signer].
   233  type SignerOpts interface {
   234  	// HashFunc returns an identifier for the hash function used to produce
   235  	// the message passed to Signer.Sign, or else zero to indicate that no
   236  	// hashing was done.
   237  	HashFunc() Hash
   238  }
   239  
   240  // Decrypter is an interface for an opaque private key that can be used for
   241  // asymmetric decryption operations. An example would be an RSA key
   242  // kept in a hardware module.
   243  type Decrypter interface {
   244  	// Public returns the public key corresponding to the opaque,
   245  	// private key.
   246  	Public() PublicKey
   247  
   248  	// Decrypt decrypts msg. The opts argument should be appropriate for
   249  	// the primitive used. See the documentation in each implementation for
   250  	// details.
   251  	Decrypt(rand io.Reader, msg []byte, opts DecrypterOpts) (plaintext []byte, err error)
   252  }
   253  
   254  type DecrypterOpts any
   255  
   256  // SignMessage signs msg with signer. If signer implements [MessageSigner],
   257  // [MessageSigner.SignMessage] is called directly. Otherwise, msg is hashed
   258  // with opts.HashFunc() and signed with [Signer.Sign].
   259  func SignMessage(signer Signer, rand io.Reader, msg []byte, opts SignerOpts) (signature []byte, err error) {
   260  	if ms, ok := signer.(MessageSigner); ok {
   261  		return ms.SignMessage(rand, msg, opts)
   262  	}
   263  	if hash := opts.HashFunc(); hash != 0 {
   264  		if !hash.Available() {
   265  			return nil, hashUnavailableError(hash)
   266  		}
   267  		h := hash.New()
   268  		h.Write(msg)
   269  		msg = h.Sum(nil)
   270  	}
   271  	return signer.Sign(rand, msg, opts)
   272  }
   273  
   274  type hashUnavailableError Hash
   275  
   276  func (h hashUnavailableError) Error() string {
   277  	return "crypto: requested hash function unavailable: " + Hash(h).String()
   278  }
   279  
   280  // Decapsulator is an interface for an opaque private KEM key that can be used for
   281  // decapsulation operations. For example, an ML-KEM key kept in a hardware module.
   282  //
   283  // It is implemented, for example, by [crypto/mlkem.DecapsulationKey768].
   284  type Decapsulator interface {
   285  	Encapsulator() Encapsulator
   286  	Decapsulate(ciphertext []byte) (sharedKey []byte, err error)
   287  }
   288  
   289  // Encapsulator is an interface for a public KEM key that can be used for
   290  // encapsulation operations.
   291  //
   292  // It is implemented, for example, by [crypto/mlkem.EncapsulationKey768].
   293  type Encapsulator interface {
   294  	Bytes() []byte
   295  	Encapsulate() (sharedKey, ciphertext []byte)
   296  }
   297  

View as plain text