gcm

Imports

Imports #

"crypto/internal/fips140"
"crypto/internal/fips140/aes"
_ "crypto/internal/fips140/check"
"errors"
"crypto/internal/fips140"
"crypto/internal/fips140/aes"
"crypto/internal/fips140/alias"
"errors"
"crypto/internal/fips140/aes"
"crypto/internal/fips140/subtle"
"crypto/internal/fips140deps/cpu"
"crypto/internal/impl"
"crypto/internal/fips140/aes"
"crypto/internal/fips140/subtle"
"crypto/internal/fips140deps/byteorder"
"crypto/internal/fips140"
"crypto/internal/fips140/aes"
"crypto/internal/fips140/alias"
"crypto/internal/fips140/drbg"
"crypto/internal/fips140deps/byteorder"
"math"
"crypto/internal/fips140/aes"
"crypto/internal/fips140/subtle"
"crypto/internal/fips140deps/byteorder"
"crypto/internal/fips140deps/godebug"
"crypto/internal/impl"
"runtime"
"crypto/internal/fips140/aes"
"crypto/internal/fips140/subtle"
"crypto/internal/fips140deps/byteorder"
"crypto/internal/fips140deps/cpu"
"crypto/internal/impl"
"crypto/internal/fips140"
"crypto/internal/fips140/aes"
"crypto/internal/fips140/subtle"
"crypto/internal/fips140"
"crypto/internal/fips140/aes"
"crypto/internal/fips140"
"crypto/internal/fips140deps/byteorder"

Constants & Variables

errOpen var #

var errOpen = *ast.CallExpr

gcmBlockSize const #

const gcmBlockSize = 16

gcmMinimumTagSize const #

const gcmMinimumTagSize = 12

gcmStandardNonceSize const #

const gcmStandardNonceSize = 12

gcmTagSize const #

const gcmTagSize = 16

ghashReductionTable var #

var ghashReductionTable = []uint16{...}

kmaDecrypt const #

flags for the KMA instruction

const kmaDecrypt = *ast.BinaryExpr

kmaHS const #

flags for the KMA instruction

const kmaHS = *ast.BinaryExpr

kmaLAAD const #

flags for the KMA instruction

const kmaLAAD = *ast.BinaryExpr

kmaLPC const #

flags for the KMA instruction

const kmaLPC = *ast.BinaryExpr

supportsAESGCM var #

The POWER architecture doesn't have a way to turn off AES-GCM support at runtime with GODEBUG=cpu.something=off, so introduce a new GODEBUG knob for that. It's intentionally only checked at init() time, to avoid the performance overhead of checking it every time.

var supportsAESGCM = *ast.BinaryExpr

supportsAESGCM var #

Keep in sync with crypto/tls.hasAESGCMHardwareSupport.

var supportsAESGCM = *ast.BinaryExpr

useGCM var #

var useGCM = *ast.BinaryExpr

useGHASH var #

Keep in sync with crypto/tls.hasAESGCMHardwareSupport.

var useGHASH = *ast.BinaryExpr

Type Aliases

gcmHashKey type #

gcmHashKey represents the 16-byte hash key required by the GHASH algorithm.

type gcmHashKey [16]byte

Structs

CMAC struct #

