aes

package module
v1.12.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 26, 2026 License: MIT Imports: 8 Imported by: 0

README

aes-go

Go Reference Go Report Card GitHub License

aes-go is a compact Go package for AES encryption. It keeps the modern AEAD APIs close at hand while still offering classic AES modes and padding helpers for interoperability work.

[!NOTE] Info: Start with an authenticated mode for new systems. NewSIV, NewAESGCMSIV, and NewGCM protect both confidentiality and integrity.

Install

go get github.com/colduction/aes-go

Choose an API

flowchart TD
    Start["Need AES encryption?"] --> NewData{"Encrypting new data?"}
    NewData -->|yes| Nonce{"Can every message use a unique nonce?"}
    Nonce -->|no or unsure| SIV["NewSIV<br/>deterministic AEAD, no nonce"]
    Nonce -->|yes| Interop{"Need standard GCM interop?"}
    Interop -->|yes| GCM["NewGCM<br/>fast AEAD, 12-byte nonce recommended"]
    Interop -->|no, prefer misuse resistance| GCMSIV["NewAESGCMSIV<br/>RFC 8452 AEAD, 12-byte nonce"]
    NewData -->|no, matching legacy data| Classic["New(mode, key, iv, padding)<br/>CBC / CTR / CFB / OFB / IGE / ECB"]
Use case API Authentication Nonce or IV Padding
Easiest safe default aes.NewSIV Yes None No
Nonce-misuse-resistant AEAD aes.NewAESGCMSIV Yes 12-byte nonce No
Standard AEAD interoperability aes.NewGCM Yes 12-byte nonce recommended No
GHASH-backed deterministic SIV aes.NewGHASHSIV Yes None No
Legacy block/stream modes aes.New No Mode-specific IV Optional

[!WARNING] Classic modes such as CBC, CTR, CFB, OFB, IGE, and ECB do not authenticate ciphertext. Add a MAC or use an AEAD mode unless a legacy protocol already defines the complete construction.

Quick Start

AES-SIV

AES-SIV is deterministic authenticated encryption. It does not need a nonce, and decryption fails if the ciphertext or additional data changes.

package main

import (
	"fmt"
	"log"

	"github.com/colduction/aes-go"
)

func main() {
	key, err := aes.GenerateSIVKey(aes.SIVKeySize256)
	if err != nil {
		log.Fatal(err)
	}

	aead, err := aes.NewSIV(key)
	if err != nil {
		log.Fatal(err)
	}

	plaintext := []byte("hello")
	metadata := []byte("user:42")

	ciphertext := aead.Seal(nil, nil, plaintext, metadata)

	decrypted, err := aead.Open(nil, nil, ciphertext, metadata)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(string(decrypted))
}

[!IMPORTANT] NewSIV reports NonceSize() == 0, so pass nil as the nonce to Seal and Open.

AES-GCM

AES-GCM is fast and widely supported. Generate a fresh nonce for every message encrypted with the same key.

key, err := aes.GenerateKey(aes.KeySize256)
if err != nil {
	log.Fatal(err)
}

seedNonce := make([]byte, 12)
aead, err := aes.NewGCM(key, seedNonce, nil)
if err != nil {
	log.Fatal(err)
}

nonce, err := aes.GenerateRandomBytes(aead.NonceSize())
if err != nil {
	log.Fatal(err)
}

metadata := []byte("user:42")
ciphertext := aead.Seal(nil, nonce, []byte("hello"), metadata)

plaintext, err := aead.Open(nil, nonce, ciphertext, metadata)
if err != nil {
	log.Fatal(err)
}

[!CAUTION] Reusing a GCM nonce with the same key can break confidentiality and authentication. Store or transmit the nonce beside the ciphertext.

AES-GCM-SIV

AES-GCM-SIV keeps an AEAD shape while reducing the damage from accidental nonce reuse.

key, err := aes.GenerateKey(aes.AESGCMSIVKeySize256)
if err != nil {
	log.Fatal(err)
}

aead, err := aes.NewAESGCMSIV(key)
if err != nil {
	log.Fatal(err)
}

nonce, err := aes.GenerateRandomBytes(aes.AESGCMSIVNonceSize)
if err != nil {
	log.Fatal(err)
}

metadata := []byte("user:42")
ciphertext := aead.Seal(nil, nonce, []byte("hello"), metadata)

plaintext, err := aead.Open(nil, nonce, ciphertext, metadata)
if err != nil {
	log.Fatal(err)
}
CBC compatibility example with PKCS#7 padding
package main

