Class desfire::crypto_with_cmac
Defined in File crypto.hpp
Inheritance Relationships
Base Type
public desfire::crypto
(Class desfire::crypto)
Derived Types
public desfire::crypto_3k3des_base
(Class desfire::crypto_3k3des_base)public desfire::crypto_aes_base
(Class desfire::crypto_aes_base)
Class Documentation
-
class crypto_with_cmac : public desfire::crypto
Abstract class that extends crypto providing CMAC capabilities.
This is the base class for modern 3K3DES and AES128 ciphers, and uses internally cmac_provider. Subclasses should
Still provide the correct crypto_operation::mac implementation through crypto::do_crypto, as this is used as a subroutine of the more sophisticated do_cmac function.
Correctly setup this class via the protected constructor crypto_with_cmac::crypto_with_cmac, since some information on the block size and a given magic number is required to correctly compute the CMAC.
Avoid overriding setup_with_key, since the implementation provided by this class does also CMAC subkey derivation. Instead, they should implement setup_primitives_with_key, with the same effect and extents as crypto::setup_with_key.
See also
Warning
It is not correct to use this class through its base interface crypto! Protocols and ciphers that use CMAC-enabled crypto should use directly do_cmac and this class. The reason is that these ciphers require the initialization vector to be in sync with the Desfire card throughout the session, and the IV is updated by a CMAC operation. Therefore, calling e.g. do_crypto naively with a crypto_operation::mac would throw the IV out of sync. Therefore, CMAC-enabled cryptographic implementation are supposed to be used as such and not through the lower abstraction layer.
Subclassed by desfire::crypto_3k3des_base, desfire::crypto_aes_base
Public Types
-
using mac_t = cmac_provider::mac_t
The type of the CMAC MAC code, which is a fixed 8 bytes sequence.
Public Functions
-
virtual mac_t do_cmac(range<std::uint8_t const*> data, range<std::uint8_t*> iv)
Computes the CMAC on
data
using the given initialization vectoriv
. The CMAC is nothing but the first 8 bytes ofiv
after crypto_operation::mac has been run ondata
.- Parameters:
data – Data sequence for which the CMAC has to be computed. Remains constant.
iv – Initialization vector to use. It is updated in place by this function.
- Returns:
The first 8 bytes of
iv
after the cryptographic operation has been done.
-
std::size_t block_size() const
Block size for this cipher. This is specified upon construction and is cipher-specific.
- Returns:
Size in bytes of the underlying block cipher.
-
virtual void setup_with_key(range<std::uint8_t const*> key) override
CMAC-enabled implementation of crypto::setup_with_key.
This method first of all calls setup_primitives_with_key and right afterwards generates CMAC subkeys for the internal cmac_provider.
Warning
Subclasses should leave this method alone and instead implement setup_primitives_with_key.
- Parameters:
key – Range of bytes containing the key to use for the following operations. This is specified as a range on raw bytes for convenience, as the underlying cryptographic functions are likely low level.
-
inline cmac_provider const &provider() const
Access the internal CMAC provider.
Protected Functions
-
crypto_with_cmac(std::uint8_t block_size, std::uint8_t last_byte_xor)
Initializes the CMAC-enabled class.
- Parameters:
block_size – Size of the cipher block. This is passed directly to cmac_provider::cmac_provider.
last_byte_xor – When deriving the key, if the MSB is 1, the last byte is XOR-ed with this value. I have no clue about why we have to do this, maybe some nice key pre-conditioning to resist certain attacks? I do not know, but it is a constant specific to the cipher used. This is passed directly to cmac_provider::cmac_provider.
-
virtual void setup_primitives_with_key(range<std::uint8_t const*> key) = 0
Subclasses should implement this instead of setup_with_key, to the same effect.
This method is called by the custom implementation of setup_with_key provided in this class, right before key derivation is performed, with the same parameters.
- Parameters:
key – Range of bytes containing the key to use for the following operations. This is specified as a range on raw bytes for convenience, as the underlying cryptographic functions are likely low level.