CMAC implements the CMAC mode from NIST SP 800-38B. It is optimized for use in Counter KDF (SP 800-108r1) and XAES-256-GCM (https://c2sp.org/XAES-256-GCM), rather than for exposing it to applications as a stand-alone MAC.

type CMAC struct {
b aes.Block
k1 [aes.BlockSize]byte
k2 [aes.BlockSize]byte
}

CounterKDF struct #

CounterKDF implements a KDF in Counter Mode instantiated with CMAC-AES, according to NIST SP 800-108 Revision 1 Update 1, Section 4.1. It produces a 256-bit output, and accepts a 8-bit Label and a 96-bit Context. It uses a counter of 16 bits placed before the fixed data. The fixed data is the sequence Label || 0x00 || Context. The L field is omitted, since the output key length is fixed. It's optimized for use in XAES-256-GCM (https://c2sp.org/XAES-256-GCM), rather than for exposing it to applications as a stand-alone KDF.

type CounterKDF struct {
mac CMAC
}

GCM struct #

GCM represents a Galois Counter Mode with a specific key.

type GCM struct {
cipher aes.Block
nonceSize int
tagSize int
gcmPlatformData
}

GCMForSSH struct #

type GCMForSSH struct {
g GCM
ready bool
start uint64
next uint64
}

GCMForTLS12 struct #

type GCMForTLS12 struct {
g GCM
next uint64
}

GCMForTLS13 struct #

type GCMForTLS13 struct {
g GCM
ready bool
mask uint64
next uint64
}

GCMWithCounterNonce struct #

type GCMWithCounterNonce struct {
g GCM
ready bool
fixedName uint32
start uint64
next uint64
}

gcmFieldElement struct #

gcmFieldElement represents a value in GF(2¹²⁸). In order to reflect the GCM standard and make binary.BigEndian suitable for marshaling these values, the bits are stored in big endian order. For example: the coefficient of x⁰ can be obtained by v.low >> 63. the coefficient of x⁶³ can be obtained by v.low & 1. the coefficient of x⁶⁴ can be obtained by v.high >> 63. the coefficient of x¹²⁷ can be obtained by v.high & 1.

type gcmFieldElement struct {
low uint64
high uint64
}

gcmPlatformData struct #

type gcmPlatformData struct {
productTable [256]byte
}

gcmPlatformData struct #

type gcmPlatformData struct {

}

gcmPlatformData struct #

type gcmPlatformData struct {
productTable [256]byte
}

gcmPlatformData struct #

type gcmPlatformData struct {
hashKey gcmHashKey
}

Functions

DeriveKey method #

DeriveKey derives a key from the given label and context.

func (kdf *CounterKDF) DeriveKey(label byte, context [12]byte) [32]byte

GHASH function #

GHASH is exposed to allow crypto/cipher to implement non-AES GCM modes. It is not allowed as a stand-alone operation in FIPS mode because it is not ACVP tested.

func GHASH(key *[16]byte, inputs ...[]byte) []byte

MAC method #

func (c *CMAC) MAC(m []byte) [aes.BlockSize]byte

New function #

func New(cipher *aes.Block, nonceSize int, tagSize int) (*GCM, error)

NewCMAC function #

func NewCMAC(b *aes.Block) *CMAC

NewCounterKDF function #

NewCounterKDF creates a new CounterKDF with the given key.

func NewCounterKDF(b *aes.Block) *CounterKDF

NewGCMForSSH function #

NewGCMForSSH returns a new AEAD that works like GCM, but enforces the construction of nonces as specified in RFC 5647. This complies with FIPS 140-3 IG C.H Scenario 1.d.

func NewGCMForSSH(cipher *aes.Block) (*GCMForSSH, error)

NewGCMForTLS12 function #

NewGCMForTLS12 returns a new AEAD that works like GCM, but enforces the construction of nonces as specified in RFC 5288, Section 3 and RFC 9325, Section 7.2.1. This complies with FIPS 140-3 IG C.H Scenario 1.a.

func NewGCMForTLS12(cipher *aes.Block) (*GCMForTLS12, error)

NewGCMForTLS13 function #

NewGCMForTLS13 returns a new AEAD that works like GCM, but enforces the construction of nonces as specified in RFC 8446, Section 5.3.

func NewGCMForTLS13(cipher *aes.Block) (*GCMForTLS13, error)

NewGCMWithCounterNonce function #

NewGCMWithCounterNonce returns a new AEAD that works like GCM, but enforces the construction of deterministic nonces. The nonce must be 96 bits, the first 32 bits must be an encoding of the module name, and the last 64 bits must be a counter. This complies with FIPS 140-3 IG C.H Scenario 3.

func NewGCMWithCounterNonce(cipher *aes.Block) (*GCMWithCounterNonce, error)

NonceSize method #

func (g *GCMForTLS13) NonceSize() int

NonceSize method #

func (g *GCMForSSH) NonceSize() int

NonceSize method #

func (g *GCMForTLS12) NonceSize() int

NonceSize method #

func (g *GCM) NonceSize() int

NonceSize method #

func (g *GCMWithCounterNonce) NonceSize() int

Open method #

func (g *GCMWithCounterNonce) Open(dst []byte, nonce []byte, ciphertext []byte, data []byte) ([]byte, error)

Open method #

func (g *GCMForTLS12) Open(dst []byte, nonce []byte, ciphertext []byte, data []byte) ([]byte, error)

Open method #

func (g *GCMForTLS13) Open(dst []byte, nonce []byte, ciphertext []byte, data []byte) ([]byte, error)

Open method #

func (g *GCMForSSH) Open(dst []byte, nonce []byte, ciphertext []byte, data []byte) ([]byte, error)

Open method #

func (g *GCM) Open(dst []byte, nonce []byte, ciphertext []byte, data []byte) ([]byte, error)

Overhead method #

func (g *GCMWithCounterNonce) Overhead() int

Overhead method #

func (g *GCM) Overhead() int

Overhead method #

func (g *GCMForTLS12) Overhead() int

Overhead method #

func (g *GCMForTLS13) Overhead() int

Overhead method #

func (g *GCMForSSH) Overhead() int

Seal method #

func (g *GCMForSSH) Seal(dst []byte, nonce []byte, plaintext []byte, data []byte) []byte

Seal method #

func (g *GCMForTLS12) Seal(dst []byte, nonce []byte, plaintext []byte, data []byte) []byte

Seal method #

func (g *GCMForTLS13) Seal(dst []byte, nonce []byte, plaintext []byte, data []byte) []byte

Seal method #

func (g *GCMWithCounterNonce) Seal(dst []byte, nonce []byte, plaintext []byte, data []byte) []byte

Seal method #

func (g *GCM) Seal(dst []byte, nonce []byte, plaintext []byte, data []byte) []byte

SealWithRandomNonce function #

SealWithRandomNonce encrypts plaintext to out, and writes a random nonce to nonce. nonce must be 12 bytes, and out must be 16 bytes longer than plaintext. out and plaintext may overlap exactly or not at all. additionalData and out must not overlap. This complies with FIPS 140-3 IG C.H Scenario 2. Note that this is NOT a [cipher.AEAD].Seal method.

func SealWithRandomNonce(g *GCM, nonce []byte, out []byte, plaintext []byte, additionalData []byte)

auth function #

auth calculates GHASH(ciphertext, additionalData), masks the result with tagMask and writes the result to out.

func auth(out []byte, ciphertext []byte, aad []byte, tagMask *[gcmTagSize]byte, productTable *[256]byte)

checkGenericIsExpected function #

checkGenericIsExpected is called by the variable-time implementation to make sure it is not used when hardware support is available. It shouldn't happen, but this way it's more evidently correct.

func checkGenericIsExpected()

checkGenericIsExpected function #

func checkGenericIsExpected()

checkGenericIsExpected function #

func checkGenericIsExpected()

checkGenericIsExpected function #

func checkGenericIsExpected()

counterCrypt function #

counterCrypt encrypts src using AES in counter mode and places the result into dst. cnt is the initial count value and will be updated with the next count value. The length of dst must be greater than or equal to the length of src.

func counterCrypt(g *GCM, dst []byte, src []byte, cnt *[gcmBlockSize]byte)

counterCrypt function #

counterCrypt encrypts in using AES in counter mode and places the result into out. counter is the initial count value and will be updated with the next count value. The length of out must be greater than or equal to the length of in. counterCryptASM implements counterCrypt which then allows the loop to be unrolled and optimized.

func counterCrypt(b *aes.Block, out []byte, in []byte, counter *[gcmBlockSize]byte)

counterCryptASM function #

func counterCryptASM(nr int, out []byte, in []byte, counter *[gcmBlockSize]byte, key *uint32)

cryptBlocksGCM function #

cryptBlocksGCM encrypts src using AES in counter mode using the given function code and key. The rightmost 32-bits of the counter are incremented between each block as required by the GCM spec. The initial counter value is given by cnt, which is updated with the value of the next counter value to use. The lengths of both dst and buf must be greater than or equal to the length of src. buf may be partially or completely overwritten during the execution of the function. go:noescape

func cryptBlocksGCM(fn int, key []byte, dst []byte, src []byte, buf []byte, cnt *[gcmBlockSize]byte)

deriveCounter function #

deriveCounter computes the initial GCM counter state from the given nonce. See NIST SP 800-38D, section 7.1 and deriveCounterGeneric in gcm_generic.go.

func deriveCounter(H *gcmHashKey, counter *[gcmBlockSize]byte, nonce []byte)

deriveCounter function #

deriveCounter computes the initial GCM counter state from the given nonce.

func deriveCounter(counter *[gcmBlockSize]byte, nonce []byte, productTable *[256]byte)

deriveCounterGeneric function #

deriveCounterGeneric computes the initial GCM counter state from the given nonce. See NIST SP 800-38D, section 7.1. This assumes that counter is filled with zeros on entry.

func deriveCounterGeneric(H *[gcmBlockSize]byte, counter *[gcmBlockSize]byte, nonce []byte)

deriveSubkeys method #

func (c *CMAC) deriveSubkeys()

gcmAesData function #

go:noescape

func gcmAesData(productTable *[256]byte, data []byte, T *[16]byte)

gcmAesDec function #

go:noescape

func gcmAesDec(productTable *[256]byte, dst []byte, src []byte, ctr *[16]byte, T *[16]byte, ks []uint32)

gcmAesEnc function #

go:noescape

func gcmAesEnc(productTable *[256]byte, dst []byte, src []byte, ctr *[16]byte, T *[16]byte, ks []uint32)

gcmAesFinish function #

go:noescape

func gcmAesFinish(productTable *[256]byte, tagMask *[16]byte, T *[16]byte, pLen uint64, dLen uint64)

gcmAesInit function #

go:noescape

func gcmAesInit(productTable *[256]byte, ks []uint32)

gcmAuth function #

gcmAuth calculates GHASH(additionalData, ciphertext), masks the result with tagMask and writes the result to out.

func gcmAuth(out []byte, H *gcmHashKey, tagMask *[gcmBlockSize]byte, ciphertext []byte, additionalData []byte)

gcmAuthGeneric function #

gcmAuthGeneric calculates GHASH(additionalData, ciphertext), masks the result with tagMask and writes the result to out.

func gcmAuthGeneric(out []byte, H *[gcmBlockSize]byte, tagMask *[gcmBlockSize]byte, ciphertext []byte, additionalData []byte)

gcmCounterCryptGeneric function #

gcmCounterCryptGeneric encrypts src using AES in counter mode with 32-bit wrapping (which is different from AES-CTR) and places the result into out. counter is the initial value and will be updated with the next value.

func gcmCounterCryptGeneric(b *aes.Block, out []byte, src []byte, counter *[gcmBlockSize]byte)

gcmHash function #

go:noescape

func gcmHash(output []byte, productTable *[256]byte, inp []byte, len int)

gcmInc32 function #

gcmInc32 treats the final four bytes of counterBlock as a big-endian value and increments it.

func gcmInc32(counterBlock *[gcmBlockSize]byte)

gcmInit function #

go:noescape

func gcmInit(productTable *[256]byte, h []byte)

gcmLengths function #

func gcmLengths(len0 uint64, len1 uint64) [16]byte

gcmLengths function #

gcmLengths writes len0 || len1 as big-endian values to a 16-byte array.

func gcmLengths(len0 uint64, len1 uint64) [16]byte

ghash function #

ghash is a variable-time generic implementation of GHASH, which shouldn't be used on any architecture with hardware support for AES-GCM. Each input is zero-padded to 128-bit before being absorbed.

func ghash(out *[gcmBlockSize]byte, H *[gcmBlockSize]byte, inputs ...[]byte)

ghashAdd function #

ghashAdd adds two elements of GF(2¹²⁸) and returns the sum.

func ghashAdd(x *gcmFieldElement, y *gcmFieldElement) gcmFieldElement

ghashAsm function #

ghashAsm uses the GHASH algorithm to hash data with the given key. The initial hash value is given by hash which will be updated with the new hash value. The length of data must be a multiple of 16-bytes. go:noescape

func ghashAsm(key *gcmHashKey, hash *[16]byte, data []byte)

ghashDouble function #

ghashDouble returns the result of doubling an element of GF(2¹²⁸).

func ghashDouble(x *gcmFieldElement) (double gcmFieldElement)

ghashMul function #

ghashMul sets y to y*H, where H is the GCM key, fixed during New.

func ghashMul(productTable *[16]gcmFieldElement, y *gcmFieldElement)

ghashUpdate function #

ghashUpdate extends y with more polynomial terms from data. If data is not a multiple of gcmBlockSize bytes long then the remainder is zero padded.

func ghashUpdate(productTable *[16]gcmFieldElement, y *gcmFieldElement, data []byte)

init function #

func init()

init function #

func init()

init function #

func init()

init function #

func init()

initGCM function #

func initGCM(g *GCM)

initGCM function #

func initGCM(g *GCM)

initGCM function #

func initGCM(g *GCM)

initGCM function #

func initGCM(g *GCM)

kmaGCM function #

kmaGCM executes the encryption or decryption operation given by fn. The tag will be calculated and written to tag. cnt should contain the current counter state and will be overwritten with the updated counter state. TODO(mundaym): could pass in hash subkey go:noescape

func kmaGCM(fn int, key []byte, dst []byte, src []byte, aad []byte, tag *[16]byte, cnt *[gcmBlockSize]byte)

newGCM function #

newGCM is marked go:noinline to avoid it inlining into New, and making New too complex to inline itself. go:noinline

func newGCM(g *GCM, cipher *aes.Block, nonceSize int, tagSize int) (*GCM, error)

open function #

func open(out []byte, g *GCM, nonce []byte, ciphertext []byte, data []byte) error

open function #

func open(out []byte, g *GCM, nonce []byte, ciphertext []byte, data []byte) error

open function #

func open(out []byte, g *GCM, nonce []byte, ciphertext []byte, data []byte) error

open function #

func open(out []byte, g *GCM, nonce []byte, ciphertext []byte, data []byte) error

openAsm function #

func openAsm(out []byte, g *GCM, nonce []byte, ciphertext []byte, additionalData []byte) error

openGeneric function #

func openGeneric(out []byte, g *GCM, nonce []byte, ciphertext []byte, additionalData []byte) error

openKMA function #

func openKMA(out []byte, g *GCM, nonce []byte, ciphertext []byte, data []byte) error

paddedGHASH function #

paddedGHASH pads data with zeroes until its length is a multiple of 16-bytes. It then calculates a new value for hash using the ghash algorithm.

func paddedGHASH(hash *[16]byte, data []byte, productTable *[256]byte)

paddedGHASH function #

paddedGHASH pads data with zeroes until its length is a multiple of 16-bytes. It then calculates a new value for hash using the GHASH algorithm.

func paddedGHASH(hashKey *gcmHashKey, hash *[16]byte, data []byte)

reverseBits function #

reverseBits reverses the order of the bits of 4-bit number in i.

func reverseBits(i int) int

seal function #

func seal(out []byte, g *GCM, nonce []byte, plaintext []byte, data []byte)

seal function #

func seal(out []byte, g *GCM, nonce []byte, plaintext []byte, data []byte)

seal function #

func seal(out []byte, g *GCM, nonce []byte, plaintext []byte, data []byte)

seal function #

func seal(out []byte, g *GCM, nonce []byte, plaintext []byte, data []byte)

sealAfterIndicator method #

func (g *GCM) sealAfterIndicator(dst []byte, nonce []byte, plaintext []byte, data []byte) []byte

sealAsm function #

func sealAsm(out []byte, g *GCM, nonce []byte, plaintext []byte, additionalData []byte)

sealGeneric function #

func sealGeneric(out []byte, g *GCM, nonce []byte, plaintext []byte, additionalData []byte)

sealKMA function #

func sealKMA(out []byte, g *GCM, nonce []byte, plaintext []byte, data []byte)

shiftLeft function #

shiftLeft sets x to x << 1, and returns MSB₁(x).

func shiftLeft(x *[aes.BlockSize]byte) byte

sliceForAppend function #

sliceForAppend takes a slice and a requested number of bytes. It returns a slice with the contents of the given slice followed by that many bytes and a second slice that aliases into it and contains only the extra bytes. If the original slice has sufficient capacity then no allocation is performed.

func sliceForAppend(in []byte, n int) (head []byte, tail []byte)

updateBlocks function #

updateBlocks extends y with more polynomial terms from blocks, based on Horner's rule. There must be a multiple of gcmBlockSize bytes in blocks.

func updateBlocks(productTable *[16]gcmFieldElement, y *gcmFieldElement, blocks []byte)

Generated with Arrow