OpenNHP/opennhp · error

failed to create HMAC hash

Error message

failed to create HMAC hash: %w

What it means

Immediately after the chain hash, createPacketParserData initializes the HMAC hash (HmacHash0) used for per-packet MAC verification; NewHash failed for the same class of reasons as the chain-hash error — the CipherSuite's HashType is unsupported or the hash backend is broken. Packet processing aborts before HMAC checking, so no message is decrypted or dispatched.

Solutions

  1. Log ppd.Ciphers.HashType and ppd.CipherScheme at failure to identify the unsupported value.
  2. Rebuild against a known-good crypto dependency version where SM3/BLAKE2s instantiate correctly.
  3. Ensure all CipherSuites are produced by NewCipherSuite rather than constructed literally.
  4. Add boot-time smoke tests calling NewHash for each supported scheme.

Example fix

// before
testSuite := &core.CipherSuite{HashType: 0xFF}
_ , err := d.CreatePacketParserData(pd) // failed to create HMAC hash
// after
testSuite := core.NewCipherSuite(common.CIPHER_SCHEME_GMSM)
_, err := d.CreatePacketParserData(pd)
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := core.NewHash(suite.HashType); err != nil {
	return fmt.Errorf("hmac hash unavailable for hashType %d", suite.HashType)
}

Try / catch

ppd.hmacHash, err = NewHash(ppd.Ciphers.HashType)
if err != nil {
	log.Error("hmac hash init failed hashType=%d: %v", ppd.Ciphers.HashType, err)
	return nil, fmt.Errorf("failed to create HMAC hash: %w", err)
}

Prevention

When it happens

Trigger: Same as the chain-hash failure: invalid HashType reaching NewHash from NewCipherSuite during PacketToMsg/parseRKNOnServer, or a failing hash backend; typically only after customizing cipher suites or upgrading the crypto dependency.

Common situations: Custom crypto builds; dependency regressions; hand-constructed CipherSuites in tests or plugins; practically never in stock deployments where both schemes use always-available hashes.

Related errors


AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07). Data as JSON: /api/errors/fddb85b85fb1f234. Report an issue: GitHub.

Appendix: source

Thrown at nhp/core/responder.go:314

	}

	// init chain hash -> ChainHash0
	ppd.chainHash, err = NewHash(ppd.Ciphers.HashType)
	if err != nil {
		return nil, fmt.Errorf("failed to create chain hash: %w", err)
	}
	ppd.chainHash.Write([]byte(InitialHashString))

	// init chain key -> ChainKey0
	ppd.noise.HashType = ppd.Ciphers.HashType
	ppd.noise.MixKey(&ppd.chainKey, ppd.chainHash.Sum(nil), []byte(InitialChainKeyString))

	ppd.HeaderType, ppd.BodySize = ppd.header.TypeAndPayloadSize()

	// init hmac hash -> HmacHash0
	ppd.hmacHash, err = NewHash(ppd.Ciphers.HashType)
	if err != nil {
		return nil, fmt.Errorf("failed to create HMAC hash: %w", err)
	}
	ppd.hmacHash.Write([]byte(InitialHashString))

	// evolve hmac hash HmacHash0 -> HmacHash1
	ppd.hmacHash.Write(ppd.deviceEcdh.PublicKey())

	// check hmac
	if ppd.device.deviceType == NHP_SERVER {
		// server overload handling
		overload := ppd.device.IsOverload()
		if overload {
			// overload, further discard unwanted packet type
			ppd.Overload = true
			if !ppd.IsAllowedAtOverload() {
				log.Critical("discard packet type %d due to overload", ppd.HeaderType)
				err = ErrServerOverload
				return
			}

View on GitHub (pinned to 6e04ca5ff0)