pub trait MAC: Sized {
// Required methods
fn new(key: &impl KeyMaterial) -> Result<Self, MACError>;
fn new_allow_weak_key(key: &impl KeyMaterial) -> Result<Self, MACError>;
fn output_len(&self) -> usize;
fn mac(self, data: &[u8]) -> Vec<u8> ⓘ;
fn mac_out(self, data: &[u8], out: &mut [u8]) -> Result<usize, MACError>;
fn verify(self, data: &[u8], mac: &[u8]) -> bool;
fn do_update(&mut self, data: &[u8]);
fn do_final(self) -> Vec<u8> ⓘ;
fn do_final_out(self, out: &mut [u8]) -> Result<usize, MACError>;
fn do_verify_final(self, mac: &[u8]) -> bool;
fn max_security_strength(&self) -> SecurityStrength;
}Expand description
A Message Authentication Code algorithm is a keyed hash function that behaves somewhat like a symmetric signature function. A MAC algorithm takes in a key and some data, and produces a MAC (message authentication code) that can be used to verify the integrity of data.
This trait provides one-shot functions MAC::mac, MAC::mac_out, and MAC::verify. It also provides streaming functions MAC::do_update, MAC::do_final, MAC::do_final_out, and MAC::do_verify_final. The workflow is that a MAC object is initialized with a key with MAC::new – or MAC::new_allow_weak_key if you need to disable the library’s safety mechanism to prevent the use of weak keys – then data is processed into one or more calls to MAC::do_update, after that the object can either create a MAC with MAC::do_final or MAC::do_final_out (which are final functions, and so consume the object), or the object can be used to verify a MAC.
For varifying an existing MAC, it is functionally equivalent to use the provided MAC::verify and MAC::do_verify_final function or to compute a new MAC and compare it to the existing MAC, however the provided verification functions use constant-time comparison to avoid cryptographic timing attacks whereby an attacker could learn the bytes of the MAC value under some conditions. Therefore, it is highly recommended to use the provided verification functions.
Note that the MAC key is not represented in this trait because it is provided to the MAC algorithm as part of its new functions.
MACs do not implement Default because they do not have a sensible no-args constructor.
Required Methods§
Sourcefn new(key: &impl KeyMaterial) -> Result<Self, MACError>
fn new(key: &impl KeyMaterial) -> Result<Self, MACError>
Create a new MAC instance with the given key.
This is a common constructor whether creating or verifying a MAC value.
Key / Salt is optional, which is indicated by providing an uninitialized KeyMaterial object of length zero, the capacity is irrelevant, so KeyMateriol256::new() or KeyMaterial_internal::<0>::new() would both count as an absent salt.
§Note about the security strength of the provided key:
If you initialize the MAC with a key that is tagged at a lower SecurityStrength than the underlying hash function then MAC::new will fail with the following error:
MACError::KeyMaterialError(KeyMaterialError::SecurityStrength("HMAC::init(): provided key has a lower security strength than the instantiated HMAC")There are situations in which it is completely reasonable and secure to provide low-entropy (and sometimes all-zero) keys / salts; for these cases we have provided MAC::new_allow_weak_key.
Sourcefn new_allow_weak_key(key: &impl KeyMaterial) -> Result<Self, MACError>
fn new_allow_weak_key(key: &impl KeyMaterial) -> Result<Self, MACError>
Create a new HMAC instance with the given key.
This constructor completely ignores the SecurityStrength tag on the input key and will “just work”. This should be used if you really do need to use a weak key, such as an all-zero salt, but use of this constructor is discouraged and you should really be asking yourself why you need it; in most cases it indicates that your key is not long enough to support the security level of this HMAC instance, or the key was derived using algorithms at a lower security level, etc.
Sourcefn output_len(&self) -> usize
fn output_len(&self) -> usize
The size of the output in bytes.
Sourcefn mac(self, data: &[u8]) -> Vec<u8> ⓘ
fn mac(self, data: &[u8]) -> Vec<u8> ⓘ
One-shot API that computes a MAC for the provided data.
data can be of any length, including zero bytes.
Note about the security strength of the provided key: If the provided key is tagged at a lower SecurityStrength than the instantiated MAC algorithm, this will fail with an error:
MACError::KeyMaterialError(KeyMaterialError::SecurityStrength("HMAC::init(): provided key has a lower security strength than the instantiated HMAC")Sourcefn mac_out(self, data: &[u8], out: &mut [u8]) -> Result<usize, MACError>
fn mac_out(self, data: &[u8], out: &mut [u8]) -> Result<usize, MACError>
One-shot API that computes a MAC for the provided data and writes it into the provided output slice.
data can be of any length, including zero bytes.
Depending on the underlying MAC implementation, NIST may require that the library enforce a minimum length on the mac output value. See documentation for the underlying implementation to see conditions under which it throws MACError::InvalidLength.
Sourcefn verify(self, data: &[u8], mac: &[u8]) -> bool
fn verify(self, data: &[u8], mac: &[u8]) -> bool
One-shot API that verifies a MAC for the provided data.
data can be of any length, including zero bytes.
Internally, this will re-compute the MAC value and then compare it to the provided mac value using constant-time comparison. It is highly encouraged to use this utility function instead of comparing mac values for equality yourself.
Returns a bool to indicate successful verification of the provided mac value. The provided mac value must be an exact match, including length; for example a mac value which has been truncated, or which contains extra bytes at the end is considered to not be a match and will return false.
Sourcefn do_update(&mut self, data: &[u8])
fn do_update(&mut self, data: &[u8])
Provide a chunk of data to be absorbed into the MAC.
data can be of any length, including zero bytes.
do_update() is intended to be used as part of a streaming interface, and so may by called multiple times.
fn do_final(self) -> Vec<u8> ⓘ
Sourcefn do_final_out(self, out: &mut [u8]) -> Result<usize, MACError>
fn do_final_out(self, out: &mut [u8]) -> Result<usize, MACError>
Depending on the underlying MAC implementation, NIST may require that the library enforce a minimum length on the mac output value. See documentation for the underlying implementation to see conditions under which it throws MACError::InvalidLength.
Sourcefn do_verify_final(self, mac: &[u8]) -> bool
fn do_verify_final(self, mac: &[u8]) -> bool
Internally, this will re-compute the MAC value and then compare it to the provided mac value using constant-time comparison. It is highly encouraged to use this utility function instead of comparing mac values for equality yourself.
Returns a bool to indicate successful verification of the provided mac value. The provided mac value must be an exact match, including length; for example a mac value which has been truncated, or which contains extra bytes at the end is considered to not be a match and will return false.
Sourcefn max_security_strength(&self) -> SecurityStrength
fn max_security_strength(&self) -> SecurityStrength
Returns the maximum security strength that this KDF is capable of supporting, based on the underlying primitives.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.