| // Copyright 2016 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| //go:build !purego |
| |
| package aes |
| |
| import ( |
| "crypto/internal/fips140/subtle" |
| "crypto/internal/fips140deps/byteorder" |
| ) |
| |
| func ctrBlocks1(b *Block, dst, src *[BlockSize]byte, ivlo, ivhi uint64) { |
| ctrBlocksS390x(b, dst[:], src[:], ivlo, ivhi) |
| } |
| |
| func ctrBlocks2(b *Block, dst, src *[2 * BlockSize]byte, ivlo, ivhi uint64) { |
| ctrBlocksS390x(b, dst[:], src[:], ivlo, ivhi) |
| } |
| |
| func ctrBlocks4(b *Block, dst, src *[4 * BlockSize]byte, ivlo, ivhi uint64) { |
| ctrBlocksS390x(b, dst[:], src[:], ivlo, ivhi) |
| } |
| |
| func ctrBlocks8(b *Block, dst, src *[8 * BlockSize]byte, ivlo, ivhi uint64) { |
| ctrBlocksS390x(b, dst[:], src[:], ivlo, ivhi) |
| } |
| |
| func ctrBlocksS390x(b *Block, dst, src []byte, ivlo, ivhi uint64) { |
| if b.fallback != nil { |
| ctrBlocks(b, dst, src, ivlo, ivhi) |
| return |
| } |
| |
| buf := make([]byte, len(src), 8*BlockSize) |
| for i := 0; i < len(buf); i += BlockSize { |
| byteorder.BEPutUint64(buf[i:], ivhi) |
| byteorder.BEPutUint64(buf[i+8:], ivlo) |
| ivlo, ivhi = add128(ivlo, ivhi, 1) |
| } |
| |
| // Encrypt the buffer using AES in ECB mode. |
| cryptBlocks(b.function, &b.key[0], &buf[0], &buf[0], len(buf)) |
| |
| // XOR into buf first, in case src and dst overlap (see ctrBlocks). |
| subtle.XORBytes(buf, src, buf) |
| copy(dst, buf) |
| } |