gitlab.com/beacon-software/gadget@v0.0.0-20181217202115-54565ea1ed5e/crypto/aes.go (about) 1 package crypto 2 3 import ( 4 "crypto/aes" 5 "crypto/cipher" 6 7 "gitlab.com/beacon-software/gadget/errors" 8 "gitlab.com/beacon-software/gadget/generator" 9 ) 10 11 // AES256KeySize for AWS256 Encryption 12 const AES256KeySize = 32 13 14 // IncompleteDataError returned when an incomplete ciphertext is passed to decrypt. 15 type IncompleteDataError struct{ trace []string } 16 17 func (err *IncompleteDataError) Error() string { 18 return "ciphertext data was incomplete" 19 } 20 21 // Trace returns the stack trace for the error 22 func (err *IncompleteDataError) Trace() []string { 23 return err.trace 24 } 25 26 // NewIncompleteDataError instantiates a IncompleteDataError with a stack trace 27 func NewIncompleteDataError() errors.TracerError { 28 return &IncompleteDataError{trace: errors.GetStackTrace()} 29 } 30 31 // AESEncryption provides AES256 Encryption with GCM tampering detection. 32 type AESEncryption struct { 33 key []byte 34 block cipher.Block 35 gcm cipher.AEAD 36 } 37 38 // NewAES using the passed key, if nil is passed a new key will be generated. 39 func NewAES(key []byte) (Encryption, error) { 40 a := &AESEncryption{} 41 var err error 42 if nil == key || len(key) == 0 { 43 a.RotateKey() 44 } else { 45 err = a.SetKey(key) 46 } 47 return a, err 48 } 49 50 // GetType returns the cipher type this instance of encryption provides. 51 func (a *AESEncryption) GetType() CipherType { 52 return AES 53 } 54 55 // GenerateKey will create a new key to use with this instance of AES 56 func (AESEncryption) GenerateKey() []byte { 57 return generator.Bytes(AES256KeySize) 58 } 59 60 // GetKey currently being used by this instance of AES 61 func (a *AESEncryption) GetKey() []byte { 62 return a.key 63 } 64 65 // RotateKey generates a new AES256 key and sets for use on this instance and returns it. 66 func (a *AESEncryption) RotateKey() []byte { 67 a.SetKey(a.GenerateKey()) 68 return a.key 69 } 70 71 // SetKey for use on this instance of AES256. 72 func (a *AESEncryption) SetKey(key []byte) error { 73 var err error 74 block, err := aes.NewCipher(key) 75 if nil != err { 76 return err 77 } 78 gcm, err := cipher.NewGCM(block) 79 if nil != err { 80 return err 81 } 82 a.key = key 83 a.block = block 84 a.gcm = gcm 85 return nil 86 } 87 88 // Encrypt with AES256-GCM 89 func (a *AESEncryption) Encrypt(plaintext []byte) (ciphertext []byte, err error) { 90 nonce := generator.Bytes(a.gcm.NonceSize()) 91 return a.gcm.Seal(nonce, nonce, plaintext, nil), nil 92 } 93 94 // Decrypt data using AES256-GCM 95 func (a *AESEncryption) Decrypt(ciphertext []byte) (plaintext []byte, err error) { 96 if len(ciphertext) < a.gcm.NonceSize() { 97 return nil, NewIncompleteDataError() 98 } 99 100 return a.gcm.Open(nil, 101 ciphertext[:a.gcm.NonceSize()], 102 ciphertext[a.gcm.NonceSize():], 103 nil, 104 ) 105 } 106 107 // Sign does nothing with AES 108 func (a *AESEncryption) Sign(plaintext []byte) (signature []byte, err error) { 109 return []byte{}, nil 110 } 111 112 // Verify does nothing with AES 113 func (a *AESEncryption) Verify(plaintext []byte, signature []byte) (err error) { 114 return nil 115 }