Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
708932b383 | ||
|
|
226c5bcef0 | ||
|
|
4a7b143d50 | ||
|
|
ff413aac3e | ||
|
|
f1a36eba42 | ||
|
|
844306dbe4 |
4
.github/workflows/c-cpp.yml
vendored
4
.github/workflows/c-cpp.yml
vendored
@@ -23,7 +23,3 @@ jobs:
|
||||
run: make check
|
||||
- name: make distcheck
|
||||
run: make distcheck
|
||||
- name: make check
|
||||
run: make check
|
||||
- name: make distcheck
|
||||
run: make distcheck
|
||||
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -30,6 +30,10 @@
|
||||
*.out
|
||||
*.app
|
||||
src/stenc
|
||||
tests/scsi
|
||||
|
||||
# dist outputs
|
||||
*.tar.gz
|
||||
|
||||
# Generated Makefile
|
||||
# (meta build system like autotools,
|
||||
@@ -57,6 +61,7 @@ autom4te.cache
|
||||
/compile
|
||||
/config.cache
|
||||
/config.guess
|
||||
/config.h
|
||||
/config.h.in
|
||||
/config.log
|
||||
/config.status
|
||||
@@ -67,3 +72,6 @@ autom4te.cache
|
||||
/install-sh
|
||||
/missing
|
||||
/stamp-h1
|
||||
|
||||
/tests/*.log
|
||||
/tests/*.trs
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
2022-04-25 Jonas Stein <news@jonasstein.de>
|
||||
* Version upgraded to 1.1.1
|
||||
* Testframework Catch added
|
||||
* Fixed bug (mixed HEX macro and std::hex)
|
||||
* More constants marked with const
|
||||
|
||||
2022-04-22 Jonas Stein <news@jonasstein.de>
|
||||
* Version upgraded to 1.1.0
|
||||
* Code cleanup
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
SUBDIRS = src man
|
||||
SUBDIRS = src man tests
|
||||
# EXTRA_DIST = buildconf
|
||||
|
||||
@@ -26,7 +26,8 @@ Get the source code and compile
|
||||
git clone git@github.com:scsitape/stenc.git
|
||||
cd stenc/
|
||||
autoreconf --install
|
||||
./configure
|
||||
./autogen.sh && ./configure
|
||||
make check # optionally run the catch testing framework
|
||||
make
|
||||
```
|
||||
|
||||
@@ -37,7 +38,7 @@ Linux Packages
|
||||
|
||||
License
|
||||
-------
|
||||
Program copyright 2012-2018 contributing authors.
|
||||
Program copyright 2012-2022 contributing authors.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
AC_INIT([stenc],[1.1.0])
|
||||
AC_CONFIG_SRCDIR([src/main.cpp])
|
||||
AM_INIT_AUTOMAKE([foreign])
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CHECK_HEADER([sys/types.h])
|
||||
@@ -105,6 +105,6 @@ fi
|
||||
|
||||
|
||||
|
||||
AC_CONFIG_FILES([Makefile src/Makefile man/Makefile])
|
||||
AC_CONFIG_FILES([Makefile src/Makefile man/Makefile tests/Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
|
||||
@@ -602,7 +602,7 @@ std::string randomKey(int length) {
|
||||
if (random.is_open()) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
random.read(reinterpret_cast<char *>(&rnd), 1);
|
||||
retval << std::hex << rnd;
|
||||
retval << std::hex << std::setfill('0') << setw(2) << static_cast<int>(rnd);
|
||||
}
|
||||
random.close();
|
||||
} else {
|
||||
|
||||
@@ -194,13 +194,8 @@ SCSI_PAGE_INQ *SCSIGetInquiry(std::string tapeDevice) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Writes encryption options to the tape drive
|
||||
bool SCSIWriteEncryptOptions(std::string tapeDevice,
|
||||
SCSIEncryptOptions *eOptions) {
|
||||
|
||||
char buffer[1024];
|
||||
memset(&buffer, 0, 1024);
|
||||
|
||||
int SCSIInitSDEPage(SCSIEncryptOptions *eOptions,
|
||||
uint8_t *buffer) {
|
||||
SSP_PAGE_SDE options;
|
||||
// copy the template over the options
|
||||
memset(&options, 0, sizeof(SSP_PAGE_SDE));
|
||||
@@ -213,23 +208,23 @@ bool SCSIWriteEncryptOptions(std::string tapeDevice,
|
||||
options.algorithmIndex = eOptions->algorithmIndex;
|
||||
// set the specific options
|
||||
switch (eOptions->cryptMode) {
|
||||
case CRYPTMODE_ON: // encrypt, read only encrypted data
|
||||
options.encryptionMode = 2;
|
||||
options.decryptionMode = 2;
|
||||
break;
|
||||
case CRYPTMODE_MIXED: // encrypt, read all data
|
||||
options.encryptionMode = 2;
|
||||
options.decryptionMode = 3;
|
||||
break;
|
||||
case CRYPTMODE_RAWREAD:
|
||||
options.encryptionMode = 2;
|
||||
options.decryptionMode = 1;
|
||||
break;
|
||||
default:
|
||||
byteswap((unsigned char *)options.keyLength, 2, DEFAULT_KEYSIZE);
|
||||
eOptions->cryptoKey = ""; // blank the key
|
||||
eOptions->keyName = ""; // blank the key name, not supported when turned off
|
||||
break;
|
||||
case CRYPTMODE_ON: // encrypt, read only encrypted data
|
||||
options.encryptionMode = 2;
|
||||
options.decryptionMode = 2;
|
||||
break;
|
||||
case CRYPTMODE_MIXED: // encrypt, read all data
|
||||
options.encryptionMode = 2;
|
||||
options.decryptionMode = 3;
|
||||
break;
|
||||
case CRYPTMODE_RAWREAD:
|
||||
options.encryptionMode = 2;
|
||||
options.decryptionMode = 1;
|
||||
break;
|
||||
default:
|
||||
byteswap((unsigned char *)options.keyLength, 2, DEFAULT_KEYSIZE);
|
||||
eOptions->cryptoKey = ""; // blank the key
|
||||
eOptions->keyName = ""; // blank the key name, not supported when turned off
|
||||
break;
|
||||
}
|
||||
|
||||
if (eOptions->cryptoKey != "") {
|
||||
@@ -263,7 +258,16 @@ bool SCSIWriteEncryptOptions(std::string tapeDevice,
|
||||
pagelen - 4); // set the page length, minus the length and pageCode
|
||||
|
||||
// copy the options to the beginning of the buffer
|
||||
memcpy(&buffer, &options, sizeof(SSP_PAGE_SDE));
|
||||
memcpy(buffer, &options, sizeof(SSP_PAGE_SDE));
|
||||
return pagelen;
|
||||
}
|
||||
|
||||
// Writes encryption options to the tape drive
|
||||
bool SCSIWriteEncryptOptions(std::string tapeDevice,
|
||||
SCSIEncryptOptions *eOptions) {
|
||||
uint8_t buffer[1024];
|
||||
memset(&buffer, 0, 1024);
|
||||
int pagelen = SCSIInitSDEPage(eOptions, buffer);
|
||||
|
||||
unsigned char spout_sde_command[SSP_SP_CMD_LEN] = {SSP_SPOUT_OPCODE,
|
||||
SSP_SP_PROTOCOL_TDE,
|
||||
@@ -371,13 +375,13 @@ bool SCSIExecute(std::string tapedrive, unsigned char *cmd_p, int cmd_len,
|
||||
#ifdef DEBUGSCSI
|
||||
std::cout << "SCSI Command: ";
|
||||
for (int i = 0; i < cmd_len; i++) {
|
||||
std::cout << std::hex << cmd_p[i];
|
||||
std::cout << HEX(cmd_p[i]);
|
||||
}
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "SCSI Data: ";
|
||||
for (int i = 0; i < dxfer_len; i++) {
|
||||
std::cout << std::hex << (dxfer_p[i]);
|
||||
std::cout << HEX(dxfer_p[i]));
|
||||
}
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
@@ -427,19 +431,19 @@ SCSIEncryptOptions::SCSIEncryptOptions() {
|
||||
rdmc = RDMC_DEFAULT;
|
||||
}
|
||||
|
||||
SSP_NBES::SSP_NBES(SSP_PAGE_BUFFER *buffer) {
|
||||
SSP_NBES::SSP_NBES(const SSP_PAGE_BUFFER *buffer) {
|
||||
memset(&nbes, 0, sizeof(SSP_PAGE_NBES));
|
||||
memcpy(&nbes, buffer, sizeof(SSP_PAGE_NBES));
|
||||
loadKADs(buffer, sizeof(SSP_PAGE_NBES));
|
||||
}
|
||||
SSP_DES::SSP_DES(SSP_PAGE_BUFFER *buffer) {
|
||||
SSP_DES::SSP_DES(const SSP_PAGE_BUFFER *buffer) {
|
||||
memset(&des, 0, sizeof(SSP_PAGE_DES));
|
||||
memcpy(&des, buffer, sizeof(SSP_PAGE_DES));
|
||||
loadKADs(buffer, sizeof(SSP_PAGE_DES));
|
||||
}
|
||||
|
||||
void KAD_CLASS::loadKADs(SSP_PAGE_BUFFER *buffer, int start) {
|
||||
char *rawbuff = (char *)buffer;
|
||||
void KAD_CLASS::loadKADs(const SSP_PAGE_BUFFER *buffer, int start) {
|
||||
const char *rawbuff = (const char *)buffer;
|
||||
int length = BSSHORT(buffer->length) + 4;
|
||||
int pos = start;
|
||||
while (pos < length) {
|
||||
@@ -569,20 +573,20 @@ void outputSense(SCSI_PAGE_SENSE *sd) {
|
||||
break;
|
||||
}
|
||||
|
||||
std::cerr << " (0x" << std::hex << (sd->senseKey) << ")\n";
|
||||
std::cerr << " (0x" << HEX(sd->senseKey) << ")\n";
|
||||
|
||||
std::cerr << std::left << std::setw(25) << " ASC:"
|
||||
<< "0x" << std::hex << (sd->addSenseCode) << "\n";
|
||||
<< "0x" << HEX(sd->addSenseCode) << "\n";
|
||||
|
||||
std::cerr << std::left << std::setw(25) << " ASCQ:"
|
||||
<< "0x" << std::hex << (sd->addSenseCodeQual) << "\n";
|
||||
<< "0x" << HEX(sd->addSenseCodeQual) << "\n";
|
||||
|
||||
if (sd->addSenseLen > 0) {
|
||||
std::cerr << std::left << std::setw(25) << " Additional data:"
|
||||
<< "0x";
|
||||
|
||||
for (int i = 0; i < sd->addSenseLen; i++) {
|
||||
std::cerr << std::hex << (sd->addSenseData[i]);
|
||||
std::cerr << HEX(sd->addSenseData[i]);
|
||||
}
|
||||
std::cerr << "\n";
|
||||
}
|
||||
@@ -592,7 +596,7 @@ void outputSense(SCSI_PAGE_SENSE *sd) {
|
||||
char *rawsense = (char *)sd;
|
||||
|
||||
for (int i = 0; i < sizeof(SCSI_PAGE_SENSE); i++) {
|
||||
std::cerr << std::hex << (rawsense[i]);
|
||||
std::cerr << HEX(rawsense[i]);
|
||||
}
|
||||
std::cerr << "\n";
|
||||
#endif
|
||||
|
||||
@@ -37,7 +37,7 @@ GNU General Public License for more details.
|
||||
|
||||
// outputs hex in a 2 digit pair
|
||||
#define HEX(x) \
|
||||
right << setw(2) << setfill('0') << hex << (int)(x) << setfill(' ')
|
||||
std::right << std::setw(2) << std::setfill('0') << std::hex << (int)(x) << std::setfill(' ')
|
||||
// macro for a byte swapped short
|
||||
#define BSSHORT(x) ((unsigned short)((x[0] << 8) + x[1]))
|
||||
// macro for a byte swapped int
|
||||
@@ -317,20 +317,20 @@ public:
|
||||
std::vector<SSP_KAD> kads;
|
||||
|
||||
protected:
|
||||
void loadKADs(SSP_PAGE_BUFFER *buffer, int start);
|
||||
void loadKADs(const SSP_PAGE_BUFFER *buffer, int start);
|
||||
};
|
||||
|
||||
// class used to parse next block encryption status page
|
||||
class SSP_NBES : public KAD_CLASS {
|
||||
public:
|
||||
SSP_PAGE_NBES nbes;
|
||||
SSP_NBES(SSP_PAGE_BUFFER *buffer);
|
||||
SSP_NBES(const SSP_PAGE_BUFFER *buffer);
|
||||
};
|
||||
// class used to parse data encryption status page
|
||||
class SSP_DES : public KAD_CLASS {
|
||||
public:
|
||||
SSP_PAGE_DES des;
|
||||
SSP_DES(SSP_PAGE_BUFFER *buffer);
|
||||
SSP_DES(const SSP_PAGE_BUFFER *buffer);
|
||||
};
|
||||
|
||||
// enum for SCSIEncryptOptions.cryptMode
|
||||
@@ -353,6 +353,8 @@ SSP_DES *SSPGetDES(std::string tapeDevice);
|
||||
// Gets the encryption status from the tape volume
|
||||
SSP_NBES *SSPGetNBES(std::string tapeDevice, bool retry);
|
||||
// Writes encryption options to the tape drive
|
||||
int SCSIInitSDEPage(SCSIEncryptOptions *eOptions,
|
||||
uint8_t *buffer);
|
||||
bool SCSIWriteEncryptOptions(std::string tapeDevice,
|
||||
SCSIEncryptOptions *eOptions);
|
||||
// Gets device inquiry
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Name: stenc
|
||||
Version: 1.1.0
|
||||
Version: 1.1.1
|
||||
Release: 3%{?dist}
|
||||
Summary: SCSI Tape Encryption Manager
|
||||
|
||||
|
||||
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