Add unit tests and add const
This commit is contained in:
118
tests/.clang-format
Normal file
118
tests/.clang-format
Normal file
@@ -0,0 +1,118 @@
|
||||
---
|
||||
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
|
||||
...
|
||||
|
||||
4
tests/Makefile.am
Normal file
4
tests/Makefile.am
Normal file
@@ -0,0 +1,4 @@
|
||||
AM_CPPFLAGS=-I${top_srcdir}/src
|
||||
TESTS=scsi
|
||||
check_PROGRAMS=scsi
|
||||
scsi_SOURCES=catch.hpp scsi.cpp ${top_srcdir}/src/scsiencrypt.cpp
|
||||
17970
tests/catch.hpp
Normal file
17970
tests/catch.hpp
Normal file
File diff suppressed because it is too large
Load Diff
221
tests/scsi.cpp
Normal file
221
tests/scsi.cpp
Normal file
@@ -0,0 +1,221 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
#include "config.h"
|
||||
#include "scsiencrypt.h"
|
||||
|
||||
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
/**
|
||||
* Compare the SPOUT Set Data Encryption pages generated by stenc to an
|
||||
* expected output buffer based on the SCSI command spec.
|
||||
*
|
||||
* This checks that the program can correctly format command buffers that
|
||||
* reflect available input and program options.
|
||||
*/
|
||||
TEST_CASE("Disable encryption command", "[scsi]") {
|
||||
SCSIEncryptOptions opt;
|
||||
uint8_t buffer[1024] {};
|
||||
const uint8_t expected[] {
|
||||
0x00, 0x10, // page code
|
||||
0x00, 0x30, // page length
|
||||
0x40, // scope
|
||||
DEFAULT_CEEM << 6, // CEEM, CKOD, RDMC, et al.
|
||||
0x00, // encyption mode
|
||||
0x00, // decryption mode
|
||||
0x01, // algorithm index
|
||||
0x00, // key format
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved [8]
|
||||
0x00, 0x20, // key length
|
||||
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
|
||||
};
|
||||
|
||||
opt.cryptMode = CRYPTMODE_OFF;
|
||||
opt.algorithmIndex = 1;
|
||||
int pagelen = SCSIInitSDEPage(&opt, buffer);
|
||||
REQUIRE(pagelen == sizeof(expected));
|
||||
REQUIRE(memcmp(buffer, expected, sizeof(expected)) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Enable encryption command", "[scsi]") {
|
||||
SCSIEncryptOptions opt;
|
||||
uint8_t buffer[1024] {};
|
||||
const uint8_t expected[] {
|
||||
0x00, 0x10, // page code
|
||||
0x00, 0x30, // page length
|
||||
0x40, // scope
|
||||
DEFAULT_CEEM << 6, // CEEM, CKOD, RDMC, et al.
|
||||
0x02, // encyption mode
|
||||
0x02, // decryption mode
|
||||
0x01, // algorithm index
|
||||
0x00, // key format
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved [8]
|
||||
0x00, 0x20, // key length
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||
};
|
||||
|
||||
opt.cryptMode = CRYPTMODE_ON;
|
||||
opt.algorithmIndex = 1;
|
||||
opt.cryptoKey = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"s
|
||||
"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"s;
|
||||
opt.keyName = ""s;
|
||||
|
||||
int pagelen = SCSIInitSDEPage(&opt, buffer);
|
||||
REQUIRE(pagelen == sizeof(expected));
|
||||
REQUIRE(memcmp(buffer, expected, sizeof(expected)) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Enable encryption command with options", "[scsi]") {
|
||||
SCSIEncryptOptions opt;
|
||||
uint8_t buffer[1024] {};
|
||||
const uint8_t expected[] {
|
||||
0x00, 0x10, // page code
|
||||
0x00, 0x30, // page length
|
||||
0x40, // scope
|
||||
DEFAULT_CEEM << 6 | 0x24, // CEEM, CKOD, RDMC, et al.
|
||||
0x02, // encyption mode
|
||||
0x02, // decryption mode
|
||||
0x01, // algorithm index
|
||||
0x00, // key format
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved [8]
|
||||
0x00, 0x20, // key length
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||
};
|
||||
|
||||
opt.rdmc = 2;
|
||||
opt.CKOD = true;
|
||||
opt.cryptMode = CRYPTMODE_ON;
|
||||
opt.algorithmIndex = 1;
|
||||
opt.cryptoKey = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"s
|
||||
"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"s;
|
||||
opt.keyName = ""s;
|
||||
|
||||
int pagelen = SCSIInitSDEPage(&opt, buffer);
|
||||
REQUIRE(pagelen == sizeof(expected));
|
||||
REQUIRE(memcmp(buffer, expected, sizeof(expected)) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Enable encryption command with key name", "[scsi]") {
|
||||
SCSIEncryptOptions opt;
|
||||
uint8_t buffer[1024] {};
|
||||
const uint8_t expected[] {
|
||||
0x00, 0x10, // page code
|
||||
0x00, 0x40, // page length
|
||||
0x40, // scope
|
||||
DEFAULT_CEEM << 6, // CEEM, CKOD, RDMC, et al.
|
||||
0x02, // encyption mode
|
||||
0x02, // decryption mode
|
||||
0x01, // algorithm index
|
||||
0x00, // key format
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved [8]
|
||||
0x00, 0x20, // key length
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||
// KAD
|
||||
0x00, // type
|
||||
0x00, // authenticated
|
||||
0x00, 0x0c, // length
|
||||
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
|
||||
};
|
||||
|
||||
opt.cryptMode = CRYPTMODE_ON;
|
||||
opt.algorithmIndex = 1;
|
||||
opt.cryptoKey = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"s
|
||||
"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"s;
|
||||
opt.keyName = "Hello world!"s;
|
||||
|
||||
int pagelen = SCSIInitSDEPage(&opt, buffer);
|
||||
REQUIRE(pagelen == sizeof(expected));
|
||||
REQUIRE(memcmp(buffer, expected, sizeof(expected)) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the representation of the SPIN Device Encryption Status page
|
||||
* matches the values from the raw buffer. Input buffers were observed
|
||||
* from device traffic.
|
||||
*
|
||||
* This checks the SSP_DES structure layout matches the spec, especially
|
||||
* with regard to byte ordering and bitfield positions.
|
||||
*/
|
||||
TEST_CASE("Interpret device encryption status page", "[scsi]") {
|
||||
const uint8_t buffer[] {
|
||||
0x00, 0x20, // page code
|
||||
0x00, 0x24, // length
|
||||
0x42, // nexus = 2h, key scope = 2h
|
||||
0x02, // encryption mode
|
||||
0x02, // decryption mode
|
||||
0x01, // algorithm index
|
||||
0x00, 0x00, 0x00, 0x01, // key instance counter
|
||||
0x18, // parameters control = 1, VCELB = 1, CEEMS = 0, RDMD = 0
|
||||
0x00, // KAD format
|
||||
0x00, 0x00, // ADSK count
|
||||
0x00, 0x00, 0x00, 0x00, // reserved[8]
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
// KAD descriptor
|
||||
0x00, // descriptor type
|
||||
0x01, // authenticated
|
||||
0x00, 0x0c, // length
|
||||
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
|
||||
};
|
||||
|
||||
SSP_DES page(reinterpret_cast<const SSP_PAGE_BUFFER*>(buffer));
|
||||
REQUIRE(BSSHORT(page.des.pageCode) == 0x20);
|
||||
REQUIRE(BSSHORT(page.des.length) == 0x24);
|
||||
REQUIRE(page.des.nexusScope == 2);
|
||||
REQUIRE(page.des.keyScope == 2);
|
||||
REQUIRE(page.des.encryptionMode == 2);
|
||||
REQUIRE(page.des.decryptionMode == 2);
|
||||
REQUIRE(page.des.algorithmIndex == 1);
|
||||
REQUIRE(BSLONG(page.des.keyInstance) == 1);
|
||||
REQUIRE(page.des.parametersControl == 1);
|
||||
REQUIRE(page.des.VCELB == 1);
|
||||
REQUIRE(page.des.CEEMS == 0);
|
||||
REQUIRE(page.des.RDMD == 0);
|
||||
|
||||
REQUIRE(page.kads.size() == 1);
|
||||
REQUIRE(page.kads[0].authenticated == 1);
|
||||
REQUIRE(BSSHORT(page.kads[0].descriptorLength) == std::strlen("Hello world!"));
|
||||
REQUIRE(memcmp(page.kads[0].descriptor, "Hello world!", BSSHORT(page.kads[0].descriptorLength)) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Interpret next block encryption status page", "[scsi]") {
|
||||
const uint8_t buffer[] {
|
||||
0x00, 0x21, // page code
|
||||
0x00, 0x1c, // length
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x05, // compression status = 0, encryption status = 5h
|
||||
0x01, // algorithm index
|
||||
0x00, // EMES = 0, RDMDS = 0
|
||||
0x00, // KAD format
|
||||
// KAD descriptor
|
||||
0x00, // descriptor type
|
||||
0x01, // authenticated
|
||||
0x00, 0x0c, // length
|
||||
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
|
||||
};
|
||||
|
||||
SSP_NBES page(reinterpret_cast<const SSP_PAGE_BUFFER*>(buffer));
|
||||
REQUIRE(BSSHORT(page.nbes.pageCode) == 0x21);
|
||||
REQUIRE(BSSHORT(page.nbes.length) == 0x1c);
|
||||
REQUIRE(page.nbes.compressionStatus == 0);
|
||||
REQUIRE(page.nbes.encryptionStatus == 5);
|
||||
REQUIRE(page.nbes.algorithmIndex == 1);
|
||||
REQUIRE(page.nbes.EMES == 0);
|
||||
REQUIRE(page.nbes.RDMDS == 0);
|
||||
|
||||
REQUIRE(page.kads.size() == 1);
|
||||
REQUIRE(page.kads[0].authenticated == 1);
|
||||
REQUIRE(BSSHORT(page.kads[0].descriptorLength) == std::strlen("Hello world!"));
|
||||
REQUIRE(memcmp(page.kads[0].descriptor, "Hello world!", BSSHORT(page.kads[0].descriptorLength)) == 0);
|
||||
}
|
||||
Reference in New Issue
Block a user