Source file src/crypto/aes/cipher_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  package aes
     6  
     7  import (
     8  	"crypto/cipher"
     9  	"crypto/internal/alias"
    10  	"internal/cpu"
    11  )
    12  
    13  type code int
    14  
    15  // Function codes for the cipher message family of instructions.
    16  const (
    17  	aes128 code = 18
    18  	aes192      = 19
    19  	aes256      = 20
    20  )
    21  
    22  type aesCipherAsm struct {
    23  	function code     // code for cipher message instruction
    24  	key      []byte   // key (128, 192 or 256 bits)
    25  	storage  [32]byte // array backing key slice
    26  }
    27  
    28  // cryptBlocks invokes the cipher message (KM) instruction with
    29  // the given function code. This is equivalent to AES in ECB
    30  // mode. The length must be a multiple of BlockSize (16).
    31  //
    32  //go:noescape
    33  func cryptBlocks(c code, key, dst, src *byte, length int)
    34  
    35  func newCipher(key []byte) (cipher.Block, error) {
    36  	// The aesCipherAsm type implements the cbcEncAble, cbcDecAble,
    37  	// ctrAble and gcmAble interfaces. We therefore need to check
    38  	// for all the features required to implement these modes.
    39  	// Keep in sync with crypto/tls/common.go.
    40  	if !(cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)) {
    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  	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
    73  		panic("crypto/aes: invalid buffer overlap")
    74  	}
    75  	cryptBlocks(c.function, &c.key[0], &dst[0], &src[0], BlockSize)
    76  }
    77  
    78  func (c *aesCipherAsm) Decrypt(dst, src []byte) {
    79  	if len(src) < BlockSize {
    80  		panic("crypto/aes: input not full block")
    81  	}
    82  	if len(dst) < BlockSize {
    83  		panic("crypto/aes: output not full block")
    84  	}
    85  	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
    86  		panic("crypto/aes: invalid buffer overlap")
    87  	}
    88  	// The decrypt function code is equal to the function code + 128.
    89  	cryptBlocks(c.function+128, &c.key[0], &dst[0], &src[0], BlockSize)
    90  }
    91  
    92  // expandKey is used by BenchmarkExpand. cipher message (KM) does not need key
    93  // expansion so there is no assembly equivalent.
    94  func expandKey(key []byte, enc, dec []uint32) {
    95  	expandKeyGo(key, enc, dec)
    96  }
    97  

View as plain text