github.com/panjjo/go@v0.0.0-20161104043856-d62b31386338/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 }