diff --git a/man/stenc.rst b/man/stenc.rst index 49c7478..a026141 100644 --- a/man/stenc.rst +++ b/man/stenc.rst @@ -8,7 +8,6 @@ stenc - SCSI Tape Hardware Encryption Manager SYNOPSIS ======== -| **stenc** **-g** *length* **-k** *file* [**-kd** *description*] | **stenc** **-f** *device* [**--detail**] | **stenc** **-f** *device* **-e** **on**\ \|\ **mixed**\ \|\ **rawread** [**-a** *index*] [**-k** *file*] [**--ckod**] [**--protect** \| **--unprotect**] | **stenc** **-f** *device* **-e** **off** [**-a** *index*] [**--ckod**] [**--protect** \| **--unprotect**] @@ -28,78 +27,63 @@ Allows you to manage hardware encryption on SSP enabled tape devices OPTIONS ======= -**-g**\ *length* **-k** **** [**-kd** **] - 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* - Specifies the device to use (i.e. */dev/nst0, /dev/rmt0.1, - /dev/sg0*). Use the **lsscsi** command to determine the appropriate + Specifies the device to use (i.e. */dev/nst0*, */dev/rmt0.1*, + */dev/sg0*). Use the **lsscsi** command to determine the appropriate 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 - of /dev/rmt0). Use commands like 'cat /proc/scsi/scsi', 'lsscsi', and + 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 '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 -displayed. To retrieve more detailed status information, add -**--detail**. If you are root and the status command fails, either the -*device* is incorrect (try another link to the device: */dev/rmt0.1*, -*/dev/nst0*, */dev/tape*, etc.), a tape may not be in the drive, you may -be using the wrong algorithm for the tape drive (see the **-a** option), -or the device does not support SCSI Security Protocol. **stenc** may -read up to 100 blocks of the tape, starting at the current position, in -order to determine if the volume has been encrypted. For this reason, -you should not run the status command while another process is accessing -the drive. If the device returns *Unable to determine* for the volume -encryption status, you may need to move to a section of the tape that -contains data (i.e. **mt -f fsr **) or rewind the tape -in order for **stenc** to output the volume status. + If this is the only option specified, the status of the device will be + displayed. To retrieve more detailed status information, add + **--detail**. If you are root and the status command fails, either the + *device* is incorrect (try another link to the device: */dev/rmt0.1*, + */dev/nst0*, */dev/tape*, etc.), a tape may not be in the drive, you may + be using the wrong algorithm for the tape drive (see the **-a** option), + or the device does not support SCSI Security Protocol. **stenc** may + read up to 100 blocks of the tape, starting at the current position, in + order to determine if the volume has been encrypted. For this reason, + you should not run the status command while another process is accessing + the drive. If the device returns *Unable to determine* for the volume + encryption status, you may need to move to a section of the tape that + contains data (i.e. **mt -f fsr **) or rewind the tape + in order for **stenc** to output the volume status. **-e** **on** \| **mixed** \| **rawread** \| **off** Sets the encryption mode for the device specified with **-f** option. 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 hexadecimal key (see *KEY INPUT SYNTAX*) and an optional key description (see *KEY DESCRIPTORS*). -**on** - The drive will encrypt all data sent to it and will only output -data it is able to decrypt, ignoring unencrypted data on the drive. + **on** - The drive will encrypt all data sent to it and will only output + data it is able to decrypt, ignoring unencrypted data on the drive. -**mixed** - The drive will encrypt all data sent to it and will output -both encrypted data and unencrypted data, providing the drive is able to -do so. + **mixed** - The drive will encrypt all data sent to it and will output + both encrypted data and unencrypted data, providing the drive is able to + do so. -**rawread** - The drive will encrypt all data sent to it and will output -unencrypted data and raw encrypted data. You will probably need to have -specified **--unprotect** when the data was written in order to read it -with this option. Some drives do not support this option. See the -**--protect** option. + **rawread** - The drive will encrypt all data sent to it and will output + unencrypted data and raw encrypted data. You will probably need to have + specified **--unprotect** when the data was written in order to read it + with this option. Some drives do not support this option. See the + **--protect** option. -**off** - The drive will neither encrypt data sent to it, or decrypt -encrypted data found on the drive. If this command fails you may have -switch your algorithm or specify a different default key size when you -configure the program + **off** - The drive will neither encrypt data sent to it, or decrypt + encrypted data found on the drive. If this command fails you may have + switch your algorithm or specify a different default key size when you + configure the program -**WARNING:** The SCSI device will revert all encryption settings if the -tape device is power cycled (if the tape drive is extenal, it may keep -the settings even if the system is rebooted). You can modify you local -startup script (/etc/rc.local, /etc/rc, etc.) to set encryption at -reboot if need be. If you do this, you will need to use the **-k** -option to prevent the system from waiting on the local console user to -enter the encryption key. + **WARNING:** The SCSI device will revert all encryption settings if the + tape device is power cycled (if the tape drive is extenal, it may keep + the settings even if the system is rebooted). You can modify you local + startup script (/etc/rc.local, /etc/rc, etc.) to set encryption at + reboot if need be. If you do this, you will need to use the **-k** + option to prevent the system from waiting on the local console user to + enter the encryption key. **-a** *index* Only valid when setting encryption (see the **-e** option). Specifies @@ -122,68 +106,64 @@ enter the encryption key. support these options. **-k** *file* - Only valid when turning encryption on (see the **-e** option) or - 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. + When turning encryption on, this specifies the location of a key file. 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 -**Example 256 bit Key:** +**Example 256 bit key:** + 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f +**Example 256 key file with key descriptor:** + + | 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f + | April backup key + EXAMPLE ======= -**stenc -g 256 -k /etc/tape.key -kd "September Tape Key"** - Generate a random 256 bit key file with the description "September - 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 +**stenc -f /dev/nst0 -e on -k /etc/stenc.key** + Turns on encryption on /dev/nst0 using the key contained in /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 - encryption for /dev/st0 using that key + encryption for /dev/nst0 using that key -**stenc -f /dev/st0 -e off** - Turns off encryption for /dev/st0 +**stenc -f /dev/nst0 -e off** + Turns off encryption for /dev/nst0 -**stenc -f /dev/st0 --detail** - Outputs the detailed encryption status of /dev/st0 - -**tail /var/log/stenc** - Lists the last few key change audit entries +**stenc -f /dev/nst0 --detail** + Outputs the detailed encryption status of /dev/nst0 KEY CHANGE AUDITING =================== 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 -device status (see the **-f** option). Each time the key is set, a -checksum of that key (or a key description) is also listed in this file. +device status (see the **-f** option). Each time the key is set, the +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 -using is the same as a prior key. If an unauthorized party would -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*). +using is the same as a prior key. 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 **-f** option). These descriptors will be written to the volume, so they should NEVER contain information that would reduce the security of the @@ -214,5 +194,6 @@ permitted by law. SEE ALSO ======== -| **mt**\ (1L) +| **openssl**\ (1SSL) +| **mt**\ (1) | **lsscsi**\ (8) diff --git a/src/main.cpp b/src/main.cpp index 6e3a375..6cb83e7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -69,7 +69,6 @@ void errorOut(std::string const message); void inquiryDrive(std::string tapeDevice); void showDriveStatus(std::string tapeDevice, bool detail); void showVolumeStatus(std::string tapeDevice); -std::string randomKey(int length); void echo(bool); static std::optional> 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"; exit(EXIT_SUCCESS); } - if (thisCmd == "-g") { // Check if the help flag was passed. If it was, - // 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 (thisCmd == "-e") { if (nextCmd == "") errorOut("Key file not specified after -k option"); 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 if (tapeDrive.empty()) { const char *env_tape = getenv("TAPE"); @@ -385,9 +351,9 @@ void errorOut(std::string const message) { // shows the command usage void showUsage() { std::cout - << "Usage: stenc --version | -g -k [-kd ] | " + << "Usage: stenc --version | " "-f [--detail] [-e [-k ] " - "[-kd ] [-a ] [--protect | --unprotect] [--ckod] ]\n\n" + "[-kd ] [-a ] [--protect | --unprotect] [--ckod] ]\n\n" "Type 'man stenc' for more information.\n"; } void inquiryDrive(std::string tapeDevice) { @@ -592,38 +558,3 @@ void echo(bool on = true) { on ? (settings.c_lflag | ECHO) : (settings.c_lflag & ~(ECHO)); 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(&rnd), 1); - retval << std::hex << std::setfill('0') << setw(2) << static_cast(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()); -}