Documentation
¶
Overview ¶
Package crypto provides cryptographic primitives for the Matter protocol. This implements the cryptographic functions defined in Matter Specification Chapter 3.
Index ¶
- Constants
- Variables
- func AESCCM128Decrypt(key, nonce, ciphertext, aad []byte) ([]byte, error)
- func AESCCM128Encrypt(key, nonce, plaintext, aad []byte) ([]byte, error)
- func AESCTRDecrypt(key, nonce, ciphertext []byte) ([]byte, error)
- func AESCTREncrypt(key, nonce, plaintext []byte) ([]byte, error)
- func BuildAEADNonce(securityFlags uint8, messageCounter uint32, sourceNodeID uint64) []byte
- func BuildPrivacyNonce(sessionID uint16, mic []byte) ([]byte, error)
- func DeriveGroupOperationalKeyV1(epochKey, compressedFabricID []byte) ([]byte, error)
- func DeriveGroupSessionIDV1(operationalKey []byte) (uint16, error)
- func DerivePrivacyKey(encryptionKey []byte) ([]byte, error)
- func HKDFExpandSHA256(prk, info []byte, length int) ([]byte, error)
- func HKDFExtractSHA256(inputKey, salt []byte) []byte
- func HKDFSHA256(inputKey, salt, info []byte, length int) ([]byte, error)
- func HMACEqual(mac1, mac2 []byte) bool
- func HMACSHA256(key, message []byte) [SHA256LenBytes]byte
- func HMACSHA256Slice(key, message []byte) []byte
- func NewHMACSHA256(key []byte) hash.Hash
- func NewSHA256() hash.Hash
- func P256ECDH(keyPair *P256KeyPair, peerPublicKey []byte) ([]byte, error)
- func P256ECDHFromPrivateKey(privateKey, peerPublicKey []byte) ([]byte, error)
- func P256PublicKeyFromCompressed(compressed []byte) ([]byte, error)
- func P256Sign(keyPair *P256KeyPair, message []byte) ([]byte, error)
- func P256ValidatePublicKey(publicKey []byte) error
- func P256Verify(publicKey, message, signature []byte) (bool, error)
- func PBKDF2SHA256(password, salt []byte, iterations, keyLen int) []byte
- func SHA256(message []byte) [SHA256LenBytes]byte
- func SHA256Slice(message []byte) []byte
- type AESCCM
- type AESCTR
- type GroupOperationalCredentials
- type P256KeyPair
Constants ¶
const ( // AESCCMKeySize is the AES-128 key size in bytes (CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES). AESCCMKeySize = 16 // AESCCMTagSize is the authentication tag size in bytes (CRYPTO_AEAD_MIC_LENGTH_BYTES). // Matter mandates 128-bit tags. AESCCMTagSize = 16 // AESCCMNonceSize is the nonce size in bytes (CRYPTO_AEAD_NONCE_LENGTH_BYTES). // Matter mandates 13-byte nonces. AESCCMNonceSize = 13 )
AES-CCM constants from Matter Specification Section 3.6.
const ( // AESCTRKeySize is the AES-128 key size in bytes. AESCTRKeySize = 16 // AESCTRNonceSize is the nonce size in bytes (CRYPTO_PRIVACY_NONCE_LENGTH_BYTES). // Matter mandates 13-byte nonces for privacy encryption. AESCTRNonceSize = 13 )
AES-CTR constants from Matter Specification Section 3.7.
const ( // CompressedFabricIDSize is the size of compressed fabric identifier (8 bytes). CompressedFabricIDSize = 8 // GroupSessionIDSize is the size of the group session ID (2 bytes). GroupSessionIDSize = 2 )
Group key derivation constants.
const ( // SHA256LenBits is the SHA-256 output length in bits (CRYPTO_HASH_LEN_BITS). SHA256LenBits = 256 // SHA256LenBytes is the SHA-256 output length in bytes (CRYPTO_HASH_LEN_BYTES). SHA256LenBytes = 32 )
SHA-256 constants from Matter Specification Section 3.3.
const ( // PBKDF2IterationsMin is the minimum allowed iterations (CRYPTO_PBKDF_ITERATIONS_MIN). PBKDF2IterationsMin = 1000 // PBKDF2IterationsMax is the maximum allowed iterations (CRYPTO_PBKDF_ITERATIONS_MAX). PBKDF2IterationsMax = 100000 )
PBKDF2 iteration limits from Matter Specification Section 3.9.
const ( // NonceSize is the AEAD nonce length (CRYPTO_AEAD_NONCE_LENGTH_BYTES). // Used for both AES-CCM message encryption and AES-CTR privacy encryption. NonceSize = 13 // SymmetricKeySize is the symmetric key length (CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES). SymmetricKeySize = 16 // MICSize is the Message Integrity Check length (CRYPTO_AEAD_MIC_LENGTH_BYTES). MICSize = 16 // PrivacyNonceMICOffset is the starting offset in the MIC for privacy nonce (5). PrivacyNonceMICOffset = 5 // PrivacyNonceMICLength is the length of MIC fragment used in privacy nonce (11). PrivacyNonceMICLength = 11 )
Message security constants from Matter Specification.
const ( // P256GroupSizeBits is the group size in bits (CRYPTO_GROUP_SIZE_BITS). P256GroupSizeBits = 256 // P256GroupSizeBytes is the group size in bytes (CRYPTO_GROUP_SIZE_BYTES). P256GroupSizeBytes = 32 // P256PublicKeySizeBytes is the uncompressed public key size (CRYPTO_PUBLIC_KEY_SIZE_BYTES). // Format: 0x04 || X (32 bytes) || Y (32 bytes) = 65 bytes P256PublicKeySizeBytes = 65 // P256CompressedPublicKeySizeBytes is the compressed public key size. // Format: 0x02/0x03 || X (32 bytes) = 33 bytes P256CompressedPublicKeySizeBytes = 33 // P256SignatureSizeBytes is the signature size (r || s). P256SignatureSizeBytes = 64 )
P-256 constants from Matter Specification Section 3.5.1.
Variables ¶
var ( ErrAESCCMInvalidKeySize = errors.New("aesccm: invalid key size, must be 16 bytes") ErrAESCCMInvalidNonceSize = errors.New("aesccm: invalid nonce size") ErrAESCCMInvalidTagSize = errors.New("aesccm: invalid tag size, must be 4, 6, 8, 10, 12, 14, or 16") ErrAESCCMPlaintextTooLong = errors.New("aesccm: plaintext too long") ErrAESCCMCiphertextTooShort = errors.New("aesccm: ciphertext too short") ErrAESCCMAuthFailed = errors.New("aesccm: message authentication failed") )
Errors
var ( ErrAESCTRInvalidKeySize = errors.New("aesctr: invalid key size, must be 16 bytes") ErrAESCTRInvalidNonceSize = errors.New("aesctr: invalid nonce size, must be 13 bytes") )
Errors for AES-CTR operations.
var ( ErrInvalidEpochKeySize = errors.New("group: invalid epoch key size, must be 16 bytes") ErrInvalidCompressedFabricIDSize = errors.New("group: invalid compressed fabric ID size, must be 8 bytes") ErrInvalidOperationalKeySize = errors.New("group: invalid operational key size, must be 16 bytes") )
Errors for group key operations.
var ( ErrInvalidKeySize = errors.New("nonce: invalid key size, must be 16 bytes") ErrInvalidMICSize = errors.New("nonce: invalid MIC size, must be 16 bytes") )
Errors for nonce operations.
Functions ¶
func AESCCM128Decrypt ¶
AESCCM128Decrypt is a convenience function for AES-128-CCM decryption. This implements Crypto_AEAD_DecryptVerify from Matter Specification Section 3.6.2.
Parameters:
- key: 16-byte AES-128 key
- nonce: 13-byte nonce
- ciphertext: encrypted data with tag
- aad: additional authenticated data
Returns the decrypted plaintext, or an error if authentication fails.
func AESCCM128Encrypt ¶
AESCCM128Encrypt is a convenience function for AES-128-CCM encryption. This implements Crypto_AEAD_GenerateEncrypt from Matter Specification Section 3.6.1.
Parameters:
- key: 16-byte AES-128 key
- nonce: 13-byte nonce
- plaintext: data to encrypt
- aad: additional authenticated data
Returns ciphertext || tag.
func AESCTRDecrypt ¶
AESCTRDecrypt is a convenience function for AES-128-CTR decryption. This implements Crypto_Privacy_Decrypt from Matter Specification Section 3.7.2.
Parameters:
- key: 16-byte AES-128 key
- nonce: 13-byte nonce
- ciphertext: data to decrypt
Returns plaintext of the same length as ciphertext.
func AESCTREncrypt ¶
AESCTREncrypt is a convenience function for AES-128-CTR encryption. This implements Crypto_Privacy_Encrypt from Matter Specification Section 3.7.1.
Parameters:
- key: 16-byte AES-128 key
- nonce: 13-byte nonce
- plaintext: data to encrypt
Returns ciphertext of the same length as plaintext.
func BuildAEADNonce ¶
BuildAEADNonce constructs a 13-byte nonce for AEAD encryption/decryption. This implements the nonce format from Matter Specification Section 4.8.1.1 (Table 17).
Format: SecurityFlags (1 byte) || MessageCounter (4 bytes LE) || SourceNodeID (8 bytes LE)
Parameters:
- securityFlags: Security flags byte from the message header
- messageCounter: Message counter (32-bit, little-endian in nonce)
- sourceNodeID: Source node ID (64-bit, little-endian in nonce) For PASE sessions, use UnspecifiedNodeID (0). For CASE sessions, use the Operational Node ID. For Group sessions, use the Source Node ID from the message.
Returns a 13-byte nonce suitable for AES-CCM operations.
func BuildPrivacyNonce ¶
BuildPrivacyNonce constructs a 13-byte nonce for privacy encryption/decryption. This implements Section 4.9.2 "Privacy Nonce".
Format: SessionID (2 bytes BE) || MIC[5..15] (11 bytes)
The privacy nonce uses the session ID in big-endian format concatenated with the lower 11 bytes of the MIC (bytes at indices 5 through 15 inclusive).
Parameters:
- sessionID: The 16-bit session identifier
- mic: The 16-byte Message Integrity Check (tag) from AEAD encryption
Returns a 13-byte nonce suitable for AES-CTR privacy operations.
func DeriveGroupOperationalKeyV1 ¶
DeriveGroupOperationalKeyV1 derives an operational group key from an epoch key. This implements Section 4.17.2 "Operational Group Key Derivation" using the "GroupKey v1.0" info string. Future protocol versions may use different info strings.
OperationalGroupKey = HKDF-SHA256(
InputKey = EpochKey, Salt = CompressedFabricIdentifier, Info = "GroupKey v1.0", Length = CRYPTO_SYMMETRIC_KEY_LENGTH_BITS
)
Parameters:
- epochKey: The 16-byte epoch key from a group key set
- compressedFabricID: The 8-byte compressed fabric identifier
Returns the 16-byte operational group key used for message encryption.
func DeriveGroupSessionIDV1 ¶
DeriveGroupSessionIDV1 derives a group session ID from an operational group key. This is used to identify messages encrypted with a particular group key. Uses HKDF-SHA256 with "GroupKeyHash" info string.
GKH = HKDF-SHA256(
InputKey = OperationalGroupKey, Salt = [], Info = "GroupKeyHash", Length = 2
) GroupSessionID = BigEndian.Get16(GKH[0:2])
Parameters:
- operationalKey: The 16-byte operational group key
Returns the 16-bit group session ID.
func DerivePrivacyKey ¶
DerivePrivacyKey derives a privacy key from an encryption key. This implements Section 4.9.1 "Privacy Key" derivation.
PrivacyKey = Crypto_KDF(
InputKey = EncryptionKey, Salt = [], Info = "PrivacyKey", Length = CRYPTO_SYMMETRIC_KEY_LENGTH_BITS
)
Parameters:
- encryptionKey: The 16-byte session encryption key
Returns the 16-byte privacy key for use with AES-CTR privacy encryption.
func HKDFExpandSHA256 ¶
HKDFExpandSHA256 performs only the HKDF-Expand operation. This expands a pseudorandom key into output keying material.
Parameters:
- prk: Pseudorandom key (from HKDFExtract or other source)
- info: Optional context/application-specific info
- length: Number of bytes to derive
Returns the derived key material.
func HKDFExtractSHA256 ¶
HKDFExtractSHA256 performs only the HKDF-Extract operation. This extracts a pseudorandom key (PRK) from the input keying material.
Parameters:
- inputKey: Input keying material (IKM)
- salt: Optional salt value (can be nil, defaults to zero-filled HashLen bytes)
Returns a 32-byte pseudorandom key.
func HKDFSHA256 ¶
HKDFSHA256 derives key material using HKDF-SHA256 (RFC 5869). This implements Crypto_KDF() from Matter Specification Section 3.8.
Parameters:
- inputKey: Input keying material (IKM)
- salt: Optional salt value (can be nil or empty)
- info: Optional context/application-specific info (can be nil or empty)
- length: Number of bytes to derive
Returns the derived key material of the specified length.
func HMACEqual ¶
HMACEqual compares two MACs for equality in constant time. This should be used instead of bytes.Equal to prevent timing attacks.
func HMACSHA256 ¶
func HMACSHA256(key, message []byte) [SHA256LenBytes]byte
HMACSHA256 computes the HMAC-SHA256 of a message using the given key. This implements Crypto_HMAC() from Matter Specification Section 3.4.
Returns a 32-byte (256-bit) MAC.
func HMACSHA256Slice ¶
HMACSHA256Slice computes the HMAC-SHA256 and returns it as a slice. This is a convenience function for cases where a slice is preferred.
func NewHMACSHA256 ¶
NewHMACSHA256 returns a new hash.Hash for computing HMAC-SHA256 incrementally. This is useful for computing MACs over streaming data.
Usage:
h := crypto.NewHMACSHA256(key) h.Write(data1) h.Write(data2) mac := h.Sum(nil)
func NewSHA256 ¶
NewSHA256 returns a new hash.Hash for computing SHA-256 digests incrementally. This is useful for hashing large data or streaming data.
Usage:
h := crypto.NewSHA256() h.Write(data1) h.Write(data2) digest := h.Sum(nil)
func P256ECDH ¶
func P256ECDH(keyPair *P256KeyPair, peerPublicKey []byte) ([]byte, error)
P256ECDH computes the ECDH shared secret. This implements Crypto_ECDH() from Matter Specification Section 3.5.4.
Parameters:
- keyPair: Our private key
- peerPublicKey: Peer's 65-byte uncompressed public key (0x04 || X || Y)
Returns the 32-byte shared secret (x-coordinate of the shared point).
func P256ECDHFromPrivateKey ¶
P256ECDHFromPrivateKey computes ECDH using raw private key bytes. This is a convenience function when you have the private key as bytes.
func P256PublicKeyFromCompressed ¶
P256PublicKeyFromCompressed decompresses a compressed public key. Input: 33-byte compressed key (0x02/0x03 || X) Output: 65-byte uncompressed key (0x04 || X || Y)
func P256Sign ¶
func P256Sign(keyPair *P256KeyPair, message []byte) ([]byte, error)
P256Sign signs a message using ECDSA with SHA-256. This implements Crypto_Sign() from Matter Specification Section 3.5.3.
The message is hashed internally using SHA-256 before signing. Returns a 64-byte signature (r || s), each component zero-padded to 32 bytes.
func P256ValidatePublicKey ¶
P256ValidatePublicKey validates that a public key is valid and on the curve.
func P256Verify ¶
P256Verify verifies an ECDSA signature on a message. This implements Crypto_Verify() from Matter Specification Section 3.5.3.
Parameters:
- publicKey: 65-byte uncompressed public key (0x04 || X || Y)
- message: The original message that was signed
- signature: 64-byte signature (r || s)
Returns true if the signature is valid, false otherwise.
func PBKDF2SHA256 ¶
PBKDF2SHA256 derives a key from a password using PBKDF2-HMAC-SHA256 (NIST 800-132). This implements Crypto_PBKDF() from Matter Specification Section 3.9.
Parameters:
- password: The password/passcode to derive from
- salt: Salt value (Matter requires 16-32 bytes)
- iterations: Number of iterations (Matter: 1000-100000)
- keyLen: Number of bytes to derive
Returns the derived key material.
func SHA256 ¶
func SHA256(message []byte) [SHA256LenBytes]byte
SHA256 computes the SHA-256 cryptographic hash of a message. This implements Crypto_Hash() from Matter Specification Section 3.3.
Returns a 32-byte (256-bit) hash digest.
func SHA256Slice ¶
SHA256Slice computes the SHA-256 hash and returns it as a slice. This is a convenience function for cases where a slice is preferred.
Types ¶
type AESCCM ¶
type AESCCM struct {
// contains filtered or unexported fields
}
AESCCM represents an AES-128-CCM cipher instance with configurable parameters.
func NewAESCCM ¶
NewAESCCM creates a new AES-128-CCM cipher with Matter-compliant parameters. The key must be exactly 16 bytes (128 bits). Uses 13-byte nonce and 16-byte tag as required by Matter Specification Section 3.6.
func NewAESCCMWithParams ¶
NewAESCCMWithParams creates a new AES-128-CCM cipher with configurable parameters. This allows testing with RFC 3610 vectors which use different nonce and tag sizes.
Parameters:
- key: 16-byte AES-128 key
- nonceSize: nonce length in bytes (7-13 per NIST 800-38C)
- tagSize: authentication tag length in bytes (4, 6, 8, 10, 12, 14, or 16)
func (*AESCCM) Open ¶
Open decrypts and verifies ciphertext with associated data. This implements Crypto_AEAD_DecryptVerify from Matter Specification Section 3.6.2.
Parameters:
- nonce: nonce of the configured size (same as used for encryption)
- ciphertext: encrypted data with tag (minimum tagSize bytes for tag)
- aad: additional authenticated data
Returns the decrypted plaintext, or an error if authentication fails.
func (*AESCCM) Seal ¶
Seal encrypts and authenticates plaintext with associated data. This implements Crypto_AEAD_GenerateEncrypt from Matter Specification Section 3.6.1.
Parameters:
- nonce: nonce of the configured size (must be unique for each encryption with the same key)
- plaintext: data to encrypt
- aad: additional authenticated data (not encrypted, but authenticated)
Returns ciphertext || tag (plaintext length + tagSize bytes for tag).
type AESCTR ¶
type AESCTR struct {
// contains filtered or unexported fields
}
AESCTR represents an AES-128-CTR cipher instance for privacy encryption.
func NewAESCTR ¶
NewAESCTR creates a new AES-128-CTR cipher for Matter privacy encryption. The key must be exactly 16 bytes (128 bits).
func (*AESCTR) Decrypt ¶
Decrypt decrypts ciphertext using AES-CTR mode. This implements Crypto_Privacy_Decrypt from Matter Specification Section 3.7.2.
Parameters:
- nonce: 13-byte nonce (same as used for encryption)
- ciphertext: data to decrypt
Returns plaintext of the same length as ciphertext.
type GroupOperationalCredentials ¶
type GroupOperationalCredentials struct {
// EncryptionKey is the 16-byte operational group key for AES-CCM encryption.
EncryptionKey []byte
// PrivacyKey is the 16-byte privacy key for AES-CTR privacy encryption.
PrivacyKey []byte
// SessionID is the 16-bit group session ID.
SessionID uint16
}
GroupOperationalCredentials holds all derived credentials for a group.
func DeriveGroupCredentialsV1 ¶
func DeriveGroupCredentialsV1(epochKey, compressedFabricID []byte) (*GroupOperationalCredentials, error)
DeriveGroupCredentialsV1 derives all group operational credentials from an epoch key. This is a convenience function that combines DeriveGroupOperationalKeyV1, DerivePrivacyKey, and DeriveGroupSessionIDV1.
Parameters:
- epochKey: The 16-byte epoch key from a group key set
- compressedFabricID: The 8-byte compressed fabric identifier
Returns a GroupOperationalCredentials struct with all derived keys and session ID.
type P256KeyPair ¶
type P256KeyPair struct {
// contains filtered or unexported fields
}
P256KeyPair represents a P-256 key pair. This implements the KeyPair type from Matter Specification Section 3.5.1.
func P256GenerateKeyPair ¶
func P256GenerateKeyPair() (*P256KeyPair, error)
P256GenerateKeyPair generates a new P-256 key pair. This implements Crypto_GenerateKeyPair() from Matter Specification Section 3.5.2.
func P256KeyPairFromPrivateKey ¶
func P256KeyPairFromPrivateKey(privateKey []byte) (*P256KeyPair, error)
P256KeyPairFromPrivateKey creates a key pair from an existing private key scalar.
func (*P256KeyPair) P256PrivateKey ¶
func (kp *P256KeyPair) P256PrivateKey() []byte
P256PrivateKey returns the private key as a 32-byte scalar.
func (*P256KeyPair) P256PublicKey ¶
func (kp *P256KeyPair) P256PublicKey() []byte
P256PublicKey returns the public key in uncompressed format (65 bytes). Format: 0x04 || X (32 bytes) || Y (32 bytes)
func (*P256KeyPair) P256PublicKeyCompressed ¶
func (kp *P256KeyPair) P256PublicKeyCompressed() []byte
P256PublicKeyCompressed returns the public key in compressed format (33 bytes). Format: 0x02 (even Y) or 0x03 (odd Y) || X (32 bytes)