HMAC

Module to test HMAC implementations.

The crypto_condor.primitives.HMAC module provides the test_hmac() function to test classes that implement HMAC. There are two types of interfaces that can be tested, described by the HMAC and HMAC_IUF protocols below. Supported hash functions are defined by the Hash enum.

This module also exposes internal test functions, mostly to illustrate where the individual test results come from. We recommend using test_hmac() and its options to select which the modes to test and test vectors to use.

Test digest

crypto_condor.primitives.HMAC.test_digest(digest, hash_function, *, compliance=True, resilience=False)

Tests an implementation of the HMAC digest operation.

The implementation is called to generate a tag for a given key and message. The returned tag is compared to the test value. Some test values are truncated: in that case, the comparison is performed up to the length of the truncated tag.

Parameters:
  • digest (Digest) – The implementation to test.

  • hash_function (Hash) – The hash function used by the implementation.

Keyword Arguments:
  • compliance – Whether to use compliance test vectors.

  • resilience – Whether to use resilience test vectors.

Returns:

A dictionary of results.

Return type:

ResultsDict

Example

Let’s test the built-in HMAC implementation.

>>> import hmac

We also import the HMAC module from crypto-condor.

>>> from crypto_condor.primitives import HMAC

We create our function conforming to Digest using SHA-256.

>>> def digest_sha256(key: bytes, msg: bytes) -> bytes:
...     return hmac.digest(key, msg, "sha256")

Then we test it.

>>> rd = HMAC.test_digest(digest_sha256, HMAC.Hash.SHA_256)
[HMAC-SHA-256] Test digest ...
>>> assert rd.check()

Added in version TODO(version): Replaces testing digest with test_hmac().

Test tag verification

crypto_condor.primitives.HMAC.test_verify(verify, hash_function, *, compliance=True, resilience=False)

Tests an implementation of HMAC tag verification.

Parameters:
  • verify (Verify) – The implementation to test.

  • hash_function (Hash) – The hash function used by the implementation.

Keyword Arguments:
  • compliance – Whether to use compliance test vectors.

  • resilience – Whether to use resilience test vectors.

Returns:

A dictionary of results.

Return type:

ResultsDict

Example

Let’s test the built-in HMAC implementation.

>>> import hmac

We also import the HMAC module from crypto-condor.

>>> from crypto_condor.primitives import HMAC

We create our function conforming to Verify using SHA-256.

>>> def verify_sha256(key: bytes, msg: bytes, mac: bytes, mac_len: int) -> bool:
...     ref_mac = hmac.digest(key, msg, "sha256")
...     return hmac.compare_digest(ref_mac[: mac_len], mac)

Then we test it.

>>> rd = HMAC.test_verify(verify_sha256, HMAC.Hash.SHA_256)
[HMAC-SHA-256] Test verify ...
>>> assert rd.check()

Added in version TODO(version): Replaces testing verify with test_hmac().

Parameters

enum crypto_condor.primitives.HMAC.Hash(value)

A hash function that can be used with HMAC.

Member Type:

str

Valid values are as follows:

SHA_1 = <Hash.SHA_1: 'SHA-1'>
SHA_224 = <Hash.SHA_224: 'SHA-224'>
SHA_256 = <Hash.SHA_256: 'SHA-256'>
SHA_384 = <Hash.SHA_384: 'SHA-384'>
SHA_512 = <Hash.SHA_512: 'SHA-512'>
SHA3_224 = <Hash.SHA3_224: 'SHA3-224'>
SHA3_256 = <Hash.SHA3_256: 'SHA3-256'>
SHA3_384 = <Hash.SHA3_384: 'SHA3-384'>
SHA3_512 = <Hash.SHA3_512: 'SHA3-512'>

Protocols

protocol crypto_condor.primitives.HMAC.Digest

Represents the HMAC digest operation.

Added in version TODO(version): Replaces HMAC.digest().

Classes that implement this protocol must have the following methods / attributes:

__call__(key, msg)

Generates a MAC using HMAC.

Parameters:
  • key (bytes) – The secret key.

  • msg (bytes) – The message to authenticate.

Returns:

The MAC, in bytes.

Return type:

bytes

protocol crypto_condor.primitives.HMAC.Verify

Represents the verification of an HMAC tag.

Some implementations may offer a verify method, while others expect the user to generate a tag from the key and message, and compare it with the existing tag.

Added in version TODO(version): Replaces HMAC.verify().

Classes that implement this protocol must have the following methods / attributes:

__call__(key, msg, mac, mac_len)

Verifies a HMAC tag.

The size of the MAC is given to indicate that the tag may be truncated, therefore shorter than the digest size.

Parameters:
  • key (bytes) – The secret key.

  • msg (bytes) – The message to authenticate.

  • mac (bytes) – The tag to verify.

  • mac_len (int) – The size of the MAC in bytes. Equal to len(mac).

Returns:

True if the tags match, False otherwise.

Return type:

bool

Deprecated API

protocol crypto_condor.primitives.HMAC.HMAC

Class that implements HMAC methods.

This class represents a simpler interface, where everything is processed in a single function. For the common init/update/final interface, see HMAC_IUF.

Raising NotImplementedError is allowed for methods you do not want to test but all methods should be present.

Deprecated since version TODO(version): Use Digest and Verify instead.

Classes that implement this protocol must have the following methods / attributes:

digest(key, message)

Computes the MAC of a message.

Parameters:
  • key (bytes) – The secret HMAC key.

  • message (bytes) – The entire message to authenticate.

Returns:

The MAC tag.

Return type:

bytes

verify(key, message, mac)

Verifies a MAC tag.

Parameters:
  • key (bytes) – The secret HMAC key.

  • message (bytes) – The entire message to authenticate.

  • mac (bytes) – The MAC tag to verify.

Returns:

True if the MAC tag is valid.

Return type:

bool

protocol crypto_condor.primitives.HMAC.HMAC_IUF

Class that implements HMAC methods.

This class represents the commonly used init/update/final interface. This interface has two final methods, final_digest() and final_verify(), both of which require init() and update(). For a simpler interface, where only one function is required, see HMAC.

Raising NotImplementedError is allowed for (final) methods you do not want to test but all methods should be present.

Deprecated since version TODO(version): Use Digest and Verify instead.

Classes that implement this protocol must have the following methods / attributes:

classmethod init(key)

Initializes an instance with a key.

Parameters:

key (bytes) – The secret HMAC key.

Returns:

An instance of the class that has been initialized with the given key.

update(message)

Processes a new chunk.

Parameters:

message (bytes) – The next part of the message to process.

final_digest()

Finalizes the processing.

Returns:

The MAC tag.

Return type:

bytes

final_verify(mac)

Finalizes the processing.

Returns:

True if the MAC is valid for the given key and message.

Return type:

bool

crypto_condor.primitives.HMAC.test_hmac(
hmac,
hash_function,
*,
compliance=True,
resilience=False,
skip_digest=False,
skip_verify=False,
)

Tests an implementation of HMAC using test vectors.

Test vectors are selected with the compliance and resilience options. SHA-3 functions are not covered by NIST vectors (see HmacVectors).

Parameters:
  • hmac (HMAC | HMAC_IUF) – The implementation to test. Must conform to either the HMAC interface or the HMAC_IUF interface.

  • hash_function (Hash) – The hash function to use with this HMAC implementation.

Keyword Arguments:
  • compliance – Whether to use compliance test vectors.

  • resilience – Whether to use resilience test vectors.

  • skip_digest – If True, skip testing the digest function.

  • skip_verify – If True, skip testing the verify function.

Deprecated since version TODO(version): Use test_digest() and test_verify() instead.