// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build ppc64le
+//go:build ppc64le || ppc64
package aes
"crypto/subtle"
"encoding/binary"
"errors"
+ "runtime"
)
// This file implements GCM using an optimized GHASH function.
// NewGCM returns the AES cipher wrapped in Galois Counter Mode. This is only
// called by crypto/cipher.NewGCM via the gcmAble interface.
func (c *aesCipherAsm) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) {
+ var h1, h2 uint64
g := &gcmAsm{cipher: c, ks: c.enc, nonceSize: nonceSize, tagSize: tagSize}
hle := make([]byte, gcmBlockSize)
+
c.Encrypt(hle, hle)
// Reverse the bytes in each 8 byte chunk
// Load little endian, store big endian
- h1 := binary.LittleEndian.Uint64(hle[:8])
- h2 := binary.LittleEndian.Uint64(hle[8:])
+ if runtime.GOARCH == "ppc64le" {
+ h1 = binary.LittleEndian.Uint64(hle[:8])
+ h2 = binary.LittleEndian.Uint64(hle[8:])
+ } else {
+ h1 = binary.BigEndian.Uint64(hle[:8])
+ h2 = binary.BigEndian.Uint64(hle[8:])
+ }
binary.BigEndian.PutUint64(hle[:8], h1)
binary.BigEndian.PutUint64(hle[8:], h2)
gcmInit(&g.productTable, hle)
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build ppc64 || ppc64le
+
// Based on CRYPTOGAMS code with the following comment:
// # ====================================================================
// # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
LXVD2X (HTBL)(R8), VHL // load pre-computed table
MOVD $0x40, R8
- LVSL (R0)(R0), LEMASK
LXVD2X (HTBL)(R9), VH
MOVD $0x50, R9
- VSPLTISB $0x07, T0
LXVD2X (HTBL)(R10), VHH
MOVD $0x60, R10
- VXOR LEMASK, T0, LEMASK
LXVD2X (HTBL)(R0), VXC2
+#ifdef GOARCH_ppc64le
+ LVSL (R0)(R0), LEMASK
+ VSPLTISB $0x07, T0
+ VXOR LEMASK, T0, LEMASK
VPERM XL, XL, LEMASK, XL
+#endif
VXOR ZERO, ZERO, ZERO
CMPU LEN, $64
LXVD2X (INP)(R0), VIN
ADD $16, INP, INP
SUBCCC $16, LEN, LEN
+#ifdef GOARCH_ppc64le
VPERM IN, IN, LEMASK, IN
+#endif
VXOR IN, XL, IN
BEQ short
loop_2x:
LXVD2X (INP)(R0), VIN1
+#ifdef GOARCH_ppc64le
VPERM IN1, IN1, LEMASK, IN1
+#endif
SUBC $32, LEN, LEN
VPMSUMD IN, H2L, XL // H^2.lo·Xi.lo
VSLDOI $8, XL, XL, T1 // 2nd reduction phase
VPMSUMD XL, XC2, XL
+#ifdef GOARCH_ppc64le
VPERM IN, IN, LEMASK, IN
+#endif
VXOR T1, XH, T1
VXOR IN, T1, IN
VXOR IN, XL, IN
even:
VXOR XL, T1, XL
+#ifdef GOARCH_ppc64le
VPERM XL, XL, LEMASK, XL
+#endif
STXVD2X VXL, (XIP+R0)
OR R12, R12, R12 // write out Xi
LXVD2X (INP)(R9), VIN2
LXVD2X (INP)(R10), VIN3
ADD $0x40, INP, INP
+#ifdef GOARCH_ppc64le
VPERM IN0, IN0, LEMASK, IN0
VPERM IN1, IN1, LEMASK, IN1
VPERM IN2, IN2, LEMASK, IN2
VPERM IN3, IN3, LEMASK, IN3
+#endif
VXOR IN0, XL, XH
LXVD2X (INP)(R9), VIN2
LXVD2X (INP)(R10), VIN3
ADD $0x40, INP, INP
+#ifdef GOARCH_ppc64le
VPERM IN1, IN1, LEMASK, IN1
VPERM IN2, IN2, LEMASK, IN2
VPERM IN3, IN3, LEMASK, IN3
VPERM IN0, IN0, LEMASK, IN0
+#endif
VPMSUMD XH, H4L, XL // H^4.lo·Xi.lo
VPMSUMD XH, H4, XM // H^4.hi·Xi.lo+H^4.lo·Xi.hi
three:
LXVD2X (INP)(R9), VIN2
+#ifdef GOARCH_ppc64le
VPERM IN0, IN0, LEMASK, IN0
VPERM IN1, IN1, LEMASK, IN1
VPERM IN2, IN2, LEMASK, IN2
+#endif
VXOR IN0, XL, XH
VOR H3L, H3L, H4L
JMP tail_4x
two:
+#ifdef GOARCH_ppc64le
VPERM IN0, IN0, LEMASK, IN0
VPERM IN1, IN1, LEMASK, IN1
+#endif
VXOR IN, XL, XH
VPERM ZERO, IN1, LOPERM, T0
JMP tail_4x
one:
+#ifdef GOARCH_ppc64le
VPERM IN0, IN0, LEMASK, IN0
+#endif
VSLDOI $8, ZERO, H, H4L
VOR H, H, H4
JMP tail_4x
done_4x:
+#ifdef GOARCH_ppc64le
VPERM XL, XL, LEMASK, XL
+#endif
STXVD2X VXL, (XIP+R0) // write out Xi
RET
LXVD2X (XIP)(R0), VIN // load Xi
LXVD2X (HTBL)(R8), VHL // Load pre-computed table
- LVSL (R0)(R0), LEMASK
LXVD2X (HTBL)(R9), VH
- VSPLTISB $0x07, T0
LXVD2X (HTBL)(R10), VHH
- VXOR LEMASK, T0, LEMASK
LXVD2X (HTBL)(R0), VXC2
+#ifdef GOARCH_ppc64le
+ VSPLTISB $0x07, T0
+ VXOR LEMASK, T0, LEMASK
VPERM IN, IN, LEMASK, IN
+#endif
VXOR ZERO, ZERO, ZERO
VPMSUMD IN, HL, XL // H.lo·Xi.lo
VXOR T1, XH, T1
VXOR XL, T1, XL
+#ifdef GOARCH_ppc64le
VPERM XL, XL, LEMASK, XL
+#endif
STXVD2X VXL, (XIP+R0) // write out Xi
RET