crypto

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Apr 24, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package crypto provides cryptographic primitives required by the Matter protocol, including SPAKE2+, AES-CCM, HKDF, PBKDF2, ECDH, ECDSA, and certificate operations.

Index

Constants

View Source
const AESCCMNonceSize = 13

AESCCMNonceSize is the nonce size in bytes used by Matter (13 bytes / 104 bits).

View Source
const AESCCMTagSize = 16

AESCCMTagSize is the authentication tag size in bytes used by Matter (128 bits).

Variables

This section is empty.

Functions

func AESCCMDecrypt

func AESCCMDecrypt(key, nonce, ciphertextWithTag, aad []byte) ([]byte, error)

AESCCMDecrypt decrypts ciphertext produced by AESCCMEncrypt. The input must be ciphertext || tag. Returns the plaintext, or an error if authentication fails.

func AESCCMEncrypt

func AESCCMEncrypt(key, nonce, plaintext, aad []byte) ([]byte, error)

AESCCMEncrypt encrypts plaintext using AES-128-CCM with the given key, nonce, and additional authenticated data (aad). The nonce must be 13 bytes and the key must be 16 bytes. It returns ciphertext || tag (len(plaintext) + AESCCMTagSize bytes). Implements RFC 3610.

func CompressPublicKey

func CompressPublicKey(pub *ecdsa.PublicKey) []byte

CompressPublicKey returns the compressed SEC1 encoding of a P-256 public key (33 bytes).

func CompressedFabricID

func CompressedFabricID(rootPubKey []byte, fabricID uint64) ([]byte, error)

CompressedFabricID derives the 8-byte Compressed Fabric Identifier from the root CA public key and fabric ID, per Matter spec section 4.3.2.2:

CompressedFabricID = HKDF-SHA256(
    IKM  = rootPubKey[1:],       // uncompressed key minus 0x04 prefix
    Salt = fabricID (LE uint64),
    Info = "CompressedFabric",
    L    = 8)

func ComputeL

func ComputeL(w1 []byte) []byte

