Source file src/crypto/internal/fips140/aes/aes_s390x.go

     1  // Copyright 2016 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  //go:build !purego
     6  
     7  package aes
     8  
     9  import (
    10  	"crypto/internal/fips140deps/cpu"
    11  	"crypto/internal/impl"
    12  )
    13  
    14  type code int
    15  
    16  // Function codes for the cipher message family of instructions.
    17  const (
    18  	aes128 code = 18
    19  	aes192 code = 19
    20  	aes256 code = 20
    21  )
    22  
    23  type block struct {
    24  	function code     // code for cipher message instruction
    25  	key      []byte   // key (128, 192 or 256 bits)
    26  	storage  [32]byte // array backing key slice
    27  
    28  	fallback *blockExpanded
    29  }
    30  
    31  // cryptBlocks invokes the cipher message (KM) instruction with
    32  // the given function code. This is equivalent to AES in ECB
    33  // mode. The length must be a multiple of BlockSize (16).
    34  //
    35  //go:noescape
    36  func cryptBlocks(c code, key, dst, src *byte, length int)
    37  
    38  var supportsAES = cpu.S390XHasAES && cpu.S390XHasAESCBC
    39  
    40  func init() {
    41  	// CP Assist for Cryptographic Functions (CPACF)
    42  	// https://www.ibm.com/docs/en/zos/3.1.0?topic=icsf-cp-assist-cryptographic-functions-cpacf
    43  	impl.Register("aes", "CPACF", &supportsAES)
    44  }
    45  
    46  func checkGenericIsExpected() {
    47  	if supportsAES {
    48  		panic("crypto/aes: internal error: using generic implementation despite hardware support")
    49  	}
    50  }
    51  
    52  func newBlock(c *Block, key []byte) *Block {
    53  	if !supportsAES {
    54  		c.fallback = &blockExpanded{}
    55  		newBlockExpanded(c.fallback, key)
    56  		return c
    57  	}
    58  
    59  	switch len(key) {
    60  	case aes128KeySize:
    61  		c.function = aes128
    62  	case aes192KeySize:
    63  		c.function = aes192
    64  	case aes256KeySize:
    65  		c.function = aes256
    66  	}
    67  	c.key = c.storage[:len(key)]
    68  	copy(c.key, key)
    69  	return c
    70  }
    71  
    72  // BlockFunction returns the function code for the block cipher.
    73  // It is used by the GCM implementation to invoke the KMA instruction.
    74  func BlockFunction(c *Block) int {
    75  	return int(c.function)
    76  }
    77  
    78  // BlockKey returns the key for the block cipher.
    79  // It is used by the GCM implementation to invoke the KMA instruction.
    80  func BlockKey(c *Block) []byte {
    81  	return c.key
    82  }
    83  
    84  func encryptBlock(c *Block, dst, src []byte) {
    85  	if c.fallback != nil {
    86  		encryptBlockGeneric(c.fallback, dst, src)
    87  	} else {
    88  		cryptBlocks(c.function, &c.key[0], &dst[0], &src[0], BlockSize)
    89  	}
    90  }
    91  
    92  func decryptBlock(c *Block, dst, src []byte) {
    93  	if c.fallback != nil {
    94  		decryptBlockGeneric(c.fallback, dst, src)
    95  	} else {
    96  		// The decrypt function code is equal to the function code + 128.
    97  		cryptBlocks(c.function+128, &c.key[0], &dst[0], &src[0], BlockSize)
    98  	}
    99  }
   100  

View as plain text