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:
@@ -3,16 +3,22 @@ Language: Cpp
|
|||||||
# BasedOnStyle: LLVM
|
# BasedOnStyle: LLVM
|
||||||
AccessModifierOffset: -2
|
AccessModifierOffset: -2
|
||||||
AlignAfterOpenBracket: Align
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveMacros: false
|
||||||
AlignConsecutiveAssignments: false
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveBitFields: false
|
||||||
AlignConsecutiveDeclarations: false
|
AlignConsecutiveDeclarations: false
|
||||||
AlignEscapedNewlines: Right
|
AlignEscapedNewlines: Right
|
||||||
AlignOperands: true
|
AlignOperands: Align
|
||||||
AlignTrailingComments: true
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
AllowShortBlocksOnASingleLine: false
|
AllowShortEnumsOnASingleLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
AllowShortFunctionsOnASingleLine: All
|
AllowShortFunctionsOnASingleLine: All
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
AlwaysBreakAfterReturnType: None
|
AlwaysBreakAfterReturnType: None
|
||||||
@@ -20,11 +26,12 @@ AlwaysBreakBeforeMultilineStrings: false
|
|||||||
AlwaysBreakTemplateDeclarations: MultiLine
|
AlwaysBreakTemplateDeclarations: MultiLine
|
||||||
BinPackArguments: true
|
BinPackArguments: true
|
||||||
BinPackParameters: true
|
BinPackParameters: true
|
||||||
BraceWrapping:
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
AfterClass: false
|
AfterClass: false
|
||||||
AfterControlStatement: false
|
AfterControlStatement: Never
|
||||||
AfterEnum: false
|
AfterEnum: false
|
||||||
AfterFunction: false
|
AfterFunction: true
|
||||||
AfterNamespace: false
|
AfterNamespace: false
|
||||||
AfterObjCDeclaration: false
|
AfterObjCDeclaration: false
|
||||||
AfterStruct: false
|
AfterStruct: false
|
||||||
@@ -32,12 +39,14 @@ BraceWrapping:
|
|||||||
AfterExternBlock: false
|
AfterExternBlock: false
|
||||||
BeforeCatch: false
|
BeforeCatch: false
|
||||||
BeforeElse: false
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
IndentBraces: false
|
IndentBraces: false
|
||||||
SplitEmptyFunction: true
|
SplitEmptyFunction: false
|
||||||
SplitEmptyRecord: true
|
SplitEmptyRecord: false
|
||||||
SplitEmptyNamespace: true
|
SplitEmptyNamespace: false
|
||||||
BreakBeforeBinaryOperators: None
|
BreakBeforeBinaryOperators: None
|
||||||
BreakBeforeBraces: Attach
|
BreakBeforeBraces: Custom
|
||||||
BreakBeforeInheritanceComma: false
|
BreakBeforeInheritanceComma: false
|
||||||
BreakInheritanceList: BeforeColon
|
BreakInheritanceList: BeforeColon
|
||||||
BreakBeforeTernaryOperators: true
|
BreakBeforeTernaryOperators: true
|
||||||
@@ -52,27 +61,36 @@ ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
|||||||
ConstructorInitializerIndentWidth: 4
|
ConstructorInitializerIndentWidth: 4
|
||||||
ContinuationIndentWidth: 4
|
ContinuationIndentWidth: 4
|
||||||
Cpp11BracedListStyle: true
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: true
|
||||||
DerivePointerAlignment: false
|
DerivePointerAlignment: false
|
||||||
DisableFormat: false
|
DisableFormat: false
|
||||||
ExperimentalAutoDetectBinPacking: false
|
ExperimentalAutoDetectBinPacking: false
|
||||||
FixNamespaceComments: true
|
FixNamespaceComments: true
|
||||||
ForEachMacros:
|
ForEachMacros:
|
||||||
- foreach
|
- foreach
|
||||||
- Q_FOREACH
|
- Q_FOREACH
|
||||||
- BOOST_FOREACH
|
- BOOST_FOREACH
|
||||||
IncludeBlocks: Preserve
|
IncludeBlocks: Preserve
|
||||||
IncludeCategories:
|
IncludeCategories:
|
||||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
Priority: 2
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
Priority: 3
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
- Regex: '.*'
|
- Regex: '.*'
|
||||||
Priority: 1
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
IncludeIsMainRegex: '(Test)?$'
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
IndentCaseLabels: false
|
IndentCaseLabels: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentGotoLabels: true
|
||||||
IndentPPDirectives: None
|
IndentPPDirectives: None
|
||||||
|
IndentExternBlock: AfterExternBlock
|
||||||
IndentWidth: 2
|
IndentWidth: 2
|
||||||
IndentWrappedFunctionNames: false
|
IndentWrappedFunctionNames: false
|
||||||
|
InsertTrailingCommas: None
|
||||||
JavaScriptQuotes: Leave
|
JavaScriptQuotes: Leave
|
||||||
JavaScriptWrapImports: true
|
JavaScriptWrapImports: true
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
@@ -82,6 +100,7 @@ MaxEmptyLinesToKeep: 1
|
|||||||
NamespaceIndentation: None
|
NamespaceIndentation: None
|
||||||
ObjCBinPackProtocolList: Auto
|
ObjCBinPackProtocolList: Auto
|
||||||
ObjCBlockIndentWidth: 2
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCBreakBeforeNestedBlockParam: true
|
||||||
ObjCSpaceAfterProperty: false
|
ObjCSpaceAfterProperty: false
|
||||||
ObjCSpaceBeforeProtocolList: true
|
ObjCSpaceBeforeProtocolList: true
|
||||||
PenaltyBreakAssignment: 2
|
PenaltyBreakAssignment: 2
|
||||||
@@ -93,26 +112,39 @@ PenaltyBreakTemplateDeclaration: 10
|
|||||||
PenaltyExcessCharacter: 1000000
|
PenaltyExcessCharacter: 1000000
|
||||||
PenaltyReturnTypeOnItsOwnLine: 60
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
|
ReferenceAlignment: Left
|
||||||
ReflowComments: true
|
ReflowComments: true
|
||||||
SortIncludes: true
|
SortIncludes: true
|
||||||
SortUsingDeclarations: true
|
SortUsingDeclarations: true
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
SpaceAfterTemplateKeyword: true
|
SpaceAfterTemplateKeyword: true
|
||||||
SpaceBeforeAssignmentOperators: true
|
SpaceBeforeAssignmentOperators: true
|
||||||
SpaceBeforeCpp11BracedList: false
|
SpaceBeforeCpp11BracedList: true
|
||||||
SpaceBeforeCtorInitializerColon: true
|
SpaceBeforeCtorInitializerColon: true
|
||||||
SpaceBeforeInheritanceColon: true
|
SpaceBeforeInheritanceColon: true
|
||||||
SpaceBeforeParens: ControlStatements
|
SpaceBeforeParens: ControlStatements
|
||||||
SpaceBeforeRangeBasedForLoopColon: true
|
SpaceBeforeRangeBasedForLoopColon: false
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
SpaceInEmptyParentheses: false
|
SpaceInEmptyParentheses: false
|
||||||
SpacesBeforeTrailingComments: 1
|
SpacesBeforeTrailingComments: 1
|
||||||
SpacesInAngles: false
|
SpacesInAngles: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
SpacesInContainerLiterals: true
|
SpacesInContainerLiterals: true
|
||||||
SpacesInCStyleCastParentheses: false
|
SpacesInCStyleCastParentheses: false
|
||||||
SpacesInParentheses: false
|
SpacesInParentheses: false
|
||||||
SpacesInSquareBrackets: false
|
SpacesInSquareBrackets: false
|
||||||
Standard: Cpp11
|
SpaceBeforeSquareBrackets: false
|
||||||
|
Standard: c++17
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
TabWidth: 8
|
TabWidth: 8
|
||||||
|
UseCRLF: false
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- STRINGIZE
|
||||||
|
- PP_STRINGIZE
|
||||||
|
- BOOST_PP_STRINGIZE
|
||||||
...
|
...
|
||||||
|
|
||||||
164
src/main.cpp
164
src/main.cpp
@@ -26,9 +26,9 @@ GNU General Public License for more details.
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <syslog.h>
|
|
||||||
#include <sys/mtio.h>
|
#include <sys/mtio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <syslog.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
|
||||||
#ifdef HAVE_STDLIB_H
|
#ifdef HAVE_STDLIB_H
|
||||||
@@ -43,14 +43,15 @@ GNU General Public License for more details.
|
|||||||
|
|
||||||
#include "scsiencrypt.h"
|
#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();
|
auto it = s.data();
|
||||||
std::vector<std::uint8_t> bytes;
|
std::vector<std::uint8_t> bytes;
|
||||||
|
|
||||||
if (s.size() % 2) { // treated as if there is an implicit leading 0
|
if (s.size() % 2) { // treated as if there is an implicit leading 0
|
||||||
std::uint8_t result;
|
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 {}) {
|
if (ec != std::errc {}) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -60,7 +61,7 @@ static std::optional<std::vector<std::uint8_t>> key_from_hex_chars(const std::st
|
|||||||
|
|
||||||
while (*it) {
|
while (*it) {
|
||||||
std::uint8_t result;
|
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 {}) {
|
if (ec != std::errc {}) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -71,16 +72,18 @@ static std::optional<std::vector<std::uint8_t>> key_from_hex_chars(const std::st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// shows the command usage
|
// shows the command usage
|
||||||
static void showUsage() {
|
static void showUsage()
|
||||||
std::cerr
|
{
|
||||||
<< "Usage: stenc --version | "
|
std::cerr << "Usage: stenc --version | "
|
||||||
"-f <device> [--detail] [-e <on/mixed/rawread/off> [-k <file>] "
|
"-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] "
|
||||||
"Type 'man stenc' for more information.\n";
|
"[--ckod] ]\n\n"
|
||||||
|
"Type 'man stenc' for more information.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// exits to shell with an error message
|
// 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";
|
std::cerr << "Error: " << message << "\n";
|
||||||
showUsage();
|
showUsage();
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
@@ -90,8 +93,8 @@ static void print_algorithm_name(std::ostream& os, const uint32_t code)
|
|||||||
{
|
{
|
||||||
// Reference: SFSC / INCITS 501-2016
|
// Reference: SFSC / INCITS 501-2016
|
||||||
if (0x80010400 <= code && code <= 0x8001FFFF) {
|
if (0x80010400 <= code && code <= 0x8001FFFF) {
|
||||||
os << "Vendor specific 0x" << std::setw(8) << std::setfill('0')
|
os << "Vendor specific 0x" << std::setw(8) << std::setfill('0') << std::hex
|
||||||
<< std::hex << code;
|
<< code;
|
||||||
}
|
}
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case 0x0001000C:
|
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";
|
os << "AES-256-XTS-HMAC-SHA-512";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
os << "Unknown 0x" << std::setw(8) << std::setfill('0')
|
os << "Unknown 0x" << std::setw(8) << std::setfill('0') << std::hex << code;
|
||||||
<< 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)};
|
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');
|
os.put('\n');
|
||||||
|
|
||||||
// Print KAD capabilities and size
|
// Print KAD capabilities and size
|
||||||
auto dkad_c {
|
auto dkad_c {static_cast<unsigned int>(
|
||||||
static_cast<unsigned int>(ad.flags3 & scsi::algorithm_descriptor::flags3_dkad_c_mask)
|
ad.flags3 & scsi::algorithm_descriptor::flags3_dkad_c_mask)};
|
||||||
};
|
|
||||||
if (dkad_c == 1u << scsi::algorithm_descriptor::flags3_dkad_c_pos) {
|
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) {
|
} else if (dkad_c) {
|
||||||
os << std::left << std::setw(5) << "";
|
os << std::left << std::setw(5) << "";
|
||||||
if (dkad_c == 1u << scsi::algorithm_descriptor::flags3_dkad_c_pos) {
|
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:
|
// Print raw decryption mode capability:
|
||||||
auto rdmc_c {
|
auto rdmc_c {static_cast<unsigned int>(
|
||||||
static_cast<unsigned int>(ad.flags3 & scsi::algorithm_descriptor::flags3_rdmc_c_mask)
|
ad.flags3 & scsi::algorithm_descriptor::flags3_rdmc_c_mask)};
|
||||||
};
|
|
||||||
switch (rdmc_c) {
|
switch (rdmc_c) {
|
||||||
case 1u << scsi::algorithm_descriptor::flags3_rdmc_c_pos:
|
case 1u << scsi::algorithm_descriptor::flags3_rdmc_c_pos:
|
||||||
case 6u << 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 << std::left << std::setw(25) << "Vendor:";
|
||||||
os.write(iresult.vendor, 8);
|
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');
|
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()
|
// todo: std::cout should not be used outside main()
|
||||||
auto iresult {scsi::get_inquiry(tapeDevice)};
|
auto iresult {scsi::get_inquiry(tapeDevice)};
|
||||||
print_device_inquiry(std::cout, iresult);
|
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";
|
std::string emode = "unknown";
|
||||||
os << std::left << std::setw(25) << "Drive Encryption:";
|
os << std::left << std::setw(25) << "Drive Encryption:";
|
||||||
if (opt.encryption_mode == scsi::encrypt_mode::on && // encrypt
|
if (opt.encryption_mode == scsi::encrypt_mode::on && // encrypt
|
||||||
opt.decryption_mode == scsi::decrypt_mode::on // read only encrypted data
|
opt.decryption_mode == scsi::decrypt_mode::on // read only encrypted data
|
||||||
)
|
) {
|
||||||
emode = "on";
|
emode = "on";
|
||||||
|
}
|
||||||
if (opt.encryption_mode == scsi::encrypt_mode::on && // encrypt
|
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";
|
emode = "mixed";
|
||||||
|
}
|
||||||
|
|
||||||
if (opt.encryption_mode == scsi::encrypt_mode::on && // encrypt
|
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";
|
emode = "rawread";
|
||||||
|
}
|
||||||
|
|
||||||
if (opt.encryption_mode == scsi::encrypt_mode::off && // encrypt
|
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";
|
emode = "off";
|
||||||
|
}
|
||||||
|
|
||||||
os << emode << "\n";
|
os << emode << "\n";
|
||||||
if (detail) {
|
if (detail) {
|
||||||
@@ -238,8 +249,8 @@ static void print_device_status(std::ostream& os, const scsi::page_des& opt, boo
|
|||||||
<< "Unencrypted data outputted\n";
|
<< "Unencrypted data outputted\n";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
os << "Unknown '0x" << std::hex << static_cast<unsigned int>(opt.decryption_mode)
|
os << "Unknown '0x" << std::hex
|
||||||
<< "' \n";
|
<< static_cast<unsigned int>(opt.decryption_mode) << "' \n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
os << std::setw(25) << "Drive Input:";
|
os << std::setw(25) << "Drive Input:";
|
||||||
@@ -252,10 +263,11 @@ static void print_device_status(std::ostream& os, const scsi::page_des& opt, boo
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
os << "Unknown result '0x" << std::hex
|
os << "Unknown result '0x" << std::hex
|
||||||
<< static_cast<unsigned int>(opt.encryption_mode) << "'\n";
|
<< static_cast<unsigned int>(opt.encryption_mode) << "'\n";
|
||||||
break;
|
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) << " "
|
os << std::setw(25) << " "
|
||||||
<< "Protecting from raw read\n";
|
<< "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) {
|
switch (kd->type) {
|
||||||
case scsi::kad_type::ukad:
|
case scsi::kad_type::ukad:
|
||||||
os << std::setw(25) << "Drive Key Desc.(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');
|
os.put('\n');
|
||||||
break;
|
break;
|
||||||
case scsi::kad_type::akad:
|
case scsi::kad_type::akad:
|
||||||
os << std::setw(25) << "Drive Key Desc.(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');
|
os.put('\n');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void showDriveStatus(const std::string& tapeDrive, bool detail) {
|
static void showDriveStatus(const std::string& tapeDrive, bool detail)
|
||||||
alignas(4) scsi::page_buffer buffer {};
|
{
|
||||||
|
alignas(4) scsi::page_buffer buffer;
|
||||||
scsi::get_des(tapeDrive, buffer, sizeof(buffer));
|
scsi::get_des(tapeDrive, buffer, sizeof(buffer));
|
||||||
auto& opt {reinterpret_cast<const scsi::page_des&>(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)
|
static void print_volume_status(std::ostream& os, const scsi::page_nbes& opt)
|
||||||
{
|
{
|
||||||
auto compression_status {
|
auto compression_status {static_cast<std::uint8_t>(
|
||||||
static_cast<std::uint8_t>((opt.status & scsi::page_nbes::status_compression_mask)
|
(opt.status & scsi::page_nbes::status_compression_mask) >>
|
||||||
>> scsi::page_nbes::status_compression_pos)
|
scsi::page_nbes::status_compression_pos)};
|
||||||
};
|
|
||||||
// From vendor docs, no known drives actually report anything other than 0
|
// From vendor docs, no known drives actually report anything other than 0
|
||||||
if (compression_status != 0u) {
|
if (compression_status != 0u) {
|
||||||
os << std::left << std::setw(25) << "Volume Compressed:";
|
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:";
|
os << std::left << std::setw(25) << "Volume Encryption:";
|
||||||
auto encryption_status {
|
auto encryption_status {static_cast<std::uint8_t>(
|
||||||
static_cast<std::uint8_t>((opt.status & scsi::page_nbes::status_encryption_mask)
|
(opt.status & scsi::page_nbes::status_encryption_mask) >>
|
||||||
>> scsi::page_nbes::status_encryption_pos)
|
scsi::page_nbes::status_encryption_pos)};
|
||||||
};
|
|
||||||
auto kads {read_page_kads(opt)};
|
auto kads {read_page_kads(opt)};
|
||||||
switch (encryption_status) {
|
switch (encryption_status) {
|
||||||
case 0u:
|
case 0u:
|
||||||
@@ -330,7 +343,8 @@ static void print_volume_status(std::ostream& os, const scsi::page_nbes& opt)
|
|||||||
break;
|
break;
|
||||||
case 5u:
|
case 5u:
|
||||||
os << "Encrypted and able to decrypt\n";
|
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";
|
os << std::left << std::setw(25) << " Protected from raw read\n";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -340,17 +354,20 @@ static void print_volume_status(std::ostream& os, const scsi::page_nbes& opt)
|
|||||||
switch (kd->type) {
|
switch (kd->type) {
|
||||||
case scsi::kad_type::ukad:
|
case scsi::kad_type::ukad:
|
||||||
os << std::setw(25) << "Volume Key Desc.(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');
|
os.put('\n');
|
||||||
break;
|
break;
|
||||||
case scsi::kad_type::akad:
|
case scsi::kad_type::akad:
|
||||||
os << std::setw(25) << "Volume Key Desc.(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');
|
os.put('\n');
|
||||||
break;
|
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";
|
os << std::left << std::setw(25) << " Protected from raw read\n";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -361,19 +378,22 @@ static void print_volume_status(std::ostream& os, const scsi::page_nbes& opt)
|
|||||||
}
|
}
|
||||||
if (opt.algorithm_index != 0) {
|
if (opt.algorithm_index != 0) {
|
||||||
os << std::left << std::setw(25)
|
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) {
|
static void showVolumeStatus(const std::string& tapeDrive)
|
||||||
alignas(4) scsi::page_buffer buffer {};
|
{
|
||||||
|
alignas(4) scsi::page_buffer buffer;
|
||||||
scsi::get_nbes(tapeDrive, buffer, sizeof(buffer));
|
scsi::get_nbes(tapeDrive, buffer, sizeof(buffer));
|
||||||
auto& opt {reinterpret_cast<const scsi::page_nbes&>(buffer)};
|
auto& opt {reinterpret_cast<const scsi::page_nbes&>(buffer)};
|
||||||
|
|
||||||
print_volume_status(std::cout, opt);
|
print_volume_status(std::cout, opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void echo(bool on) {
|
static void echo(bool on)
|
||||||
|
{
|
||||||
struct termios settings {};
|
struct termios settings {};
|
||||||
tcgetattr(STDIN_FILENO, &settings);
|
tcgetattr(STDIN_FILENO, &settings);
|
||||||
settings.c_lflag =
|
settings.c_lflag =
|
||||||
@@ -382,7 +402,8 @@ static void echo(bool on) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(CATCH_CONFIG_MAIN)
|
#if !defined(CATCH_CONFIG_MAIN)
|
||||||
int main(int argc, const char **argv) {
|
int main(int argc, const char **argv)
|
||||||
|
{
|
||||||
std::string tapeDrive;
|
std::string tapeDrive;
|
||||||
int action = 0; // 0 = status, 1 =setting param, 2 = generating key
|
int action = 0; // 0 = status, 1 =setting param, 2 = generating key
|
||||||
std::string keyFile, keyDesc;
|
std::string keyFile, keyDesc;
|
||||||
@@ -429,11 +450,11 @@ int main(int argc, const char **argv) {
|
|||||||
// encrypt, read encrypted and unencrypted data
|
// encrypt, read encrypted and unencrypted data
|
||||||
enc_mode = scsi::encrypt_mode::off;
|
enc_mode = scsi::encrypt_mode::off;
|
||||||
dec_mode = scsi::decrypt_mode::off;
|
dec_mode = scsi::decrypt_mode::off;
|
||||||
} else{
|
} else {
|
||||||
errorOut("Unknown encryption mode '" + nextCmd +
|
errorOut("Unknown encryption mode '" + nextCmd +
|
||||||
"'"); // encrypt, read encrypted and unencrypted data
|
"'"); // encrypt, read encrypted and unencrypted data
|
||||||
}
|
}
|
||||||
i++; // skip the next argument
|
i++; // skip the next argument
|
||||||
action = 1;
|
action = 1;
|
||||||
} else if (thisCmd == "-f") {
|
} else if (thisCmd == "-f") {
|
||||||
if (nextCmd == "")
|
if (nextCmd == "")
|
||||||
@@ -498,7 +519,7 @@ int main(int argc, const char **argv) {
|
|||||||
|
|
||||||
if (action == 0) {
|
if (action == 0) {
|
||||||
std::cout << "Status for " << tapeDrive << "\n"
|
std::cout << "Status for " << tapeDrive << "\n"
|
||||||
<< "--------------------------------------------------\n";
|
<< "--------------------------------------------------\n";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (detail) {
|
if (detail) {
|
||||||
@@ -511,9 +532,8 @@ int main(int argc, const char **argv) {
|
|||||||
} catch (const scsi::scsi_error& err) {
|
} catch (const scsi::scsi_error& err) {
|
||||||
// #71: ignore BLANK CHECK sense key that some drives may return
|
// #71: ignore BLANK CHECK sense key that some drives may return
|
||||||
// during media access check in getting NBES
|
// during media access check in getting NBES
|
||||||
auto sense_key {
|
auto sense_key {err.get_sense().flags &
|
||||||
err.get_sense().flags & scsi::sense_data::flags_sense_key_mask
|
scsi::sense_data::flags_sense_key_mask};
|
||||||
};
|
|
||||||
if (sense_key != scsi::sense_data::blank_check) {
|
if (sense_key != scsi::sense_data::blank_check) {
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@@ -594,18 +614,20 @@ int main(int argc, const char **argv) {
|
|||||||
<< (enc_mode != scsi::encrypt_mode::off ? "on" : "off")
|
<< (enc_mode != scsi::encrypt_mode::off ? "on" : "off")
|
||||||
<< " encryption on device '" << tapeDrive << "'..." << std::endl;
|
<< " encryption on device '" << tapeDrive << "'..." << std::endl;
|
||||||
try {
|
try {
|
||||||
auto sde_buffer {scsi::make_sde(enc_mode, dec_mode, algorithm_index,
|
auto sde_buffer {scsi::make_sde(enc_mode, dec_mode, algorithm_index, key,
|
||||||
key, key_name, rdmc, ckod)};
|
key_name, rdmc, ckod)};
|
||||||
scsi::write_sde(tapeDrive, sde_buffer.get());
|
scsi::write_sde(tapeDrive, sde_buffer.get());
|
||||||
|
|
||||||
alignas(4) scsi::page_buffer buffer {};
|
alignas(4) scsi::page_buffer buffer {};
|
||||||
scsi::get_des(tapeDrive, buffer, sizeof(buffer));
|
scsi::get_des(tapeDrive, buffer, sizeof(buffer));
|
||||||
auto& opt {reinterpret_cast<const scsi::page_des&>(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!");
|
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!");
|
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());
|
syslog(LOG_NOTICE, "%s", msg.str().c_str());
|
||||||
} else {
|
} else {
|
||||||
std::stringstream msg{};
|
std::stringstream msg {};
|
||||||
|
|
||||||
msg << "Encryption turned off for device '" << tapeDrive << "'.";
|
msg << "Encryption turned off for device '" << tapeDrive << "'.";
|
||||||
msg << " Key Instance: " << std::dec << ntohl(opt.key_instance_counter)
|
msg << " Key Instance: " << std::dec << ntohl(opt.key_instance_counter)
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ GNU General Public License for more details.
|
|||||||
#include <scsi/sg.h>
|
#include <scsi/sg.h>
|
||||||
#define SCSI_TIMEOUT 5000
|
#define SCSI_TIMEOUT 5000
|
||||||
#elif defined(OS_FREEBSD)
|
#elif defined(OS_FREEBSD)
|
||||||
#include <camlib.h>
|
|
||||||
#include <cam/scsi/scsi_message.h>
|
#include <cam/scsi/scsi_message.h>
|
||||||
|
#include <camlib.h>
|
||||||
#define SCSI_TIMEOUT 5000
|
#define SCSI_TIMEOUT 5000
|
||||||
#else
|
#else
|
||||||
#error "OS type is not set"
|
#error "OS type is not set"
|
||||||
@@ -50,31 +50,37 @@ constexpr std::uint8_t SSP_SP_PROTOCOL_TDE = 0x20;
|
|||||||
|
|
||||||
constexpr int RETRYCOUNT = 1;
|
constexpr int RETRYCOUNT = 1;
|
||||||
|
|
||||||
#define BSINTTOCHAR(x) \
|
#define BSINTTOCHAR(x) \
|
||||||
static_cast<std::uint8_t>((x) >> 24), \
|
static_cast<std::uint8_t>((x) >> 24), static_cast<std::uint8_t>((x) >> 16), \
|
||||||
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) >> 8), \
|
|
||||||
static_cast<std::uint8_t>((x))
|
|
||||||
|
|
||||||
// generic_deleter permits the use of std::unique_ptr for RAII on non-pointer
|
// generic_deleter permits the use of std::unique_ptr for RAII on non-pointer
|
||||||
// types like file descriptors.
|
// 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 {
|
struct generic_deleter {
|
||||||
class pointer {
|
class pointer {
|
||||||
T t;
|
T t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pointer() : t {null_value} {}
|
pointer() : t {null_value} {}
|
||||||
pointer(T t) : t {t} {}
|
pointer(T t) : t {t} {}
|
||||||
pointer(std::nullptr_t) : t {null_value} {}
|
pointer(std::nullptr_t) : t {null_value} {}
|
||||||
explicit operator bool() const noexcept { return 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
|
||||||
friend bool operator !=(pointer lhs, pointer rhs) noexcept { return !(lhs == rhs); }
|
{
|
||||||
|
return lhs.t == rhs.t;
|
||||||
|
}
|
||||||
|
friend bool operator!=(pointer lhs, pointer rhs) noexcept
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
operator T() const noexcept { return t; }
|
operator T() const noexcept { return t; }
|
||||||
};
|
};
|
||||||
|
|
||||||
void operator()(pointer p) const noexcept { d(p); }
|
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 };
|
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.cmd_len = cmd_len;
|
||||||
cmdio.dxfer_direction = (direction == scsi_direction::to_device)
|
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.dxfer_len = dxfer_len;
|
||||||
cmdio.dxferp = dxfer_p;
|
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.sbp = sense_buf->data();
|
||||||
cmdio.mx_sb_len = sizeof(decltype(sense_buf)::element_type);
|
cmdio.mx_sb_len = sizeof(decltype(sense_buf)::element_type);
|
||||||
cmdio.timeout = SCSI_TIMEOUT;
|
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)};
|
throw scsi::scsi_error {std::move(sense_buf)};
|
||||||
}
|
}
|
||||||
#elif defined(OS_FREEBSD)
|
#elif defined(OS_FREEBSD)
|
||||||
auto dev = std::unique_ptr<struct cam_device, decltype(&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};
|
cam_open_device(device.c_str(), O_RDWR), &cam_close_device};
|
||||||
if (dev == nullptr) {
|
if (dev == nullptr) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "Cannot open device " << device << ": " << cam_errbuf;
|
oss << "Cannot open device " << device << ": " << cam_errbuf;
|
||||||
throw std::runtime_error {oss.str()};
|
throw std::runtime_error {oss.str()};
|
||||||
}
|
}
|
||||||
auto ccb = std::unique_ptr<union ccb, decltype(&cam_freeccb)>
|
auto ccb = std::unique_ptr<union ccb, decltype(&cam_freeccb)> {
|
||||||
{cam_getccb(dev.get()), &cam_freeccb};
|
cam_getccb(dev.get()), &cam_freeccb};
|
||||||
if (ccb == nullptr) {
|
if (ccb == nullptr) {
|
||||||
throw std::bad_alloc {};
|
throw std::bad_alloc {};
|
||||||
}
|
}
|
||||||
CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
|
CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
|
||||||
|
|
||||||
cam_fill_csio(&ccb->csio, RETRYCOUNT, nullptr,
|
cam_fill_csio(
|
||||||
CAM_PASS_ERR_RECOVER | CAM_CDB_POINTER |
|
&ccb->csio, RETRYCOUNT, nullptr,
|
||||||
(direction == scsi_direction::to_device ? CAM_DIR_OUT : CAM_DIR_IN),
|
CAM_PASS_ERR_RECOVER | CAM_CDB_POINTER |
|
||||||
MSG_SIMPLE_Q_TAG, dxfer_p, dxfer_len, SSD_FULL_SIZE, cmd_len,
|
(direction == scsi_direction::to_device ? CAM_DIR_OUT : CAM_DIR_IN),
|
||||||
SCSI_TIMEOUT);
|
MSG_SIMPLE_Q_TAG, dxfer_p, dxfer_len, SSD_FULL_SIZE, cmd_len,
|
||||||
ccb->csio.cdb_io.cdb_ptr = const_cast<u_int8_t*>(cmd_p);
|
SCSI_TIMEOUT);
|
||||||
|
ccb->csio.cdb_io.cdb_ptr = const_cast<u_int8_t *>(cmd_p);
|
||||||
if (cam_send_ccb(dev.get(), ccb.get())) {
|
if (cam_send_ccb(dev.get(), ccb.get())) {
|
||||||
throw std::system_error {errno, std::generic_category()};
|
throw std::system_error {errno, std::generic_category()};
|
||||||
}
|
}
|
||||||
if (ccb->csio.scsi_status) {
|
if (ccb->csio.scsi_status) {
|
||||||
auto sense_buf {std::make_unique<scsi::sense_buffer>()};
|
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)};
|
throw scsi::scsi_error {std::move(sense_buf)};
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -159,72 +168,76 @@ 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[] {
|
const std::uint8_t spin_des_command[] {
|
||||||
SSP_SPIN_OPCODE,
|
SSP_SPIN_OPCODE,
|
||||||
SSP_SP_PROTOCOL_TDE,
|
SSP_SP_PROTOCOL_TDE,
|
||||||
0,
|
0,
|
||||||
0X20,
|
0X20,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
BSINTTOCHAR(length),
|
BSINTTOCHAR(length),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
scsi_execute(device, spin_des_command, sizeof(spin_des_command),
|
scsi_execute(device, spin_des_command, sizeof(spin_des_command), buffer,
|
||||||
buffer, length, scsi_direction::from_device);
|
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[] {
|
const std::uint8_t spin_nbes_command[] {
|
||||||
SSP_SPIN_OPCODE,
|
SSP_SPIN_OPCODE,
|
||||||
SSP_SP_PROTOCOL_TDE,
|
SSP_SP_PROTOCOL_TDE,
|
||||||
0,
|
0,
|
||||||
0X21,
|
0X21,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
BSINTTOCHAR(length),
|
BSINTTOCHAR(length),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
scsi_execute(device, spin_nbes_command, sizeof(spin_nbes_command),
|
scsi_execute(device, spin_nbes_command, sizeof(spin_nbes_command), buffer,
|
||||||
buffer, length, scsi_direction::from_device);
|
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_SPIN_OPCODE,
|
||||||
SSP_SP_PROTOCOL_TDE,
|
SSP_SP_PROTOCOL_TDE,
|
||||||
0x00, 0x10,
|
0x00,
|
||||||
0,
|
0x10,
|
||||||
0,
|
0,
|
||||||
BSINTTOCHAR(length),
|
0,
|
||||||
0,
|
BSINTTOCHAR(length),
|
||||||
0,
|
0,
|
||||||
|
0,
|
||||||
};
|
};
|
||||||
scsi_execute(device, spin_dec_command, sizeof(spin_dec_command),
|
scsi_execute(device, spin_dec_command, sizeof(spin_dec_command), buffer,
|
||||||
buffer, length, scsi_direction::from_device);
|
length, scsi_direction::from_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
inquiry_data get_inquiry(const std::string& 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 {};
|
inquiry_data inq {};
|
||||||
scsi_execute(device, scsi_inq_command, sizeof(scsi_inq_command),
|
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);
|
scsi_direction::from_device);
|
||||||
return inq;
|
return inq;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<const std::uint8_t[]> make_sde(encrypt_mode enc_mode,
|
std::unique_ptr<const std::uint8_t[]>
|
||||||
decrypt_mode dec_mode,
|
make_sde(encrypt_mode enc_mode, decrypt_mode dec_mode,
|
||||||
std::uint8_t algorithm_index,
|
std::uint8_t algorithm_index, const std::vector<std::uint8_t>& key,
|
||||||
const std::vector<std::uint8_t>& key,
|
const std::string& key_name, sde_rdmc rdmc, bool ckod)
|
||||||
const std::string& key_name,
|
|
||||||
sde_rdmc rdmc, bool ckod)
|
|
||||||
{
|
{
|
||||||
std::size_t length {sizeof(page_sde) + key.size()};
|
std::size_t length {sizeof(page_sde) + key.size()};
|
||||||
if (!key_name.empty()) {
|
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.page_code = htons(0x10);
|
||||||
page.length = htons(length - sizeof(page_header));
|
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 {DEFAULT_CEEM} << page_sde::flags_ceem_pos;
|
||||||
page.flags |= std::byte {static_cast<std::underlying_type_t<sde_rdmc>>(rdmc)};
|
page.flags |= std::byte {static_cast<std::underlying_type_t<sde_rdmc>>(rdmc)};
|
||||||
if (ckod) {
|
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());
|
std::memcpy(page.key, key.data(), key.size());
|
||||||
|
|
||||||
if (!key_name.empty()) {
|
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());
|
ukad.length = htons(key_name.size());
|
||||||
std::memcpy(ukad.descriptor, key_name.data(), key_name.size());
|
std::memcpy(ukad.descriptor, key_name.data(), key_name.size());
|
||||||
}
|
}
|
||||||
@@ -260,23 +275,25 @@ void write_sde(const std::string& device, const std::uint8_t *sde_buffer)
|
|||||||
{
|
{
|
||||||
auto& page {reinterpret_cast<const page_sde&>(*sde_buffer)};
|
auto& page {reinterpret_cast<const page_sde&>(*sde_buffer)};
|
||||||
std::size_t length {sizeof(page_header) + ntohs(page.length)};
|
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_SPOUT_OPCODE,
|
||||||
SSP_SP_PROTOCOL_TDE,
|
SSP_SP_PROTOCOL_TDE,
|
||||||
0,
|
0,
|
||||||
0X10,
|
0X10,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
BSINTTOCHAR(length),
|
BSINTTOCHAR(length),
|
||||||
0,
|
0,
|
||||||
0
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
scsi_execute(device, spout_sde_command, sizeof(spout_sde_command),
|
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: ";
|
os << std::left << std::setw(25) << "Sense Code: ";
|
||||||
|
|
||||||
auto sense_key {sd.flags & sense_data::flags_sense_key_mask};
|
auto sense_key {sd.flags & sense_data::flags_sense_key_mask};
|
||||||
@@ -317,10 +334,11 @@ void print_sense_data(std::ostream& os, const sense_data& sd) {
|
|||||||
<< "0x" << HEX(sd.additional_sense_qualifier) << "\n";
|
<< "0x" << HEX(sd.additional_sense_qualifier) << "\n";
|
||||||
|
|
||||||
if (sd.additional_sense_length > 0) {
|
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++) {
|
for (int i = 0; i < sd.additional_sense_length; i++) {
|
||||||
os << HEX(sd.additional_sense_bytes[i]);
|
os << HEX(sd.additional_sense_bytes[i]);
|
||||||
}
|
}
|
||||||
os << "\n";
|
os << "\n";
|
||||||
}
|
}
|
||||||
@@ -336,18 +354,19 @@ void print_sense_data(std::ostream& os, const sense_data& sd) {
|
|||||||
#endif
|
#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])};
|
auto it {reinterpret_cast<const std::uint8_t *>(&page.ads[0])};
|
||||||
const auto end {reinterpret_cast<const uint8_t*>(&page) + ntohs(page.length) + sizeof(page_header)};
|
const auto end {reinterpret_cast<const std::uint8_t *>(&page) +
|
||||||
std::vector<const algorithm_descriptor*> v {};
|
ntohs(page.length) + sizeof(page_header)};
|
||||||
|
std::vector<const algorithm_descriptor *> v {};
|
||||||
|
|
||||||
while (it < end) {
|
while (it < end) {
|
||||||
auto elem {reinterpret_cast<const algorithm_descriptor*>(it)};
|
auto elem {reinterpret_cast<const algorithm_descriptor *>(it)};
|
||||||
v.push_back(elem);
|
v.push_back(elem);
|
||||||
it += ntohs(elem->length) + 4u; // length field + preceding 4 byte header
|
it += ntohs(elem->length) + 4u; // length field + preceding 4 byte header
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace scsi
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ GNU General Public License for more details.
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <cstdint>
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -39,28 +39,29 @@ constexpr std::size_t SSP_UKAD_LENGTH = 0x1e;
|
|||||||
|
|
||||||
// outputs hex in a 2 digit pair
|
// outputs hex in a 2 digit pair
|
||||||
#define HEX(x) \
|
#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 {
|
namespace scsi {
|
||||||
|
|
||||||
enum class encrypt_mode: std::uint8_t {
|
enum class encrypt_mode : std::uint8_t {
|
||||||
off = 0u,
|
off = 0u,
|
||||||
external = 1u,
|
external = 1u,
|
||||||
on = 2u,
|
on = 2u,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class decrypt_mode: std::uint8_t {
|
enum class decrypt_mode : std::uint8_t {
|
||||||
off = 0u,
|
off = 0u,
|
||||||
raw = 1u,
|
raw = 1u,
|
||||||
on = 2u,
|
on = 2u,
|
||||||
mixed = 3u,
|
mixed = 3u,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class kad_type: std::uint8_t {
|
enum class kad_type : std::uint8_t {
|
||||||
ukad = 0u, // unauthenticated key-associated data
|
ukad = 0u, // unauthenticated key-associated data
|
||||||
akad = 1u, // authenticated key-associated data
|
akad = 1u, // authenticated key-associated data
|
||||||
nonce = 2u, // nonce value
|
nonce = 2u, // nonce value
|
||||||
mkad = 3u, // metadata key-associated data
|
mkad = 3u, // metadata key-associated data
|
||||||
wkkad = 4u, // wrapped key key-associated data
|
wkkad = 4u, // wrapped key key-associated data
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,7 +70,8 @@ struct __attribute__((packed)) kad {
|
|||||||
kad_type type;
|
kad_type type;
|
||||||
std::byte flags;
|
std::byte flags;
|
||||||
static constexpr auto flags_authenticated_pos {0u};
|
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::uint16_t length;
|
||||||
std::uint8_t descriptor[];
|
std::uint8_t descriptor[];
|
||||||
};
|
};
|
||||||
@@ -97,12 +99,16 @@ struct __attribute__((packed)) page_des {
|
|||||||
std::uint32_t key_instance_counter;
|
std::uint32_t key_instance_counter;
|
||||||
std::byte flags;
|
std::byte flags;
|
||||||
static constexpr auto flags_parameters_control_pos {4u};
|
static constexpr auto flags_parameters_control_pos {4u};
|
||||||
static constexpr std::byte flags_parameters_control_mask {7u << flags_parameters_control_pos};
|
static constexpr std::byte flags_parameters_control_mask {
|
||||||
static constexpr auto flags_vcelb_pos {3u}; // volume contains encrypted logical blocks
|
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 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 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};
|
static constexpr std::byte flags_rdmd_mask {1u << flags_rdmd_pos};
|
||||||
std::uint8_t kad_format;
|
std::uint8_t kad_format;
|
||||||
std::uint16_t asdk_count;
|
std::uint16_t asdk_count;
|
||||||
@@ -123,17 +129,23 @@ struct __attribute__((packed)) page_sde {
|
|||||||
static constexpr auto control_lock_pos {0u};
|
static constexpr auto control_lock_pos {0u};
|
||||||
static constexpr std::byte control_lock_mask {1u << control_lock_pos};
|
static constexpr std::byte control_lock_mask {1u << control_lock_pos};
|
||||||
std::byte flags;
|
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 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 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 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 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 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};
|
static constexpr std::byte flags_ckorl_mask {1u << flags_ckorl_pos};
|
||||||
encrypt_mode encryption_mode;
|
encrypt_mode encryption_mode;
|
||||||
decrypt_mode decryption_mode;
|
decrypt_mode decryption_mode;
|
||||||
@@ -146,10 +158,12 @@ struct __attribute__((packed)) page_sde {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(page_sde) == 20u);
|
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,
|
algorithm_default = 0u << page_sde::flags_rdmc_pos,
|
||||||
enabled = 2u << page_sde::flags_rdmc_pos, // corresponds to --unprotect command line option
|
enabled = 2u << page_sde::flags_rdmc_pos, // corresponds to --unprotect
|
||||||
disabled = 3u << page_sde::flags_rdmc_pos, // corresponds to --protect command line option
|
// command line option
|
||||||
|
disabled = 3u << page_sde::flags_rdmc_pos, // corresponds to --protect command
|
||||||
|
// line option
|
||||||
};
|
};
|
||||||
|
|
||||||
// next block encryption status page
|
// next block encryption status page
|
||||||
@@ -159,14 +173,18 @@ struct __attribute__((packed)) page_nbes {
|
|||||||
std::uint64_t logical_object_number;
|
std::uint64_t logical_object_number;
|
||||||
std::byte status;
|
std::byte status;
|
||||||
static constexpr auto status_compression_pos {4u};
|
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 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::uint8_t algorithm_index;
|
||||||
std::byte flags;
|
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 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};
|
static constexpr std::byte flags_rdmds_mask {1u << flags_rdmds_pos};
|
||||||
std::uint8_t kad_format;
|
std::uint8_t kad_format;
|
||||||
kad kads[];
|
kad kads[];
|
||||||
@@ -178,46 +196,63 @@ struct __attribute__((packed)) algorithm_descriptor {
|
|||||||
std::byte reserved1;
|
std::byte reserved1;
|
||||||
std::uint16_t length;
|
std::uint16_t length;
|
||||||
std::byte flags1;
|
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 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 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 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 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 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};
|
static constexpr std::byte flags1_encrypt_c_mask {3u << flags1_encrypt_c_pos};
|
||||||
std::byte flags2;
|
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 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 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 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 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 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};
|
static constexpr std::byte flags2_akadf_mask {1u << flags2_akadf_pos};
|
||||||
std::uint16_t maximum_ukad_length;
|
std::uint16_t maximum_ukad_length;
|
||||||
std::uint16_t maximum_akad_length;
|
std::uint16_t maximum_akad_length;
|
||||||
std::uint16_t key_length;
|
std::uint16_t key_length;
|
||||||
std::byte flags3;
|
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 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 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 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};
|
static constexpr std::byte flags3_earem_mask {1u << flags3_earem_pos};
|
||||||
std::uint8_t maximum_eedk_count;
|
std::uint8_t maximum_eedk_count;
|
||||||
static constexpr auto maximum_eedk_count_pos {0u};
|
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 msdk_count;
|
||||||
std::uint16_t maximum_eedk_size;
|
std::uint16_t maximum_eedk_size;
|
||||||
std::byte reserved2[2];
|
std::byte reserved2[2];
|
||||||
@@ -230,9 +265,11 @@ struct __attribute__((packed)) page_dec {
|
|||||||
std::uint16_t page_code;
|
std::uint16_t page_code;
|
||||||
std::uint16_t length;
|
std::uint16_t length;
|
||||||
std::byte flags;
|
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 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};
|
static constexpr std::byte flags_cfg_p_mask {3u << flags_cfg_p_pos};
|
||||||
std::byte reserved[15];
|
std::byte reserved[15];
|
||||||
algorithm_descriptor ads[];
|
algorithm_descriptor ads[];
|
||||||
@@ -304,22 +341,26 @@ static_assert(sizeof(sense_data) == 18u);
|
|||||||
// std::unique_ptr does not allow construction of fixed-sized arrays
|
// std::unique_ptr does not allow construction of fixed-sized arrays
|
||||||
using sense_buffer = std::array<std::uint8_t, sense_data::maximum_size>;
|
using sense_buffer = std::array<std::uint8_t, sense_data::maximum_size>;
|
||||||
|
|
||||||
class scsi_error: public std::runtime_error {
|
class scsi_error : public std::runtime_error {
|
||||||
public:
|
public:
|
||||||
explicit scsi_error(std::unique_ptr<sense_buffer>&& buf) :
|
explicit scsi_error(std::unique_ptr<sense_buffer>&& buf)
|
||||||
sense_buf {std::move(buf)}, std::runtime_error {""} {}
|
: sense_buf {std::move(buf)}, std::runtime_error {""}
|
||||||
const sense_data& get_sense() const { return reinterpret_cast<sense_data&>(*sense_buf->data()); }
|
{}
|
||||||
|
const sense_data& get_sense() const
|
||||||
|
{
|
||||||
|
return reinterpret_cast<sense_data&>(*sense_buf->data());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<sense_buffer> sense_buf;
|
std::unique_ptr<sense_buffer> sense_buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extract pointers to kad structures within a variable-length page.
|
// Extract pointers to kad structures within a variable-length page.
|
||||||
// Page must have a page_header layout
|
// Page must have a page_header layout
|
||||||
template<typename Page>
|
template <typename Page>
|
||||||
std::vector<const kad *> read_page_kads(const Page& 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)};
|
auto it {start + sizeof(Page)};
|
||||||
const auto end {start + ntohs(page.length) + sizeof(page_header)};
|
const auto end {start + ntohs(page.length) + sizeof(page_header)};
|
||||||
std::vector<const kad *> v {};
|
std::vector<const kad *> v {};
|
||||||
@@ -337,25 +378,26 @@ bool is_device_ready(const std::string& device);
|
|||||||
// Get SCSI inquiry data from device
|
// Get SCSI inquiry data from device
|
||||||
inquiry_data get_inquiry(const std::string& device);
|
inquiry_data get_inquiry(const std::string& device);
|
||||||
// Get data encryption status page
|
// 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
|
// 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
|
// 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.
|
// Fill out a set data encryption page with parameters.
|
||||||
// Result is allocated and returned as a std::unique_ptr and should
|
// Result is allocated and returned as a std::unique_ptr and should
|
||||||
// be sent to the device using scsi::write_sde
|
// be sent to the device using scsi::write_sde
|
||||||
std::unique_ptr<const std::uint8_t[]> make_sde(encrypt_mode enc_mode,
|
std::unique_ptr<const std::uint8_t[]>
|
||||||
decrypt_mode dec_mode,
|
make_sde(encrypt_mode enc_mode, decrypt_mode dec_mode,
|
||||||
std::uint8_t algorithm_index,
|
std::uint8_t algorithm_index, const std::vector<std::uint8_t>& key,
|
||||||
const std::vector<std::uint8_t>& key,
|
const std::string& key_name, sde_rdmc rdmc, bool ckod);
|
||||||
const std::string& key_name,
|
|
||||||
sde_rdmc rdmc, bool ckod);
|
|
||||||
// Write set data encryption parameters to device
|
// Write set data encryption parameters to device
|
||||||
void write_sde(const std::string& device, const std::uint8_t *sde_buffer);
|
void write_sde(const std::string& device, const std::uint8_t *sde_buffer);
|
||||||
void print_sense_data(std::ostream& os, const sense_data& sd);
|
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
|
#endif
|
||||||
|
|||||||
@@ -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
|
|
||||||
...
|
|
||||||
|
|
||||||
@@ -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("ab cd"s) == std::nullopt);
|
||||||
REQUIRE(key_from_hex_chars("a"s) == std::vector<std::uint8_t> {0x0a});
|
REQUIRE(key_from_hex_chars("a"s) == std::vector<std::uint8_t> {0x0a});
|
||||||
REQUIRE(key_from_hex_chars("0123456789abcdef"s) ==
|
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) ==
|
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]")
|
TEST_CASE("Test SCSI inquiry output", "[output]")
|
||||||
{
|
{
|
||||||
const uint8_t response[] {
|
const uint8_t response[] {
|
||||||
0x01, 0x80, 0x00, 0x02, 0x5b, 0x00, 0x00, 0x02,
|
0x01, 0x80, 0x00, 0x02, 0x5b, 0x00, 0x00, 0x02, 0x41, 0x43, 0x4d, 0x45,
|
||||||
0x41, 0x43, 0x4d, 0x45, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x55, 0x6c, 0x74, 0x72, 0x69, 0x75, 0x6d, 0x2d,
|
||||||
0x55, 0x6c, 0x74, 0x72, 0x69, 0x75, 0x6d, 0x2d,
|
0x31, 0x30, 0x30, 0x30, 0x20, 0x20, 0x20, 0x20, 0x31, 0x32, 0x33, 0x34,
|
||||||
0x31, 0x30, 0x30, 0x30, 0x20, 0x20, 0x20, 0x20,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
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, 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
|
// note: fixed width strings in output
|
||||||
const std::string expected_output {"\
|
const std::string expected_output {"\
|
||||||
@@ -52,16 +50,16 @@ Vendor: ACME \n\
|
|||||||
Product ID: Ultrium-1000 \n\
|
Product ID: Ultrium-1000 \n\
|
||||||
Product Revision: 1234\n"s};
|
Product Revision: 1234\n"s};
|
||||||
std::ostringstream oss;
|
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);
|
REQUIRE(oss.str() == expected_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("SCSI get device encryption status output 1", "[output]")
|
TEST_CASE("SCSI get device encryption status output 1", "[output]")
|
||||||
{
|
{
|
||||||
const uint8_t page[] {
|
const uint8_t page[] {
|
||||||
0x00, 0x20, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x20, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
};
|
};
|
||||||
const std::string expected_output {"\
|
const std::string expected_output {"\
|
||||||
Drive Encryption: off\n\
|
Drive Encryption: off\n\
|
||||||
@@ -77,11 +75,10 @@ Key Instance Counter: 0\n"s};
|
|||||||
TEST_CASE("SCSI get device encryption status output 2", "[output]")
|
TEST_CASE("SCSI get device encryption status output 2", "[output]")
|
||||||
{
|
{
|
||||||
const uint8_t page[] {
|
const uint8_t page[] {
|
||||||
0x00, 0x20, 0x00, 0x24, 0x42, 0x02, 0x02, 0x01,
|
0x00, 0x20, 0x00, 0x24, 0x42, 0x02, 0x02, 0x01, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00,
|
0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x48, 0x65,
|
||||||
0x00, 0x00, 0x00, 0x0c, 0x48, 0x65, 0x6c, 0x6c,
|
0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
|
||||||
0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
|
|
||||||
};
|
};
|
||||||
const std::string expected_output {"\
|
const std::string expected_output {"\
|
||||||
Drive Encryption: on\n\
|
Drive Encryption: on\n\
|
||||||
@@ -99,8 +96,8 @@ Drive Key Desc.(uKAD): Hello world!\n"s};
|
|||||||
TEST_CASE("Test SCSI get next block encryption status output 1", "[output]")
|
TEST_CASE("Test SCSI get next block encryption status output 1", "[output]")
|
||||||
{
|
{
|
||||||
const uint8_t page[] {
|
const uint8_t page[] {
|
||||||
0x00, 0x21, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x21, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||||
};
|
};
|
||||||
const std::string expected_output {"\
|
const std::string expected_output {"\
|
||||||
Volume Encryption: Not encrypted\n"s};
|
Volume Encryption: Not encrypted\n"s};
|
||||||
@@ -112,10 +109,9 @@ Volume Encryption: Not encrypted\n"s};
|
|||||||
TEST_CASE("Test SCSI get next block encryption status output 2", "[output]")
|
TEST_CASE("Test SCSI get next block encryption status output 2", "[output]")
|
||||||
{
|
{
|
||||||
const uint8_t page[] {
|
const uint8_t page[] {
|
||||||
0x00, 0x21, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x21, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00,
|
0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x48, 0x65,
|
||||||
0x00, 0x01, 0x00, 0x0c, 0x48, 0x65, 0x6c, 0x6c,
|
0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
|
||||||
0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
|
|
||||||
};
|
};
|
||||||
const std::string expected_output {"\
|
const std::string expected_output {"\
|
||||||
Volume Encryption: Encrypted and able to decrypt\n\
|
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]")
|
TEST_CASE("Test SCSI get data encryption capabilities output", "[output]")
|
||||||
{
|
{
|
||||||
const std::uint8_t page[] {
|
const std::uint8_t page[] {
|
||||||
0x00, 0x10, 0x00, 0x3c, 0x09, 0x00, 0x00, 0x00,
|
0x00, 0x10, 0x00, 0x3c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x14,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x14,
|
0x8a, 0x8c, 0x00, 0x20, 0x00, 0x3c, 0x00, 0x20, 0xed, 0x00, 0x00, 0x00,
|
||||||
0x8a, 0x8c, 0x00, 0x20, 0x00, 0x3c, 0x00, 0x20,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x14, 0x02, 0x00, 0x00, 0x14,
|
||||||
0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x8a, 0x8f, 0x00, 0x20, 0x00, 0x3c, 0x00, 0x20, 0xd9, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x01, 0x00, 0x14, 0x02, 0x00, 0x00, 0x14,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10,
|
||||||
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 {"\
|
const std::string expected_output {"\
|
||||||
Supported algorithms:\n\
|
Supported algorithms:\n\
|
||||||
|
|||||||
104
tests/scsi.cpp
104
tests/scsi.cpp
@@ -18,6 +18,7 @@ using namespace std::literals::string_literals;
|
|||||||
TEST_CASE("Disable encryption command", "[scsi]")
|
TEST_CASE("Disable encryption command", "[scsi]")
|
||||||
{
|
{
|
||||||
const std::uint8_t expected[] {
|
const std::uint8_t expected[] {
|
||||||
|
// clang-format off
|
||||||
0x00, 0x10, // page code
|
0x00, 0x10, // page code
|
||||||
0x00, 0x10, // page length
|
0x00, 0x10, // page length
|
||||||
0x40, // scope
|
0x40, // scope
|
||||||
@@ -28,14 +29,15 @@ TEST_CASE("Disable encryption command", "[scsi]")
|
|||||||
0x00, // key format
|
0x00, // key format
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved [8]
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved [8]
|
||||||
0x00, 0x00 // key length
|
0x00, 0x00 // key length
|
||||||
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::uint8_t> key {};
|
std::vector<std::uint8_t> key {};
|
||||||
std::string key_name {};
|
std::string key_name {};
|
||||||
|
|
||||||
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::off, scsi::decrypt_mode::off,
|
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::off,
|
||||||
1u, key, key_name, scsi::sde_rdmc::algorithm_default,
|
scsi::decrypt_mode::off, 1u, key, key_name,
|
||||||
false)};
|
scsi::sde_rdmc::algorithm_default, false)};
|
||||||
auto& page {reinterpret_cast<const scsi::page_sde&>(*page_buffer.get())};
|
auto& page {reinterpret_cast<const scsi::page_sde&>(*page_buffer.get())};
|
||||||
REQUIRE(sizeof(scsi::page_header) + ntohs(page.length) == sizeof(expected));
|
REQUIRE(sizeof(scsi::page_header) + ntohs(page.length) == sizeof(expected));
|
||||||
REQUIRE(std::memcmp(&page, expected, sizeof(expected)) == 0);
|
REQUIRE(std::memcmp(&page, expected, sizeof(expected)) == 0);
|
||||||
@@ -44,6 +46,7 @@ TEST_CASE("Disable encryption command", "[scsi]")
|
|||||||
TEST_CASE("Enable encryption command", "[scsi]")
|
TEST_CASE("Enable encryption command", "[scsi]")
|
||||||
{
|
{
|
||||||
const std::uint8_t expected[] {
|
const std::uint8_t expected[] {
|
||||||
|
// clang-format off
|
||||||
0x00, 0x10, // page code
|
0x00, 0x10, // page code
|
||||||
0x00, 0x30, // page length
|
0x00, 0x30, // page length
|
||||||
0x40, // scope
|
0x40, // scope
|
||||||
@@ -58,19 +61,19 @@ TEST_CASE("Enable encryption command", "[scsi]")
|
|||||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||||
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::uint8_t> key {
|
std::vector<std::uint8_t> key {
|
||||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
|
||||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
|
||||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
|
||||||
};
|
};
|
||||||
std::string key_name {};
|
std::string key_name {};
|
||||||
|
|
||||||
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::on, scsi::decrypt_mode::on,
|
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::on,
|
||||||
1u, key, key_name, scsi::sde_rdmc::algorithm_default,
|
scsi::decrypt_mode::on, 1u, key, key_name,
|
||||||
false)};
|
scsi::sde_rdmc::algorithm_default, false)};
|
||||||
auto& page {reinterpret_cast<const scsi::page_sde&>(*page_buffer.get())};
|
auto& page {reinterpret_cast<const scsi::page_sde&>(*page_buffer.get())};
|
||||||
REQUIRE(sizeof(scsi::page_header) + ntohs(page.length) == sizeof(expected));
|
REQUIRE(sizeof(scsi::page_header) + ntohs(page.length) == sizeof(expected));
|
||||||
REQUIRE(std::memcmp(&page, expected, sizeof(expected)) == 0);
|
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]")
|
TEST_CASE("Enable encryption command with options", "[scsi]")
|
||||||
{
|
{
|
||||||
const std::uint8_t expected[] {
|
const std::uint8_t expected[] {
|
||||||
|
// clang-format off
|
||||||
0x00, 0x10, // page code
|
0x00, 0x10, // page code
|
||||||
0x00, 0x30, // page length
|
0x00, 0x30, // page length
|
||||||
0x40, // scope
|
0x40, // scope
|
||||||
@@ -93,19 +97,19 @@ TEST_CASE("Enable encryption command with options", "[scsi]")
|
|||||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||||
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::uint8_t> key {
|
std::vector<std::uint8_t> key {
|
||||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
|
||||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
|
||||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
|
||||||
};
|
};
|
||||||
std::string key_name {};
|
std::string key_name {};
|
||||||
|
|
||||||
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::on, scsi::decrypt_mode::on,
|
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::on,
|
||||||
1u, key, key_name, scsi::sde_rdmc::enabled,
|
scsi::decrypt_mode::on, 1u, key, key_name,
|
||||||
true)};
|
scsi::sde_rdmc::enabled, true)};
|
||||||
auto& page {reinterpret_cast<const scsi::page_sde&>(*page_buffer.get())};
|
auto& page {reinterpret_cast<const scsi::page_sde&>(*page_buffer.get())};
|
||||||
REQUIRE(sizeof(scsi::page_header) + ntohs(page.length) == sizeof(expected));
|
REQUIRE(sizeof(scsi::page_header) + ntohs(page.length) == sizeof(expected));
|
||||||
REQUIRE(std::memcmp(&page, expected, sizeof(expected)) == 0);
|
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]")
|
TEST_CASE("Enable encryption command with key name", "[scsi]")
|
||||||
{
|
{
|
||||||
const std::uint8_t expected[] {
|
const std::uint8_t expected[] {
|
||||||
|
// clang-format off
|
||||||
0x00, 0x10, // page code
|
0x00, 0x10, // page code
|
||||||
0x00, 0x40, // page length
|
0x00, 0x40, // page length
|
||||||
0x40, // scope
|
0x40, // scope
|
||||||
@@ -133,20 +138,19 @@ TEST_CASE("Enable encryption command with key name", "[scsi]")
|
|||||||
0x00, // authenticated
|
0x00, // authenticated
|
||||||
0x00, 0x0c, // length
|
0x00, 0x0c, // length
|
||||||
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
|
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
|
||||||
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::uint8_t> key {
|
std::vector<std::uint8_t> key {
|
||||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
|
||||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
|
||||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
|
||||||
};
|
};
|
||||||
std::string key_name {"Hello world!"s};
|
std::string key_name {"Hello world!"s};
|
||||||
|
|
||||||
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::on, scsi::decrypt_mode::on,
|
auto page_buffer {scsi::make_sde(scsi::encrypt_mode::on,
|
||||||
1u, key, key_name,
|
scsi::decrypt_mode::on, 1u, key, key_name,
|
||||||
scsi::sde_rdmc::algorithm_default,
|
scsi::sde_rdmc::algorithm_default, false)};
|
||||||
false)};
|
|
||||||
auto& page {reinterpret_cast<const scsi::page_sde&>(*page_buffer.get())};
|
auto& page {reinterpret_cast<const scsi::page_sde&>(*page_buffer.get())};
|
||||||
REQUIRE(sizeof(scsi::page_header) + ntohs(page.length) == sizeof(expected));
|
REQUIRE(sizeof(scsi::page_header) + ntohs(page.length) == sizeof(expected));
|
||||||
REQUIRE(std::memcmp(&page, expected, sizeof(expected)) == 0);
|
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]")
|
TEST_CASE("Interpret device encryption status page", "[scsi]")
|
||||||
{
|
{
|
||||||
const std::uint8_t buffer[] {
|
const std::uint8_t buffer[] {
|
||||||
|
// clang-format off
|
||||||
0x00, 0x20, // page code
|
0x00, 0x20, // page code
|
||||||
0x00, 0x24, // length
|
0x00, 0x24, // length
|
||||||
0x42, // nexus = 2h, key scope = 2h
|
0x42, // nexus = 2h, key scope = 2h
|
||||||
@@ -180,21 +185,22 @@ TEST_CASE("Interpret device encryption status page", "[scsi]")
|
|||||||
0x01, // authenticated
|
0x01, // authenticated
|
||||||
0x00, 0x0c, // length
|
0x00, 0x0c, // length
|
||||||
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
|
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)};
|
auto& page_des {reinterpret_cast<const scsi::page_des&>(buffer)};
|
||||||
REQUIRE(ntohs(page_des.page_code) == 0x20u);
|
REQUIRE(ntohs(page_des.page_code) == 0x20u);
|
||||||
REQUIRE(ntohs(page_des.length) == 36u);
|
REQUIRE(ntohs(page_des.length) == 36u);
|
||||||
REQUIRE((page_des.scope & scsi::page_des::scope_it_nexus_mask)
|
REQUIRE((page_des.scope & scsi::page_des::scope_it_nexus_mask) ==
|
||||||
>> scsi::page_des::scope_it_nexus_pos == std::byte {2u});
|
std::byte {2u} << scsi::page_des::scope_it_nexus_pos);
|
||||||
REQUIRE((page_des.scope & scsi::page_des::scope_encryption_mask)
|
REQUIRE((page_des.scope & scsi::page_des::scope_encryption_mask) ==
|
||||||
>> scsi::page_des::scope_encryption_pos == std::byte {2u});
|
std::byte {2u} << scsi::page_des::scope_encryption_pos);
|
||||||
REQUIRE(page_des.encryption_mode == scsi::encrypt_mode::on);
|
REQUIRE(page_des.encryption_mode == scsi::encrypt_mode::on);
|
||||||
REQUIRE(page_des.decryption_mode == scsi::decrypt_mode::on);
|
REQUIRE(page_des.decryption_mode == scsi::decrypt_mode::on);
|
||||||
REQUIRE(page_des.algorithm_index == 1u);
|
REQUIRE(page_des.algorithm_index == 1u);
|
||||||
REQUIRE(ntohl(page_des.key_instance_counter) == 1u);
|
REQUIRE(ntohl(page_des.key_instance_counter) == 1u);
|
||||||
REQUIRE((page_des.flags & scsi::page_des::flags_parameters_control_mask)
|
REQUIRE((page_des.flags & scsi::page_des::flags_parameters_control_mask) ==
|
||||||
== std::byte {1u} << scsi::page_des::flags_parameters_control_pos);
|
std::byte {1u} << scsi::page_des::flags_parameters_control_pos);
|
||||||
REQUIRE((page_des.flags & scsi::page_des::flags_vcelb_mask) ==
|
REQUIRE((page_des.flags & scsi::page_des::flags_vcelb_mask) ==
|
||||||
scsi::page_des::flags_vcelb_mask);
|
scsi::page_des::flags_vcelb_mask);
|
||||||
REQUIRE((page_des.flags & scsi::page_des::flags_ceems_mask) == std::byte {});
|
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);
|
auto kads = read_page_kads(page_des);
|
||||||
REQUIRE(kads.size() == 1u);
|
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(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]")
|
TEST_CASE("Interpret next block encryption status page", "[scsi]")
|
||||||
{
|
{
|
||||||
const std::uint8_t buffer[] {
|
const std::uint8_t buffer[] {
|
||||||
|
// clang-format off
|
||||||
0x00, 0x21, // page code
|
0x00, 0x21, // page code
|
||||||
0x00, 0x1c, // length
|
0x00, 0x1c, // length
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||||
@@ -222,28 +231,34 @@ TEST_CASE("Interpret next block encryption status page", "[scsi]")
|
|||||||
0x01, // authenticated
|
0x01, // authenticated
|
||||||
0x00, 0x0c, // length
|
0x00, 0x0c, // length
|
||||||
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
|
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)};
|
auto& page_nbes {reinterpret_cast<const scsi::page_nbes&>(buffer)};
|
||||||
REQUIRE(ntohs(page_nbes.page_code) == 0x21u);
|
REQUIRE(ntohs(page_nbes.page_code) == 0x21u);
|
||||||
REQUIRE(ntohs(page_nbes.length) == 28u);
|
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_compression_mask) ==
|
||||||
REQUIRE((page_nbes.status & scsi::page_nbes::status_encryption_mask)
|
std::byte {});
|
||||||
== std::byte {5u} << scsi::page_nbes::status_encryption_pos);
|
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.algorithm_index == 1u);
|
||||||
REQUIRE((page_nbes.flags & scsi::page_nbes::flags_emes_mask) == std::byte {});
|
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);
|
auto kads = read_page_kads(page_nbes);
|
||||||
REQUIRE(kads.size() == 1u);
|
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(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]")
|
TEST_CASE("Interpret data encryption capabilties page", "[scsi]")
|
||||||
{
|
{
|
||||||
const std::uint8_t buffer[] {
|
const std::uint8_t buffer[] {
|
||||||
|
// clang-format off
|
||||||
0x00, 0x10, // page code
|
0x00, 0x10, // page code
|
||||||
0x00, 0x3c, // length
|
0x00, 0x3c, // length
|
||||||
0x09, // EXTDECC and CFG_P
|
0x09, // EXTDECC and CFG_P
|
||||||
@@ -279,9 +294,10 @@ TEST_CASE("Interpret data encryption capabilties page", "[scsi]")
|
|||||||
0x00, 0x00,
|
0x00, 0x00,
|
||||||
0x00, 0x00,
|
0x00, 0x00,
|
||||||
0x00, 0x01, 0x00, 0x10,
|
0x00, 0x01, 0x00, 0x10,
|
||||||
|
// clang-format on
|
||||||
};
|
};
|
||||||
static_assert(sizeof(buffer) == sizeof(scsi::page_dec) +
|
static_assert(sizeof(buffer) == sizeof(scsi::page_dec) +
|
||||||
2 * sizeof(scsi::algorithm_descriptor));
|
2 * sizeof(scsi::algorithm_descriptor));
|
||||||
|
|
||||||
auto& page_dec {reinterpret_cast<const scsi::page_dec&>(buffer)};
|
auto& page_dec {reinterpret_cast<const scsi::page_dec&>(buffer)};
|
||||||
REQUIRE(ntohs(page_dec.page_code) == 0x10u);
|
REQUIRE(ntohs(page_dec.page_code) == 0x10u);
|
||||||
@@ -337,8 +353,8 @@ TEST_CASE("Interpret data encryption capabilties page", "[scsi]")
|
|||||||
REQUIRE((algo1.flags3 & scsi::algorithm_descriptor::flags3_earem_mask) ==
|
REQUIRE((algo1.flags3 & scsi::algorithm_descriptor::flags3_earem_mask) ==
|
||||||
scsi::algorithm_descriptor::flags3_earem_mask);
|
scsi::algorithm_descriptor::flags3_earem_mask);
|
||||||
|
|
||||||
REQUIRE((algo1.maximum_eedk_count & scsi::algorithm_descriptor::maximum_eedk_count_mask) ==
|
REQUIRE((algo1.maximum_eedk_count &
|
||||||
0u);
|
scsi::algorithm_descriptor::maximum_eedk_count_mask) == 0u);
|
||||||
REQUIRE(ntohs(algo1.msdk_count) == 0u);
|
REQUIRE(ntohs(algo1.msdk_count) == 0u);
|
||||||
REQUIRE(ntohs(algo1.maximum_eedk_size) == 0u);
|
REQUIRE(ntohs(algo1.maximum_eedk_size) == 0u);
|
||||||
REQUIRE(ntohl(algo1.security_algorithm_code) == 0x00010014u);
|
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) ==
|
REQUIRE((algo2.flags3 & scsi::algorithm_descriptor::flags3_earem_mask) ==
|
||||||
scsi::algorithm_descriptor::flags3_earem_mask);
|
scsi::algorithm_descriptor::flags3_earem_mask);
|
||||||
|
|
||||||
REQUIRE((algo2.maximum_eedk_count & scsi::algorithm_descriptor::maximum_eedk_count_mask) ==
|
REQUIRE((algo2.maximum_eedk_count &
|
||||||
0u);
|
scsi::algorithm_descriptor::maximum_eedk_count_mask) == 0u);
|
||||||
REQUIRE(ntohs(algo2.msdk_count) == 0u);
|
REQUIRE(ntohs(algo2.msdk_count) == 0u);
|
||||||
REQUIRE(ntohs(algo2.maximum_eedk_size) == 0u);
|
REQUIRE(ntohs(algo2.maximum_eedk_size) == 0u);
|
||||||
REQUIRE(ntohl(algo2.security_algorithm_code) == 0x00010010u);
|
REQUIRE(ntohl(algo2.security_algorithm_code) == 0x00010010u);
|
||||||
|
|||||||
Reference in New Issue
Block a user