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 7package aes 8 9import ( 10 "crypto/cipher" 11 "crypto/internal/cipherhw" 12) 13 14type code int 15 16// Function codes for the cipher message family of instructions. 17const ( 18 aes128 code = 18 19 aes192 = 19 20 aes256 = 20 21) 22 23type aesCipherAsm struct { 24 function code // code for cipher message instruction 25 key []byte // key (128, 192 or 256 bytes) 26 storage [256]byte // array backing key slice 27} 28 29// cryptBlocks invokes the cipher message (KM) instruction with 30// the given function code. This is equivalent to AES in ECB 31// mode. The length must be a multiple of BlockSize (16). 32//go:noescape 33func cryptBlocks(c code, key, dst, src *byte, length int) 34 35var useAsm = cipherhw.AESGCMSupport() 36 37func newCipher(key []byte) (cipher.Block, error) { 38 if !useAsm { 39 return newCipherGeneric(key) 40 } 41 42 var function code 43 switch len(key) { 44 case 128 / 8: 45 function = aes128 46 case 192 / 8: 47 function = aes192 48 case 256 / 8: 49 function = aes256 50 default: 51 return nil, KeySizeError(len(key)) 52 } 53 54 var c aesCipherAsm 55 c.function = function 56 c.key = c.storage[:len(key)] 57 copy(c.key, key) 58 return &c, nil 59} 60 61func (c *aesCipherAsm) BlockSize() int { return BlockSize } 62 63func (c *aesCipherAsm) Encrypt(dst, src []byte) { 64 if len(src) < BlockSize { 65 panic("crypto/aes: input not full block") 66 } 67 if len(dst) < BlockSize { 68 panic("crypto/aes: output not full block") 69 } 70 cryptBlocks(c.function, &c.key[0], &dst[0], &src[0], BlockSize) 71} 72 73func (c *aesCipherAsm) Decrypt(dst, src []byte) { 74 if len(src) < BlockSize { 75 panic("crypto/aes: input not full block") 76 } 77 if len(dst) < BlockSize { 78 panic("crypto/aes: output not full block") 79 } 80 // The decrypt function code is equal to the function code + 128. 81 cryptBlocks(c.function+128, &c.key[0], &dst[0], &src[0], BlockSize) 82} 83 84// expandKey is used by BenchmarkExpand. cipher message (KM) does not need key 85// expansion so there is no assembly equivalent. 86func expandKey(key []byte, enc, dec []uint32) { 87 expandKeyGo(key, enc, dec) 88} 89