From 8caaf85fbbec2722f06f3b47bc06f7201b3744df Mon Sep 17 00:00:00 2001 From: James Wilson Date: Sun, 15 May 2022 17:05:14 -0700 Subject: [PATCH] Cleanup & reorganization (#73) scsi::get_des & others should take a non-const buffer since they modify it Reorder functions in main.cpp to declare internal functions static Fix compile error in newer GCC (Compilation error #72) with more explicit cast Remove some unused constants Add KAD type enum Pass key vector by reference instead of copying Closes: https://github.com/scsitape/stenc/issues/72 --- src/main.cpp | 475 ++++++++++++++++++++++---------------------- src/scsiencrypt.cpp | 35 ++-- src/scsiencrypt.h | 41 ++-- 3 files changed, 265 insertions(+), 286 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0929341..a16be28 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,20 +43,13 @@ GNU General Public License for more details. #include "scsiencrypt.h" -void showUsage(); -void errorOut(const std::string& message); -void inquiryDrive(const std::string& tapeDevice); -void showDriveStatus(const std::string& tapeDevice, bool detail); -void showVolumeStatus(const std::string& tapeDevice); -void echo(bool); - -static std::optional> key_from_hex_chars(const std::string& s) +static std::optional> key_from_hex_chars(const std::string& s) { auto it = s.data(); - std::vector bytes; + std::vector bytes; if (s.size() % 2) { // treated as if there is an implicit leading 0 - uint8_t result; + std::uint8_t result; auto [ptr, ec] { std::from_chars(it, it + 1, result, 16) }; if (ec != std::errc {}) { return {}; @@ -66,7 +59,7 @@ static std::optional> key_from_hex_chars(const std::string& } while (*it) { - uint8_t result; + std::uint8_t result; auto [ptr, ec] { std::from_chars(it, it + 2, result, 16) }; if (ec != std::errc {}) { return {}; @@ -77,6 +70,232 @@ static std::optional> key_from_hex_chars(const std::string& return bytes; } +// shows the command usage +static void showUsage() { + std::cerr + << "Usage: stenc --version | " + "-f [--detail] [-e [-k ] " + "[-kd ] [-a ] [--protect | --unprotect] [--ckod] ]\n\n" + "Type 'man stenc' for more information.\n"; +} + +// exits to shell with an error message +static void errorOut(const std::string& message) { + std::cerr << "Error: " << message << "\n"; + showUsage(); + exit(EXIT_FAILURE); +} + +static void print_device_inquiry(std::ostream& os, const scsi::inquiry_data& iresult) +{ + os << std::left << std::setw(25) << "Vendor:"; + os.write(iresult.vendor, 8); + os.put('\n'); + os << std::left << std::setw(25) << "Product ID:"; + os.write(iresult.product_id, 16); + os.put('\n'); + os << std::left << std::setw(25) << "Product Revision:"; + os.write(iresult.product_rev, 4); + os.put('\n'); +} + +static void inquiryDrive(const std::string& tapeDevice) { + // todo: std::cout should not be used outside main() + auto iresult {scsi::get_inquiry(tapeDevice)}; + print_device_inquiry(std::cout, iresult); +} + +static void print_device_status(std::ostream& os, const scsi::page_des& opt, bool detail) +{ + std::string emode = "unknown"; + os << std::left << std::setw(25) << "Drive Encryption:"; + if (opt.encryption_mode == scsi::encrypt_mode::on && // encrypt + opt.decryption_mode == scsi::decrypt_mode::on // read only encrypted data + ) + emode = "on"; + if (opt.encryption_mode == scsi::encrypt_mode::on && // encrypt + opt.decryption_mode == scsi::decrypt_mode::mixed // read encrypted and unencrypted + ) + emode = "mixed"; + + if (opt.encryption_mode == scsi::encrypt_mode::on && // encrypt + opt.decryption_mode == scsi::decrypt_mode::raw // read encrypted and unencrypted + ) + emode = "rawread"; + + if (opt.encryption_mode == scsi::encrypt_mode::off && // encrypt + opt.decryption_mode == scsi::decrypt_mode::off // read encrypted and unencrypted + ) + emode = "off"; + + os << emode << "\n"; + if (detail) { + os << std::left << std::setw(25) << "Drive Output:"; + switch (opt.decryption_mode) { + case scsi::decrypt_mode::off: + os << "Not decrypting\n"; + os << std::setw(25) << " " + << "Raw encrypted data not outputted\n"; + break; + case scsi::decrypt_mode::raw: + os << "Not decrypting\n"; + os << std::setw(25) << " " + << "Raw encrypted data outputted\n"; + break; + case scsi::decrypt_mode::on: + os << "Decrypting\n"; + os << std::setw(25) << " " + << "Unencrypted data not outputted\n"; + break; + case scsi::decrypt_mode::mixed: + os << "Decrypting\n"; + os << std::setw(25) << " " + << "Unencrypted data outputted\n"; + break; + default: + os << "Unknown '0x" << std::hex << static_cast(opt.decryption_mode) + << "' \n"; + break; + } + os << std::setw(25) << "Drive Input:"; + switch (opt.encryption_mode) { + case scsi::encrypt_mode::off: + os << "Not encrypting\n"; + break; + case scsi::encrypt_mode::on: + os << "Encrypting\n"; + break; + default: + os << "Unknown result '0x" << std::hex + << static_cast(opt.encryption_mode) << "'\n"; + break; + } + if ((opt.flags & scsi::page_des::flags_rdmd_mask) == scsi::page_des::flags_rdmd_mask) { + os << std::setw(25) << " " + << "Protecting from raw read\n"; + } + + os << std::setw(25) << "Key Instance Counter:" << std::dec + << ntohl(opt.key_instance_counter) << "\n"; + if (opt.algorithm_index != 0) { + os << std::setw(25) << "Encryption Algorithm:" << std::hex + << static_cast(opt.algorithm_index) << "\n"; + } + } + auto kads {scsi::read_page_kads(opt)}; + for (auto kd: kads) { + switch (kd->type) { + case scsi::kad_type::ukad: + os << std::setw(25) << "Drive Key Desc.(uKAD): "; + os.write(reinterpret_cast(kd->descriptor), ntohs(kd->length)); + os.put('\n'); + break; + case scsi::kad_type::akad: + os << std::setw(25) << "Drive Key Desc.(aKAD): "; + os.write(reinterpret_cast(kd->descriptor), ntohs(kd->length)); + os.put('\n'); + break; + } + } +} + +static void showDriveStatus(const std::string& tapeDrive, bool detail) { + alignas(4) scsi::page_buffer buffer; + scsi::get_des(tapeDrive, buffer, sizeof(buffer)); + auto& opt {reinterpret_cast(buffer)}; + + print_device_status(std::cout, opt, detail); +} + +static void print_volume_status(std::ostream& os, const scsi::page_nbes& opt) +{ + auto compression_status { + static_cast((opt.status & scsi::page_nbes::status_compression_mask) + >> scsi::page_nbes::status_compression_pos) + }; + // From vendor docs, no known drives actually report anything other than 0 + if (compression_status != 0u) { + os << std::left << std::setw(25) << "Volume Compressed:"; + switch (compression_status) { + case 0u: + os << "Drive cannot determine\n"; + break; + default: + os << "Unknown result '" << std::hex + << static_cast(compression_status) << "'\n"; + break; + } + } + os << std::left << std::setw(25) << "Volume Encryption:"; + auto encryption_status { + static_cast((opt.status & scsi::page_nbes::status_encryption_mask) + >> scsi::page_nbes::status_encryption_pos) + }; + auto kads {read_page_kads(opt)}; + switch (encryption_status) { + case 0u: + case 1u: + os << "Unable to determine\n"; + break; + case 2u: + os << "Tape position not at a logical block\n"; + break; + case 3u: + os << "Not encrypted\n"; + break; + case 5u: + os << "Encrypted and able to decrypt\n"; + if ((opt.flags & scsi::page_nbes::flags_rdmds_mask) == scsi::page_nbes::flags_rdmds_mask) { + os << std::left << std::setw(25) << " Protected from raw read\n"; + } + break; + case 6u: + os << "Encrypted, but unable to decrypt due to invalid key.\n"; + for (auto kd: kads) { + switch (kd->type) { + case scsi::kad_type::ukad: + os << std::setw(25) << "Volume Key Desc.(uKAD): "; + os.write(reinterpret_cast(kd->descriptor), ntohs(kd->length)); + os.put('\n'); + break; + case scsi::kad_type::akad: + os << std::setw(25) << "Volume Key Desc.(aKAD): "; + os.write(reinterpret_cast(kd->descriptor), ntohs(kd->length)); + os.put('\n'); + break; + } + } + if ((opt.flags & scsi::page_nbes::flags_rdmds_mask) == scsi::page_nbes::flags_rdmds_mask) { + os << std::left << std::setw(25) << " Protected from raw read\n"; + } + break; + default: + os << "Unknown result '" << std::hex + << static_cast(encryption_status) << "'\n"; + break; + } + if (opt.algorithm_index != 0) { + os << std::left << std::setw(25) + << "Volume Algorithm:" << static_cast(opt.algorithm_index) << "\n"; + } +} + +static void showVolumeStatus(const std::string& tapeDrive) { + alignas(4) scsi::page_buffer buffer; + scsi::get_nbes(tapeDrive, buffer, sizeof(buffer)); + auto& opt {reinterpret_cast(buffer)}; + + print_volume_status(std::cout, opt); +} + +static void echo(bool on) { + struct termios settings {}; + tcgetattr(STDIN_FILENO, &settings); + settings.c_lflag = + on ? (settings.c_lflag | ECHO) : (settings.c_lflag & ~(ECHO)); + tcsetattr(STDIN_FILENO, TCSANOW, &settings); +} + #if !defined(CATCH_CONFIG_MAIN) int main(int argc, const char **argv) { std::string tapeDrive; @@ -106,10 +325,10 @@ int main(int argc, const char **argv) { exit(EXIT_SUCCESS); } if (thisCmd == "-e") { - if (nextCmd == ""){ + if (nextCmd == "") { errorOut("Key file not specified after -k option"); } - if (nextCmd == "on"){ + if (nextCmd == "on") { // encrypt, read only encrypted data enc_mode = scsi::encrypt_mode::on; dec_mode = scsi::decrypt_mode::on; @@ -156,7 +375,7 @@ int main(int argc, const char **argv) { } rdmc = scsi::sde_rdmc::disabled; } else if (thisCmd == "--unprotect") { - if (rdmc == scsi::sde_rdmc::disabled){ + if (rdmc == scsi::sde_rdmc::disabled) { errorOut("'--unprotect' cannot be specified at the same time as " "'--protect'"); } @@ -197,11 +416,11 @@ int main(int argc, const char **argv) { << "--------------------------------------------------\n"; try { - if (detail){ + if (detail) { inquiryDrive(tapeDrive); } showDriveStatus(tapeDrive, detail); - if (detail){ + if (detail) { showVolumeStatus(tapeDrive); } exit(EXIT_SUCCESS); @@ -321,227 +540,3 @@ int main(int argc, const char **argv) { } } #endif // defined(CATCH_CONFIG_MAIN) - -// exits to shell with an error message -void errorOut(const std::string& message) { - std::cerr << "Error: " << message << "\n"; - showUsage(); - exit(EXIT_FAILURE); -} - -// shows the command usage -void showUsage() { - std::cerr - << "Usage: stenc --version | " - "-f [--detail] [-e [-k ] " - "[-kd ] [-a ] [--protect | --unprotect] [--ckod] ]\n\n" - "Type 'man stenc' for more information.\n"; -} - -static void print_device_inquiry(std::ostream& os, const scsi::inquiry_data& iresult) -{ - os << std::left << std::setw(25) << "Vendor:"; - os.write(iresult.vendor, 8); - os.put('\n'); - os << std::left << std::setw(25) << "Product ID:"; - os.write(iresult.product_id, 16); - os.put('\n'); - os << std::left << std::setw(25) << "Product Revision:"; - os.write(iresult.product_rev, 4); - os.put('\n'); -} - -void inquiryDrive(const std::string& tapeDevice) { - // todo: std::cout should not be used outside main() - auto iresult {scsi::get_inquiry(tapeDevice)}; - print_device_inquiry(std::cout, iresult); -} - -static void print_device_status(std::ostream& os, const scsi::page_des& opt, bool detail) -{ - std::string emode = "unknown"; - os << std::left << std::setw(25) << "Drive Encryption:"; - if (opt.encryption_mode == scsi::encrypt_mode::on && // encrypt - opt.decryption_mode == scsi::decrypt_mode::on // read only encrypted data - ) - emode = "on"; - if (opt.encryption_mode == scsi::encrypt_mode::on && // encrypt - opt.decryption_mode == scsi::decrypt_mode::mixed // read encrypted and unencrypted - ) - emode = "mixed"; - - if (opt.encryption_mode == scsi::encrypt_mode::on && // encrypt - opt.decryption_mode == scsi::decrypt_mode::raw // read encrypted and unencrypted - ) - emode = "rawread"; - - if (opt.encryption_mode == scsi::encrypt_mode::off && // encrypt - opt.decryption_mode == scsi::decrypt_mode::off // read encrypted and unencrypted - ) - emode = "off"; - - os << emode << "\n"; - if (detail) { - os << std::left << std::setw(25) << "Drive Output:"; - switch (opt.decryption_mode) { - case scsi::decrypt_mode::off: - os << "Not decrypting\n"; - os << std::setw(25) << " " - << "Raw encrypted data not outputted\n"; - break; - case scsi::decrypt_mode::raw: - os << "Not decrypting\n"; - os << std::setw(25) << " " - << "Raw encrypted data outputted\n"; - break; - case scsi::decrypt_mode::on: - os << "Decrypting\n"; - os << std::setw(25) << " " - << "Unencrypted data not outputted\n"; - break; - case scsi::decrypt_mode::mixed: - os << "Decrypting\n"; - os << std::setw(25) << " " - << "Unencrypted data outputted\n"; - break; - default: - os << "Unknown '0x" << std::hex << static_cast(opt.decryption_mode) - << "' \n"; - break; - } - os << std::setw(25) << "Drive Input:"; - switch (opt.encryption_mode) { - case scsi::encrypt_mode::off: - os << "Not encrypting\n"; - break; - case scsi::encrypt_mode::on: - os << "Encrypting\n"; - break; - default: - os << "Unknown result '0x" << std::hex - << static_cast(opt.encryption_mode) << "'\n"; - break; - } - if ((opt.flags & scsi::page_des::flags_rdmd_mask) == scsi::page_des::flags_rdmd_mask) { - os << std::setw(25) << " " - << "Protecting from raw read\n"; - } - - os << std::setw(25) << "Key Instance Counter:" << std::dec - << ntohl(opt.key_instance_counter) << "\n"; - if (opt.algorithm_index != 0) { - os << std::setw(25) << "Encryption Algorithm:" << std::hex - << static_cast(opt.algorithm_index) << "\n"; - } - } - auto kads {scsi::read_page_kads(opt)}; - for (auto kd: kads) { - switch (kd->type) { - case KAD_TYPE_UKAD: - os << std::setw(25) << "Drive Key Desc.(uKAD): "; - os.write(reinterpret_cast(kd->descriptor), ntohs(kd->length)); - os.put('\n'); - break; - case KAD_TYPE_AKAD: - os << std::setw(25) << "Drive Key Desc.(aKAD): "; - os.write(reinterpret_cast(kd->descriptor), ntohs(kd->length)); - os.put('\n'); - break; - } - } -} - -void showDriveStatus(const std::string& tapeDrive, bool detail) { - alignas(4) scsi::page_buffer buffer; - scsi::get_des(tapeDrive, buffer, sizeof(buffer)); - auto& opt {reinterpret_cast(buffer)}; - - print_device_status(std::cout, opt, detail); -} - -static void print_volume_status(std::ostream& os, const scsi::page_nbes& opt) -{ - auto compression_status { - static_cast((opt.status & scsi::page_nbes::status_compression_mask) - >> scsi::page_nbes::status_compression_pos) - }; - if (compression_status != 0u) { - os << std::left << std::setw(25) << "Volume Compressed:"; - switch (compression_status) { - case 0u: - os << "Drive cannot determine\n"; - break; - default: - os << "Unknown result '" << std::hex - << static_cast(compression_status) << "'\n"; - break; - } - } - os << std::left << std::setw(25) << "Volume Encryption:"; - auto encryption_status { - static_cast((opt.status & scsi::page_nbes::status_encryption_mask) - >> scsi::page_nbes::status_encryption_pos) - }; - auto kads {read_page_kads(opt)}; - switch (encryption_status) { - case 1u: - os << "Unable to determine\n"; - break; - case 2u: - os << "Logical block is not a logical block\n"; - break; - case 3u: - os << "Not encrypted\n"; - break; - case 5u: - os << "Encrypted and able to decrypt\n"; - if ((opt.flags & scsi::page_nbes::flags_rdmds_mask) == scsi::page_nbes::flags_rdmds_mask) { - os << std::left << std::setw(25) << " Protected from raw read\n"; - } - break; - case 6u: - os << "Encrypted, but unable to decrypt due to invalid key.\n"; - for (auto kd: kads) { - switch (kd->type) { - case KAD_TYPE_UKAD: - os << std::setw(25) << "Volume Key Desc.(uKAD): "; - os.write(reinterpret_cast(kd->descriptor), ntohs(kd->length)); - os.put('\n'); - break; - case KAD_TYPE_AKAD: - os << std::setw(25) << "Volume Key Desc.(aKAD): "; - os.write(reinterpret_cast(kd->descriptor), ntohs(kd->length)); - os.put('\n'); - break; - } - } - if ((opt.flags & scsi::page_nbes::flags_rdmds_mask) == scsi::page_nbes::flags_rdmds_mask) { - os << std::left << std::setw(25) << " Protected from raw read\n"; - } - break; - default: - os << "Unknown result '" << std::hex - << static_cast(encryption_status) << "'\n"; - break; - } - if (opt.algorithm_index != 0) { - os << std::left << std::setw(25) - << "Volume Algorithm:" << static_cast(opt.algorithm_index) << "\n"; - } -} - -void showVolumeStatus(const std::string& tapeDrive) { - alignas(4) scsi::page_buffer buffer; - scsi::get_nbes(tapeDrive, buffer, sizeof(buffer)); - auto& opt {reinterpret_cast(buffer)}; - - print_volume_status(std::cout, opt); -} - -void echo(bool on) { - struct termios settings {}; - tcgetattr(STDIN_FILENO, &settings); - settings.c_lflag = - on ? (settings.c_lflag | ECHO) : (settings.c_lflag & ~(ECHO)); - tcsetattr(STDIN_FILENO, TCSANOW, &settings); -} diff --git a/src/scsiencrypt.cpp b/src/scsiencrypt.cpp index 8e103f4..02f3b3e 100644 --- a/src/scsiencrypt.cpp +++ b/src/scsiencrypt.cpp @@ -20,20 +20,14 @@ GNU General Public License for more details. #include #include #include +#include #include #include -#include #ifdef HAVE_UNISTD_H #include #endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif #if defined(OS_LINUX) #include @@ -85,7 +79,7 @@ using unique_fd = std::unique_ptr(dxfer_p); + cmdio.dxferp = dxfer_p; cmdio.cmdp = const_cast(cmd_p); cmdio.sbp = sense_buf->data(); cmdio.mx_sb_len = sizeof(decltype(sense_buf)::element_type); @@ -134,8 +128,8 @@ static void scsi_execute(const std::string& device, const std::uint8_t *cmd_p, cam_fill_csio(&ccb->csio, RETRYCOUNT, nullptr, CAM_PASS_ERR_RECOVER | CAM_CDB_POINTER | (direction == scsi_direction::to_device ? CAM_DIR_OUT : CAM_DIR_IN), - MSG_SIMPLE_Q_TAG, const_cast(dxfer_p), - dxfer_len, SSD_FULL_SIZE, cmd_len, SCSI_TIMEOUT); + MSG_SIMPLE_Q_TAG, dxfer_p, dxfer_len, SSD_FULL_SIZE, cmd_len, + SCSI_TIMEOUT); ccb->csio.cdb_io.cdb_ptr = const_cast(cmd_p); if (cam_send_ccb(dev.get(), ccb.get())) { throw std::system_error {errno, std::generic_category()}; @@ -152,8 +146,7 @@ static void scsi_execute(const std::string& device, const std::uint8_t *cmd_p, namespace scsi { -void get_des(const std::string& device, const std::uint8_t *buffer, - std::size_t length) +void get_des(const std::string& device, std::uint8_t *buffer, std::size_t length) { const std::uint8_t spin_des_command[] { SSP_SPIN_OPCODE, @@ -170,8 +163,7 @@ void get_des(const std::string& device, const std::uint8_t *buffer, buffer, length, scsi_direction::from_device); } -void get_nbes(const std::string& device, const std::uint8_t *buffer, - std::size_t length) +void get_nbes(const std::string& device, std::uint8_t *buffer, std::size_t length) { const std::uint8_t spin_nbes_command[] { SSP_SPIN_OPCODE, @@ -188,8 +180,7 @@ void get_nbes(const std::string& device, const std::uint8_t *buffer, buffer, length, scsi_direction::from_device); } -void get_dec(const std::string& device, const std::uint8_t *buffer, - std::size_t length) +void get_dec(const std::string& device, std::uint8_t *buffer, std::size_t length) { const uint8_t spin_dec_command[] { SSP_SPIN_OPCODE, @@ -208,9 +199,9 @@ void get_dec(const std::string& device, const std::uint8_t *buffer, inquiry_data get_inquiry(const std::string& device) { const uint8_t scsi_inq_command[] {0x12, 0, 0, 0, sizeof(inquiry_data), 0}; - inquiry_data inq; + inquiry_data inq {}; scsi_execute(device, scsi_inq_command, sizeof(scsi_inq_command), - reinterpret_cast(&inq), sizeof(inq), + reinterpret_cast(&inq), sizeof(inq), scsi_direction::from_device); return inq; } @@ -218,7 +209,7 @@ inquiry_data get_inquiry(const std::string& device) std::unique_ptr make_sde(encrypt_mode enc_mode, decrypt_mode dec_mode, std::uint8_t algorithm_index, - const std::vector key, + const std::vector& key, const std::string& key_name, sde_rdmc rdmc, bool ckod) { @@ -233,7 +224,7 @@ std::unique_ptr make_sde(encrypt_mode enc_mode, page.length = htons(length - sizeof(page_header)); page.control = std::byte {2u} << page_sde::control_scope_pos; // all IT nexus = 10b page.flags |= std::byte {DEFAULT_CEEM} << page_sde::flags_ceem_pos; - page.flags |= std::byte {rdmc}; + page.flags |= std::byte {static_cast>(rdmc)}; if (ckod) { page.flags |= page_sde::flags_ckod_mask; } @@ -269,7 +260,7 @@ void write_sde(const std::string& device, const std::uint8_t *sde_buffer) }; scsi_execute(device, spout_sde_command, sizeof(spout_sde_command), - sde_buffer, length, scsi_direction::to_device); + const_cast(sde_buffer), length, scsi_direction::to_device); } void print_sense_data(std::ostream& os, const sense_data& sd) { diff --git a/src/scsiencrypt.h b/src/scsiencrypt.h index 337908e..7c6cbe3 100644 --- a/src/scsiencrypt.h +++ b/src/scsiencrypt.h @@ -34,20 +34,8 @@ GNU General Public License for more details. #include #endif -constexpr size_t SSP_KEY_LENGTH = 0X20; -constexpr size_t SSP_DESCRIPTOR_LENGTH = 1024; -constexpr size_t SSP_KAD_HEAD_LENGTH = 4; -constexpr size_t SSP_PAGE_ALLOCATION = 8192; -constexpr size_t SSP_UKAD_LENGTH = 0x1e; - -constexpr uint8_t KAD_TYPE_UKAD = 0x00; -constexpr uint8_t KAD_TYPE_AKAD = 0x01; -constexpr uint8_t KAD_TYPE_NONCE = 0x02; -constexpr uint8_t KAD_TYPE_META = 0x03; - -constexpr uint8_t RDMC_PROTECT = 0x03; -constexpr uint8_t RDMC_UNPROTECT = 0x02; -constexpr uint8_t RDMC_DEFAULT = 0x00; +constexpr std::size_t SSP_PAGE_ALLOCATION = 8192; +constexpr std::size_t SSP_UKAD_LENGTH = 0x1e; // outputs hex in a 2 digit pair #define HEX(x) \ @@ -68,9 +56,17 @@ enum class decrypt_mode: std::uint8_t { mixed = 3u, }; +enum class kad_type: std::uint8_t { + ukad = 0u, // unauthenticated key-associated data + akad = 1u, // authenticated key-associated data + nonce = 2u, // nonce value + mkad = 3u, // metadata key-associated data + wkkad = 4u, // wrapped key key-associated data +}; + // key-associated data struct __attribute__((packed)) kad { - std::uint8_t type; + kad_type type; std::byte flags; static constexpr auto flags_authenticated_pos {0u}; static constexpr std::byte flags_authenticated_mask {7u << flags_authenticated_pos}; @@ -152,8 +148,8 @@ static_assert(sizeof(page_sde) == 20u); enum class sde_rdmc: std::uint8_t { algorithm_default = 0u << page_sde::flags_rdmc_pos, - enabled = 2u << page_sde::flags_rdmc_pos, - disabled = 3u << page_sde::flags_rdmc_pos, + enabled = 2u << page_sde::flags_rdmc_pos, // corresponds to --unprotect command line option + disabled = 3u << page_sde::flags_rdmc_pos, // corresponds to --protect command line option }; // next block encryption status page @@ -327,21 +323,18 @@ std::vector read_page_kads(const Page& page) inquiry_data get_inquiry(const std::string& device); // Get data encryption status page -void get_des(const std::string& device, const std::uint8_t *buffer, - std::size_t length); +void get_des(const std::string& device, std::uint8_t *buffer, std::size_t length); // Get next block encryption status page -void get_nbes(const std::string& device, const std::uint8_t *buffer, - std::size_t length); +void get_nbes(const std::string& device, std::uint8_t *buffer, std::size_t length); // Get device encryption capabilities -void get_dec(const std::string& device, const std::uint8_t *buffer, - std::size_t length); +void get_dec(const std::string& device, std::uint8_t *buffer, std::size_t length); // Fill out a set data encryption page with parameters. // Result is allocated and returned as a std::unique_ptr and should // be sent to the device using scsi::write_sde std::unique_ptr make_sde(encrypt_mode enc_mode, decrypt_mode dec_mode, std::uint8_t algorithm_index, - const std::vector key, + const std::vector& key, const std::string& key_name, sde_rdmc rdmc, bool ckod); // Write set data encryption parameters to device