aes.mx raw

   1  // Copyright 2009 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  package aes
   6  
   7  import (
   8  	"crypto/internal/fips140"
   9  	"crypto/internal/fips140/alias"
  10  	"strconv"
  11  )
  12  
  13  // BlockSize is the AES block size in bytes.
  14  const BlockSize = 16
  15  
  16  // A Block is an instance of AES using a particular key.
  17  // It is safe for concurrent use.
  18  type Block struct {
  19  	block
  20  }
  21  
  22  // blockExpanded is the block type used for all architectures except s390x,
  23  // which feeds the raw key directly to its instructions.
  24  type blockExpanded struct {
  25  	rounds int
  26  	// Round keys, where only the first (rounds + 1) × (128 ÷ 32) words are used.
  27  	enc [60]uint32
  28  	dec [60]uint32
  29  }
  30  
  31  const (
  32  	// AES-128 has 128-bit keys, 10 rounds, and uses 11 128-bit round keys
  33  	// (11×128÷32 = 44 32-bit words).
  34  
  35  	// AES-192 has 192-bit keys, 12 rounds, and uses 13 128-bit round keys
  36  	// (13×128÷32 = 52 32-bit words).
  37  
  38  	// AES-256 has 256-bit keys, 14 rounds, and uses 15 128-bit round keys
  39  	// (15×128÷32 = 60 32-bit words).
  40  
  41  	aes128KeySize = 16
  42  	aes192KeySize = 24
  43  	aes256KeySize = 32
  44  
  45  	aes128Rounds = 10
  46  	aes192Rounds = 12
  47  	aes256Rounds = 14
  48  )
  49  
  50  // roundKeysSize returns the number of uint32 of c.end or c.dec that are used.
  51  func (b *blockExpanded) roundKeysSize() int {
  52  	return (b.rounds + 1) * (128 / 32)
  53  }
  54  
  55  type KeySizeError int
  56  
  57  func (k KeySizeError) Error() string {
  58  	var buf []byte
  59  	buf = append(buf, "crypto/aes: invalid key size "...)
  60  	buf = append(buf, strconv.Itoa(int(k))...)
  61  	return string(buf)
  62  }
  63  
  64  // New creates and returns a new [cipher.Block] implementation.
  65  // The key argument should be the AES key, either 16, 24, or 32 bytes to select
  66  // AES-128, AES-192, or AES-256.
  67  func New(key []byte) (*Block, error) {
  68  	// This call is outline to let the allocation happen on the parent stack.
  69  	return newOutlined(&Block{}, key)
  70  }
  71  
  72  // newOutlined is marked go:noinline to avoid it inlining into New, and making New
  73  // too complex to inline itself.
  74  //
  75  //go:noinline
  76  func newOutlined(b *Block, key []byte) (*Block, error) {
  77  	switch len(key) {
  78  	case aes128KeySize, aes192KeySize, aes256KeySize:
  79  	default:
  80  		return nil, KeySizeError(len(key))
  81  	}
  82  	return newBlock(b, key), nil
  83  }
  84  
  85  func newBlockExpanded(c *blockExpanded, key []byte) {
  86  	switch len(key) {
  87  	case aes128KeySize:
  88  		c.rounds = aes128Rounds
  89  	case aes192KeySize:
  90  		c.rounds = aes192Rounds
  91  	case aes256KeySize:
  92  		c.rounds = aes256Rounds
  93  	}
  94  	expandKeyGeneric(c, key)
  95  }
  96  
  97  func (c *Block) BlockSize() int { return BlockSize }
  98  
  99  func (c *Block) Encrypt(dst, src []byte) {
 100  	// AES-ECB is not approved in FIPS 140-3 mode.
 101  	fips140.RecordNonApproved()
 102  	if len(src) < BlockSize {
 103  		panic("crypto/aes: input not full block")
 104  	}
 105  	if len(dst) < BlockSize {
 106  		panic("crypto/aes: output not full block")
 107  	}
 108  	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 109  		panic("crypto/aes: invalid buffer overlap")
 110  	}
 111  	encryptBlock(c, dst, src)
 112  }
 113  
 114  func (c *Block) Decrypt(dst, src []byte) {
 115  	// AES-ECB is not approved in FIPS 140-3 mode.
 116  	fips140.RecordNonApproved()
 117  	if len(src) < BlockSize {
 118  		panic("crypto/aes: input not full block")
 119  	}
 120  	if len(dst) < BlockSize {
 121  		panic("crypto/aes: output not full block")
 122  	}
 123  	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 124  		panic("crypto/aes: invalid buffer overlap")
 125  	}
 126  	decryptBlock(c, dst, src)
 127  }
 128  
 129  // EncryptBlockInternal applies the AES encryption function to one block.
 130  //
 131  // It is an internal function meant only for the gcm package.
 132  func EncryptBlockInternal(c *Block, dst, src []byte) {
 133  	encryptBlock(c, dst, src)
 134  }
 135