OpenNHP/opennhp · warning
failed to write HRK data to SM3
Error message
failed to write HRK data to SM3: %v
What it means
Sm3Digest computes an SM3 hash of the input bytes using hash.Write. Per Go's hash.Hash contract, Write never returns an error, but this wrapper defensively propagates any hypothetical write failure as "failed to write HRK data to SM3". In practice this error is effectively unreachable; it exists to satisfy error-handling style and would only indicate a corrupted hasher state.
Solutions
- Treat the error as an internal invariant violation: if it occurs, verify the golang.org/x/crypto/sm3 dependency version is unmodified (go mod verify).
- Call the exported wrapper normally — no input preprocessing is needed; empty or nil data is valid.
- If you control the code, you could switch to sm3.Sum(data) which returns the digest without an error path, eliminating this branch.
- Retry the attestation verification once; a transient memory/hash-state issue would clear, while a persistent failure indicates a broken dependency.
Example fix
// before
digest, err := Sm3Digest(data)
if err != nil {
return fmt.Errorf("attestation failed: %w", err) // unreachable in practice
}
// after — bypass the error path entirely
digest := sm3.Sum(data)
// digest is [32]byte; use digest[:] where []byte is needed Defensive patterns
Strategy: try-catch
Try / catch
digest, err := Sm3Digest(data)
if err != nil {
// Practically unreachable: hash.Hash.Write never errors.
return fmt.Errorf("sm3 digest failed (check golang.org/x/crypto/sm3 integrity): %w", err)
} Prevention
- No input validation is needed — empty or nil data is a valid SM3 input
- Pin and verify golang.org/x/crypto version (go mod verify) so the sm3 package is unmodified
- Prefer sm3.Sum(data) in new code to avoid the theoretical error path entirely
When it happens
Trigger: Only if hash.Write on the sm3.New() hasher returns a non-nil error, which cannot happen for the golang.org/x/crypto/sm3 implementation regardless of input (even empty or nil data is fine). Called from verifySm2SignatureWithId and verifyCertChain during CSV attestation verification.
Common situations: Developers rarely see this in the field; encountering it would suggest a build with a patched/broken sm3 package or a panic-recovery misattribution. More common confusion: callers assuming empty hrkData triggers it — it does not, empty input hashes successfully.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- failed to create blake2s hash
- failed to create chain hash
- failed to create device
- failed to create device from new key
- keystore: generate otp
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/116387549b4bf121.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/core/verifier/csv/csv.go:171
// 转换十六进制字符串为字节
ecKeyBytes, _ := hex.DecodeString(ecKeyHex)
pubkeyBytes, _ := hex.DecodeString(pubkeyHex)
// 拼接所有字节切片
var result []byte
result = append(result, firstByte)
result = append(result, secondByte)
result = append(result, id...)
result = append(result, ecKeyBytes...)
result = append(result, pubkeyBytes...)
return result
}
func Sm3Digest(hrkData []byte) ([]byte, error) {
hash := sm3.New()
if _, err := hash.Write(hrkData); err != nil {
return nil, fmt.Errorf("failed to write HRK data to SM3: %v", err)
}
digest := hash.Sum(nil)
return digest, nil
}
func Sm3Hmac(data []byte, key []byte) []byte {
// Block size of SM3 is 64 bytes (as specified in GM/T 0004-2012)
const blockSize = 64
// Ensure key is not longer than block size by hashing if necessary
if len(key) > blockSize {
hash := sm3.Sum(key)
key = hash[:]
}
// Pad key to block size with zeros
paddedKey := make([]byte, blockSize)
copy(paddedKey, key)View on GitHub (pinned to 6e04ca5ff0)