OpenNHP/opennhp · error
curve id mismatch: got
Error message
curve id mismatch: got %d, want %d
What it means
verifyHygonCertInfo parses the curve-id field at offset 0x40..0x44 of a Hygon HRK/HSK certificate blob as a little-endian uint32 and compares it to the expected curveId (0x03 = SM2 for both HRK and HSK calls). A mismatch means the certificate blob does not declare the expected SM2 curve, so signature verification would be meaningless. NOTE: the format string is buggy — it prints curveId twice instead of the parsed value, so both numbers shown are the EXPECTED value.
Solutions
- Fix the format string to print hygonCurveIdInt so the actual observed curve id is visible.
- Validate blob size and structure (length >= 0x340, plausible magic/fields) before caching/parsing to avoid misaligned offsets.
- Re-fetch or replace the hskCek entry — clear any cached bogus value so the real certificate is downloaded again.
- If the certificate layout changed with new Hygon firmware, update the offset constants (0x24, 0x40, 0x14) in verifyHygonCertInfo.
Example fix
// before
if hygonCurveIdInt != curveId {
return fmt.Errorf("curve id mismatch: got %d, want %d", curveId, curveId)
}
// after
if hygonCurveIdInt != curveId {
return fmt.Errorf("curve id mismatch: got %d, want %d", hygonCurveIdInt, curveId)
} Defensive patterns
Strategy: validation
Validate before calling
func validHygonCurve(blob []byte) bool {
if len(blob) < 0x340 {
return false
}
return binary.LittleEndian.Uint32(blob[0x40:0x44]) == 0x03
} Type guard
func asSM2HygonCert(b []byte) ([]byte, bool) {
if len(b) >= 0x44 && binary.LittleEndian.Uint32(b[0x40:0x44]) == 0x03 {
return b, true
}
return nil, false
} Try / catch
if err := attestation.Verify(ctx, evidence); err != nil {
if strings.Contains(err.Error(), "curve id mismatch") {
// cert blob is not the expected SM2 layout: clear cached CEK and re-fetch, else reject evidence
}
} Prevention
- Sanity-check the curve-id dword (0x40) before trusting any Hygon cert blob.
- Clear stale hskCek cache entries when the CA download may have returned non-certificate content.
- Fix the logging bug so mismatches print the actual observed curve id.
- Track Hygon firmware/certificate format changes and adjust hardcoded offsets.
When it happens
Trigger: verifyCertChain calls verifyHygonCertInfo expecting curveId 0x03; the error fires when the dword at 0x40 of the HRK or downloaded HSK blob is not 3 — e.g. a different/garbage certificate was downloaded for the chipId, the blob is truncated/shifted so offset 0x40 lands on other data, or a future Hygon format uses a different curve id.
Common situations: Cached hskCek entry polluted by a non-certificate response (e.g. HTML error page cached after a mis-handled 200); attesting mixed-generation Hygon evidence; layout changes in newer Hygon firmware certificates.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- key usage mismatch: got
- failed to unmarshal evidence
- unsupported key type, expect RSA
- JWT signing key is not initialized
- TEE public key is not found for specified token
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/4d77ec6d127105ad.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/core/verifier/csv/csv.go:425
); err != nil {
return err
}
return nil
}
func (a *Attestation) verifyHygonCertInfo(hrk []byte, curveId, keyUsage int, keyId []byte) error {
hygonKeyUsage := hrk[0x24:0x28]
hygonKeyUsageInt := int(binary.LittleEndian.Uint32(hygonKeyUsage))
if hygonKeyUsageInt != keyUsage {
return fmt.Errorf("key usage mismatch: got %d, want %d", keyUsage, keyUsage)
}
hygonCurveId := hrk[0x40:0x44]
hygonCurveIdInt := int(binary.LittleEndian.Uint32(hygonCurveId))
if hygonCurveIdInt != curveId {
return fmt.Errorf("curve id mismatch: got %d, want %d", curveId, curveId)
}
hygonCertifyingId := hrk[0x14:0x24]
if !bytes.Equal(hygonCertifyingId, keyId) {
return fmt.Errorf("certifying id mismatch: got %x, want %x", hygonCertifyingId, keyId)
}
return nil
}
func (a *Attestation) verifyCSVCertInfo(csvCert []byte, sigUsage int, sigAlgo int, keyUsage int, keyId []byte) error {
csvKeyUsage := csvCert[0x08:0x0C]
csvKeyUsageInt := int(binary.LittleEndian.Uint32(csvKeyUsage))
if csvKeyUsageInt != keyUsage {
return fmt.Errorf("key usage mismatch: got %d, want %d", csvKeyUsageInt, sigUsage)
}
csvSigUsage := csvCert[0x414:0x418]View on GitHub (pinned to 6e04ca5ff0)