ComputeL computes L = w1 * G (the verifier's precomputed public point). w1 is a 32-byte big-endian scalar.

func DecompressPublicKey

func DecompressPublicKey(data []byte) (*ecdsa.PublicKey, error)

DecompressPublicKey parses a compressed SEC1-encoded P-256 public key.

func DeriveGroupOperationalKey

func DeriveGroupOperationalKey(epochKey, compressedFabricID []byte) ([]byte, error)

DeriveGroupOperationalKey derives an operational group key from an epoch key and the compressed fabric ID, per Matter spec section 4.14.2.6.1:

OperationalKey = HKDF-SHA256(
    IKM  = epochKey,
    Salt = compressedFabricID (8 bytes),
    Info = "GroupKey v1.0",
    L    = 16)

For the Identity Protection Key (IPK, key set 0), this produces the Operational Identity Protection Key used in CASE DestinationID computation.

func DeriveSPAKE2PValues

func DeriveSPAKE2PValues(passcode uint32, salt []byte, iterations int) (w0, w1 []byte, err error)

DeriveSPAKE2PValues derives the w0 and w1 scalars from a Matter passcode using PBKDF2 as specified in the Matter protocol. The passcode is encoded as a little-endian uint32. Returns w0 and w1 as 32-byte big-endian scalars reduced modulo the P-256 order.

func ECDH

func ECDH(privKey *ecdsa.PrivateKey, pubKey *ecdsa.PublicKey) ([]byte, error)

ECDH performs an Elliptic Curve Diffie-Hellman key exchange using P-256. It returns the raw shared secret (the x-coordinate of the shared point).

func ECDHFromBytes

func ECDHFromBytes(privScalar, peerPubUncompressed []byte) ([]byte, error)

ECDHFromBytes performs ECDH given a private key scalar (32 bytes) and a peer's uncompressed public key (65 bytes).

func ExtractPublicKey

func ExtractPublicKey(certDER []byte) (*ecdsa.PublicKey, error)

ExtractPublicKey extracts the ECDSA P-256 public key from a DER-encoded certificate.

func ExtractPublicKeyFromTLV

func ExtractPublicKeyFromTLV(cert []byte) (*ecdsa.PublicKey, error)

ExtractPublicKeyFromTLV extracts the ECDSA P-256 public key from a certificate that may be in either Matter TLV or X.509 DER format. It tries TLV first (looking for tag 9 / certTagECPubKey), then falls back to DER parsing.

func GenerateICAC

func GenerateICAC(icacKey *ecdsa.PrivateKey, icacID uint64, fabricID uint64, rcacCertDER []byte, rcacKey *ecdsa.PrivateKey, opts CertificateOptions) ([]byte, error)

GenerateICAC generates a Matter Intermediate CA Certificate (ICAC) signed by the RCAC key. Returns the DER-encoded certificate.

func GenerateKeyPair

func GenerateKeyPair() (*ecdsa.PrivateKey, error)

GenerateKeyPair generates a new ECDSA P-256 key pair suitable for Matter operations.

func GenerateNOC

func GenerateNOC(nodeKey *ecdsa.PrivateKey, nodeID uint64, fabricID uint64, caCertDER []byte, caKey *ecdsa.PrivateKey, opts CertificateOptions) ([]byte, error)

GenerateNOC generates a Matter Node Operational Certificate (NOC) signed by the given CA key (either RCAC or ICAC). nodeID is the Matter node ID, fabricID is the fabric ID. Returns the DER-encoded certificate.

func GenerateNOCForPublicKey

func GenerateNOCForPublicKey(nodePubKey *ecdsa.PublicKey, nodeID uint64, fabricID uint64, caCertDER []byte, caKey *ecdsa.PrivateKey, opts CertificateOptions) ([]byte, error)

GenerateNOCForPublicKey generates a Matter Node Operational Certificate (NOC) for a given public key, signed by the CA key (either RCAC or ICAC). This is used when the device provides its public key via a CSR.

func GenerateRCAC

func GenerateRCAC(key *ecdsa.PrivateKey, rcacID uint64, fabricID uint64, opts CertificateOptions) ([]byte, error)

GenerateRCAC generates a self-signed Matter Root CA Certificate (RCAC). The rcacID is a hex-encoded identifier used in the subject. Returns the DER-encoded certificate.

func HKDFExpandSHA256

func HKDFExpandSHA256(prk, info []byte, length int) ([]byte, error)

HKDFExpandSHA256 performs HKDF-Expand using SHA-256, returning length bytes of output keying material. The prk must be a pseudorandom key from a prior extract step.

func HKDFExtractSHA256

func HKDFExtractSHA256(salt, ikm []byte) []byte

HKDFExtractSHA256 performs HKDF-Extract using SHA-256, returning a pseudorandom key suitable for use with HKDFExpandSHA256.

func HKDFSHA256

func HKDFSHA256(ikm, salt, info []byte, length int) ([]byte, error)

HKDFSHA256 performs the full HKDF (Extract-then-Expand) using SHA-256. It derives length bytes of keying material from the input keying material ikm, optional salt, and optional info.

func MarshalPrivateKeyDER

func MarshalPrivateKeyDER(privKey *ecdsa.PrivateKey) ([]byte, error)

MarshalPrivateKeyDER returns the PKCS#8 DER encoding of a P-256 private key.

func P256

func P256() elliptic.Curve

P256 returns the NIST P-256 elliptic curve used throughout Matter.

func PBKDF2SHA256

func PBKDF2SHA256(password, salt []byte, iterations, keyLen int) []byte

PBKDF2SHA256 derives key material from a password using PBKDF2 with SHA-256. The returned slice is keyLen bytes long.

func ParseCSR

func ParseCSR(csrDER []byte) (*ecdsa.PublicKey, error)

ParseCSR parses a DER-encoded PKCS#10 Certificate Signing Request and extracts the ECDSA P-256 public key from it.

func ParseCertificate

func ParseCertificate(der []byte) (*x509.Certificate, error)

ParseCertificate parses a DER-encoded X.509 certificate.

func ParsePrivateKeyDER

func ParsePrivateKeyDER(der []byte) (*ecdsa.PrivateKey, error)

ParsePrivateKeyDER parses a PKCS#8 DER-encoded P-256 private key.

func PrivateKeyFromBytes

func PrivateKeyFromBytes(scalar []byte) (*ecdsa.PrivateKey, error)

PrivateKeyFromBytes reconstructs a P-256 ECDSA private key from a 32-byte scalar.

func PrivateKeyToBytes

func PrivateKeyToBytes(privKey *ecdsa.PrivateKey) []byte

PrivateKeyToBytes returns the raw 32-byte scalar of a P-256 private key.

func PublicKeyFromUncompressed

func PublicKeyFromUncompressed(data []byte) (*ecdsa.PublicKey, error)

PublicKeyFromUncompressed parses an uncompressed SEC1-encoded P-256 public key.

func PublicKeyToUncompressed

func PublicKeyToUncompressed(pub *ecdsa.PublicKey) []byte

PublicKeyToUncompressed returns the uncompressed SEC1 encoding of a P-256 public key (65 bytes: 0x04 || X || Y).

func SignECDSA

func SignECDSA(privKey *ecdsa.PrivateKey, msg []byte) ([]byte, error)

SignECDSA signs the SHA-256 hash of msg using the given P-256 private key. It returns the DER-encoded ASN.1 signature.

func SignECDSARaw

func SignECDSARaw(privKey *ecdsa.PrivateKey, msg []byte) ([]byte, error)

SignECDSARaw signs the SHA-256 hash of msg using the given P-256 private key. It returns the signature in IEEE P1363 format (raw r||s, 64 bytes) as used by the Matter protocol for CASE signatures.

func VerifyCertificateSignature

func VerifyCertificateSignature(child, parent *x509.Certificate) error

VerifyCertificateSignature verifies that child was signed by parent's key.

func VerifyConfirmation

func VerifyConfirmation(expected, received []byte) bool

VerifyConfirmation checks the peer's confirmation value.

func VerifyECDSA

func VerifyECDSA(pubKey *ecdsa.PublicKey, msg, sig []byte) bool

VerifyECDSA verifies a DER-encoded ASN.1 ECDSA signature over the SHA-256 hash of msg.

func VerifyECDSARaw

func VerifyECDSARaw(pubKey *ecdsa.PublicKey, msg, sig []byte) bool

VerifyECDSARaw verifies an IEEE P1363 (raw r||s, 64 bytes) ECDSA signature over the SHA-256 hash of msg. This is the format used by the Matter protocol for CASE signatures.

func X509ToMatterCert

func X509ToMatterCert(certDER []byte) ([]byte, error)

X509ToMatterCert converts a DER-encoded X.509 certificate to Matter TLV certificate format as required by the Matter specification (section 6.6). The resulting TLV cert preserves the original X.509 DER signature. This is the correct function for device-bound certs (AddNOC, AddTrustedRootCertificate, CASE handshake) because the CHIP SDK verifies signatures by reconstructing X.509 DER TBS from the decoded TLV fields, not by hashing the TLV TBS directly.

func X509ToMatterCertResigned

func X509ToMatterCertResigned(certDER []byte, signingKey *ecdsa.PrivateKey) ([]byte, error)

X509ToMatterCertResigned converts a DER-encoded X.509 certificate to Matter TLV format and re-signs the TLV TBS (to-be-signed) portion with the provided signing key. This produces a TLV certificate whose signature is valid when verified over the TLV encoding, as required by Matter devices.

signingKey is the key that signed this certificate:

  • For RCAC (self-signed): pass the RCAC's own private key
  • For ICAC: pass the RCAC's private key
  • For NOC: pass the ICAC's private key

Types

type CertificateOptions

type CertificateOptions struct {
	// SerialNumber for the certificate. If nil, a random one is generated.
	SerialNumber *big.Int
	// NotBefore is the start of the certificate validity period.
	NotBefore time.Time
	// NotAfter is the end of the certificate validity period.
	NotAfter time.Time
}

CertificateOptions holds parameters for Matter certificate generation.

func DefaultCertificateOptions

func DefaultCertificateOptions() CertificateOptions

DefaultCertificateOptions returns sane defaults: valid from now for 10 years.

type SPAKE2PProver

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

SPAKE2PProver implements the prover (commissioner) side of the SPAKE2+ protocol.

func NewSPAKE2PProver

func NewSPAKE2PProver(w0, w1 []byte) (*SPAKE2PProver, error)

NewSPAKE2PProver creates a new SPAKE2+ prover using w0 and w1 as 32-byte big-endian scalars.

func (*SPAKE2PProver) ComputePublicShare

func (p *SPAKE2PProver) ComputePublicShare() ([]byte, error)

ComputePublicShare computes and returns pA = x*G + w0*M (uncompressed point).

func (*SPAKE2PProver) ComputeSecretAndConfirm

func (p *SPAKE2PProver) ComputeSecretAndConfirm(context, idProver, idVerifier, pB []byte) (Ke, cA, cB []byte, err error)

ComputeSecretAndConfirm processes the verifier's public share pB and computes the shared secret and confirmation values. Returns (Ke, cA, cB) where Ke is the encryption key, cA is our confirmation to send, and cB is the expected confirmation from the verifier.

type SPAKE2PVerifier

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

SPAKE2PVerifier implements the verifier (commissionee/device) side of the SPAKE2+ protocol.

func NewSPAKE2PVerifier

func NewSPAKE2PVerifier(w0, L []byte) (*SPAKE2PVerifier, error)

NewSPAKE2PVerifier creates a new SPAKE2+ verifier using w0 (32-byte scalar) and L (uncompressed point = w1*G).

func (*SPAKE2PVerifier) ComputePublicShare

func (v *SPAKE2PVerifier) ComputePublicShare() ([]byte, error)

ComputePublicShare computes and returns pB = y*G + w0*N (uncompressed point).

func (*SPAKE2PVerifier) ComputeSecretAndConfirm

func (v *SPAKE2PVerifier) ComputeSecretAndConfirm(context, idProver, idVerifier, pA []byte) (Ke, cB, cA []byte, err error)

ComputeSecretAndConfirm processes the prover's public share pA and computes the shared secret and confirmation values. Returns (Ke, cB, cA) where Ke is the encryption key, cB is our confirmation to send, and cA is the expected confirmation from the prover.

Jump to

Keyboard shortcuts

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