clang-format run (#77)

* pull updated template .clang-format with `clang-format-14 --style=llvm --dump-config`, move to base directory so it is shared between `src` and `tests`
* tweak to match existing style a little (e.g. K&R style for function braces)
* run on all sources
This commit is contained in:
James Wilson
2022-05-18 14:48:31 -07:00
committed by GitHub
parent 86cca0804c
commit d2b7363769
7 changed files with 447 additions and 441 deletions

View File

@@ -3,16 +3,22 @@ Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveBitFields: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
@@ -21,10 +27,11 @@ AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
@@ -32,12 +39,14 @@ BraceWrapping:
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
@@ -52,6 +61,7 @@ ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
@@ -64,15 +74,23 @@ IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
@@ -82,6 +100,7 @@ MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
@@ -93,26 +112,39 @@ PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReferenceAlignment: Left
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
SpaceBeforeSquareBrackets: false
Standard: c++17
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
...

View File

@@ -26,9 +26,9 @@ GNU General Public License for more details.
#include <string>
#include <vector>
#include <syslog.h>
#include <sys/mtio.h>
#include <sys/stat.h>
#include <syslog.h>
#include <termios.h>
#ifdef HAVE_STDLIB_H
@@ -43,14 +43,15 @@ GNU General Public License for more details.
#include "scsiencrypt.h"
static std::optional<std::vector<std::uint8_t>> key_from_hex_chars(const std::string& s)
static std::optional<std::vector<std::uint8_t>>
key_from_hex_chars(const std::string& s)
{
auto it = s.data();
std::vector<std::uint8_t> bytes;
if (s.size() % 2) { // treated as if there is an implicit leading 0
std::uint8_t result;
auto [ptr, ec] { std::from_chars(it, it + 1, result, 16) };
auto [ptr, ec] {std::from_chars(it, it + 1, result, 16)};
if (ec != std::errc {}) {
return {};
}
@@ -60,7 +61,7 @@ static std::optional<std::vector<std::uint8_t>> key_from_hex_chars(const std::st
while (*it) {
std::uint8_t result;
auto [ptr, ec] { std::from_chars(it, it + 2, result, 16) };
auto [ptr, ec] {std::from_chars(it, it + 2, result, 16)};
if (ec != std::errc {}) {
return {};
}
@@ -71,16 +72,18 @@ static std::optional<std::vector<std::uint8_t>> key_from_hex_chars(const std::st
}
// shows the command usage
static void showUsage() {
std::cerr
<< "Usage: stenc --version | "
static void showUsage()
{
std::cerr << "Usage: stenc --version | "
"-f <device> [--detail] [-e <on/mixed/rawread/off> [-k <file>] "
"[-kd <description>] [-a <index>] [--protect | --unprotect] [--ckod] ]\n\n"
"[-kd <description>] [-a <index>] [--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) {
static void errorOut(const std::string& message)
{
std::cerr << "Error: " << message << "\n";
showUsage();
exit(EXIT_FAILURE);
@@ -90,8 +93,8 @@ static void print_algorithm_name(std::ostream& os, const uint32_t code)
{
// Reference: SFSC / INCITS 501-2016
if (0x80010400 <= code && code <= 0x8001FFFF) {
os << "Vendor specific 0x" << std::setw(8) << std::setfill('0')
<< std::hex << code;
os << "Vendor specific 0x" << std::setw(8) << std::setfill('0') << std::hex
<< code;
}
switch (code) {
case 0x0001000C:
@@ -107,12 +110,11 @@ static void print_algorithm_name(std::ostream& os, const uint32_t code)
os << "AES-256-XTS-HMAC-SHA-512";
break;
default:
os << "Unknown 0x" << std::setw(8) << std::setfill('0')
<< std::hex << code;
os << "Unknown 0x" << std::setw(8) << std::setfill('0') << std::hex << code;
}
}
static void print_algorithms(std::ostream& os, const scsi::page_dec &page)
static void print_algorithms(std::ostream& os, const scsi::page_dec& page)
{
auto algorithms {scsi::read_algorithms(page)};
@@ -125,11 +127,11 @@ static void print_algorithms(std::ostream& os, const scsi::page_dec &page)
os.put('\n');
// Print KAD capabilities and size
auto dkad_c {
static_cast<unsigned int>(ad.flags3 & scsi::algorithm_descriptor::flags3_dkad_c_mask)
};
auto dkad_c {static_cast<unsigned int>(
ad.flags3 & scsi::algorithm_descriptor::flags3_dkad_c_mask)};
if (dkad_c == 1u << scsi::algorithm_descriptor::flags3_dkad_c_pos) {
os << std::left << std::setw(5) << "" << "Key descriptors not allowed\n";
os << std::left << std::setw(5) << ""
<< "Key descriptors not allowed\n";
} else if (dkad_c) {
os << std::left << std::setw(5) << "";
if (dkad_c == 1u << scsi::algorithm_descriptor::flags3_dkad_c_pos) {
@@ -147,9 +149,8 @@ static void print_algorithms(std::ostream& os, const scsi::page_dec &page)
}
// Print raw decryption mode capability:
auto rdmc_c {
static_cast<unsigned int>(ad.flags3 & scsi::algorithm_descriptor::flags3_rdmc_c_mask)
};
auto rdmc_c {static_cast<unsigned int>(
ad.flags3 & scsi::algorithm_descriptor::flags3_rdmc_c_mask)};
switch (rdmc_c) {
case 1u << scsi::algorithm_descriptor::flags3_rdmc_c_pos:
case 6u << scsi::algorithm_descriptor::flags3_rdmc_c_pos:
@@ -171,7 +172,8 @@ static void print_algorithms(std::ostream& os, const scsi::page_dec &page)
}
}
static void print_device_inquiry(std::ostream& os, const scsi::inquiry_data& iresult)
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);
@@ -184,34 +186,43 @@ static void print_device_inquiry(std::ostream& os, const scsi::inquiry_data& ire
os.put('\n');
}
static void inquiryDrive(const std::string& tapeDevice) {
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)
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
)
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
)
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
)
opt.decryption_mode ==
scsi::decrypt_mode::off // read encrypted and unencrypted
) {
emode = "off";
}
os << emode << "\n";
if (detail) {
@@ -238,8 +249,8 @@ static void print_device_status(std::ostream& os, const scsi::page_des& opt, boo
<< "Unencrypted data outputted\n";
break;
default:
os << "Unknown '0x" << std::hex << static_cast<unsigned int>(opt.decryption_mode)
<< "' \n";
os << "Unknown '0x" << std::hex
<< static_cast<unsigned int>(opt.decryption_mode) << "' \n";
break;
}
os << std::setw(25) << "Drive Input:";
@@ -255,7 +266,8 @@ static void print_device_status(std::ostream& os, const scsi::page_des& opt, boo
<< static_cast<unsigned int>(opt.encryption_mode) << "'\n";
break;
}
if ((opt.flags & scsi::page_des::flags_rdmd_mask) == scsi::page_des::flags_rdmd_mask) {
if ((opt.flags & scsi::page_des::flags_rdmd_mask) ==
scsi::page_des::flags_rdmd_mask) {
os << std::setw(25) << " "
<< "Protecting from raw read\n";
}
@@ -272,20 +284,23 @@ static void print_device_status(std::ostream& os, const scsi::page_des& opt, boo
switch (kd->type) {
case scsi::kad_type::ukad:
os << std::setw(25) << "Drive Key Desc.(uKAD): ";
os.write(reinterpret_cast<const char *>(kd->descriptor), ntohs(kd->length));
os.write(reinterpret_cast<const char *>(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<const char *>(kd->descriptor), ntohs(kd->length));
os.write(reinterpret_cast<const char *>(kd->descriptor),
ntohs(kd->length));
os.put('\n');
break;
}
}
}
static void showDriveStatus(const std::string& tapeDrive, bool detail) {
alignas(4) scsi::page_buffer buffer {};
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<const scsi::page_des&>(buffer)};
@@ -294,10 +309,9 @@ static void showDriveStatus(const std::string& tapeDrive, bool detail) {
static void print_volume_status(std::ostream& os, const scsi::page_nbes& opt)
{
auto compression_status {
static_cast<std::uint8_t>((opt.status & scsi::page_nbes::status_compression_mask)
>> scsi::page_nbes::status_compression_pos)
};
auto compression_status {static_cast<std::uint8_t>(
(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:";
@@ -312,10 +326,9 @@ static void print_volume_status(std::ostream& os, const scsi::page_nbes& opt)
}
}
os << std::left << std::setw(25) << "Volume Encryption:";
auto encryption_status {
static_cast<std::uint8_t>((opt.status & scsi::page_nbes::status_encryption_mask)
>> scsi::page_nbes::status_encryption_pos)
};
auto encryption_status {static_cast<std::uint8_t>(
(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:
@@ -330,7 +343,8 @@ static void print_volume_status(std::ostream& os, const scsi::page_nbes& opt)
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) {
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;
@@ -340,17 +354,20 @@ static void print_volume_status(std::ostream& os, const scsi::page_nbes& opt)
switch (kd->type) {
case scsi::kad_type::ukad:
os << std::setw(25) << "Volume Key Desc.(uKAD): ";
os.write(reinterpret_cast<const char *>(kd->descriptor), ntohs(kd->length));
os.write(reinterpret_cast<const char *>(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<const char *>(kd->descriptor), ntohs(kd->length));
os.write(reinterpret_cast<const char *>(kd->descriptor),
ntohs(kd->length));
os.put('\n');
break;
}
}
if ((opt.flags & scsi::page_nbes::flags_rdmds_mask) == scsi::page_nbes::flags_rdmds_mask) {
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;
@@ -361,19 +378,22 @@ static void print_volume_status(std::ostream& os, const scsi::page_nbes& opt)
}
if (opt.algorithm_index != 0) {
os << std::left << std::setw(25)
<< "Volume Algorithm:" << static_cast<unsigned int>(opt.algorithm_index) << "\n";
<< "Volume Algorithm:" << static_cast<unsigned int>(opt.algorithm_index)
<< "\n";
}
}
static void showVolumeStatus(const std::string& tapeDrive) {
alignas(4) scsi::page_buffer buffer {};
static void showVolumeStatus(const std::string& tapeDrive)
{
alignas(4) scsi::page_buffer buffer;
scsi::get_nbes(tapeDrive, buffer, sizeof(buffer));
auto& opt {reinterpret_cast<const scsi::page_nbes&>(buffer)};
print_volume_status(std::cout, opt);
}
static void echo(bool on) {
static void echo(bool on)
{
struct termios settings {};
tcgetattr(STDIN_FILENO, &settings);
settings.c_lflag =
@@ -382,7 +402,8 @@ static void echo(bool on) {
}
#if !defined(CATCH_CONFIG_MAIN)
int main(int argc, const char **argv) {
int main(int argc, const char **argv)
{
std::string tapeDrive;
int action = 0; // 0 = status, 1 =setting param, 2 = generating key
std::string keyFile, keyDesc;
@@ -429,7 +450,7 @@ int main(int argc, const char **argv) {
// encrypt, read encrypted and unencrypted data
enc_mode = scsi::encrypt_mode::off;
dec_mode = scsi::decrypt_mode::off;
} else{
} else {
errorOut("Unknown encryption mode '" + nextCmd +
"'"); // encrypt, read encrypted and unencrypted data
}
@@ -511,9 +532,8 @@ int main(int argc, const char **argv) {
} catch (const scsi::scsi_error& err) {
// #71: ignore BLANK CHECK sense key that some drives may return
// during media access check in getting NBES
auto sense_key {
err.get_sense().flags & scsi::sense_data::flags_sense_key_mask
};
auto sense_key {err.get_sense().flags &
scsi::sense_data::flags_sense_key_mask};
if (sense_key != scsi::sense_data::blank_check) {
throw;
}
@@ -594,18 +614,20 @@ int main(int argc, const char **argv) {
<< (enc_mode != scsi::encrypt_mode::off ? "on" : "off")
<< " encryption on device '" << tapeDrive << "'..." << std::endl;
try {
auto sde_buffer {scsi::make_sde(enc_mode, dec_mode, algorithm_index,
key, key_name, rdmc, ckod)};
auto sde_buffer {scsi::make_sde(enc_mode, dec_mode, algorithm_index, key,
key_name, rdmc, ckod)};
scsi::write_sde(tapeDrive, sde_buffer.get());
alignas(4) scsi::page_buffer buffer {};
scsi::get_des(tapeDrive, buffer, sizeof(buffer));
auto& opt {reinterpret_cast<const scsi::page_des&>(buffer)};
if (enc_mode != scsi::encrypt_mode::off && opt.encryption_mode == scsi::encrypt_mode::off) {
if (enc_mode != scsi::encrypt_mode::off &&
opt.encryption_mode == scsi::encrypt_mode::off) {
errorOut("Turning encryption on for '" + tapeDrive + "' failed!");
}
if (enc_mode == scsi::encrypt_mode::off && opt.encryption_mode != scsi::encrypt_mode::off) {
if (enc_mode == scsi::encrypt_mode::off &&
opt.encryption_mode != scsi::encrypt_mode::off) {
errorOut("Turning encryption off for '" + tapeDrive + "' failed!");
}
@@ -620,7 +642,7 @@ int main(int argc, const char **argv) {
syslog(LOG_NOTICE, "%s", msg.str().c_str());
} else {
std::stringstream msg{};
std::stringstream msg {};
msg << "Encryption turned off for device '" << tapeDrive << "'.";
msg << " Key Instance: " << std::dec << ntohl(opt.key_instance_counter)

View File

@@ -34,8 +34,8 @@ GNU General Public License for more details.
#include <scsi/sg.h>
#define SCSI_TIMEOUT 5000
#elif defined(OS_FREEBSD)
#include <camlib.h>
#include <cam/scsi/scsi_message.h>
#include <camlib.h>
#define SCSI_TIMEOUT 5000
#else
#error "OS type is not set"
@@ -51,30 +51,36 @@ constexpr std::uint8_t SSP_SP_PROTOCOL_TDE = 0x20;
constexpr int RETRYCOUNT = 1;
#define BSINTTOCHAR(x) \
static_cast<std::uint8_t>((x) >> 24), \
static_cast<std::uint8_t>((x) >> 16), \
static_cast<std::uint8_t>((x) >> 8), \
static_cast<std::uint8_t>((x))
static_cast<std::uint8_t>((x) >> 24), static_cast<std::uint8_t>((x) >> 16), \
static_cast<std::uint8_t>((x) >> 8), static_cast<std::uint8_t>((x))
// generic_deleter permits the use of std::unique_ptr for RAII on non-pointer
// types like file descriptors.
template<typename T, T null_value, typename Deleter, Deleter d>
template <typename T, T null_value, typename Deleter, Deleter d>
struct generic_deleter {
class pointer {
T t;
public:
pointer() : t {null_value} {}
pointer(T t) : t {t} {}
pointer(std::nullptr_t) : t {null_value} {}
explicit operator bool() const noexcept { return t != null_value; }
friend bool operator ==(pointer lhs, pointer rhs) noexcept { return lhs.t == rhs.t; }
friend bool operator !=(pointer lhs, pointer rhs) noexcept { return !(lhs == rhs); }
friend bool operator==(pointer lhs, pointer rhs) noexcept
{
return lhs.t == rhs.t;
}
friend bool operator!=(pointer lhs, pointer rhs) noexcept
{
return !(lhs == rhs);
}
operator T() const noexcept { return t; }
};
void operator()(pointer p) const noexcept { d(p); }
};
using unique_fd = std::unique_ptr<int, generic_deleter<int, -1, decltype(&close), &close>>;
using unique_fd =
std::unique_ptr<int, generic_deleter<int, -1, decltype(&close), &close>>;
enum class scsi_direction { to_device, from_device };
@@ -95,10 +101,11 @@ static void scsi_execute(const std::string& device, const std::uint8_t *cmd_p,
cmdio.cmd_len = cmd_len;
cmdio.dxfer_direction = (direction == scsi_direction::to_device)
? SG_DXFER_TO_DEV : SG_DXFER_FROM_DEV;
? SG_DXFER_TO_DEV
: SG_DXFER_FROM_DEV;
cmdio.dxfer_len = dxfer_len;
cmdio.dxferp = dxfer_p;
cmdio.cmdp = const_cast<unsigned char*>(cmd_p);
cmdio.cmdp = const_cast<unsigned char *>(cmd_p);
cmdio.sbp = sense_buf->data();
cmdio.mx_sb_len = sizeof(decltype(sense_buf)::element_type);
cmdio.timeout = SCSI_TIMEOUT;
@@ -111,32 +118,34 @@ static void scsi_execute(const std::string& device, const std::uint8_t *cmd_p,
throw scsi::scsi_error {std::move(sense_buf)};
}
#elif defined(OS_FREEBSD)
auto dev = std::unique_ptr<struct cam_device, decltype(&cam_close_device)>
{cam_open_device(device.c_str(), O_RDWR), &cam_close_device};
auto dev = std::unique_ptr<struct cam_device, decltype(&cam_close_device)> {
cam_open_device(device.c_str(), O_RDWR), &cam_close_device};
if (dev == nullptr) {
std::ostringstream oss;
oss << "Cannot open device " << device << ": " << cam_errbuf;
throw std::runtime_error {oss.str()};
}
auto ccb = std::unique_ptr<union ccb, decltype(&cam_freeccb)>
{cam_getccb(dev.get()), &cam_freeccb};
auto ccb = std::unique_ptr<union ccb, decltype(&cam_freeccb)> {
cam_getccb(dev.get()), &cam_freeccb};
if (ccb == nullptr) {
throw std::bad_alloc {};
}
CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
cam_fill_csio(&ccb->csio, RETRYCOUNT, nullptr,
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, dxfer_p, dxfer_len, SSD_FULL_SIZE, cmd_len,
SCSI_TIMEOUT);
ccb->csio.cdb_io.cdb_ptr = const_cast<u_int8_t*>(cmd_p);
ccb->csio.cdb_io.cdb_ptr = const_cast<u_int8_t *>(cmd_p);
if (cam_send_ccb(dev.get(), ccb.get())) {
throw std::system_error {errno, std::generic_category()};
}
if (ccb->csio.scsi_status) {
auto sense_buf {std::make_unique<scsi::sense_buffer>()};
std::memcpy(sense_buf->data(), &ccb->csio.sense_data, sizeof(scsi::sense_buffer));
std::memcpy(sense_buf->data(), &ccb->csio.sense_data,
sizeof(scsi::sense_buffer));
throw scsi::scsi_error {std::move(sense_buf)};
}
#else
@@ -159,7 +168,8 @@ bool is_device_ready(const std::string& device)
}
}
void get_des(const std::string& device, 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,
@@ -172,11 +182,12 @@ void get_des(const std::string& device, std::uint8_t *buffer, std::size_t length
0,
0,
};
scsi_execute(device, spin_des_command, sizeof(spin_des_command),
buffer, length, scsi_direction::from_device);
scsi_execute(device, spin_des_command, sizeof(spin_des_command), buffer,
length, scsi_direction::from_device);
}
void get_nbes(const std::string& device, 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,
@@ -189,42 +200,44 @@ void get_nbes(const std::string& device, std::uint8_t *buffer, std::size_t lengt
0,
0,
};
scsi_execute(device, spin_nbes_command, sizeof(spin_nbes_command),
buffer, length, scsi_direction::from_device);
scsi_execute(device, spin_nbes_command, sizeof(spin_nbes_command), buffer,
length, scsi_direction::from_device);
}
void get_dec(const std::string& device, 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[] {
const std::uint8_t spin_dec_command[] {
SSP_SPIN_OPCODE,
SSP_SP_PROTOCOL_TDE,
0x00, 0x10,
0x00,
0x10,
0,
0,
BSINTTOCHAR(length),
0,
0,
};
scsi_execute(device, spin_dec_command, sizeof(spin_dec_command),
buffer, length, scsi_direction::from_device);
scsi_execute(device, spin_dec_command, sizeof(spin_dec_command), buffer,
length, scsi_direction::from_device);
}
inquiry_data get_inquiry(const std::string& device)
{
const uint8_t scsi_inq_command[] {0x12, 0, 0, 0, sizeof(inquiry_data), 0};
const std::uint8_t scsi_inq_command[] {
0x12, 0, 0, 0, sizeof(inquiry_data), 0,
};
inquiry_data inq {};
scsi_execute(device, scsi_inq_command, sizeof(scsi_inq_command),
reinterpret_cast<std::uint8_t*>(&inq), sizeof(inq),
reinterpret_cast<std::uint8_t *>(&inq), sizeof(inq),
scsi_direction::from_device);
return inq;
}
std::unique_ptr<const std::uint8_t[]> make_sde(encrypt_mode enc_mode,
decrypt_mode dec_mode,
std::uint8_t algorithm_index,
const std::vector<std::uint8_t>& key,
const std::string& key_name,
sde_rdmc rdmc, bool ckod)
std::unique_ptr<const std::uint8_t[]>
make_sde(encrypt_mode enc_mode, decrypt_mode dec_mode,
std::uint8_t algorithm_index, const std::vector<std::uint8_t>& key,
const std::string& key_name, sde_rdmc rdmc, bool ckod)
{
std::size_t length {sizeof(page_sde) + key.size()};
if (!key_name.empty()) {
@@ -235,7 +248,8 @@ std::unique_ptr<const std::uint8_t[]> make_sde(encrypt_mode enc_mode,
page.page_code = htons(0x10);
page.length = htons(length - sizeof(page_header));
page.control = std::byte {2u} << page_sde::control_scope_pos; // all IT nexus = 10b
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 {static_cast<std::underlying_type_t<sde_rdmc>>(rdmc)};
if (ckod) {
@@ -248,7 +262,8 @@ std::unique_ptr<const std::uint8_t[]> make_sde(encrypt_mode enc_mode,
std::memcpy(page.key, key.data(), key.size());
if (!key_name.empty()) {
auto &ukad {reinterpret_cast<kad&>(*(buffer.get() + sizeof(page_sde) + key.size()))};
auto& ukad {reinterpret_cast<kad&>(
*(buffer.get() + sizeof(page_sde) + key.size()))};
ukad.length = htons(key_name.size());
std::memcpy(ukad.descriptor, key_name.data(), key_name.size());
}
@@ -260,7 +275,7 @@ void write_sde(const std::string& device, const std::uint8_t *sde_buffer)
{
auto& page {reinterpret_cast<const page_sde&>(*sde_buffer)};
std::size_t length {sizeof(page_header) + ntohs(page.length)};
const uint8_t spout_sde_command[] {
const std::uint8_t spout_sde_command[] {
SSP_SPOUT_OPCODE,
SSP_SP_PROTOCOL_TDE,
0,
@@ -269,14 +284,16 @@ void write_sde(const std::string& device, const std::uint8_t *sde_buffer)
0,
BSINTTOCHAR(length),
0,
0
0,
};
scsi_execute(device, spout_sde_command, sizeof(spout_sde_command),
const_cast<std::uint8_t*>(sde_buffer), length, scsi_direction::to_device);
const_cast<std::uint8_t *>(sde_buffer), length,
scsi_direction::to_device);
}
void print_sense_data(std::ostream& os, const sense_data& sd) {
void print_sense_data(std::ostream& os, const sense_data& sd)
{
os << std::left << std::setw(25) << "Sense Code: ";
auto sense_key {sd.flags & sense_data::flags_sense_key_mask};
@@ -317,7 +334,8 @@ void print_sense_data(std::ostream& os, const sense_data& sd) {
<< "0x" << HEX(sd.additional_sense_qualifier) << "\n";
if (sd.additional_sense_length > 0) {
os << std::left << std::setw(25) << " Additional data: " << "0x";
os << std::left << std::setw(25) << " Additional data: "
<< "0x";
for (int i = 0; i < sd.additional_sense_length; i++) {
os << HEX(sd.additional_sense_bytes[i]);
@@ -336,18 +354,19 @@ void print_sense_data(std::ostream& os, const sense_data& sd) {
#endif
}
std::vector<const algorithm_descriptor*> read_algorithms(const page_dec& page)
std::vector<const algorithm_descriptor *> read_algorithms(const page_dec& page)
{
auto it {reinterpret_cast<const uint8_t*>(&page.ads[0])};
const auto end {reinterpret_cast<const uint8_t*>(&page) + ntohs(page.length) + sizeof(page_header)};
std::vector<const algorithm_descriptor*> v {};
auto it {reinterpret_cast<const std::uint8_t *>(&page.ads[0])};
const auto end {reinterpret_cast<const std::uint8_t *>(&page) +
ntohs(page.length) + sizeof(page_header)};
std::vector<const algorithm_descriptor *> v {};
while (it < end) {
auto elem {reinterpret_cast<const algorithm_descriptor*>(it)};
auto elem {reinterpret_cast<const algorithm_descriptor *>(it)};
v.push_back(elem);
it += ntohs(elem->length) + 4u; // length field + preceding 4 byte header
}
return v;
}
}
} // namespace scsi

View File

@@ -18,8 +18,8 @@ GNU General Public License for more details.
#include <array>
#include <bitset>
#include <cstdint>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
@@ -39,24 +39,25 @@ constexpr std::size_t SSP_UKAD_LENGTH = 0x1e;
// outputs hex in a 2 digit pair
#define HEX(x) \
std::right << std::setw(2) << std::setfill('0') << std::hex << (int)(x) << std::setfill(' ')
std::right << std::setw(2) << std::setfill('0') << std::hex << (int)(x) \
<< std::setfill(' ')
namespace scsi {
enum class encrypt_mode: std::uint8_t {
enum class encrypt_mode : std::uint8_t {
off = 0u,
external = 1u,
on = 2u,
};
enum class decrypt_mode: std::uint8_t {
enum class decrypt_mode : std::uint8_t {
off = 0u,
raw = 1u,
on = 2u,
mixed = 3u,
};
enum class kad_type: std::uint8_t {
enum class kad_type : std::uint8_t {
ukad = 0u, // unauthenticated key-associated data
akad = 1u, // authenticated key-associated data
nonce = 2u, // nonce value
@@ -69,7 +70,8 @@ struct __attribute__((packed)) kad {
kad_type type;
std::byte flags;
static constexpr auto flags_authenticated_pos {0u};
static constexpr std::byte flags_authenticated_mask {7u << flags_authenticated_pos};
static constexpr std::byte flags_authenticated_mask {
7u << flags_authenticated_pos};
std::uint16_t length;
std::uint8_t descriptor[];
};
@@ -97,12 +99,16 @@ struct __attribute__((packed)) page_des {
std::uint32_t key_instance_counter;
std::byte flags;
static constexpr auto flags_parameters_control_pos {4u};
static constexpr std::byte flags_parameters_control_mask {7u << flags_parameters_control_pos};
static constexpr auto flags_vcelb_pos {3u}; // volume contains encrypted logical blocks
static constexpr std::byte flags_parameters_control_mask {
7u << flags_parameters_control_pos};
// volume contains encrypted logical blocks
static constexpr auto flags_vcelb_pos {3u};
static constexpr std::byte flags_vcelb_mask {1u << flags_vcelb_pos};
static constexpr auto flags_ceems_pos {1u}; // check external encryption mode status
// check external encryption mode status
static constexpr auto flags_ceems_pos {1u};
static constexpr std::byte flags_ceems_mask {3u << flags_ceems_pos};
static constexpr auto flags_rdmd_pos {0u}; // raw decryption mode disabled
// raw decryption mode disabled
static constexpr auto flags_rdmd_pos {0u};
static constexpr std::byte flags_rdmd_mask {1u << flags_rdmd_pos};
std::uint8_t kad_format;
std::uint16_t asdk_count;
@@ -123,17 +129,23 @@ struct __attribute__((packed)) page_sde {
static constexpr auto control_lock_pos {0u};
static constexpr std::byte control_lock_mask {1u << control_lock_pos};
std::byte flags;
static constexpr auto flags_ceem_pos {6u}; // check external encryption mode
// check external encryption mode
static constexpr auto flags_ceem_pos {6u};
static constexpr std::byte flags_ceem_mask {3u << flags_ceem_pos};
static constexpr auto flags_rdmc_pos {4u}; // raw decryption mode control
// raw decryption mode control
static constexpr auto flags_rdmc_pos {4u};
static constexpr std::byte flags_rdmc_mask {3u << flags_rdmc_pos};
static constexpr auto flags_sdk_pos {3u}; // supplemental decryption key
// supplemental decryption key
static constexpr auto flags_sdk_pos {3u};
static constexpr std::byte flags_sdk_mask {1u << flags_sdk_pos};
static constexpr auto flags_ckod_pos {2u}; // clear key on demount
// clear key on demount
static constexpr auto flags_ckod_pos {2u};
static constexpr std::byte flags_ckod_mask {1u << flags_ckod_pos};
static constexpr auto flags_ckorp_pos {1u}; // clear key on reservation preempt
// clear key on reservation preempt
static constexpr auto flags_ckorp_pos {1u};
static constexpr std::byte flags_ckorp_mask {1u << flags_ckorp_pos};
static constexpr auto flags_ckorl_pos {0u}; // clear key on reservation loss
// clear key on reservation loss
static constexpr auto flags_ckorl_pos {0u};
static constexpr std::byte flags_ckorl_mask {1u << flags_ckorl_pos};
encrypt_mode encryption_mode;
decrypt_mode decryption_mode;
@@ -146,10 +158,12 @@ struct __attribute__((packed)) page_sde {
};
static_assert(sizeof(page_sde) == 20u);
enum class sde_rdmc: std::uint8_t {
enum class sde_rdmc : std::uint8_t {
algorithm_default = 0u << 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
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
@@ -159,14 +173,18 @@ struct __attribute__((packed)) page_nbes {
std::uint64_t logical_object_number;
std::byte status;
static constexpr auto status_compression_pos {4u};
static constexpr std::byte status_compression_mask {15u << status_compression_pos};
static constexpr std::byte status_compression_mask {
15u << status_compression_pos};
static constexpr auto status_encryption_pos {0u};
static constexpr std::byte status_encryption_mask {15u << status_encryption_pos};
static constexpr std::byte status_encryption_mask {15u
<< status_encryption_pos};
std::uint8_t algorithm_index;
std::byte flags;
static constexpr auto flags_emes_pos {1u}; // encryption mode external status
// encryption mode external status
static constexpr auto flags_emes_pos {1u};
static constexpr std::byte flags_emes_mask {1u << flags_emes_pos};
static constexpr auto flags_rdmds_pos {0u}; // raw decryption mode disabled status
// raw decryption mode disabled status
static constexpr auto flags_rdmds_pos {0u};
static constexpr std::byte flags_rdmds_mask {1u << flags_rdmds_pos};
std::uint8_t kad_format;
kad kads[];
@@ -178,46 +196,63 @@ struct __attribute__((packed)) algorithm_descriptor {
std::byte reserved1;
std::uint16_t length;
std::byte flags1;
static constexpr auto flags1_avfmv_pos {7u}; // algorithm valid for mounted volume
// algorithm valid for mounted volume
static constexpr auto flags1_avfmv_pos {7u};
static constexpr std::byte flags1_avfmv_mask {1u << flags1_avfmv_pos};
static constexpr auto flags1_sdk_c_pos {6u}; // supplemental decryption key capable
// supplemental decryption key capable
static constexpr auto flags1_sdk_c_pos {6u};
static constexpr std::byte flags1_sdk_c_mask {1u << flags1_sdk_c_pos};
static constexpr auto flags1_mac_c_pos {5u}; // message authentication code capable
// message authentication code capable
static constexpr auto flags1_mac_c_pos {5u};
static constexpr std::byte flags1_mac_c_mask {1u << flags1_mac_c_pos};
static constexpr auto flags1_delb_c_pos {4u}; // distinguish encrypted logical block capable
// distinguish encrypted logical block capable
static constexpr auto flags1_delb_c_pos {4u};
static constexpr std::byte flags1_delb_c_mask {1u << flags1_delb_c_pos};
static constexpr auto flags1_decrypt_c_pos {2u}; // decryption capabilities
// decryption capabilities
static constexpr auto flags1_decrypt_c_pos {2u};
static constexpr std::byte flags1_decrypt_c_mask {3u << flags1_decrypt_c_pos};
static constexpr auto flags1_encrypt_c_pos {0u}; // encryption capabilities
// encryption capabilities
static constexpr auto flags1_encrypt_c_pos {0u};
static constexpr std::byte flags1_encrypt_c_mask {3u << flags1_encrypt_c_pos};
std::byte flags2;
static constexpr auto flags2_avfcp_pos {6u}; // algorithm valid for current logical position
// algorithm valid for current logical position
static constexpr auto flags2_avfcp_pos {6u};
static constexpr std::byte flags2_avfcp_mask {3u << flags2_avfcp_pos};
static constexpr auto flags2_nonce_pos {4u}; // nonce capabilities
// nonce capabilities
static constexpr auto flags2_nonce_pos {4u};
static constexpr std::byte flags2_nonce_mask {3u << flags2_nonce_pos};
static constexpr auto flags2_kadf_c_pos {3u}; // KAD format capable
// KAD format capable
static constexpr auto flags2_kadf_c_pos {3u};
static constexpr std::byte flags2_kadf_c_mask {1u << flags2_kadf_c_pos};
static constexpr auto flags2_vcelb_c_pos {2u}; // volume contains encrypted logical blocks capable
// volume contains encrypted logical blocks capable
static constexpr auto flags2_vcelb_c_pos {2u};
static constexpr std::byte flags2_vcelb_c_mask {1u << flags2_vcelb_c_pos};
static constexpr auto flags2_ukadf_pos {1u}; // U-KAD fixed
// U-KAD fixed
static constexpr auto flags2_ukadf_pos {1u};
static constexpr std::byte flags2_ukadf_mask {1u << flags2_ukadf_pos};
static constexpr auto flags2_akadf_pos {0u}; // A-KAD fixed
// A-KAD fixed
static constexpr auto flags2_akadf_pos {0u};
static constexpr std::byte flags2_akadf_mask {1u << flags2_akadf_pos};
std::uint16_t maximum_ukad_length;
std::uint16_t maximum_akad_length;
std::uint16_t key_length;
std::byte flags3;
static constexpr auto flags3_dkad_c_pos {6u}; // decryption capabilities
// decryption capabilities
static constexpr auto flags3_dkad_c_pos {6u};
static constexpr std::byte flags3_dkad_c_mask {3u << flags3_dkad_c_pos};
static constexpr auto flags3_eemc_c_pos {4u}; // external encryption mode control capabilities
// external encryption mode control capabilities
static constexpr auto flags3_eemc_c_pos {4u};
static constexpr std::byte flags3_eemc_c_mask {3u << flags3_eemc_c_pos};
static constexpr auto flags3_rdmc_c_pos {1u}; // raw decryption mode control capabilities
// raw decryption mode control capabilities
static constexpr auto flags3_rdmc_c_pos {1u};
static constexpr std::byte flags3_rdmc_c_mask {7u << flags3_rdmc_c_pos};
static constexpr auto flags3_earem_pos {0u}; // encryption algorithm records encryption mode
// encryption algorithm records encryption mode
static constexpr auto flags3_earem_pos {0u};
static constexpr std::byte flags3_earem_mask {1u << flags3_earem_pos};
std::uint8_t maximum_eedk_count;
static constexpr auto maximum_eedk_count_pos {0u};
static constexpr std::uint8_t maximum_eedk_count_mask {15u << maximum_eedk_count_pos};
static constexpr std::uint8_t maximum_eedk_count_mask {
15u << maximum_eedk_count_pos};
std::uint16_t msdk_count;
std::uint16_t maximum_eedk_size;
std::byte reserved2[2];
@@ -230,9 +265,11 @@ struct __attribute__((packed)) page_dec {
std::uint16_t page_code;
std::uint16_t length;
std::byte flags;
static constexpr auto flags_extdecc_pos {2u}; // external data encryption control capable
// external data encryption control capable
static constexpr auto flags_extdecc_pos {2u};
static constexpr std::byte flags_extdecc_mask {3u << flags_extdecc_pos};
static constexpr auto flags_cfg_p_pos {0u}; // configuration prevented
// configuration prevented
static constexpr auto flags_cfg_p_pos {0u};
static constexpr std::byte flags_cfg_p_mask {3u << flags_cfg_p_pos};
std::byte reserved[15];
algorithm_descriptor ads[];
@@ -304,22 +341,26 @@ static_assert(sizeof(sense_data) == 18u);
// std::unique_ptr does not allow construction of fixed-sized arrays
using sense_buffer = std::array<std::uint8_t, sense_data::maximum_size>;
class scsi_error: public std::runtime_error {
public:
explicit scsi_error(std::unique_ptr<sense_buffer>&& buf) :
sense_buf {std::move(buf)}, std::runtime_error {""} {}
const sense_data& get_sense() const { return reinterpret_cast<sense_data&>(*sense_buf->data()); }
class scsi_error : public std::runtime_error {
public:
explicit scsi_error(std::unique_ptr<sense_buffer>&& buf)
: sense_buf {std::move(buf)}, std::runtime_error {""}
{}
const sense_data& get_sense() const
{
return reinterpret_cast<sense_data&>(*sense_buf->data());
}
private:
private:
std::unique_ptr<sense_buffer> sense_buf;
};
// Extract pointers to kad structures within a variable-length page.
// Page must have a page_header layout
template<typename Page>
template <typename Page>
std::vector<const kad *> read_page_kads(const Page& page)
{
const auto start {reinterpret_cast<const uint8_t*>(&page)};
const auto start {reinterpret_cast<const std::uint8_t *>(&page)};
auto it {start + sizeof(Page)};
const auto end {start + ntohs(page.length) + sizeof(page_header)};
std::vector<const kad *> v {};
@@ -337,25 +378,26 @@ bool is_device_ready(const std::string& device);
// Get SCSI inquiry data from device
inquiry_data get_inquiry(const std::string& device);
// Get data encryption status page
void get_des(const std::string& device, 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, 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, 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<const std::uint8_t[]> make_sde(encrypt_mode enc_mode,
decrypt_mode dec_mode,
std::uint8_t algorithm_index,
const std::vector<std::uint8_t>& key,
const std::string& key_name,
sde_rdmc rdmc, bool ckod);
std::unique_ptr<const std::uint8_t[]>
make_sde(encrypt_mode enc_mode, decrypt_mode dec_mode,
std::uint8_t algorithm_index, const std::vector<std::uint8_t>& key,
const std::string& key_name, sde_rdmc rdmc, bool ckod);
// Write set data encryption parameters to device
void write_sde(const std::string& device, const std::uint8_t *sde_buffer);
void print_sense_data(std::ostream& os, const sense_data& sd);
std::vector<const algorithm_descriptor*> read_algorithms(const page_dec& page);
std::vector<const algorithm_descriptor *> read_algorithms(const page_dec& page);
}
} // namespace scsi
#endif

View File

@@ -1,118 +0,0 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...

View File

@@ -19,9 +19,11 @@ TEST_CASE("Test key_from_hex_chars", "[output]")
REQUIRE(key_from_hex_chars("ab cd"s) == std::nullopt);
REQUIRE(key_from_hex_chars("a"s) == std::vector<std::uint8_t> {0x0a});
REQUIRE(key_from_hex_chars("0123456789abcdef"s) ==
std::vector<std::uint8_t> {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef});
std::vector<std::uint8_t> {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd,
0xef});
REQUIRE(key_from_hex_chars("0123456789ABCDEF"s) ==
std::vector<std::uint8_t> {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef});
std::vector<std::uint8_t> {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd,
0xef});
}
/**
@@ -33,18 +35,14 @@ TEST_CASE("Test key_from_hex_chars", "[output]")
TEST_CASE("Test SCSI inquiry output", "[output]")
{
const uint8_t response[] {
0x01, 0x80, 0x00, 0x02, 0x5b, 0x00, 0x00, 0x02,
0x41, 0x43, 0x4d, 0x45, 0x20, 0x20, 0x20, 0x20,
0x55, 0x6c, 0x74, 0x72, 0x69, 0x75, 0x6d, 0x2d,
0x31, 0x30, 0x30, 0x30, 0x20, 0x20, 0x20, 0x20,
0x31, 0x32, 0x33, 0x34, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x80, 0x00, 0x02, 0x5b, 0x00, 0x00, 0x02, 0x41, 0x43, 0x4d, 0x45,
0x20, 0x20, 0x20, 0x20, 0x55, 0x6c, 0x74, 0x72, 0x69, 0x75, 0x6d, 0x2d,
0x31, 0x30, 0x30, 0x30, 0x20, 0x20, 0x20, 0x20, 0x31, 0x32, 0x33, 0x34,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
// note: fixed width strings in output
const std::string expected_output {"\
@@ -52,16 +50,16 @@ Vendor: ACME \n\
Product ID: Ultrium-1000 \n\
Product Revision: 1234\n"s};
std::ostringstream oss;
print_device_inquiry(oss, reinterpret_cast<const scsi::inquiry_data&>(response));
print_device_inquiry(oss,
reinterpret_cast<const scsi::inquiry_data&>(response));
REQUIRE(oss.str() == expected_output);
}
TEST_CASE("SCSI get device encryption status output 1", "[output]")
{
const uint8_t page[] {
0x00, 0x20, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const std::string expected_output {"\
Drive Encryption: off\n\
@@ -77,11 +75,10 @@ Key Instance Counter: 0\n"s};
TEST_CASE("SCSI get device encryption status output 2", "[output]")
{
const uint8_t page[] {
0x00, 0x20, 0x00, 0x24, 0x42, 0x02, 0x02, 0x01,
0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0c, 0x48, 0x65, 0x6c, 0x6c,
0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
0x00, 0x20, 0x00, 0x24, 0x42, 0x02, 0x02, 0x01, 0x00, 0x00,
0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x48, 0x65,
0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
};
const std::string expected_output {"\
Drive Encryption: on\n\
@@ -112,10 +109,9 @@ Volume Encryption: Not encrypted\n"s};
TEST_CASE("Test SCSI get next block encryption status output 2", "[output]")
{
const uint8_t page[] {
0x00, 0x21, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x0c, 0x48, 0x65, 0x6c, 0x6c,
0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
0x00, 0x21, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x48, 0x65,
0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
};
const std::string expected_output {"\
Volume Encryption: Encrypted and able to decrypt\n\
@@ -128,15 +124,12 @@ Volume Algorithm: 1\n"s};
TEST_CASE("Test SCSI get data encryption capabilities output", "[output]")
{
const std::uint8_t page[] {
0x00, 0x10, 0x00, 0x3c, 0x09, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x14,
0x8a, 0x8c, 0x00, 0x20, 0x00, 0x3c, 0x00, 0x20,
0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x14, 0x02, 0x00, 0x00, 0x14,
0x8a, 0x8f, 0x00, 0x20, 0x00, 0x3c, 0x00, 0x20,
0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x10,
0x00, 0x10, 0x00, 0x3c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x14,
0x8a, 0x8c, 0x00, 0x20, 0x00, 0x3c, 0x00, 0x20, 0xed, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x14, 0x02, 0x00, 0x00, 0x14,
0x8a, 0x8f, 0x00, 0x20, 0x00, 0x3c, 0x00, 0x20, 0xd9, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10,
};
const std::string expected_output {"\
Supported algorithms:\n\

View File

@@ -18,6 +18,7 @@ using namespace std::literals::string_literals;
TEST_CASE("Disable encryption command", "[scsi]")
{
const std::uint8_t expected[] {
// clang-format off
0x00, 0x10, // page code
0x00, 0x10, // page length
0x40, // scope
@@ -28,14 +29,15 @@ TEST_CASE("Disable encryption command", "[scsi]")
0x00, // key format
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved [8]
0x00, 0x00 // key length
// clang-format on
};
std::vector<std::uint8_t> key {};
std::string key_name {};
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::off, scsi::decrypt_mode::off,
1u, key, key_name, scsi::sde_rdmc::algorithm_default,
false)};
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::off,
scsi::decrypt_mode::off, 1u, key, key_name,
scsi::sde_rdmc::algorithm_default, false)};
auto& page {reinterpret_cast<const scsi::page_sde&>(*page_buffer.get())};
REQUIRE(sizeof(scsi::page_header) + ntohs(page.length) == sizeof(expected));
REQUIRE(std::memcmp(&page, expected, sizeof(expected)) == 0);
@@ -44,6 +46,7 @@ TEST_CASE("Disable encryption command", "[scsi]")
TEST_CASE("Enable encryption command", "[scsi]")
{
const std::uint8_t expected[] {
// clang-format off
0x00, 0x10, // page code
0x00, 0x30, // page length
0x40, // scope
@@ -58,19 +61,19 @@ TEST_CASE("Enable encryption command", "[scsi]")
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
// clang-format on
};
std::vector<std::uint8_t> key {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
};
std::string key_name {};
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::on, scsi::decrypt_mode::on,
1u, key, key_name, scsi::sde_rdmc::algorithm_default,
false)};
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::on,
scsi::decrypt_mode::on, 1u, key, key_name,
scsi::sde_rdmc::algorithm_default, false)};
auto& page {reinterpret_cast<const scsi::page_sde&>(*page_buffer.get())};
REQUIRE(sizeof(scsi::page_header) + ntohs(page.length) == sizeof(expected));
REQUIRE(std::memcmp(&page, expected, sizeof(expected)) == 0);
@@ -79,6 +82,7 @@ TEST_CASE("Enable encryption command", "[scsi]")
TEST_CASE("Enable encryption command with options", "[scsi]")
{
const std::uint8_t expected[] {
// clang-format off
0x00, 0x10, // page code
0x00, 0x30, // page length
0x40, // scope
@@ -93,19 +97,19 @@ TEST_CASE("Enable encryption command with options", "[scsi]")
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
// clang-format on
};
std::vector<std::uint8_t> key {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
};
std::string key_name {};
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::on, scsi::decrypt_mode::on,
1u, key, key_name, scsi::sde_rdmc::enabled,
true)};
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::on,
scsi::decrypt_mode::on, 1u, key, key_name,
scsi::sde_rdmc::enabled, true)};
auto& page {reinterpret_cast<const scsi::page_sde&>(*page_buffer.get())};
REQUIRE(sizeof(scsi::page_header) + ntohs(page.length) == sizeof(expected));
REQUIRE(std::memcmp(&page, expected, sizeof(expected)) == 0);
@@ -114,6 +118,7 @@ TEST_CASE("Enable encryption command with options", "[scsi]")
TEST_CASE("Enable encryption command with key name", "[scsi]")
{
const std::uint8_t expected[] {
// clang-format off
0x00, 0x10, // page code
0x00, 0x40, // page length
0x40, // scope
@@ -133,20 +138,19 @@ TEST_CASE("Enable encryption command with key name", "[scsi]")
0x00, // authenticated
0x00, 0x0c, // length
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
// clang-format on
};
std::vector<std::uint8_t> key {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
};
std::string key_name {"Hello world!"s};
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::on, scsi::decrypt_mode::on,
1u, key, key_name,
scsi::sde_rdmc::algorithm_default,
false)};
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::on,
scsi::decrypt_mode::on, 1u, key, key_name,
scsi::sde_rdmc::algorithm_default, false)};
auto& page {reinterpret_cast<const scsi::page_sde&>(*page_buffer.get())};
REQUIRE(sizeof(scsi::page_header) + ntohs(page.length) == sizeof(expected));
REQUIRE(std::memcmp(&page, expected, sizeof(expected)) == 0);
@@ -163,6 +167,7 @@ TEST_CASE("Enable encryption command with key name", "[scsi]")
TEST_CASE("Interpret device encryption status page", "[scsi]")
{
const std::uint8_t buffer[] {
// clang-format off
0x00, 0x20, // page code
0x00, 0x24, // length
0x42, // nexus = 2h, key scope = 2h
@@ -180,21 +185,22 @@ TEST_CASE("Interpret device encryption status page", "[scsi]")
0x01, // authenticated
0x00, 0x0c, // length
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
// clang-format on
};
auto& page_des {reinterpret_cast<const scsi::page_des&>(buffer)};
REQUIRE(ntohs(page_des.page_code) == 0x20u);
REQUIRE(ntohs(page_des.length) == 36u);
REQUIRE((page_des.scope & scsi::page_des::scope_it_nexus_mask)
>> scsi::page_des::scope_it_nexus_pos == std::byte {2u});
REQUIRE((page_des.scope & scsi::page_des::scope_encryption_mask)
>> scsi::page_des::scope_encryption_pos == std::byte {2u});
REQUIRE((page_des.scope & scsi::page_des::scope_it_nexus_mask) ==
std::byte {2u} << scsi::page_des::scope_it_nexus_pos);
REQUIRE((page_des.scope & scsi::page_des::scope_encryption_mask) ==
std::byte {2u} << scsi::page_des::scope_encryption_pos);
REQUIRE(page_des.encryption_mode == scsi::encrypt_mode::on);
REQUIRE(page_des.decryption_mode == scsi::decrypt_mode::on);
REQUIRE(page_des.algorithm_index == 1u);
REQUIRE(ntohl(page_des.key_instance_counter) == 1u);
REQUIRE((page_des.flags & scsi::page_des::flags_parameters_control_mask)
== std::byte {1u} << scsi::page_des::flags_parameters_control_pos);
REQUIRE((page_des.flags & scsi::page_des::flags_parameters_control_mask) ==
std::byte {1u} << scsi::page_des::flags_parameters_control_pos);
REQUIRE((page_des.flags & scsi::page_des::flags_vcelb_mask) ==
scsi::page_des::flags_vcelb_mask);
REQUIRE((page_des.flags & scsi::page_des::flags_ceems_mask) == std::byte {});
@@ -202,14 +208,17 @@ TEST_CASE("Interpret device encryption status page", "[scsi]")
auto kads = read_page_kads(page_des);
REQUIRE(kads.size() == 1u);
REQUIRE((kads[0]->flags & scsi::kad::flags_authenticated_mask) == std::byte {1u});
REQUIRE((kads[0]->flags & scsi::kad::flags_authenticated_mask) ==
std::byte {1u});
REQUIRE(ntohs(kads[0]->length) == std::strlen("Hello world!"));
REQUIRE(std::memcmp(kads[0]->descriptor, "Hello world!", ntohs(kads[0]->length)) == 0);
REQUIRE(std::memcmp(kads[0]->descriptor, "Hello world!",
ntohs(kads[0]->length)) == 0);
}
TEST_CASE("Interpret next block encryption status page", "[scsi]")
{
const std::uint8_t buffer[] {
// clang-format off
0x00, 0x21, // page code
0x00, 0x1c, // length
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
@@ -222,28 +231,34 @@ TEST_CASE("Interpret next block encryption status page", "[scsi]")
0x01, // authenticated
0x00, 0x0c, // length
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
// clang-format on
};
auto& page_nbes {reinterpret_cast<const scsi::page_nbes&>(buffer)};
REQUIRE(ntohs(page_nbes.page_code) == 0x21u);
REQUIRE(ntohs(page_nbes.length) == 28u);
REQUIRE((page_nbes.status & scsi::page_nbes::status_compression_mask) == std::byte {});
REQUIRE((page_nbes.status & scsi::page_nbes::status_encryption_mask)
== std::byte {5u} << scsi::page_nbes::status_encryption_pos);
REQUIRE((page_nbes.status & scsi::page_nbes::status_compression_mask) ==
std::byte {});
REQUIRE((page_nbes.status & scsi::page_nbes::status_encryption_mask) ==
std::byte {5u} << scsi::page_nbes::status_encryption_pos);
REQUIRE(page_nbes.algorithm_index == 1u);
REQUIRE((page_nbes.flags & scsi::page_nbes::flags_emes_mask) == std::byte {});
REQUIRE((page_nbes.flags & scsi::page_nbes::flags_rdmds_mask) == std::byte {});
REQUIRE((page_nbes.flags & scsi::page_nbes::flags_rdmds_mask) ==
std::byte {});
auto kads = read_page_kads(page_nbes);
REQUIRE(kads.size() == 1u);
REQUIRE((kads[0]->flags & scsi::kad::flags_authenticated_mask) == std::byte {1u});
REQUIRE((kads[0]->flags & scsi::kad::flags_authenticated_mask) ==
std::byte {1u});
REQUIRE(ntohs(kads[0]->length) == std::strlen("Hello world!"));
REQUIRE(std::memcmp(kads[0]->descriptor, "Hello world!", ntohs(kads[0]->length)) == 0);
REQUIRE(std::memcmp(kads[0]->descriptor, "Hello world!",
ntohs(kads[0]->length)) == 0);
}
TEST_CASE("Interpret data encryption capabilties page", "[scsi]")
{
const std::uint8_t buffer[] {
// clang-format off
0x00, 0x10, // page code
0x00, 0x3c, // length
0x09, // EXTDECC and CFG_P
@@ -279,6 +294,7 @@ TEST_CASE("Interpret data encryption capabilties page", "[scsi]")
0x00, 0x00,
0x00, 0x00,
0x00, 0x01, 0x00, 0x10,
// clang-format on
};
static_assert(sizeof(buffer) == sizeof(scsi::page_dec) +
2 * sizeof(scsi::algorithm_descriptor));
@@ -337,8 +353,8 @@ TEST_CASE("Interpret data encryption capabilties page", "[scsi]")
REQUIRE((algo1.flags3 & scsi::algorithm_descriptor::flags3_earem_mask) ==
scsi::algorithm_descriptor::flags3_earem_mask);
REQUIRE((algo1.maximum_eedk_count & scsi::algorithm_descriptor::maximum_eedk_count_mask) ==
0u);
REQUIRE((algo1.maximum_eedk_count &
scsi::algorithm_descriptor::maximum_eedk_count_mask) == 0u);
REQUIRE(ntohs(algo1.msdk_count) == 0u);
REQUIRE(ntohs(algo1.maximum_eedk_size) == 0u);
REQUIRE(ntohl(algo1.security_algorithm_code) == 0x00010014u);
@@ -385,8 +401,8 @@ TEST_CASE("Interpret data encryption capabilties page", "[scsi]")
REQUIRE((algo2.flags3 & scsi::algorithm_descriptor::flags3_earem_mask) ==
scsi::algorithm_descriptor::flags3_earem_mask);
REQUIRE((algo2.maximum_eedk_count & scsi::algorithm_descriptor::maximum_eedk_count_mask) ==
0u);
REQUIRE((algo2.maximum_eedk_count &
scsi::algorithm_descriptor::maximum_eedk_count_mask) == 0u);
REQUIRE(ntohs(algo2.msdk_count) == 0u);
REQUIRE(ntohs(algo2.maximum_eedk_size) == 0u);
REQUIRE(ntohl(algo2.security_algorithm_code) == 0x00010010u);