{"record":{"id":"a4da07c7a62652a2","repo":"OpenNHP/opennhp","slug":"failed-to-create-hmac-hash-w","errorCode":null,"errorMessage":"failed to create HMAC hash: %w","messagePattern":"failed to create HMAC hash: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nhp/core/initiator.go","lineNumber":153,"sourceCode":"\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create chain hash: %w\", err)\n\t}\n\tmad.chainHash.Write([]byte(InitialHashString))\n\n\t// init chain key -> ChainKey0\n\tmad.noise.HashType = mad.ciphers.HashType\n\tmad.noise.MixKey(&mad.chainKey, mad.chainHash.Sum(nil), []byte(InitialChainKeyString))\n\n\t// init timestamp\n\tmad.LocalInitTime = time.Now().UnixNano()\n\n\t// assign channel\n\tmad.ResponseMsgCh = md.ResponseMsgCh\n\n\t// init hmac hash -> HmacHash0\n\tmad.hmacHash, err = NewHash(mad.ciphers.HashType)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create HMAC hash: %w\", err)\n\t}\n\tmad.hmacHash.Write([]byte(InitialHashString))\n\n\t// create ephermeral key\n\tephermalEccType := mad.ciphers.EccType\n\tmad.ephermeralEcdh = NewECDH(ephermalEccType)\n\tcopy(mad.header.EphermeralBytes(), mad.ephermeralEcdh.PublicKey())\n\n\treturn mad, nil\n}\n\nfunc (mad *MsgAssemblerData) derivePacketParserData(pkt *Packet, initTime int64) (ppd *PacketParserData) {\n\tppd = &PacketParserData{}\n\tppd.device = mad.device\n\tppd.basePacket = pkt\n\tppd.CipherScheme = mad.CipherScheme\n\tppd.ConnData = mad.connData\n\tppd.LocalInitTime = initTime","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/nhp/core/initiator.go#L135-L171","documentation":"createMsgAssemblerData initializes the HMAC hash (HmacHash0) used for message-chain MACs. This error means NewHash failed for the negotiated HashType at the HMAC stage — same class as the chain-hash failure but occurring after it. It points to an invalid or unsupported hash type in the cipher suite.","triggerScenarios":"Same as the chain-hash error but reached when chain hash creation succeeded: createMsgAssemblerData called with a ciphers.HashType that the crypto layer cannot instantiate for HMAC.","commonSituations":"Partially configured CipherSuites struct (some fields set, HashType invalid); algorithm registry changed between library versions; custom cipher suite definitions.","solutions":["Use a predefined CipherSuites constant instead of hand-assembling the struct","Verify the HashType value is supported (BLAKE2s for CURVE, SM3 for GMSM)","Keep chain-hash and HMAC hash creation consistent by setting HashType once from the scheme","Add a unit test calling createMsgAssemblerData with your configured suite"],"exampleFix":"// before\nciphers := &nhpcore.CipherSuites{EccType: nhpcore.ECC_CURVE25519} // HashType unset\n// after\nciphers := &nhpcore.CipherSuites{EccType: nhpcore.ECC_CURVE25519, HashType: nhpcore.HASH_TYPE_BLAKE2S}","handlingStrategy":"validation","validationCode":"if md.Ciphers.HashType == 0 {\n    return errors.New(\"HashType unset\")\n}","typeGuard":"func hasHashType(c *nhpcore.CipherSuites) bool { return c.HashType != 0 }","tryCatchPattern":"if _, err := dev.MsgToPacket(md); err != nil && strings.Contains(err.Error(), \"failed to create HMAC hash\") {\n    return fmt.Errorf(\"invalid cipher suite: %w\", err)\n}","preventionTips":["Set HashType once from the scheme constant and share it across all hash uses","Keep suite construction centralized in one constructor function","Add a round-trip unit test through createMsgAssemblerData"],"tags":["go","crypto","hmac"],"backgroundTag":"invalid-enum-value","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}