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