import (
	"log"

	"github.com/colduction/aes-go"
	"github.com/colduction/aes-go/padding"
)

func main() {
	key, err := aes.GenerateKey(aes.KeySize256)
	if err != nil {
		log.Fatal(err)
	}

	iv, err := aes.GenerateIV()
	if err != nil {
		log.Fatal(err)
	}

	c, err := aes.New(aes.ModeCBC, key, iv, padding.PKCS7)
	if err != nil {
		log.Fatal(err)
	}

	ciphertext, err := c.Encrypt([]byte("hello"))
	if err != nil {
		log.Fatal(err)
	}

	plaintext, err := c.Decrypt(ciphertext)
	if err != nil {
		log.Fatal(err)
	}

	_ = plaintext
}

Key Sizes

Constant Bytes Purpose
aes.KeySize128 16 AES-128
aes.KeySize192 24 AES-192
aes.KeySize256 32 AES-256
aes.SIVKeySize128 32 AES-128-SIV
aes.SIVKeySize192 48 AES-192-SIV
aes.SIVKeySize256 64 AES-256-SIV
aes.GHASHSIVKeySize128 16 AES-128-GHASH-SIV
aes.GHASHSIVKeySize192 24 AES-192-GHASH-SIV
aes.GHASHSIVKeySize256 32 AES-256-GHASH-SIV
aes.AESGCMSIVKeySize128 16 AES-128-GCM-SIV
aes.AESGCMSIVKeySize256 32 AES-256-GCM-SIV

Use aes.GenerateSIVKey for SIVKeySize* constants. Use aes.GenerateKey for standard AES, GHASH-SIV, and AES-GCM-SIV constants that are 16, 24, or 32 bytes.

Classic Modes

Mode IV requirement Notes
aes.ModeCBC 16 bytes Needs padding for most plaintext.
aes.ModeCFB 16 bytes Stream-like compatibility mode.
aes.ModeCTR 16 bytes Never reuse the same key and IV pair.
aes.ModeECB None Legacy-only; leaks repeated blocks.
aes.ModeIGE 32 bytes Compatibility mode for protocols that require IGE.
aes.ModeOFB 16 bytes Stream-like compatibility mode.

[!WARNING] Avoid ModeECB for new data. It reveals patterns in plaintext and is included only for compatibility.

Padding

Padding helpers live in a subpackage:

import "github.com/colduction/aes-go/padding"

Available schemes:

Padding Typical use
padding.PKCS7 Default choice for AES-CBC, AES-ECB, and AES-IGE compatibility.
padding.PKCS5 Legacy PKCS#5 interoperability.
padding.X923 ANSI X9.23 interoperability.
padding.ISO7816 ISO/IEC 7816-4 style padding.
padding.ISO10126 Legacy randomized padding.
padding.Bit Bit padding compatibility.
padding.TBC Trailing bit complement padding.
padding.Zero Zero padding when the protocol can disambiguate trailing zero bytes.

Safety Checklist

  • Generate keys with aes.GenerateKey or aes.GenerateSIVKey.
  • Generate IVs and nonces with aes.GenerateIV or aes.GenerateRandomBytes.
  • Prefer NewSIV, NewAESGCMSIV, or NewGCM for new designs.
  • Treat additional data as authenticated metadata and pass the same value to decrypt.
  • Never reuse a GCM nonce with the same key.
  • Never reuse a CTR, CFB, or OFB key/IV pair.
  • Avoid ECB unless a legacy protocol requires it.

[!TIP] Keep keys out of source code and logs. Load them from a secret manager, KMS, or another environment-specific secret source.

License

This project is released under the MIT License. See LICENSE.

Documentation

Overview

Package aes implements convenience helpers for AES block cipher modes.

Index

Constants

