Remove key generation (#60)

Closes: https://github.com/scsitape/stenc/issues/3
Closes: https://github.com/scsitape/stenc/issues/32
This commit is contained in:
James Wilson
2022-05-09 02:43:59 -07:00
committed by GitHub
parent 859c1a0757
commit 44603e4884
2 changed files with 76 additions and 164 deletions

View File

@@ -8,7 +8,6 @@ stenc - SCSI Tape Hardware Encryption Manager
SYNOPSIS SYNOPSIS
======== ========
| **stenc** **-g** *length* **-k** *file* [**-kd** *description*]
| **stenc** **-f** *device* [**--detail**] | **stenc** **-f** *device* [**--detail**]
| **stenc** **-f** *device* **-e** **on**\ \|\ **mixed**\ \|\ **rawread** [**-a** *index*] [**-k** *file*] [**--ckod**] [**--protect** \| **--unprotect**] | **stenc** **-f** *device* **-e** **on**\ \|\ **mixed**\ \|\ **rawread** [**-a** *index*] [**-k** *file*] [**--ckod**] [**--protect** \| **--unprotect**]
| **stenc** **-f** *device* **-e** **off** [**-a** *index*] [**--ckod**] [**--protect** \| **--unprotect**] | **stenc** **-f** *device* **-e** **off** [**-a** *index*] [**--ckod**] [**--protect** \| **--unprotect**]
@@ -28,29 +27,14 @@ Allows you to manage hardware encryption on SSP enabled tape devices
OPTIONS OPTIONS
======= =======
**-g**\ *length* **-k** **<file to save as>** [**-kd** *<key descriptor(uKAD)>*]
Generates a key file of *length* (in bits) containing a random
hexadecimal key. After entering this option, you will be required to
press random keys followed by the enter key. This will seed the
random number generator so that your key is more secure. On systems
with **/dev/random**, the key is automatically generated from the
random content read from this file. Specify the file to save the key
into with the -k option (you will need write permissions to that file
location). Lastly you can enter an optional key description using the
-kd flag (see *KEY DESCRIPTORS*). This key file can then be used with
the **-k** option. You should not generate a key file over an
unsecured remote session. Typically, key files should be set to 256
bits (32 hexadecimal bytes), however your device may only support 128
bits.
**-f** *device* **-f** *device*
Specifies the device to use (i.e. */dev/nst0, /dev/rmt0.1, Specifies the device to use (i.e. */dev/nst0*, */dev/rmt0.1*,
/dev/sg0*). Use the **lsscsi** command to determine the appropriate */dev/sg0*). Use the **lsscsi** command to determine the appropriate
device to use. You should always use a device name that does not device to use. You should always use a device name that does not
rewind (i.e. use /dev/nst0 instead of /dev/st0, /dev/rmt0.1 instead rewind (i.e. use */dev/nst0* instead of */dev/st0*, */dev/rmt0.1* instead
of /dev/rmt0). Use commands like 'cat /proc/scsi/scsi', 'lsscsi', and of */dev/rmt0*). Use commands like 'cat /proc/scsi/scsi', 'lsscsi', and
'lsdev' to determine the proper device to use. On some distros, a 'lsdev' to determine the proper device to use. On some distros, a
/dev/sg device must be used instead of a /dev/st device. */dev/sg* device must be used instead of a */dev/st* device.
If this is the only option specified, the status of the device will be If this is the only option specified, the status of the device will be
displayed. To retrieve more detailed status information, add displayed. To retrieve more detailed status information, add
@@ -70,7 +54,7 @@ in order for **stenc** to output the volume status.
**-e** **on** \| **mixed** \| **rawread** \| **off** **-e** **on** \| **mixed** \| **rawread** \| **off**
Sets the encryption mode for the device specified with **-f** option. Sets the encryption mode for the device specified with **-f** option.
Successful operations of this type will create an audit entry in the Successful operations of this type will create an audit entry in the
*/var/log/stenc* file. If **off** is not specified and the **-k** system log. If **off** is not specified and the **-k**
option is not specified, the program will require the user to enter a option is not specified, the program will require the user to enter a
hexadecimal key (see *KEY INPUT SYNTAX*) and an optional key hexadecimal key (see *KEY INPUT SYNTAX*) and an optional key
description (see *KEY DESCRIPTORS*). description (see *KEY DESCRIPTORS*).
@@ -122,68 +106,64 @@ enter the encryption key.
support these options. support these options.
**-k** *file* **-k** *file*
Only valid when turning encryption on (see the **-e** option) or When turning encryption on, this specifies the location of a key file.
generating a new key (see the **-g** option). When turning encryption
on, this specifies the location of a key file previously generated
with the **-g** option. When generating a new key with the **-g**
option, this specifies the key file that the new key will be saved
into. Key files should be owned by root ('**chown root**') and only
readable by root ('**chmod 600**'). **stenc** automatically chmods
key files generated with the **-g** option.
KEY INPUT SYNTAX KEY INPUT SYNTAX
================ ================
All keys should be a maximum of 256 bits (32 bytes). **stenc** requires that all keys are entered using 2 digit hexadecimal bytes, with no delimiters in between bytes. Do not precede your key input with '0x'. If you try to use a key size that the drive does not support, the command will error. When using a key file, the second line in the file can contain an optional key description that will be displayed with the device status (see the **-f** option). **stenc** requires that all keys are entered using 2 digit hexadecimal bytes, with no delimiters in between bytes. Do not precede your key input with '0x'. If you try to use a key size that the drive does not support, the command will error. When using a key file, the second line in the file can contain an optional key description that will be displayed with the device status (see *KEY DESCRIPTORS*).
Keys can be generated using any cryptographically secure entropy source,
such as the **random**(4) device or the **openssl**(1SSL) suite of commands.
A 256-bit key file can be created with the following command:
openssl rand -hex 32
**Example 128 bit key:**
**Example 128 bit Key:**
000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f
**Example 256 bit Key:** **Example 256 bit key:**
000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f
**Example 256 key file with key descriptor:**
| 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f
| April backup key
EXAMPLE EXAMPLE
======= =======
**stenc -g 256 -k /etc/tape.key -kd "September Tape Key"** **stenc -f /dev/nst0 -e on -k /etc/stenc.key**
Generate a random 256 bit key file with the description "September Turns on encryption on /dev/nst0 using the key contained in
Tape Key" and save it into /etc/tape.key
**stenc -f /dev/st0 -e on -k /etc/stenc.key**
Turns on encryption on /dev/st0 using the key contained in
/etc/stenc.key /etc/stenc.key
**stenc -f /dev/st0 -e on** **stenc -f /dev/nst0 -e on**
Asks user to input a key in hexadecimal format and then turns on Asks user to input a key in hexadecimal format and then turns on
encryption for /dev/st0 using that key encryption for /dev/nst0 using that key
**stenc -f /dev/st0 -e off** **stenc -f /dev/nst0 -e off**
Turns off encryption for /dev/st0 Turns off encryption for /dev/nst0
**stenc -f /dev/st0 --detail** **stenc -f /dev/nst0 --detail**
Outputs the detailed encryption status of /dev/st0 Outputs the detailed encryption status of /dev/nst0
**tail /var/log/stenc**
Lists the last few key change audit entries
KEY CHANGE AUDITING KEY CHANGE AUDITING
=================== ===================
Each time a key is changed using this program, a corresponding entry Each time a key is changed using this program, a corresponding entry
will be entered into the */var/log/stenc* file. These entries will have will be entered in the system log. These entries will have
an *Key Instance Counter* corresponding to the counter listed in the an *Key Instance Counter* corresponding to the counter listed in the
device status (see the **-f** option). Each time the key is set, a device status (see the **-f** option). Each time the key is set, the
checksum of that key (or a key description) is also listed in this file. key descriptor, if any, is also listed in this file.
This allows you to know when keys were changed and if the key you are This allows you to know when keys were changed and if the key you are
using is the same as a prior key. If an unauthorized party would using is the same as a prior key.
compromise this log file, your key security would be decreased if
checksums were present in the log. To prevent this, you should use key
descriptors instead of checksums (see *KEY DESCRIPTORS*).
KEY DESCRIPTORS KEY DESCRIPTORS
=============== ===============
Key descriptors are set when using the **-g** option or the **-e** Key descriptors are set when using the **-e**
option. They will be displayed when retrieving the drive status (see the option. They will be displayed when retrieving the drive status (see the
**-f** option). These descriptors will be written to the volume, so they **-f** option). These descriptors will be written to the volume, so they
should NEVER contain information that would reduce the security of the should NEVER contain information that would reduce the security of the
@@ -214,5 +194,6 @@ permitted by law.
SEE ALSO SEE ALSO
======== ========
| **mt**\ (1L) | **openssl**\ (1SSL)
| **mt**\ (1)
| **lsscsi**\ (8) | **lsscsi**\ (8)

View File

@@ -69,7 +69,6 @@ void errorOut(std::string const message);
void inquiryDrive(std::string tapeDevice); void inquiryDrive(std::string tapeDevice);
void showDriveStatus(std::string tapeDevice, bool detail); void showDriveStatus(std::string tapeDevice, bool detail);
void showVolumeStatus(std::string tapeDevice); void showVolumeStatus(std::string tapeDevice);
std::string randomKey(int length);
void echo(bool); void echo(bool);
static std::optional<std::vector<uint8_t>> key_from_hex_chars(const std::string& s) static std::optional<std::vector<uint8_t>> key_from_hex_chars(const std::string& s)
@@ -148,21 +147,7 @@ int main(int argc, char **argv) {
std::cout << "https://github.com/scsitape/stenc \n"; std::cout << "https://github.com/scsitape/stenc \n";
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
if (thisCmd == "-g") { // Check if the help flag was passed. If it was, if (thisCmd == "-e") {
// show usage and exit
if (nextCmd == "")
errorOut("Key size must be specified when using -g");
i++; // skip the next argument
keyLength = std::atoi(nextCmd.c_str());
if (keyLength % 8 != 0)
errorOut("Key size must be divisible by 8");
keyLength = keyLength / 8;
if (keyLength > SSP_KEY_LENGTH) {
std::cout << "Warning: Keys over " << (SSP_KEY_LENGTH * 8)
<< " bits cannot be used by this program! \n";
}
action = 2; // generating key
} else if (thisCmd == "-e") {
if (nextCmd == "") if (nextCmd == "")
errorOut("Key file not specified after -k option"); errorOut("Key file not specified after -k option");
if (nextCmd == "on") if (nextCmd == "on")
@@ -225,25 +210,6 @@ int main(int argc, char **argv) {
} }
} }
if (action == 2) { // generate key
if (keyFile == "") {
errorOut("Specify file to save into with the -k argument.");
}
std::string const newkey = randomKey(keyLength);
std::ofstream kf{};
umask(077); // make sure that no one else can read the new key file
kf.open(keyFile.c_str(), std::ios::trunc);
if (!kf.is_open()) {
errorOut("Could not open '" + keyFile + "' for writing.");
}
kf << newkey << keyDesc;
kf.close();
std::cout << "Random key saved into '" << keyFile << "'\n";
chmod(keyFile.c_str(), 0600);
std::cout << "Permissions of keyfile set to 600\n";
exit(EXIT_SUCCESS);
}
// select device from env variable or system default if not given with -f // select device from env variable or system default if not given with -f
if (tapeDrive.empty()) { if (tapeDrive.empty()) {
const char *env_tape = getenv("TAPE"); const char *env_tape = getenv("TAPE");
@@ -385,7 +351,7 @@ void errorOut(std::string const message) {
// shows the command usage // shows the command usage
void showUsage() { void showUsage() {
std::cout std::cout
<< "Usage: stenc --version | -g <length> -k <file> [-kd <description>] | " << "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] [--ckod] ]\n\n"
"Type 'man stenc' for more information.\n"; "Type 'man stenc' for more information.\n";
@@ -592,38 +558,3 @@ void echo(bool on = true) {
on ? (settings.c_lflag | ECHO) : (settings.c_lflag & ~(ECHO)); on ? (settings.c_lflag | ECHO) : (settings.c_lflag & ~(ECHO));
tcsetattr(STDIN_FILENO, TCSANOW, &settings); tcsetattr(STDIN_FILENO, TCSANOW, &settings);
} }
std::string randomKey(int length) {
unsigned char rnd;
std::stringstream retval{};
std::ifstream random{};
// Under Linux and AIX /dev/random provides much more cryptographically secure
// random output than rand()
random.open("/dev/random", std::ios::in | std::ios::binary);
if (random.is_open()) {
for (int i = 0; i < length; i++) {
random.read(reinterpret_cast<char *>(&rnd), 1);
retval << std::hex << std::setfill('0') << setw(2) << static_cast<int>(rnd);
}
random.close();
} else {
std::cout << "Enter random keys on the keyboard to seed the generator.\n"
"End by pressing enter...\n";
double check = 0;
char c = 0;
echo(false);
while (c != 10) {
check += (int)c;
c = getchar();
}
echo(true);
srand(time(NULL) + (int)check);
for (int i = 0; i < length; i++) {
retval << std::hex << (std::rand() % 256);
}
}
retval << std::endl;
return (retval.str());
}