1 // Copyright 2017 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 sha3
8 9 import (
10 "crypto/internal/fips140/subtle"
11 "crypto/internal/fips140deps/cpu"
12 "crypto/internal/impl"
13 )
14 15 // This file contains code for using the 'compute intermediate
16 // message digest' (KIMD) and 'compute last message digest' (KLMD)
17 // instructions to compute SHA-3 and SHAKE hashes on IBM Z. See
18 // [z/Architecture Principles of Operation, Fourteen Edition].
19 //
20 // [z/Architecture Principles of Operation, Fourteen Edition]: https://www.ibm.com/docs/en/module_1678991624569/pdf/SA22-7832-13.pdf
21 22 var useSHA3 = cpu.S390XHasSHA3
23 24 func init() {
25 // CP Assist for Cryptographic Functions (CPACF)
26 impl.Register("sha3", "CPACF", &useSHA3)
27 }
28 29 func keccakF1600(a *[200]byte) {
30 keccakF1600Generic(a)
31 }
32 33 // codes represent 7-bit KIMD/KLMD function codes as defined in
34 // the Principles of Operation.
35 type code uint64
36 37 const (
38 // Function codes for KIMD/KLMD, from Figure 7-207.
39 sha3_224 code = 32
40 sha3_256 code = 33
41 sha3_384 code = 34
42 sha3_512 code = 35
43 shake_128 code = 36
44 shake_256 code = 37
45 nopad = 0x100
46 )
47 48 // kimd is a wrapper for the 'compute intermediate message digest' instruction.
49 // src is absorbed into the sponge state a.
50 // len(src) must be a multiple of the rate for the given function code.
51 //
52 //go:noescape
53 func kimd(function code, a *[200]byte, src []byte)
54 55 // klmd is a wrapper for the 'compute last message digest' instruction.
56 // src is padded and absorbed into the sponge state a.
57 //
58 // If the function is a SHAKE XOF, the sponge is then optionally squeezed into
59 // dst by first applying the permutation and then copying the output until dst
60 // runs out. If len(dst) is a multiple of rate (including zero), the final
61 // permutation is not applied. If the nopad bit of function is set and len(src)
62 // is zero, only squeezing is performed.
63 //
64 //go:noescape
65 func klmd(function code, a *[200]byte, dst, src []byte)
66 67 func (d *Digest) write(p []byte) (n int, err error) {
68 if d.state != spongeAbsorbing {
69 panic("sha3: Write after Read")
70 }
71 if !useSHA3 {
72 return d.writeGeneric(p)
73 }
74 75 n = len(p)
76 77 // If there is buffered input in the state, keep XOR'ing.
78 if d.n > 0 {
79 x := subtle.XORBytes(d.a[d.n:d.rate], d.a[d.n:d.rate], p)
80 d.n += x
81 p = p[x:]
82 }
83 84 // If the sponge is full, apply the permutation.
85 if d.n == d.rate {
86 // Absorbing a "rate"ful of zeroes effectively XORs the state with
87 // zeroes (a no-op) and then runs the permutation. The actual function
88 // doesn't matter, they all run the same permutation.
89 kimd(shake_128, &d.a, []byte{:rateK256})
90 d.n = 0
91 }
92 93 // Absorb full blocks with KIMD.
94 if len(p) >= d.rate {
95 wholeBlocks := len(p) / d.rate * d.rate
96 kimd(d.function(), &d.a, p[:wholeBlocks])
97 p = p[wholeBlocks:]
98 }
99 100 // If there is any trailing input, XOR it into the state.
101 if len(p) > 0 {
102 d.n += subtle.XORBytes(d.a[d.n:d.rate], d.a[d.n:d.rate], p)
103 }
104 105 return
106 }
107 108 func (d *Digest) sum(b []byte) []byte {
109 if d.state != spongeAbsorbing {
110 panic("sha3: Sum after Read")
111 }
112 if !useSHA3 || d.dsbyte != dsbyteSHA3 && d.dsbyte != dsbyteShake {
113 return d.sumGeneric(b)
114 }
115 116 // Copy the state to preserve the original.
117 a := d.a
118 119 // We "absorb" a buffer of zeroes as long as the amount of input we already
120 // XOR'd into the sponge, to skip over it. The max cap is specified to avoid
121 // an allocation.
122 buf := []byte{:d.n:rateK256}
123 function := d.function()
124 switch function {
125 case sha3_224, sha3_256, sha3_384, sha3_512:
126 klmd(function, &a, nil, buf)
127 return append(b, a[:d.outputLen]...)
128 case shake_128, shake_256:
129 h := []byte{:d.outputLen:64}
130 klmd(function, &a, h, buf)
131 return append(b, h...)
132 default:
133 panic("sha3: unknown function")
134 }
135 }
136 137 func (d *Digest) read(out []byte) (n int, err error) {
138 if !useSHA3 || d.dsbyte != dsbyteShake {
139 return d.readGeneric(out)
140 }
141 142 n = len(out)
143 144 if d.state == spongeAbsorbing {
145 d.state = spongeSqueezing
146 147 // We "absorb" a buffer of zeroes as long as the amount of input we
148 // already XOR'd into the sponge, to skip over it. The max cap is
149 // specified to avoid an allocation.
150 buf := []byte{:d.n:rateK256}
151 klmd(d.function(), &d.a, out, buf)
152 } else {
153 // We have "buffered" output still to copy.
154 if d.n < d.rate {
155 x := copy(out, d.a[d.n:d.rate])
156 d.n += x
157 out = out[x:]
158 }
159 if len(out) == 0 {
160 return
161 }
162 163 klmd(d.function()|nopad, &d.a, out, nil)
164 }
165 166 if len(out)%d.rate == 0 {
167 // The final permutation was not performed,
168 // so there is no "buffered" output.
169 d.n = d.rate
170 } else {
171 d.n = len(out) % d.rate
172 }
173 174 return
175 }
176 177 func (d *Digest) function() code {
178 switch d.rate {
179 case rateK256:
180 return shake_128
181 case rateK448:
182 return sha3_224
183 case rateK512:
184 if d.dsbyte == dsbyteSHA3 {
185 return sha3_256
186 } else {
187 return shake_256
188 }
189 case rateK768:
190 return sha3_384
191 case rateK1024:
192 return sha3_512
193 default:
194 panic("invalid rate")
195 }
196 }
197