github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/crypto/aes/cipher_s390x.go (about)

     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  package aes
     6  
     7  import (
     8  	"crypto/cipher"
     9  )
    10  
    11  type code int
    12  
    13  // Function codes for the cipher message family of instructions.
    14  const (
    15  	aes128 code = 18
    16  	aes192      = 19
    17  	aes256      = 20
    18  )
    19  
    20  type aesCipherAsm struct {
    21  	function code      // code for cipher message instruction
    22  	key      []byte    // key (128, 192 or 256 bytes)
    23  	storage  [256]byte // array backing key slice
    24  }
    25  
    26  // hasAsm reports whether the AES-128, AES-192 and AES-256
    27  // cipher message (KM) function codes are supported.
    28  // Note: this function call is expensive.
    29  func hasAsm() bool
    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  //go:noesape
    35  func cryptBlocks(c code, key, dst, src *byte, length int)
    36  
    37  var useAsm = hasAsm()
    38  
    39  func newCipher(key []byte) (cipher.Block, error) {
    40  	if !useAsm {
    41  		return newCipherGeneric(key)
    42  	}
    43  
    44  	var function code
    45  	switch len(key) {
    46  	case 128 / 8:
    47  		function = aes128
    48  	case 192 / 8:
    49  		function = aes192
    50  	case 256 / 8:
    51  		function = aes256
    52  	default:
    53  		return nil, KeySizeError(len(key))
    54  	}
    55  
    56  	var c aesCipherAsm
    57  	c.function = function
    58  	c.key = c.storage[:len(key)]
    59  	copy(c.key, key)
    60  	return &c, nil
    61  }
    62  
    63  func (c *aesCipherAsm) BlockSize() int { return BlockSize }
    64  
    65  func (c *aesCipherAsm) Encrypt(dst, src []byte) {
    66  	if len(src) < BlockSize {
    67  		panic("crypto/aes: input not full block")
    68  	}
    69  	if len(dst) < BlockSize {
    70  		panic("crypto/aes: output not full block")
    71  	}
    72  	cryptBlocks(c.function, &c.key[0], &dst[0], &src[0], BlockSize)
    73  }
    74  
    75  func (c *aesCipherAsm) Decrypt(dst, src []byte) {
    76  	if len(src) < BlockSize {
    77  		panic("crypto/aes: input not full block")
    78  	}
    79  	if len(dst) < BlockSize {
    80  		panic("crypto/aes: output not full block")
    81  	}
    82  	// The decrypt function code is equal to the function code + 128.
    83  	cryptBlocks(c.function+128, &c.key[0], &dst[0], &src[0], BlockSize)
    84  }
    85  
    86  // expandKey is used by BenchmarkExpand. cipher message (KM) does not need key
    87  // expansion so there is no assembly equivalent.
    88  func expandKey(key []byte, enc, dec []uint32) {
    89  	expandKeyGo(key, enc, dec)
    90  }