// Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build !purego package aes import ( "crypto/internal/fips140deps/cpu" "crypto/internal/impl" ) type code int // Function codes for the cipher message family of instructions. const ( aes128 code = 18 aes192 code = 19 aes256 code = 20 ) type block struct { function code // code for cipher message instruction key []byte // key (128, 192 or 256 bits) storage [32]byte // array backing key slice fallback *blockExpanded } // cryptBlocks invokes the cipher message (KM) instruction with // the given function code. This is equivalent to AES in ECB // mode. The length must be a multiple of BlockSize (16). // //go:noescape func cryptBlocks(c code, key, dst, src *byte, length int) var supportsAES = cpu.S390XHasAES && cpu.S390XHasAESCBC func init() { // CP Assist for Cryptographic Functions (CPACF) // https://www.ibm.com/docs/en/zos/3.1.0?topic=icsf-cp-assist-cryptographic-functions-cpacf impl.Register("aes", "CPACF", &supportsAES) } func checkGenericIsExpected() { if supportsAES { panic("crypto/aes: internal error: using generic implementation despite hardware support") } } func newBlock(c *Block, key []byte) *Block { if !supportsAES { c.fallback = &blockExpanded{} newBlockExpanded(c.fallback, key) return c } switch len(key) { case aes128KeySize: c.function = aes128 case aes192KeySize: c.function = aes192 case aes256KeySize: c.function = aes256 } c.key = c.storage[:len(key)] copy(c.key, key) return c } // BlockFunction returns the function code for the block cipher. // It is used by the GCM implementation to invoke the KMA instruction. func BlockFunction(c *Block) int { return int(c.function) } // BlockKey returns the key for the block cipher. // It is used by the GCM implementation to invoke the KMA instruction. func BlockKey(c *Block) []byte { return c.key } func encryptBlock(c *Block, dst, src []byte) { if c.fallback != nil { encryptBlockGeneric(c.fallback, dst, src) } else { cryptBlocks(c.function, &c.key[0], &dst[0], &src[0], BlockSize) } } func decryptBlock(c *Block, dst, src []byte) { if c.fallback != nil { decryptBlockGeneric(c.fallback, dst, src) } else { // The decrypt function code is equal to the function code + 128. cryptBlocks(c.function+128, &c.key[0], &dst[0], &src[0], BlockSize) } }