OpenNHP/opennhp · error

failed to create chain hash

Error message

failed to create chain hash: %w

What it means

createMsgAssemblerData initializes the per-message chain hash (ChainHash0) with NewHash for the negotiated cipher suite's hash type. If the hash algorithm cannot be instantiated, the wrapped error is returned. This indicates the configured ciphers.HashType is unsupported or crypto backend initialization failed.

Solutions

  1. Set md.Ciphers to a valid CipherSuites value (e.g. from the negotiated ConnData) before assembly
  2. Ensure the cipher scheme constant is one of the supported values (CURVE or GMSM)
  3. Test NewHash(hashType) directly to confirm the hash type is registered
  4. Rebuild with full crypto backends if using a trimmed build

Example fix

// before
md := &MsgData{Msg: msg} // Ciphers zero-valued
// after
md := &MsgData{Msg: msg, Ciphers: connData.Ciphers} // negotiated suite
Defensive patterns

Strategy: validation

Validate before calling

if _, err := nhpcore.NewHash(md.Ciphers.HashType); err != nil {
    return fmt.Errorf("unsupported hash type %v", md.Ciphers.HashType)
}

Type guard

func supportedSuite(c *nhpcore.CipherSuites) bool {
    _, err := nhpcore.NewHash(c.HashType)
    return err == nil
}

Try / catch

mad, err := dev.MsgToPacket(md)
if err != nil && strings.Contains(err.Error(), "failed to create chain hash") {
    return fmt.Errorf("bad cipher config: %w", err)
}

Prevention

When it happens

Trigger: MsgToPacket or packet assembly calls createMsgAssemblerData with a MsgData whose ciphers.HashType is unknown/zero, or the underlying hash constructor fails (e.g. unregistered algorithm).

Common situations: Cipher-scheme mismatch after switching between CIPHER_SCHEME_CURVE and CIPHER_SCHEME_GMSM; manually built MsgData with an uninitialized Ciphers struct; missing SM3 support in a custom crypto build.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at nhp/core/initiator.go:136

		}

		// create header and init device ecdh
		log.Info("start encryption using CIPHER_SCHEME_%d(0: CURVE; 1: GMSM.)", mad.CipherScheme)
		mad.header = mad.BasePacket.HeaderWithCipherScheme(mad.CipherScheme)
		mad.ciphers = NewCipherSuite(mad.CipherScheme)
		mad.deviceEcdh = d.GetEcdhByCipherScheme(mad.CipherScheme)

		// init version
		mad.header.SetVersion(ProtocolVersionMajor, ProtocolVersionMinor)

		// init header counter
		mad.header.SetCounter(mad.TransactionId)
	}

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

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

	// init timestamp
	mad.LocalInitTime = time.Now().UnixNano()

	// assign channel
	mad.ResponseMsgCh = md.ResponseMsgCh

	// init hmac hash -> HmacHash0
	mad.hmacHash, err = NewHash(mad.ciphers.HashType)
	if err != nil {
		return nil, fmt.Errorf("failed to create HMAC hash: %w", err)
	}

View on GitHub (pinned to 6e04ca5ff0)