aes_s390x.mx raw

   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