Program Listing for File bits.hpp
↰ Return to documentation for file (libspookyaction/include/desfire/bits.hpp
)
//
// Created by Pietro Saccardi on 02/01/2021.
//
#ifndef DESFIRE_BITS_HPP
#define DESFIRE_BITS_HPP
#include <array>
#include <cstdint>
#include <desfire/log.h>
namespace desfire {
enum struct comm_mode : std::uint8_t {
plain = 0b00,
maced = 0b01,
ciphered = 0b11,
ciphered_no_crc
};
[[nodiscard]] constexpr comm_mode comm_mode_most_secure(comm_mode l, comm_mode r);
enum struct file_security : std::uint8_t {
none = static_cast<std::uint8_t>(comm_mode::plain),
authenticated = static_cast<std::uint8_t>(comm_mode::maced),
encrypted = static_cast<std::uint8_t>(comm_mode::ciphered)
};
enum struct cipher_type : std::uint8_t {
none = 0x0,
des = 0x1,
des3_2k = 0x2,
des3_3k = 0x3,
aes128 = 0x4
};
enum struct app_crypto : std::uint8_t {
legacy_des_2k3des = 0x00,
iso_3k3des = 0x40,
aes_128 = 0x80
};
[[nodiscard]] constexpr app_crypto app_crypto_from_cipher(cipher_type c);
enum struct file_type : std::uint8_t {
standard = 0x00,
backup = 0x01,
value = 0x02,
linear_record = 0x03,
cyclic_record = 0x04
};
#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace bits {
enum struct command_code : std::uint8_t {
authenticate_legacy = 0x0a,
change_key_settings = 0x54,
get_key_settings = 0x45,
change_key = 0xc4,
get_key_version = 0x64,
create_application = 0xca,
delete_application = 0xda,
get_application_ids = 0x6a,
select_application = 0x5a,
format_picc = 0xfc,
get_version = 0x60,
get_file_ids = 0x6f,
get_file_settings = 0xf5,
change_file_settings = 0x5f,
create_std_data_file = 0xcd,
create_backup_data_file = 0xcb,
create_value_file = 0xcc,
create_linear_record_file = 0xc1,
create_cyclic_record_file = 0xc0,
delete_file = 0xdf,
read_data = 0xbd,
write_data = 0x3d,
get_value = 0x6c,
credit = 0x0c,
debit = 0xdc,
limited_credit = 0x1c,
write_record = 0x3b,
read_records = 0xbb,
clear_record_file = 0xeb,
commit_transaction = 0xc7,
abort_transaction = 0xa7,
additional_frame = 0xaf,
authenticate_iso = 0x1a,
authenticate_aes = 0xaa,
free_mem = 0x6e,
get_df_names = 0x6d,
get_card_uid = 0x51,
get_iso_file_ids = 0x61,
set_configuration = 0x5c
};
[[nodiscard]] constexpr command_code auth_command(cipher_type t);
enum struct status : std::uint8_t {
ok = 0x00,
no_changes = 0x0c,
out_of_eeprom = 0x0e,
illegal_command = 0x1c,
integrity_error = 0x1e,
no_such_key = 0x40,
length_error = 0x7e,
permission_denied = 0x9d,
parameter_error = 0x9e,
app_not_found = 0xa0,
app_integrity_error = 0xa1,
authentication_error = 0xae,
additional_frame = 0xaf,
boundary_error = 0xbe,
picc_integrity_error = 0xc1,
command_aborted = 0xca,
picc_disabled_error = 0xcd,
count_error = 0xce,
duplicate_error = 0xde,
eeprom_error = 0xee,
file_not_found = 0xf0,
file_integrity_error = 0xf1
};
static constexpr std::size_t max_packet_length = 60;
static constexpr std::uint8_t max_keys_per_app = 14;
static constexpr unsigned app_change_keys_right_shift = 4;
static constexpr std::uint8_t app_change_keys_right_same = 0x0e;
static constexpr std::uint8_t app_change_keys_right_none = 0x0f;
static constexpr std::uint8_t app_change_config_allowed_flag = 1 << 3;
static constexpr std::uint8_t app_create_delete_without_master_key_flag = 1 << 2;
static constexpr std::uint8_t app_list_without_master_key_flag = 1 << 1;
static constexpr std::uint8_t app_changeable_master_key_flag = 1 << 0;
static constexpr unsigned app_id_length = 3;
static constexpr std::uint8_t max_keys_mask = 0xf;
static_assert((max_keys_per_app & max_keys_mask) == max_keys_per_app,
"There's no spec for this max key mask, so let's make sure at least it works.");
static constexpr std::uint8_t storage_size_approx_bit = 0b1;
static constexpr unsigned storage_size_exponent_shift = 1;
static constexpr unsigned file_access_rights_change_shift = 0;
static constexpr unsigned file_access_rights_read_write_shift = 4;
static constexpr unsigned file_access_rights_write_shift = 8;
static constexpr unsigned file_access_rights_read_shift = 12;
static constexpr std::uint8_t max_standard_data_file_id = 0xf;
static constexpr std::uint8_t max_backup_data_file_id = 0x7;
static constexpr std::uint8_t max_value_file_id = 0x7;
static constexpr std::uint8_t max_record_file_id = 0x7;
static constexpr std::uint8_t config_flag_enable_random_uid = 0x02;
static constexpr std::uint8_t config_flag_disable_format = 0x01;
static constexpr std::uint8_t crypto_cmac_xor_byte_3k3des = 0x1b;
static constexpr std::uint8_t crypto_cmac_xor_byte_2k3des = 0x1b;
static constexpr std::uint8_t crypto_cmac_xor_byte_des = 0x1b;
static constexpr std::uint8_t crypto_cmac_xor_byte_aes = 0x87;
static constexpr std::array<std::uint8_t, 1> kdf_aes_const = {0x01};
static constexpr std::array<std::uint8_t, 3> kdf_3k3des_const = {0x31, 0x32, 0x33};
static constexpr std::array<std::uint8_t, 2> kdf_2k3des_const = {0x21, 0x22};
static constexpr std::array<std::uint8_t, 1> kdf_des_const = {0x11};
}// namespace bits
#endif
}// namespace desfire
namespace desfire {
constexpr comm_mode comm_mode_most_secure(comm_mode l, comm_mode r) {
if (l == comm_mode::ciphered or r == comm_mode::ciphered) {
return comm_mode::ciphered;
} else if (l == comm_mode::ciphered_no_crc or r == comm_mode::ciphered_no_crc) {
return comm_mode::ciphered_no_crc;
} else if (l == comm_mode::maced or r == comm_mode::maced) {
return comm_mode::maced;
} else {
return comm_mode::plain;
}
}
constexpr app_crypto app_crypto_from_cipher(cipher_type c) {
switch (c) {
case cipher_type::none:
DESFIRE_LOGE("cipher_type::none cannot be converted to app_crypto!.");
return app_crypto::legacy_des_2k3des;
case cipher_type::des:
[[fallthrough]];
case cipher_type::des3_2k:
return app_crypto::legacy_des_2k3des;
case cipher_type::des3_3k:
return app_crypto::iso_3k3des;
case cipher_type::aes128:
return app_crypto::aes_128;
}
return app_crypto::legacy_des_2k3des;
}
namespace bits {
constexpr command_code auth_command(cipher_type t) {
switch (t) {
case cipher_type::des3_2k:
return command_code::authenticate_legacy;
case cipher_type::des3_3k:
return command_code::authenticate_iso;
case cipher_type::des:
return command_code::authenticate_legacy;
case cipher_type::aes128:
return command_code::authenticate_aes;
default:
DESFIRE_LOGE("Requesting authentication command for no cipher!");
return command_code::additional_frame;
}
}
}// namespace bits
}// namespace desfire
#endif//DESFIRE_BITS_HPP