OpenNHP/opennhp · error
failed to verify signature
Error message
failed to verify signature
What it means
verifySm2SignatureWithId fails when an SM2 signature does not verify against the given public key, message, and signer ID. It builds the ZA/SM3 digest per the SM2 signing standard and calls VerifySignature; a mismatch means the signature bytes were not produced by the holder of the private key over this message+ID. In the CSV attestation flow this indicates a corrupted, truncated, or forged certificate/blob, or a bad signer-ID/public-key extraction.
Solutions
- Verify the attestation blob is intact and matches the Hygon CSV certificate layout expected by this code (check size and byte offsets for hrk/hsk_cek fields).
- Confirm the blob actually comes from a Hygon CSV-capable chip and the remote attestation report corresponds to the chipId being verified.
- Check the hrkIdLen little-endian field at offset 0xd4-0xd6 is sane before slicing the ID; a corrupt length misaligns the signer ID and breaks verification.
- Confirm byte reversal (ReverseBytes) conventions match the producer of the signature (little- vs big-endian r/s/coordinates).
- If you control the signing side, re-sign with the same SM2 signer ID and message framing used here (buildIDMsg with ECKEY).
Example fix
// before: slicing ID with unvalidated length
hrkIdLen := int(binary.LittleEndian.Uint16(a.hrk[0xd4:0xd6]))
if err := a.verifySm2SignatureWithId(
a.hrk[0x44:0x64], a.hrk[0x8c:0xac],
a.hrk[0x240:0x260], a.hrk[0x288:0x2a8],
a.hrk[0xd6:0xd6+hrkIdLen], a.hrk[:0x240],
); err != nil {
return err
}
// after: sanity-check length/bounds first
hrkIdLen := int(binary.LittleEndian.Uint16(a.hrk[0xd4:0xd6]))
if hrkIdLen <= 0 || 0xd6+hrkIdLen > len(a.hrk) {
return fmt.Errorf("invalid HRK signer ID length: %d", hrkIdLen)
} Defensive patterns
Strategy: validation
Validate before calling
// verify blob shape and signer-ID length before calling Verify/attestation APIs
if len(blob) < 0x2a8 {
return fmt.Errorf("attestation blob too small: %d", len(blob))
}
idLen := int(binary.LittleEndian.Uint16(blob[0xd4:0xd6]))
if idLen <= 0 || 0xd6+idLen > len(blob) {
return fmt.Errorf("invalid signer ID length %d in blob", idLen)
} Type guard
func isValidCSVBlob(blob []byte) bool {
return len(blob) >= 0x2a8 &&
binary.LittleEndian.Uint16(blob[0xd4:0xd6]) > 0 &&
0xd6+int(binary.LittleEndian.Uint16(blob[0xd4:0xd6])) <= len(blob)
} Try / catch
err := att.Verify(chipId)
if err != nil {
if strings.Contains(err.Error(), "failed to verify signature") {
// treat as untrusted attestation: reject the workload, log blob fingerprint
return ErrAttestationUntrusted
}
return err
} Prevention
- Checksum attestation blobs end-to-end in transit (TLS, signed channels) so corruption is detected before verification.
- Keep the verifier and any blob producer on the same Hygon CSV format version.
- Log the blob's key fields (sizes, ID length) on failure to speed diagnosis of offset drift.
When it happens
Trigger: Called from verifyCertChain (self-signed HRK verification, HSK/CEK chain verification) and from Attestation.Verify. Triggered when the SM2 signature extracted from the certificate blob (e.g. hrk[0x240:0x260], hrk[0x288:0x2a8]) does not match the SM3 digest of the message hashed with the extracted public key and the ID at hrk[0xd6:0xd6+hrkIdLen].
Common situations: Guest quote/certificate blobs are corrupted or truncated in transit; the wrong certificate (non-Hygon, wrong chip generation) is passed; byte offsets change in a newer Hygon CSV format so the signature region sliced is stale; reverse-byte-order handling of r/s or coordinates differs from the producer; verifying a blob whose signer ID length field (0xd4:0xd6) is wrong so the ID slice is misaligned.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- invalid public key length: got
- invalid signature length: got
- size incorrect
- private key too short: got
- size incorrect
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/cb3214e5bdb2323c.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/core/verifier/csv/csv.go:288
return err
}
xBig := new(big.Int).SetBytes(qx)
yBig := new(big.Int).SetBytes(qy)
pubKey := &ecdsa.PublicKey{
Curve: sm2.P256(),
X: xBig,
Y: yBig,
}
rBig := new(big.Int).SetBytes(r)
sBig := new(big.Int).SetBytes(s)
if VerifySignature(pubKey, msgAllDigest, rBig, sBig) {
return nil
} else {
return fmt.Errorf("failed to verify signature")
}
}
func (a *Attestation) verifyCertChain(chipId string) error {
// Download HRK from Hygon's certificate server
if a.hrk == nil {
resp, err := http.Get("https://cert.hygon.cn/hrk")
if err != nil {
return fmt.Errorf("failed to download HRK: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status code when download HRK: %d", resp.StatusCode)
}
// Read the response body (HRK content)
hrkData, err := io.ReadAll(resp.Body)View on GitHub (pinned to 6e04ca5ff0)