HMAC wrappers

Digest

Generates a MAC tag using HMAC.

Naming convention

CC_HMAC_digest_<hash function>

Where hash function is one of:

  • sha1, sha224, sha256, sha384, sha512.

  • sha3_224, sha3_256, sha3_384, sha3_512.

Protocol

The function must conform to the following protocol:

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

Verify

Verifies an HMAC tag.

Naming convention

CC_HMAC_verify_<hash function>

Where hash function is one of:

  • sha1, sha224, sha256, sha384, sha512.

  • sha3_224, sha3_256, sha3_384, sha3_512.

Protocol

The function must conform to the following protocol:

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

Example

"""HMAC wrapper example.

Uses Python's built-in ``hmac`` module.

To test this example:

    crypto-condor-cli test wrapper HMAC hmac_wrapper_example.py
"""

import hmac


def CC_HMAC_digest_sha256(key: bytes, msg: bytes) -> bytes:
    """Tests HMAC-SHA-256 digest."""
    return hmac.digest(key, msg, "sha256")


def CC_HMAC_digest_sha3_512(key: bytes, msg: bytes) -> bytes:
    """Tests HMAC-SHA3-512 digest."""
    return hmac.digest(key, msg, "sha3_512")


def CC_HMAC_verify_sha256(key: bytes, msg: bytes, mac: bytes, mac_len: int) -> bool:
    """Tests HMAC-SHA-256 verify."""
    _mac = hmac.digest(key, msg, "sha256")
    # Some MACs are truncated, so we have to truncate ours to in order to compare them.
    ref_mac = _mac[:mac_len]
    return hmac.compare_digest(ref_mac, mac)


def CC_HMAC_verify_sha3_512(key: bytes, msg: bytes, mac: bytes, mac_len: int) -> bool:
    """Tests HMAC-SHA3-512 verify."""
    _mac = hmac.digest(key, msg, "sha3_512")
    # Some MACs are truncated, so we have to truncate ours to in order to compare them.
    ref_mac = _mac[:mac_len]
    return hmac.compare_digest(ref_mac, mac)