Documentation ¶
Overview ¶
Package caam implements a driver for the NXP Cryptographic Acceleration and Assurance Module (CAAM) adopting the following reference specifications:
- IMX6ULSRM - i.MX6UL Security Reference Manual - Rev 0 04/2016
- IMX7DSSRM - i.MX7DS Security Reference Manual - Rev 0 03/2017
This package is only meant to be used with `GOOS=tamago GOARCH=arm` as supported by the TamaGo framework for bare metal Go on ARM SoCs, see https://github.com/usbarmory/tamago.
Index ¶
- Constants
- Variables
- type CAAM
- func (hw *CAAM) Decrypt(buf []byte, key []byte, iv []byte) (err error)
- func (hw *CAAM) DeriveKey(diversifier []byte, key []byte) (err error)
- func (hw *CAAM) EnableRTIC(blocks []MemoryBlock) (err error)
- func (hw *CAAM) Encrypt(buf []byte, key []byte, iv []byte) (err error)
- func (hw *CAAM) GetRandomData(b []byte)
- func (hw *CAAM) Init()
- func (hw *CAAM) New256() (Hash, error)
- func (hw *CAAM) RSTA() (cs uint32, err error)
- func (hw *CAAM) SetOwner(secure bool)
- func (hw *CAAM) Sign(priv *ecdsa.PrivateKey, hash []byte, pdb *SignPDB) (r, s *big.Int, err error)
- func (hw *CAAM) Sum256(data []byte) (sum [32]byte, err error)
- func (hw *CAAM) SumAES(msg []byte, key []byte) (sum [16]byte, err error)
- type Command
- type ExtendedLengthCommand
- type FIFOLoad
- type FIFOStore
- type Hash
- type Header
- type Jump
- type Key
- type LengthCommand
- type Load
- type MemoryBlock
- type Operation
- type SeqInPtr
- type SeqOutPtr
- type SignPDB
- type Store
Constants ¶
const ( CAAM_SCFGR = 0xc SCFGR_RNGSH0 = 9 SCFGR_RANDDPAR = 8 CAAM_RTMCTL = 0x600 RTMCTL_PRGM = 16 RTMCTL_ENT_VAL = 10 RTMCTL_RST_DEF = 6 RTMCTL_TRNG_ACC = 5 CAAM_RTENT0 = 0x640 CAAM_RTENT15 = 0x67c CAAM_C0CWR = 0x8044 C0CWR_C1M = 0 )
CAAM registers
const ( CTYPE = 27 CTYPE_KEY = 0b00000 CTYPE_LOAD = 0b00010 CTYPE_FIFO_LOAD = 0b00100 CTYPE_STORE = 0b01010 CTYPE_FIFO_STORE = 0b01100 CTYPE_OPERATION = 0b10000 CTYPE_JUMP = 0b10100 CTYPE_HEADER = 0b10110 CTYPE_SEQ_IN_PTR = 0b11110 CTYPE_SEQ_OUT_PTR = 0b11111 )
p266, 6.6.7.3 Command types, IMX6ULSRM
const ( // KEY, LOAD, STORE, JUMP commands CLASS = 25 // ALGORITHM, PROTOCOL, PKHA OPERATION commands OPERATION_OPTYPE = 24 // LOAD, STORE commands EXT = 22 DATA_TYPE = 16 LENGTH = 0 )
Fields common across multiple commands
const ( // LOAD, STORE commands CLRW = 0x08 CTX = 0x20 )
Field values common across multiple commands
const ( INPUT_DATA_TYPE_PKHA_Ax = 0b000000 INPUT_DATA_TYPE_IV = 0b100000 INPUT_DATA_TYPE_MESSAGE_DATA = 0b010000 INPUT_DATA_TYPE_LC2 = 1 << 2 INPUT_DATA_TYPE_LC1 = 1 << 1 OUTPUT_DATA_TYPE_MESSAGE_DATA = 0x30 )
p296, 6.6.11 FIFO LOAD command, IMX6ULSRM p313, 6.6.14 FIFO STORE command, IMX6ULSRM
const ( OPTYPE_ALG_CLASS1 = 0b010 OPTYPE_ALG_CLASS2 = 0b100 OPERATION_ALG = 16 ALG_AES = 0x10 ALG_SHA256 = 0x43 ALG_SHA512 = 0x45 ALG_RNG = 0x50 OPERATION_AAI = 4 AAI_AES_CBC = 0x10 AAI_AES_CMAC = 0x60 AAI_RNG_SK = 8 OPERATION_AS = 2 AS_UPDATE = 0b00 AS_INITIALIZE = 0b01 AS_FINALIZE = 0b10 OPERATION_ENC = 0 )
p328, 6.6.16 ALGORITHM OPERATION command, IMX6ULSRM
const ( OPTYPE_PROT_UNI = 0b000 OPTYPE_PROT_DEC = 0b110 OPTYPE_PROT_ENC = 0b111 OPERATION_PROTID = 16 PROTID_BLOB = 0x0d PROTID_ECDSA_SIGN = 0x15 OPERATION_PROTINFO = 0 PROTINFO_BLOB_FORMAT = 0 BLOB_FORMAT_MKV = 0b10 PROTINFO_SIGN_NO_TEQ = 12 PROTINFO_ECC = 1 )
p333, 6.6.17 PROTOCOL OPERATION command, IMX6ULSRM
const ( HEADER_ONE = 23 HEADER_START_INDEX = 16 HEADER_DESCLEN = 0 )
p276, 6.6.8 HEADER command, IMX6ULSRM
const ( DSA_SIG_PDB_PD = 22 DSA_SIG_PDB_ECDSEL = 7 )
p451, Table 8-112, IMX7DSSRM
const ( // Table 8-101 ECDSEL_P256 = 0x02 ECDSEL_P256K1 = 0x20 )
p443, Table 8-101, IMX7DSSRM
const ( CAAM_JR0_MIDR_MS = 0x10 CAAM_JR1_MIDR_MS = 0x18 CAAM_JR2_MIDR_MS = 0x20 JRxMIDR_MS_JROWN_NS = 3 CAAM_JRSTART = 0x5c CAAM_JR0_BASE = 0x1000 CAAM_JR1_BASE = 0x2000 CAAM_JR2_BASE = 0x3000 CAAM_IRBAR_JRx = 0x04 CAAM_IRSR_JRx = 0x0c CAAM_IRJAR_JRx = 0x1c CAAM_ORBAR_JRx = 0x24 CAAM_ORSR_JRx = 0x2c CAAM_ORJRR_JRx = 0x34 CAAM_ORSFR_JRx = 0x3c )
CAAM Job Ring registers
const ( CAAM_RSTA = 0x6004 RSTA_CS = 25 RSTA_AE = 8 RSTA_MIS = 4 RSTA_HE = 3 RSTA_SV = 2 RSTA_HD = 1 RSTA_BSY = 0 CAAM_RCMD = 0x600c RCMD_RTC = 2 RCMD_HO = 1 CAAM_RCTL = 0x6014 RCTL_RTME = 8 RCTL_HOME = 4 RCTL_RREQS = 1 CAAM_RTHR = 0x601c CAAM_RWDOG = 0x6028 // RTIC Memory Block Address CAAM_RMaAb = 0x6100 // RTIC Memory Block Length CAAM_RMaLb = 0x610c )
CAAM RTIC registers
const ( CS_IDLE = iota CS_SINGLE CS_RUN CS_ERR )
CAAM RTIC states
const (
JUMP_OFFSET = 0
)
p356, 6.6.20 JUMP command, IMX6ULSRM
const (
LOAD_IMM = 23
)
p285, 6.6.10 JUMP command, IMX6ULSRM
Variables ¶
var ( // RTICThrottle defines the clock cycles between RTIC hash operations RTICThrottle uint32 = 0x000000ff // RTICWatchdog defines the starting value for the RTIC Watchdog Timer RTICWatchdog uint64 = 0x0000ffffffffffff )
CAAM RTIC tuning
Functions ¶
This section is empty.
Types ¶
type CAAM ¶
type CAAM struct { sync.Mutex // Base register Base uint32 // Clock gate register CCGR uint32 // Clock gate CG int // DeriveKeyMemory represents the DMA memory region where the CAAM blob // key encryption key (BKEK), derived from the hardware unique key, is // placed to derive diversified keys. The memory region must be // initialized before DeriveKey(). // // When BEE is not used to encrypt external RAM it is recommended to // use a DMA region within the internal RAM (e.g. i.MX6 On-Chip // OCRAM/iRAM). // // The DeriveKey() function uses DeriveKeyMemory only if the default // DMA region start does not overlap with it. DeriveKeyMemory *dma.Region // Disable Timing Equalization protections (when supported) DisableTimingEqualization bool // contains filtered or unexported fields }
CAAM represents the Cryptographic Acceleration and Assurance Module instance.
func (*CAAM) Decrypt ¶
Decrypt performs in-place buffer decryption using AES-CBC, the key argument should be the AES key, either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.
All argument buffers are copied to reserved buffers in the default DMA region, buffers previously created with dma.Reserve() can be used to avoid external RAM exposure, when placed in iRAM, as their pointers are directly passed to the CAAM without access by the Go runtime.
func (*CAAM) DeriveKey ¶
DeriveKey derives a hardware unique key in a manner equivalent to NXP Symmetric key diversifications guidelines (AN10922 - Rev. 2.2) for AES-256 keys.
The diversifier is used as message for AES-256-CMAC authentication using a blob key encryption key (BKEK) derived from the hardware unique key (internal OTPMK, when SNVS is enabled, through Master Key Verification Blob).
*WARNING*: when SNVS is not enabled a default non-unique test vector is used and therefore key derivation is *unsafe*, see snvs.Available().
The unencrypted BKEK is used through DeriveKeyMemory. An output key buffer previously created with DeriveKeyMemory.Reserve() can be used to avoid external RAM exposure, when placed in iRAM, as its pointer is directly passed to the CAAM without access by the Go runtime.
func (*CAAM) EnableRTIC ¶
func (hw *CAAM) EnableRTIC(blocks []MemoryBlock) (err error)
EnableRTIC enables the CAAM Run Time Integrity Checker (RTIC) for up to 4 memory blocks.
Once enabled, the RTIC performs periodic (see RTICThrottle) hardware backed SHA256 hashing and raising a security violation (see RSTA()) in case of mismatch with the first computed hash.
Any security violation (which also affects the SNVS SSM) or memory block reconfiguration require a hardware reset.
func (*CAAM) Encrypt ¶
Encrypt performs in-place buffer encryption using AES-CBC, the key argument should be the AES key, either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.
All argument buffers are copied to reserved buffers in the default DMA region, buffers previously created with dma.Reserve() can be used to avoid external RAM exposure, when placed in iRAM, as their pointers are directly passed to the CAAM without access by the Go runtime.
func (*CAAM) GetRandomData ¶
GetRandomData returns len(b) random bytes gathered from the CAAM TRNG.
func (*CAAM) New256 ¶
New256 returns a new Digest computing the SHA256 checksum.
A single CAAM channel is used for all operations, this entails that only one digest instance can be kept at any given time, if this condition is not met an error is returned.
The digest instance starts with New256() and terminates when when Sum() is invoked, after which the digest state can no longer be changed.
func (*CAAM) SetOwner ¶
SetOwner defines the bus master that is permitted to access CAAM job ring registers. The argument defines either secure (e.g. TrustZone Secure World) or non-secure (e.g. TrustZone Normal World) ownership.
func (*CAAM) Sign ¶
Sign signs a hash (which should be the result of hashing a larger message) using the private key, priv. If the hash is longer than the bit-length of the private key's curve order, the hash will be truncated to that length. It returns the signature as a pair of integers.
A previously initialized sign protocol data block (see SignPDB.Init()) may be passed to cache private key initialization, in this case priv is ignored.
func (*CAAM) Sum256 ¶
Sum256 returns the SHA256 checksum of the data.
There must be sufficient DMA memory allocated to hold the data, otherwise the function will panic.
func (*CAAM) SumAES ¶
SumAES returns the AES Cipher-based message authentication code (CMAC) of the input message, the key argument should be the AES key, either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.
There must be sufficient DMA memory allocated to hold the message, otherwise the function will panic.
type Command ¶
Command represents a CAAM command (p266, 6.6.7.3 Command types, IMX6ULSRM).
type ExtendedLengthCommand ¶
type ExtendedLengthCommand struct {
Command
}
ExtendedLengthCommand represents a CAAM command with Extended Length and Pointer fields.
func (*ExtendedLengthCommand) Pointer ¶
func (c *ExtendedLengthCommand) Pointer(addr uint, n int)
Pointer sets the command POINTER and EXT LENGTH fields.
type FIFOLoad ¶
type FIFOLoad struct {
ExtendedLengthCommand
}
FIFOLoad represents a FIFO LOAD command (p296, 6.6.11 FIFO LOAD command, IMX6ULSRM).
func (*FIFOLoad) SetDefaults ¶
func (c *FIFOLoad) SetDefaults()
SetDefaults initializes default values for the FIFO LOAD command.
type FIFOStore ¶
type FIFOStore struct {
ExtendedLengthCommand
}
FIFOStore represents a FIFO STORE command (p313, 6.6.14 FIFO STORE command, IMX6ULSRM).
func (*FIFOStore) SetDefaults ¶
func (c *FIFOStore) SetDefaults()
SetDefaults initializes default values for the FIFO STORE command.
type Hash ¶
type Hash interface { // Write (via the embedded io.Writer interface) adds more data to the running hash. // It can return an error. It returns an error if Sum has been already invoked. io.Writer // Sum appends the current hash to b and returns the resulting slice. // Its invocation terminates the digest instance, for this reason Write // will return errors after Sum is invoked. Sum(b []byte) ([]byte, error) // BlockSize returns the hash's underlying block size. // The Write method must be able to accept any amount // of data, but it may operate more efficiently if all writes // are a multiple of the block size. BlockSize() int }
Hash is the common interface to CAAM hardware backed hash functions.
While similar to Go native hash.Hash, this interface is not fully compatible with it as hardware errors must be checked and checksum computation affects state.
type Header ¶
type Header struct {
Command
}
Header represents a CAAM HEADER command. (p276, 6.6.8 HEADER command, IMX6ULSRM).
func (*Header) SetDefaults ¶
func (c *Header) SetDefaults()
SetDefaults initializes default values for the HEADER command.
func (*Header) StartIndex ¶
StartIndex sets the HEADER command START INDEX field.
type Jump ¶
type Jump struct {
Command
}
Jump represents a CAAM JUMP command. (p356, 6.6.20 JUMP command, IMX6ULSRM).
func (*Jump) SetDefaults ¶
func (c *Jump) SetDefaults()
SetDefaults initializes default values for the JUMP command.
type Key ¶
type Key struct {
LengthCommand
}
Key represents a KEY command (p281, 6.6.9 KEY commands, IMX6ULSRM).
func (*Key) SetDefaults ¶
func (c *Key) SetDefaults()
SetDefaults initializes default values for the KEY command.
type LengthCommand ¶
type LengthCommand struct {
Command
}
LengthCommand represents a CAAM command with Length and Pointer fields.
func (*LengthCommand) Pointer ¶
func (c *LengthCommand) Pointer(addr uint, n int)
Pointer sets the command POINTER and EXT LENGTH fields.
type Load ¶
type Load struct {
LengthCommand
}
Load represents a LOAD command (p285, 6.6.10 LOAD commands, IMX6ULSRM).
func (*Load) Destination ¶
Destination sets the LOAD command DST field.
func (*Load) SetDefaults ¶
func (c *Load) SetDefaults()
SetDefaults initializes default values for the LOAD command.
type MemoryBlock ¶
MemoryBlock represents a memory region for RTIC monitoring.
type Operation ¶
type Operation struct {
Command
}
Operation represents a CAAM OPERATION command.
func (*Operation) Protocol ¶
Protocol sets the PROTOCOL OPERATION command PROTID and PROTINFO fields.
func (*Operation) SetDefaults ¶
func (c *Operation) SetDefaults()
SetDefaults initializes default values for the OPERATION command.
type SeqInPtr ¶
type SeqInPtr struct {
ExtendedLengthCommand
}
SeqInPtr represents a CAAM SEQ IN PTR command (p372, 6.6.22 SEQ IN PTR command, IMX6ULSRM).
func (*SeqInPtr) SetDefaults ¶
func (c *SeqInPtr) SetDefaults()
SetDefaults initializes default values for the SEQ IN PTR command.
type SeqOutPtr ¶
type SeqOutPtr struct {
ExtendedLengthCommand
}
SeqOutPtr represents a CAAM SEQ OUT PTR command (p375, 6.6.23 SEQ OUT PTR command, IMX6ULSRM).
func (*SeqOutPtr) SetDefaults ¶
func (c *SeqOutPtr) SetDefaults()
SetDefaults initializes default values for the SEQ OUT PTR command.
type SignPDB ¶
type SignPDB struct {
// contains filtered or unexported fields
}
SignPDB represents an ECDSA sign protocol data block (PDB).
type Store ¶
type Store struct {
LengthCommand
}
Store represents a STORE command (p306, 6.6.13 STORE command, IMX6ULSRM).
func (*Store) SetDefaults ¶
func (c *Store) SetDefaults()
SetDefaults initializes default values for the STORE command.