View Source
const (
	// IGEIVSize is the size, in bytes, of an IGE initialization vector.
	IGEIVSize = stdaes.BlockSize << 1

	// KeySize128 is the size, in bytes, of an AES-128 key.
	KeySize128 = 16

	// KeySize192 is the size, in bytes, of an AES-192 key.
	KeySize192 = 24

	// KeySize256 is the size, in bytes, of an AES-256 key.
	KeySize256 = 32
)
View Source
const (
	// SIVTagSize is the size, in bytes, of an AES-SIV authentication tag.
	SIVTagSize = 16

	// SIVKeySize128 is the size, in bytes, of an AES-128-SIV key.
	SIVKeySize128 = KeySize128 << 1

	// SIVKeySize192 is the size, in bytes, of an AES-192-SIV key.
	SIVKeySize192 = KeySize192 << 1

	// SIVKeySize256 is the size, in bytes, of an AES-256-SIV key.
	SIVKeySize256 = KeySize256 << 1
)
View Source
const (
	// GHASHSIVKeySize128 is the size, in bytes, of an AES-128-GHASH-SIV key.
	GHASHSIVKeySize128 = KeySize128

	// GHASHSIVKeySize192 is the size, in bytes, of an AES-192-GHASH-SIV key.
	GHASHSIVKeySize192 = KeySize192

	// GHASHSIVKeySize256 is the size, in bytes, of an AES-256-GHASH-SIV key.
	GHASHSIVKeySize256 = KeySize256
)
View Source
const (
	// AESGCMSIVKeySize128 is the size, in bytes, of an AES-128-GCM-SIV key.
	AESGCMSIVKeySize128 = KeySize128

	// AESGCMSIVKeySize256 is the size, in bytes, of an AES-256-GCM-SIV key.
	AESGCMSIVKeySize256 = KeySize256

	// AESGCMSIVNonceSize is the required AES-GCM-SIV nonce size, in bytes.
	AESGCMSIVNonceSize = 12

	// AESGCMSIVTagSize is the size, in bytes, of an AES-GCM-SIV tag.
	AESGCMSIVTagSize = 16
)

Variables

View Source
var ErrSIVAuthFailed = aesinternal.ErrSIVOpen

ErrSIVAuthFailed is returned when SIV authentication fails.

View Source
var ErrUnknownMode = errors.New("aes: unknown cipher mode")

ErrUnknownMode is returned when New is called with an unknown mode.

Functions

func GenerateIV

func GenerateIV() ([]byte, error)

GenerateIV returns a new random AES initialization vector.

func GenerateKey

func GenerateKey(size int) ([]byte, error)

GenerateKey returns a new random AES key of the given size.

The size must be KeySize128, KeySize192, or KeySize256.

func GenerateRandomBytes

func GenerateRandomBytes(n int) ([]byte, error)

GenerateRandomBytes returns n cryptographically secure random bytes.

func GenerateSIVKey

func GenerateSIVKey(size int) ([]byte, error)

GenerateSIVKey returns a new random AES-SIV key of the given size.

The size must be SIVKeySize128, SIVKeySize192, or SIVKeySize256.

Types

type AEADCipher

type AEADCipher interface {
	cipher.AEAD
	Encrypt(plaintext []byte) ([]byte, error)
	Decrypt(ciphertext []byte) ([]byte, error)
}

AEADCipher is an authenticated encryption cipher.

It includes the standard cipher.AEAD API and the package's Encrypt and Decrypt convenience methods.

func NewAESGCMSIV

func NewAESGCMSIV(masterKey []byte, nonceAndData ...[]byte) (AEADCipher, error)

NewAESGCMSIV returns a new RFC 8452 AES-GCM-SIV AEAD.

The masterKey must be AESGCMSIVKeySize128 or AESGCMSIVKeySize256 bytes long. New code should pass the nonce and additional data to Seal and Open. Passing nonce and additionalData here is supported for the legacy Encrypt and Decrypt helpers.

func NewGCM

func NewGCM(key, nonce, additionalData []byte) (AEADCipher, error)

NewGCM returns a new AES-GCM cipher with the standard 16-byte tag.

The key must be 16, 24, or 32 bytes. The nonce must not be reused with the same key. A 12-byte nonce is recommended.

func NewGCMWithTagSize

func NewGCMWithTagSize(key, nonce, additionalData []byte, tagSize int) (AEADCipher, error)

NewGCMWithTagSize returns a new AES-GCM cipher with a custom tag size.

The tagSize must be between 12 and 16 bytes. The nonce must be 12 bytes.

func NewGHASHSIV

func NewGHASHSIV(key []byte, additionalData ...[]byte) (AEADCipher, error)

NewGHASHSIV returns a new AES-GHASH-SIV AEAD.

AES-GHASH-SIV has the same public behavior as NewSIV, but uses GHASH instead of CMAC for the synthetic IV calculation.

func NewSIV

func NewSIV(key []byte, additionalData ...[]byte) (AEADCipher, error)

NewSIV returns a new AES-SIV AEAD.

