.. _program_listing_file_libspookyaction_include_desfire_bits.hpp: Program Listing for File bits.hpp ================================= |exhale_lsh| :ref:`Return to documentation for file ` (``libspookyaction/include/desfire/bits.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // // Created by Pietro Saccardi on 02/01/2021. // #ifndef DESFIRE_BITS_HPP #define DESFIRE_BITS_HPP #include #include #include 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(comm_mode::plain), authenticated = static_cast(comm_mode::maced), encrypted = static_cast(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 kdf_aes_const = {0x01}; static constexpr std::array kdf_3k3des_const = {0x31, 0x32, 0x33}; static constexpr std::array kdf_2k3des_const = {0x21, 0x22}; static constexpr std::array 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