Class desfire::cmac_keychain
Defined in File cmac_provider.hpp
Class Documentation
-
class cmac_keychain
Class which holds and derives subkeys to use when computing CMAC.
CMAC as used by Desfire pads and xors the data with two different keys, derived from the cryptographic implementation (by encrypting sequences of zeroes). This class manages the subkeys for CMAC operations.
Public Functions
-
inline cmac_keychain(std::size_t block_size, std::uint8_t last_byte_xor)
Initialize a new CMAC keychain with zero subkeys.
See also
- Parameters:
block_size – Size of the block used in the crypto object (8 bytes for 3K3DES, 16 for AES128).
last_byte_xor – Used in subkey generation, this is specific to the Desfire implementation. Refer to prepare_subkey for more details; the values used are xor_byte_3k3des for 3K3DES, and xor_byte_aes for AES128.
-
inline range<std::uint8_t*> key_pad() const
Key to use for messages that need padding.
-
inline range<std::uint8_t*> key_nopad() const
Key to use for messages that do not need padding.
-
inline std::size_t block_size() const
Block size of the underlying crypto implementation.
- Returns:
The block size in bytes specified in cmac_provider::cmac_provider.
-
inline std::uint8_t last_byte_xor() const
The value used in subkey generation for the underlying crypto implementation.
See also
- Returns:
The value specified in cmac_provider::cmac_provider.
-
void initialize_subkeys(crypto &crypto)
Recomputes the subkeys.
This method performs the following key-derivation operations:
Call crypto::do_crypto with crypto_operation::mac, a zero-filled IV and a zero-filled data.
Pass the result through prepare_subkey with last_byte_xor. This produces the first key that is used for messages that need padding.
Pass the newly generated key through prepare_subkey again, with last_byte_xor. This produces the second key, that is used for messages that do not need padding.
Note
This method actually performs cryptographic operations via crypto::do_crypto in order to derive the subkeys used in the CMAC operation. This is the reason why it’s not performed automatically in the constructor: the crypto object in the constructor is allowed to not be fully initialized at that point in time. However, it must be fully initialized when this method is called. The rationale is that this class might be used as a member variable in some crypto subclass: since it’s abstract, we first need to initialize the subclass in order to have full access to crypto::do_crypto, and thus we perform delayed subkey initialization.
- Parameters:
crypto – Cryptographic implementation to use for deriving the keys. Make sure that the block size matches to what used in the constructor (i.e. block_size).
-
void prepare_cmac_data(bin_data &data) const
Prepares data for CMAC operation by padding it and XORing with the appropriate key.
This performs a subset of the operations of cmac_provider::compute_cmac, namely:
Pads
data
with80 00 .. 00
.XORs the last block with the appropriate key, depending on whether it was padded or not.
See also
- Parameters:
data – Data to pad and XOR, modified in-place. Will be resized to a multiple of block_size.
-
void prepare_cmac_data(bin_data &data, std::size_t desired_padded_length) const
Prepares data for CMAC operation by padding it and XORing with the appropriate key.
This performs a subset of the operations of cmac_provider::compute_cmac, namely:
Pads
data
with80 00 .. 00
up todesired_padded_length
.XORs the last block with the appropriate key, depending on whether it was padded or not.
See also
- Parameters:
data – Data to pad and XOR, modified in-place. Will be resized to a multiple of the block size.
desired_padded_length – Minimum length for the padded message. Will be rounded to the next multiple of block_size.
Public Static Functions
-
static void prepare_subkey(range<std::uint8_t*> subkey, std::uint8_t last_byte_xor)
Transform a cryptogram into a subkey to use for CMACing.
This seems to be something specific to Desfire. First some cryptographic operation is performed, then the result is shifted and if the MSB is 1, the last byte is XORed with
last_byte_xor
. Maybe it is done to precondition the algorithm to be more resistant?- Parameters:
subkey – Cryptogram resulting from running a regular crypto_operation::mac on the appropriate IV. Upon exit, this contains the result (the shift and XOR operations are performed in-place on this range).
last_byte_xor – Value that is XORed with the last byte if the MSB of the shifted
subkey
is 1.
Public Static Attributes
-
static constexpr auto xor_byte_des = desfire::bits::crypto_cmac_xor_byte_des
Xor byte for DES cipher (presumed).
-
static constexpr auto xor_byte_2k3des = desfire::bits::crypto_cmac_xor_byte_2k3des
Xor byte for 2K3DES cipher (presumed).
-
static constexpr auto xor_byte_3k3des = desfire::bits::crypto_cmac_xor_byte_3k3des
Xor byte for 3K3DES cipher.
-
static constexpr auto xor_byte_aes = desfire::bits::crypto_cmac_xor_byte_aes
Xor byte for AES128 cipher.
-
inline cmac_keychain(std::size_t block_size, std::uint8_t last_byte_xor)