github.com/dorkamotorka/go/src@v0.0.0-20230614113921-187095f0e316/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/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 }