aes_s390x.mx raw
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 //go:build !purego
6
7 package aes
8
9 import (
10 "crypto/internal/fips140deps/cpu"
11 "crypto/internal/impl"
12 )
13
14 type code int
15
16 // Function codes for the cipher message family of instructions.
17 const (
18 aes128 code = 18
19 aes192 code = 19
20 aes256 code = 20
21 )
22
23 type block struct {
24 function code // code for cipher message instruction
25 key []byte // key (128, 192 or 256 bits)
26 storage [32]byte // array backing key slice
27
28 fallback *blockExpanded
29 }
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 //
35 //go:noescape
36 func cryptBlocks(c code, key, dst, src *byte, length int)
37
38 var supportsAES = cpu.S390XHasAES && cpu.S390XHasAESCBC
39
40 func init() {
41 // CP Assist for Cryptographic Functions (CPACF)
42 // https://www.ibm.com/docs/en/zos/3.1.0?topic=icsf-cp-assist-cryptographic-functions-cpacf
43 impl.Register("aes", "CPACF", &supportsAES)
44 }
45
46 func checkGenericIsExpected() {
47 if supportsAES {
48 panic("crypto/aes: internal error: using generic implementation despite hardware support")
49 }
50 }
51
52 func newBlock(c *Block, key []byte) *Block {
53 if !supportsAES {
54 c.fallback = &blockExpanded{}
55 newBlockExpanded(c.fallback, key)
56 return c
57 }
58
59 switch len(key) {
60 case aes128KeySize:
61 c.function = aes128
62 case aes192KeySize:
63 c.function = aes192
64 case aes256KeySize:
65 c.function = aes256
66 }
67 c.key = c.storage[:len(key)]
68 copy(c.key, key)
69 return c
70 }
71
72 // BlockFunction returns the function code for the block cipher.
73 // It is used by the GCM implementation to invoke the KMA instruction.
74 func BlockFunction(c *Block) int {
75 return int(c.function)
76 }
77
78 // BlockKey returns the key for the block cipher.
79 // It is used by the GCM implementation to invoke the KMA instruction.
80 func BlockKey(c *Block) []byte {
81 return c.key
82 }
83
84 func encryptBlock(c *Block, dst, src []byte) {
85 if c.fallback != nil {
86 encryptBlockGeneric(c.fallback, dst, src)
87 } else {
88 cryptBlocks(c.function, &c.key[0], &dst[0], &src[0], BlockSize)
89 }
90 }
91
92 func decryptBlock(c *Block, dst, src []byte) {
93 if c.fallback != nil {
94 decryptBlockGeneric(c.fallback, dst, src)
95 } else {
96 // The decrypt function code is equal to the function code + 128.
97 cryptBlocks(c.function+128, &c.key[0], &dst[0], &src[0], BlockSize)
98 }
99 }
100