github.com/AESNooper/go/src@v0.0.0-20220218095104-b56a4ab1bbbb/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 "crypto/internal/subtle" 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 //go:noescape 32 func cryptBlocks(c code, key, dst, src *byte, length int) 33 34 func newCipher(key []byte) (cipher.Block, error) { 35 // The aesCipherAsm type implements the cbcEncAble, cbcDecAble, 36 // ctrAble and gcmAble interfaces. We therefore need to check 37 // for all the features required to implement these modes. 38 // Keep in sync with crypto/tls/common.go. 39 if !(cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)) { 40 return newCipherGeneric(key) 41 } 42 43 var function code 44 switch len(key) { 45 case 128 / 8: 46 function = aes128 47 case 192 / 8: 48 function = aes192 49 case 256 / 8: 50 function = aes256 51 default: 52 return nil, KeySizeError(len(key)) 53 } 54 55 var c aesCipherAsm 56 c.function = function 57 c.key = c.storage[:len(key)] 58 copy(c.key, key) 59 return &c, nil 60 } 61 62 func (c *aesCipherAsm) BlockSize() int { return BlockSize } 63 64 func (c *aesCipherAsm) Encrypt(dst, src []byte) { 65 if len(src) < BlockSize { 66 panic("crypto/aes: input not full block") 67 } 68 if len(dst) < BlockSize { 69 panic("crypto/aes: output not full block") 70 } 71 if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) { 72 panic("crypto/aes: invalid buffer overlap") 73 } 74 cryptBlocks(c.function, &c.key[0], &dst[0], &src[0], BlockSize) 75 } 76 77 func (c *aesCipherAsm) Decrypt(dst, src []byte) { 78 if len(src) < BlockSize { 79 panic("crypto/aes: input not full block") 80 } 81 if len(dst) < BlockSize { 82 panic("crypto/aes: output not full block") 83 } 84 if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) { 85 panic("crypto/aes: invalid buffer overlap") 86 } 87 // The decrypt function code is equal to the function code + 128. 88 cryptBlocks(c.function+128, &c.key[0], &dst[0], &src[0], BlockSize) 89 } 90 91 // expandKey is used by BenchmarkExpand. cipher message (KM) does not need key 92 // expansion so there is no assembly equivalent. 93 func expandKey(key []byte, enc, dec []uint32) { 94 expandKeyGo(key, enc, dec) 95 }