pub struct KeyCheckValue(/* private fields */);Expand description
What a symmetric key answers to, in place of a public key.
AES-CMAC over a 16-byte zero block under the key, leftmost three bytes, as specified for AES keys in ANSI X9.24-1 Annex A and used by TR-31. It is what an HSM displays and what custodians read back, so a transcript carrying it records the value the room checked rather than a parallel one only Rite can compute.
Three bytes, not a digest of the key. A full-length hash of a secret is what rite#126 removed from the transcript, and a reader cannot tell by looking whether such a value came from a 256-bit key or a 4-digit PIN. The truncation here is the part that makes it evident.
Renders as cmac-aes:763cbc. The method is in the string because the
older convention of encrypting a zero block in ECB is still in use and
gives a different answer for the same key.
use rite_sdk::KeyCheckValue;
// A backend computes the CMAC; this keeps the leftmost bytes of it.
let cmac = [0x76, 0x3c, 0xbc, 0xde, 0x81, 0xdf, 0x91, 0x31];
let kcv = KeyCheckValue::from_cmac(&cmac)?;
assert_eq!(kcv.to_string(), "cmac-aes:763cbc");
assert_eq!(kcv.as_bytes(), &[0x76, 0x3c, 0xbc]);
// It round-trips through the string a transcript records.
assert_eq!("cmac-aes:763cbc".parse::<KeyCheckValue>()?, kcv);
// Uppercase hex is a different string for the same bytes, so it is not one.
assert!("cmac-aes:763CBC".parse::<KeyCheckValue>().is_err());