Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Equal ¶ added in v0.1.5
Equal compares two MACs for equality without leaking timing information. This is a drop-in replacement for crypto/hmac.Equal.
It should be used whenever comparing HMAC digests to prevent timing side-channel attacks that could allow an attacker to forge valid MACs.
Example usage:
expected := computeMAC(message, key)
if !hmac.Equal(expected, received) {
return errors.New("authentication failed")
}
func HMACSHA256 ¶ added in v0.1.5
HMACSHA256 computes HMAC-SHA256 over data using the provided key and returns the 32-byte digest as a fixed-size array. Unlike I2PHMAC, this function accepts arbitrary-length key and data slices, making it suitable as a general-purpose HMAC-SHA256 primitive for use across I2P components such as noise handshakes and NTCP2 KDF chains.
Parameters:
- key: HMAC key of arbitrary length (will be hashed internally if >64 bytes)
- data: The message data to authenticate
Returns:
- [32]byte: The 32-byte HMAC-SHA256 digest
Example usage:
mac := hmac.HMACSHA256(chainKey[:], inputKeyMaterial) // mac is a [32]byte ready for further KDF chaining
func New ¶ added in v0.1.5
New returns a new HMAC hash using the given hash function and key. This is a drop-in replacement for crypto/hmac.New, allowing callers to use github.com/go-i2p/crypto/hmac as a substitute for the standard library package.
The returned hash.Hash supports streaming writes via Write() and final digest retrieval via Sum(nil), which is required for multi-step HMAC chains such as the NTCP2 KDF.
Example usage:
mac := hmac.New(sha256.New, key) mac.Write(data) digest := mac.Sum(nil)
Types ¶
type HMACDigest ¶
type HMACDigest [32]byte
HMACDigest represents a 256-bit HMAC-SHA256 authentication digest output. This fixed-size array contains the computed HMAC signature that authenticates data integrity and origin verification in I2P cryptographic protocols. The 32-byte length matches SHA-256 output size and provides 256-bit authentication strength against forgery attacks. Digest values should be compared using constant-time operations to prevent timing attacks. Example usage: digest := I2PHMAC(data, key); if hmac.Equal(digest[:], expected[:]) { ... } Moved from: hmac.go
func I2PHMAC ¶
func I2PHMAC(data []byte, k HMACKey) (d HMACDigest)
I2PHMAC computes HMAC-SHA256 using the provided key and data. This function implements the I2P standard HMAC computation using SHA256. Moved from: hmac.go
type HMACKey ¶
type HMACKey [32]byte
HMACKey represents a 256-bit cryptographic key for HMAC-SHA256 authentication operations. This fixed-size array provides the symmetric key material required for generating and verifying HMAC signatures in I2P network communications. The 32-byte length ensures 256-bit security strength compatible with SHA-256 hash function requirements and I2P protocol specifications.
⚠️ CRITICAL SECURITY WARNING ⚠️ Always use NewHMACKey() or GenerateHMACKey() to create instances. Direct construction creates zero-value keys which are cryptographically invalid.
WRONG - Cryptographically invalid:
var key HMACKey // All zeros - predictable and insecure!
key := HMACKey{} // Same issue
CORRECT - Use constructors:
key, err := hmac.NewHMACKey(keyBytes)
if err != nil {
return err
}
defer key.Zero() // Clear sensitive material when done
Or generate a new random key:
key, err := hmac.GenerateHMACKey()
if err != nil {
return err
}
defer key.Zero()
Keys should be generated using cryptographically secure random number generators to prevent authentication bypass attacks. Zero-value keys compromise the entire HMAC authentication scheme.
Moved from: hmac.go
func GenerateHMACKey ¶ added in v0.1.0
GenerateHMACKey creates a new random HMAC key using cryptographically secure randomness. This is the recommended way to create new HMAC keys for authentication operations.
The key is generated using crypto/rand, which provides cryptographically secure random bytes suitable for key material. Returns error if the system's random number generator fails.
Security considerations:
- Always check the error return - random number generation can fail
- Call Zero() on the key when no longer needed to clear sensitive material
- Store keys securely (encrypted at rest, never in logs or version control)
Example usage:
key, err := hmac.GenerateHMACKey()
if err != nil {
return err
}
defer key.Zero()
// Use key for HMAC operations
digest := I2PHMAC(data, *key)
func NewHMACKey ¶ added in v0.1.0
NewHMACKey creates a validated HMAC key from bytes. This is the REQUIRED constructor for creating HMAC keys from existing key material.
Parameters:
- data: Must be exactly 32 bytes (256 bits) for HMAC-SHA256
Returns error if data length is invalid or key is all zeros (cryptographically weak).
Security considerations:
- Key material should come from cryptographically secure random sources
- Never use predictable values, hardcoded constants, or passwords directly
- Use key derivation functions (like HKDF) if deriving from passwords
- Call Zero() on the key when no longer needed to clear sensitive material
Example usage:
keyBytes := make([]byte, 32)
if _, err := rand.Read(keyBytes); err != nil {
return err
}
key, err := hmac.NewHMACKey(keyBytes)
if err != nil {
return err
}
defer key.Zero()
func (*HMACKey) Zero ¶ added in v0.1.0
func (k *HMACKey) Zero()
Zero securely clears the HMAC key material from memory. This method should be called when the key is no longer needed to prevent sensitive material from remaining in memory where it could be disclosed through memory dumps, swap files, or other memory access vectors.
Best practice: Use defer to ensure keys are always zeroed:
key, err := hmac.GenerateHMACKey()
if err != nil {
return err
}
defer key.Zero()
Note: While Go's garbage collector will eventually reclaim the memory, it does not guarantee that the memory contents will be overwritten. Explicit zeroing provides defense-in-depth against memory disclosure attacks.