{"record":{"id":"48211cec52c5bcb4","repo":"OpenNHP/opennhp","slug":"extractinitiatorstaticpubkey-aead-w","errorCode":null,"errorMessage":"extractInitiatorStaticPubKey: aead: %w","messagePattern":"extractInitiatorStaticPubKey: aead: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nhp/core/responder.go","lineNumber":169,"sourceCode":"\tdefer SetZero(chainKey[:])\n\t// ChainKey0\n\tinitHash, err := NewHash(ciphers.HashType)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"extractInitiatorStaticPubKey: init hash: %w\", err)\n\t}\n\tinitHash.Write([]byte(InitialHashString))\n\tnoise.MixKey(&chainKey, initHash.Sum(nil), []byte(InitialChainKeyString))\n\t// ChainKey0 → ChainKey1\n\tnoise.MixKey(&chainKey, chainKey[:], header.EphermeralBytes())\n\n\t// Derive AEAD key for static-field decryption.\n\tvar key [SymmetricKeySize]byte\n\tdefer SetZero(key[:])\n\tnoise.KeyGen2(&chainKey, &key, chainKey[:], ess[:])\n\n\taead, err := AeadFromKey(ciphers.GcmType, &key)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"extractInitiatorStaticPubKey: aead: %w\", err)\n\t}\n\t// Trust the AEAD's returned plaintext length over a static\n\t// scheme→size mapping. The previous version allocated a\n\t// PublicKeySizeEx-sized buffer and sliced it back down based on\n\t// header.CipherScheme(); that worked because the only two ciphers\n\t// today happen to match the scheme→size table exactly, but a\n\t// future cipher whose plaintext length doesn't fit either fixed\n\t// size would silently mis-key the cookie HMAC (Open writes\n\t// however many bytes the AEAD decrypted, then the caller would\n\t// either truncate them or hash trailing zero-padding).\n\t//\n\t// Validate the length explicitly before returning so future\n\t// breakage manifests as an error here, not as cookie failures\n\t// further down. Pass nil for the dst so Open allocates exactly\n\t// the right size.\n\tpeerPk, err := aead.Open(nil, header.NonceBytes(), header.StaticBytes(), chainHash.Sum(nil))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"extractInitiatorStaticPubKey: open: %w\", err)","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/nhp/core/responder.go#L151-L187","documentation":"After deriving the AEAD key (KeyGen2 from the Noise chain key and ephemeral shared secret), extractInitiatorStaticPubKey builds an AEAD instance via AeadFromKey using ciphers.GcmType (AES-256-GCM or SM4-GCM). This error means the AEAD construction itself failed — the key material was fine size-wise but the GcmType is not a recognized AEAD algorithm, or the AEAD backend could not accept the key.","triggerScenarios":"checkHMAC on an overload-path RKN packet where the CipherSuite's GcmType is not one of the registered GCM implementations (e.g. CipherSuite built manually with an unsupported GcmType constant), or an SM4/AES backend initialization failure in the crypto package.","commonSituations":"Mixing cipher scheme constants between builds (scheme table changed between versions so old persisted config maps to a GcmType that no longer exists); a custom crypto plugin returning an unsupported GcmType; corrupted in-memory CipherSuite.","solutions":["Ensure the CipherSuite originates from NewCipherSuite(common.CIPHER_SCHEME_CURVE|GMSM) so HashType/GcmType are consistent with what AeadFromKey supports.","Confirm both AES-GCM and SM4-GCM backends are compiled in for your build tags if using the GMSM scheme.","Log ciphers.GcmType alongside the wrapped error to see which unsupported value reached AeadFromKey.","If adding a new cipher scheme, register its AEAD constructor in AeadFromKey before deploying senders that use it."],"exampleFix":"// before\nsuite := &core.CipherSuite{HashType: ht, GcmType: 99} // unsupported\npeerPk, err := extractInitiatorStaticPubKey(dev, suite, hdr)\n// after\nsuite := core.NewCipherSuite(common.CIPHER_SCHEME_GMSM)\npeerPk, err := extractInitiatorStaticPubKey(dev, suite, hdr)","handlingStrategy":"validation","validationCode":"switch suite.GcmType {\ncase common.CIPHER_SCHEME_CURVE, common.CIPHER_SCHEME_GMSM:\n\t// ok\ndefault:\n\treturn fmt.Errorf(\"unsupported gcm type %d\", suite.GcmType)\n}","typeGuard":"func hasKnownAead(c *core.CipherSuite) bool {\n\treturn c != nil && c.GcmType == common.CIPHER_SCHEME_CURVE || (c != nil && c.GcmType == common.CIPHER_SCHEME_GMSM)\n}","tryCatchPattern":"aead, err := AeadFromKey(ciphers.GcmType, &key)\nif err != nil {\n\tlog.Error(\"aead init failed gcmType=%d: %v\", ciphers.GcmType, err)\n\treturn nil, err // abort packet, do not fall through to cookie verification\n}","preventionTips":["Construct cipher suites only through NewCipherSuite.","Keep AES-GCM and SM4-GCM backends compiled into your build.","Test AeadFromKey for all schemes at daemon startup.","Log GcmType on failure to speed diagnosis."],"tags":["go","cryptography","aead","gcm"],"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"}