github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/crypto/aes/ctr_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  // +build ignore
     6  
     7  package aes
     8  
     9  import (
    10  	"crypto/cipher"
    11  	"crypto/internal/subtle"
    12  	"encoding/binary"
    13  )
    14  
    15  // Assert that aesCipherAsm implements the ctrAble interface.
    16  var _ ctrAble = (*aesCipherAsm)(nil)
    17  
    18  // xorBytes xors the contents of a and b and places the resulting values into
    19  // dst. If a and b are not the same length then the number of bytes processed
    20  // will be equal to the length of shorter of the two. Returns the number
    21  // of bytes processed.
    22  //go:noescape
    23  func xorBytes(dst, a, b []byte) int
    24  
    25  // streamBufferSize is the number of bytes of encrypted counter values to cache.
    26  const streamBufferSize = 32 * BlockSize
    27  
    28  type aesctr struct {
    29  	block   *aesCipherAsm          // block cipher
    30  	ctr     [2]uint64              // next value of the counter (big endian)
    31  	buffer  []byte                 // buffer for the encrypted counter values
    32  	storage [streamBufferSize]byte // array backing buffer slice
    33  }
    34  
    35  // NewCTR returns a Stream which encrypts/decrypts using the AES block
    36  // cipher in counter mode. The length of iv must be the same as BlockSize.
    37  func (c *aesCipherAsm) NewCTR(iv []byte) cipher.Stream {
    38  	if len(iv) != BlockSize {
    39  		panic("cipher.NewCTR: IV length must equal block size")
    40  	}
    41  	var ac aesctr
    42  	ac.block = c
    43  	ac.ctr[0] = binary.BigEndian.Uint64(iv[0:]) // high bits
    44  	ac.ctr[1] = binary.BigEndian.Uint64(iv[8:]) // low bits
    45  	ac.buffer = ac.storage[:0]
    46  	return &ac
    47  }
    48  
    49  func (c *aesctr) refill() {
    50  	// Fill up the buffer with an incrementing count.
    51  	c.buffer = c.storage[:streamBufferSize]
    52  	c0, c1 := c.ctr[0], c.ctr[1]
    53  	for i := 0; i < streamBufferSize; i += 16 {
    54  		binary.BigEndian.PutUint64(c.buffer[i+0:], c0)
    55  		binary.BigEndian.PutUint64(c.buffer[i+8:], c1)
    56  
    57  		// Increment in big endian: c0 is high, c1 is low.
    58  		c1++
    59  		if c1 == 0 {
    60  			// add carry
    61  			c0++
    62  		}
    63  	}
    64  	c.ctr[0], c.ctr[1] = c0, c1
    65  	// Encrypt the buffer using AES in ECB mode.
    66  	cryptBlocks(c.block.function, &c.block.key[0], &c.buffer[0], &c.buffer[0], streamBufferSize)
    67  }
    68  
    69  func (c *aesctr) XORKeyStream(dst, src []byte) {
    70  	if len(dst) < len(src) {
    71  		panic("crypto/cipher: output smaller than input")
    72  	}
    73  	if subtle.InexactOverlap(dst[:len(src)], src) {
    74  		panic("crypto/cipher: invalid buffer overlap")
    75  	}
    76  	for len(src) > 0 {
    77  		if len(c.buffer) == 0 {
    78  			c.refill()
    79  		}
    80  		n := xorBytes(dst, src, c.buffer)
    81  		c.buffer = c.buffer[n:]
    82  		src = src[n:]
    83  		dst = dst[n:]
    84  	}
    85  }