The key must be SIVKeySize128, SIVKeySize192, or SIVKeySize256 bytes long. Additional data should normally be supplied to Seal and Open. The optional additionalData values are kept for the legacy Encrypt and Decrypt helpers.

type AESGCMSIVKeySizeError

type AESGCMSIVKeySizeError int

AESGCMSIVKeySizeError is returned when an AES-GCM-SIV key has the wrong length.

func (AESGCMSIVKeySizeError) Error

func (e AESGCMSIVKeySizeError) Error() string

type AESGCMSIVNonceSizeError

type AESGCMSIVNonceSizeError int

AESGCMSIVNonceSizeError is returned when an AES-GCM-SIV nonce has the wrong length.

func (AESGCMSIVNonceSizeError) Error

func (e AESGCMSIVNonceSizeError) Error() string

type Cipher

type Cipher struct {
	// contains filtered or unexported fields
}

Cipher is a reusable AES cipher with a fixed mode, key, IV, and padding mode.

func New

func New(mode Mode, key, iv []byte, pad padding.Padding) (*Cipher, error)

New returns a new Cipher for the given mode.

The key must be 16, 24, or 32 bytes. The IV must be 16 bytes for most modes, IGEIVSize bytes for ModeIGE, and nil for ModeECB. The padding mode may be nil when the input is already block aligned.

func (*Cipher) Decrypt

func (c *Cipher) Decrypt(ciphertext []byte) ([]byte, error)

Decrypt decrypts ciphertext and returns the plaintext.

func (*Cipher) Encrypt

func (c *Cipher) Encrypt(plaintext []byte) ([]byte, error)

Encrypt encrypts plaintext and returns the ciphertext.

type GCMDataSizeError

type GCMDataSizeError int

GCMDataSizeError is returned when AES-GCM plaintext is too large.

func (GCMDataSizeError) Error

func (e GCMDataSizeError) Error() string

type GCMNonceSizeError

type GCMNonceSizeError int

GCMNonceSizeError is returned when an AES-GCM nonce has the wrong length.

func (GCMNonceSizeError) Error

func (e GCMNonceSizeError) Error() string

type GCMTagSizeError

type GCMTagSizeError int

GCMTagSizeError is returned when an AES-GCM tag has the wrong length.

func (GCMTagSizeError) Error

func (e GCMTagSizeError) Error() string

type GHASHSIVKeySizeError

type GHASHSIVKeySizeError int

GHASHSIVKeySizeError is returned when an AES-GHASH-SIV key has the wrong length.

func (GHASHSIVKeySizeError) Error

func (e GHASHSIVKeySizeError) Error() string

type IgeIvSizeError

type IgeIvSizeError int

IgeIvSizeError is returned when an IGE initialization vector has the wrong length.

func (IgeIvSizeError) Error

func (e IgeIvSizeError) Error() string

type InvalidCiphertextError

type InvalidCiphertextError int

InvalidCiphertextError is returned when ciphertext is empty or not block aligned.

func (InvalidCiphertextError) Error

func (e InvalidCiphertextError) Error() string

type InvalidDataError

type InvalidDataError int

InvalidDataError is returned when plaintext is empty or not block aligned.

func (InvalidDataError) Error

func (e InvalidDataError) Error() string

type IvSizeError

type IvSizeError int

IvSizeError is returned when an initialization vector has the wrong length.

func (IvSizeError) Error

func (e IvSizeError) Error() string

type KeySizeError

type KeySizeError int

KeySizeError is returned when an AES key has the wrong length.

func (KeySizeError) Error

func (e KeySizeError) Error() string

type Mode

type Mode uint8

Mode identifies an AES mode of operation.

const (
	// ModeCBC selects cipher block chaining mode.
	ModeCBC Mode = iota + 1

	// ModeCFB selects cipher feedback mode.
	ModeCFB

	// ModeCTR selects counter mode.
	ModeCTR

	// ModeECB selects electronic codebook mode.
	ModeECB

	// ModeIGE selects infinite garble extension mode.
	ModeIGE

	// ModeOFB selects output feedback mode.
	ModeOFB
)

type SIVKeySizeError

type SIVKeySizeError int

SIVKeySizeError is returned when an AES-SIV key has the wrong length.

func (SIVKeySizeError) Error

func (e SIVKeySizeError) Error() string

Directories

Path Synopsis
internal
aes
Package aes provides internal AES cipher-mode primitives.
Package aes provides internal AES cipher-mode primitives.
Package padding implements common block cipher padding schemes.
Package padding implements common block cipher padding schemes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL