summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/LongOperationInProgressException.h28
-rw-r--r--include/NitrokeyManager.h28
-rw-r--r--include/command.h84
-rw-r--r--include/command_id.h59
-rw-r--r--include/device.h1
-rw-r--r--include/device_proto.h44
-rw-r--r--include/misc.h30
-rw-r--r--include/stick20_commands.h600
8 files changed, 503 insertions, 371 deletions
diff --git a/include/LongOperationInProgressException.h b/include/LongOperationInProgressException.h
new file mode 100644
index 0000000..7f182b0
--- /dev/null
+++ b/include/LongOperationInProgressException.h
@@ -0,0 +1,28 @@
+//
+// Created by sz on 24.10.16.
+//
+
+#ifndef LIBNITROKEY_LONGOPERATIONINPROGRESSEXCEPTION_H
+#define LIBNITROKEY_LONGOPERATIONINPROGRESSEXCEPTION_H
+
+#include "CommandFailedException.h"
+
+class LongOperationInProgressException : public CommandFailedException {
+
+public:
+ unsigned char progress_bar_value;
+
+ LongOperationInProgressException(
+ unsigned char _command_id, uint8_t last_command_status, unsigned char _progress_bar_value)
+ : CommandFailedException(_command_id, last_command_status), progress_bar_value(_progress_bar_value){
+ nitrokey::log::Log::instance()(
+ std::string("LongOperationInProgressException, progress bar status: ")+
+ std::to_string(progress_bar_value), nitrokey::log::Loglevel::DEBUG);
+ }
+ virtual const char *what() const throw() {
+ return "Device returned busy status with long operation in progress";
+ }
+};
+
+
+#endif //LIBNITROKEY_LONGOPERATIONINPROGRESSEXCEPTION_H
diff --git a/include/NitrokeyManager.h b/include/NitrokeyManager.h
index 52c18d7..60fa753 100644
--- a/include/NitrokeyManager.h
+++ b/include/NitrokeyManager.h
@@ -82,6 +82,33 @@ namespace nitrokey {
bool is_AES_supported(const char *user_password);
+ void unlock_encrypted_volume(const char *user_password);
+
+ void unlock_hidden_volume(const char *hidden_volume_password);
+
+ void set_unencrypted_read_only(const char *user_pin);
+
+ void set_unencrypted_read_write(const char *user_pin);
+
+ void export_firmware(const char *admin_pin);
+
+ void clear_new_sd_card_warning(const char *admin_pin);
+
+ void fill_SD_card_with_random_data(const char *admin_pin);
+
+ void change_update_password(const char *current_update_password, const char *new_update_password);
+
+ void create_hidden_volume(uint8_t slot_nr, uint8_t start_percent, uint8_t end_percent,
+ const char *hidden_volume_password);
+
+ void send_startup(uint64_t seconds_from_epoch);
+
+ const char * get_status_storage_as_string();
+
+ const char *get_SD_usage_data_as_string();
+
+ int get_progress_bar_value();
+
~NitrokeyManager();
private:
NitrokeyManager();
@@ -101,7 +128,6 @@ namespace nitrokey {
template <typename ProCommand, PasswordKind StoKind>
void change_PIN_general(char *current_PIN, char *new_PIN);
-
};
}
diff --git a/include/command.h b/include/command.h
index 715902d..0a875e4 100644
--- a/include/command.h
+++ b/include/command.h
@@ -5,19 +5,77 @@
#include "cxx_semantics.h"
namespace nitrokey {
-namespace proto {
-
-template <CommandID cmd_id>
-class Command : semantics::non_constructible {
- public:
- constexpr static CommandID command_id() { return cmd_id; }
-
- template <typename T>
- static std::string dissect(const T &) {
- return std::string("Payload dissection is unavailable");
- }
-};
-}
+ namespace proto {
+
+ template<CommandID cmd_id>
+ class Command : semantics::non_constructible {
+ public:
+ constexpr static CommandID command_id() { return cmd_id; }
+
+ template<typename T>
+ std::string dissect(const T &) {
+ return std::string("Payload dissection is unavailable");
+ }
+ };
+
+#define print_to_ss(x) ( ss << " " << (#x) <<":\t" << (x) << std::endl );
+namespace stick20{
+ enum class PasswordKind : uint8_t {
+ User = 'P',
+ Admin = 'A',
+ AdminPrefixed
+ };
+
+ template<CommandID cmd_id, PasswordKind Tpassword_kind = PasswordKind::User, int password_length = 20>
+ class PasswordCommand : public Command<cmd_id> {
+ public:
+ struct CommandPayload {
+ uint8_t kind;
+ uint8_t password[password_length];
+
+ std::string dissect() const {
+ std::stringstream ss;
+ print_to_ss( kind );
+ print_to_ss(password);
+ return ss.str();
+ }
+ void set_kind_admin() {
+ kind = (uint8_t) 'A';
+ }
+ void set_kind_admin_prefixed() {
+ kind = (uint8_t) 'P';
+ }
+ void set_kind_user() {
+ kind = (uint8_t) 'P';
+ }
+
+ void set_defaults(){
+ set_kind(Tpassword_kind);
+ }
+
+ void set_kind(PasswordKind password_kind){
+ switch (password_kind){
+ case PasswordKind::Admin:
+ set_kind_admin();
+ break;
+ case PasswordKind::User:
+ set_kind_user();
+ break;
+ case PasswordKind::AdminPrefixed:
+ set_kind_admin_prefixed();
+ break;
+ }
+ };
+
+ } __packed;
+
+ typedef Transaction<Command<cmd_id>::command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+
+ };
+ }
+ }
}
+#undef print_to_ss
#endif
diff --git a/include/command_id.h b/include/command_id.h
index 8148cc1..a3806f0 100644
--- a/include/command_id.h
+++ b/include/command_id.h
@@ -66,43 +66,40 @@ enum class CommandID : uint8_t {
CHANGE_USER_PIN = 0x14,
CHANGE_ADMIN_PIN = 0x15,
- STICK20_CMD_SEND_PASSWORD = stick20::CMD_START_VALUE + 18,
- STICK20_CMD_SEND_NEW_PASSWORD = stick20::CMD_START_VALUE + 19,
-
ENABLE_CRYPTED_PARI = 0x20,
- DISABLE_CRYPTED_PARI,
- ENABLE_HIDDEN_CRYPTED_PARI,
- DISABLE_HIDDEN_CRYPTED_PARI,
- ENABLE_FIRMWARE_UPDATE,
- EXPORT_FIRMWARE_TO_FILE,
- GENERATE_NEW_KEYS,
- FILL_SD_CARD_WITH_RANDOM_CHARS,
+ DISABLE_CRYPTED_PARI = 0x20 + 1, //@unused
+ ENABLE_HIDDEN_CRYPTED_PARI = 0x20 + 2,
+ DISABLE_HIDDEN_CRYPTED_PARI = 0x20 + 3, //@unused
+ ENABLE_FIRMWARE_UPDATE = 0x20 + 4, //enables update mode
+ EXPORT_FIRMWARE_TO_FILE = 0x20 + 5,
+ GENERATE_NEW_KEYS = 0x20 + 6,
+ FILL_SD_CARD_WITH_RANDOM_CHARS = 0x20 + 7,
- WRITE_STATUS_DATA,
- ENABLE_READONLY_UNCRYPTED_LUN,
- ENABLE_READWRITE_UNCRYPTED_LUN,
+ WRITE_STATUS_DATA = 0x20 + 8, //@unused
+ ENABLE_READONLY_UNCRYPTED_LUN = 0x20 + 9,
+ ENABLE_READWRITE_UNCRYPTED_LUN = 0x20 + 10,
- SEND_PASSWORD_MATRIX,
- SEND_PASSWORD_MATRIX_PINDATA,
- SEND_PASSWORD_MATRIX_SETUP,
+ SEND_PASSWORD_MATRIX = 0x20 + 11, //@unused
+ SEND_PASSWORD_MATRIX_PINDATA = 0x20 + 12, //@unused
+ SEND_PASSWORD_MATRIX_SETUP = 0x20 + 13, //@unused
- GET_DEVICE_STATUS,
- SEND_DEVICE_STATUS,
+ GET_DEVICE_STATUS = 0x20 + 14,
+ SEND_DEVICE_STATUS = 0x20 + 15,
- SEND_HIDDEN_VOLUME_PASSWORD,
- SEND_HIDDEN_VOLUME_SETUP,
- SEND_PASSWORD,
- SEND_NEW_PASSWORD,
- CLEAR_NEW_SD_CARD_FOUND,
+ SEND_HIDDEN_VOLUME_PASSWORD = 0x20 + 16, //@unused
+ SEND_HIDDEN_VOLUME_SETUP = 0x20 + 17,
+ SEND_PASSWORD = 0x20 + 18,
+ SEND_NEW_PASSWORD = 0x20 + 19,
+ CLEAR_NEW_SD_CARD_FOUND = 0x20 + 20,
- SEND_STARTUP,
- SEND_CLEAR_STICK_KEYS_NOT_INITIATED,
- SEND_LOCK_STICK_HARDWARE,
+ SEND_STARTUP = 0x20 + 21,
+ SEND_CLEAR_STICK_KEYS_NOT_INITIATED = 0x20 + 22,
+ SEND_LOCK_STICK_HARDWARE = 0x20 + 23, //locks firmware upgrade
- PRODUCTION_TEST,
- SEND_DEBUG_DATA,
+ PRODUCTION_TEST = 0x20 + 24,
+ SEND_DEBUG_DATA = 0x20 + 25, //@unused
- CHANGE_UPDATE_PIN,
+ CHANGE_UPDATE_PIN = 0x20 + 26,
GET_PW_SAFE_SLOT_STATUS = 0x60,
GET_PW_SAFE_SLOT_NAME = 0x61,
@@ -112,8 +109,8 @@ enum class CommandID : uint8_t {
SET_PW_SAFE_SLOT_DATA_2 = 0x65,
PW_SAFE_ERASE_SLOT = 0x66,
PW_SAFE_ENABLE = 0x67,
- PW_SAFE_INIT_KEY = 0x68,
- PW_SAFE_SEND_DATA = 0x69,
+ PW_SAFE_INIT_KEY = 0x68, //@unused
+ PW_SAFE_SEND_DATA = 0x69, //@unused
SD_CARD_HIGH_WATERMARK = 0x70,
DETECT_SC_AES = 0x6a,
NEW_AES_KEY = 0x6b
diff --git a/include/device.h b/include/device.h
index 34b7a5b..3f18921 100644
--- a/include/device.h
+++ b/include/device.h
@@ -21,6 +21,7 @@ class Device {
public:
Device();
+ virtual ~Device(){disconnect();}
// lack of device is not actually an error,
// so it doesn't throw
diff --git a/include/device_proto.h b/include/device_proto.h
index cde1d51..0953566 100644
--- a/include/device_proto.h
+++ b/include/device_proto.h
@@ -16,6 +16,7 @@
#include "command_id.h"
#include "dissect.h"
#include "CommandFailedException.h"
+#include "LongOperationInProgressException.h"
#define STICK20_UPDATE_MODE_VID 0x03EB
#define STICK20_UPDATE_MODE_PID 0x2FF1
@@ -89,24 +90,38 @@ namespace nitrokey {
* command_id member in incoming HIDReport structure carries the command
* type last used.
*/
+ namespace DeviceResponseConstants{
+ //magic numbers from firmware
+ static constexpr auto storage_status_absolute_address = 21;
+ static constexpr auto storage_data_absolute_address = storage_status_absolute_address + 5;
+ static constexpr auto header_size = 8; //from _zero to last_command_status inclusive
+ static constexpr auto footer_size = 4; //crc
+ static constexpr auto wrapping_size = header_size + footer_size;
+ }
+
template<CommandID cmd_id, typename ResponsePayload>
struct DeviceResponse {
+ static constexpr auto storage_status_padding_size =
+ DeviceResponseConstants::storage_status_absolute_address - DeviceResponseConstants::header_size;
+
uint8_t _zero;
uint8_t device_status;
uint8_t command_id; // originally last_command_type
uint32_t last_command_crc;
uint8_t last_command_status;
+
union {
- uint8_t _padding[HID_REPORT_SIZE - 12];
+ uint8_t _padding[HID_REPORT_SIZE - DeviceResponseConstants::wrapping_size];
ResponsePayload payload;
struct {
- uint8_t _storage_status_padding[20 - 8 + 1]; //starts on 20th byte minus already 8 used + zero byte
+ uint8_t _storage_status_padding[storage_status_padding_size];
uint8_t command_counter;
uint8_t command_id;
uint8_t device_status; //@see stick20::device_status
uint8_t progress_bar_value;
} __packed storage_status;
} __packed;
+
uint32_t crc;
void initialize() { bzero(this, sizeof *this); }
@@ -119,9 +134,7 @@ namespace nitrokey {
}
void update_CRC() { crc = calculate_CRC(); }
-
bool isCRCcorrect() const { return crc == calculate_CRC(); }
-
bool isValid() const {
// return !_zero && payload.isValid() && isCRCcorrect() &&
// command_id == (uint8_t)(cmd_id);
@@ -216,6 +229,7 @@ namespace nitrokey {
if (!outp.isValid()) throw std::runtime_error("Invalid outgoing packet");
+ bool successful_communication = false;
int receiving_retry_counter = 0;
int sending_retry_counter = dev.get_retry_sending_count();
while (sending_retry_counter-- > 0) {
@@ -263,12 +277,21 @@ namespace nitrokey {
//SENDPASSWORD gives wrong CRC , for now rely on !=0 (TODO report)
// if (resp.device_status == 0 && resp.last_command_crc == outp.crc && resp.isCRCcorrect()) break;
if (resp.device_status == static_cast<uint8_t>(stick10::device_status::ok) &&
- resp.last_command_crc == outp.crc && resp.isValid()) break;
+ resp.last_command_crc == outp.crc && resp.isValid()){
+ successful_communication = true;
+ break;
+ }
if (resp.device_status == static_cast<uint8_t>(stick10::device_status::busy)) {
receiving_retry_counter++;
Log::instance()("Status busy, not decresing receiving_retry_counter counter: " +
std::to_string(receiving_retry_counter), Loglevel::DEBUG_L2);
}
+ if (resp.device_status == static_cast<uint8_t>(stick10::device_status::busy) &&
+ static_cast<stick20::device_status>(resp.storage_status.device_status)
+ == stick20::device_status::busy_progressbar){
+ successful_communication = true;
+ break;
+ }
Log::instance()(std::string("Retry status - dev status, equal crc, correct CRC: ")
+ std::to_string(resp.device_status) + " " +
std::to_string(resp.last_command_crc == outp.crc) +
@@ -282,7 +305,7 @@ namespace nitrokey {
std::this_thread::sleep_for(dev.get_retry_timeout());
continue;
}
- if (resp.device_status == 0 && resp.last_command_crc == outp.crc) break;
+ if (successful_communication) break;
Log::instance()(std::string("Resending (outer loop) "), Loglevel::DEBUG_L2);
Log::instance()(std::string("sending_retry_counter count: ") + std::to_string(sending_retry_counter),
Loglevel::DEBUG);
@@ -293,7 +316,7 @@ namespace nitrokey {
clear_packet(outp);
if (status <= 0)
- throw std::runtime_error(
+ throw std::runtime_error( //FIXME replace with CriticalErrorException
std::string("Device error while executing command ") +
std::to_string(status));
@@ -302,6 +325,13 @@ namespace nitrokey {
Log::instance()(std::string("receiving_retry_counter count: ") + std::to_string(receiving_retry_counter),
Loglevel::DEBUG);
+ if (resp.device_status == static_cast<uint8_t>(stick10::device_status::busy) &&
+ static_cast<stick20::device_status>(resp.storage_status.device_status)
+ == stick20::device_status::busy_progressbar){
+ throw LongOperationInProgressException(
+ resp.command_id, resp.device_status, resp.storage_status.progress_bar_value);
+ }
+
if (!resp.isValid()) throw std::runtime_error("Invalid incoming packet");
if (receiving_retry_counter <= 0)
throw std::runtime_error(
diff --git a/include/misc.h b/include/misc.h
index 5fcd16d..5158de0 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -3,11 +3,32 @@
#include <stdio.h>
#include <string>
#include <vector>
+#include <string.h>
+#include "log.h"
+#include "LibraryException.h"
namespace nitrokey {
namespace misc {
-template <typename T>
+ template <typename T>
+ void strcpyT(T& dest, const char* src){
+
+ if (src == nullptr)
+// throw EmptySourceStringException(slot_number);
+ return;
+ const size_t s_dest = sizeof dest;
+ nitrokey::log::Log::instance()(std::string("strcpyT sizes dest src ")
+ +std::to_string(s_dest)+ " "
+ +std::to_string(strlen(src))+ " "
+ ,nitrokey::log::Loglevel::DEBUG);
+ if (strlen(src) > s_dest){
+ throw TooLongStringException(strlen(src), s_dest, src);
+ }
+ strncpy((char*) &dest, src, s_dest);
+ }
+
+
+ template <typename T>
typename T::CommandPayload get_payload(){
//Create, initialize and return by value command payload
typename T::CommandPayload st;
@@ -15,6 +36,13 @@ typename T::CommandPayload get_payload(){
return st;
}
+ template<typename CMDTYPE, typename Tdev>
+ void execute_password_command(Tdev &stick, const char *password) {
+ auto p = get_payload<CMDTYPE>();
+ p.set_defaults();
+ strcpyT(p.password, password);
+ CMDTYPE::CommandTransaction::run(stick, p);
+ }
std::string hexdump(const char *p, size_t size, bool print_header=true);
uint32_t stm_crc32(const uint8_t *data, size_t size);
diff --git a/include/stick20_commands.h b/include/stick20_commands.h
index f4e7500..1af9da3 100644
--- a/include/stick20_commands.h
+++ b/include/stick20_commands.h
@@ -1,5 +1,6 @@
#ifndef STICK20_COMMANDS_H
#define STICK20_COMMANDS_H
+
#include "inttypes.h"
#include "command.h"
#include <string>
@@ -8,336 +9,299 @@
namespace nitrokey {
-namespace proto {
+ namespace proto {
/*
* STICK20 protocol command ids
* a superset (almost) of STICK10
*/
-namespace stick20 {
-
- enum class PasswordKind : uint8_t {
- User = 'P',
- Admin = 'A'
- };
-
- class ChangeAdminUserPin20Current : Command<CommandID::STICK20_CMD_SEND_PASSWORD> {
- public:
- struct CommandPayload {
- uint8_t kind;
- uint8_t old_pin[20];
- std::string dissect() const {
- std::stringstream ss;
- ss << " old_pin:\t" << old_pin<< std::endl;
- return ss.str();
- }
- void set_kind(PasswordKind k){
- kind = (uint8_t)k;
- }
- } __packed;
-
- typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
- CommandTransaction;
- };
-
-
- class ChangeAdminUserPin20New : Command<CommandID::STICK20_CMD_SEND_NEW_PASSWORD> {
- public:
-
- struct CommandPayload {
- uint8_t kind;
- uint8_t new_pin[20];
- std::string dissect() const {
- std::stringstream ss;
- ss << " new_pin:\t" << new_pin<< std::endl;
- return ss.str();
- }
- void set_kind(PasswordKind k){
- kind = (uint8_t)k;
+#define print_to_ss(x) ( ss << " " << (#x) <<":\t" << (x) << std::endl );
+ namespace stick20 {
+
+ class ChangeAdminUserPin20Current :
+ public PasswordCommand<CommandID::SEND_PASSWORD, PasswordKind::Admin> {};
+ class ChangeAdminUserPin20New :
+ public PasswordCommand<CommandID::SEND_NEW_PASSWORD, PasswordKind::Admin> {};
+ class UnlockUserPin :
+ public PasswordCommand<CommandID::UNLOCK_USER_PASSWORD, PasswordKind::Admin> {};
+
+ class EnableEncryptedPartition : public PasswordCommand<CommandID::ENABLE_CRYPTED_PARI> {};
+ class DisableEncryptedPartition : public PasswordCommand<CommandID::DISABLE_CRYPTED_PARI> {};
+ class EnableHiddenEncryptedPartition : public PasswordCommand<CommandID::ENABLE_HIDDEN_CRYPTED_PARI> {};
+ class DisableHiddenEncryptedPartition : public PasswordCommand<CommandID::DISABLE_CRYPTED_PARI> {};
+ class EnableFirmwareUpdate : public PasswordCommand<CommandID::ENABLE_FIRMWARE_UPDATE> {};
+
+ class ChangeUpdatePassword : Command<CommandID::CHANGE_UPDATE_PIN> {
+ public:
+ struct CommandPayload {
+ uint8_t __gap;
+ uint8_t current_update_password[20];
+ uint8_t __gap2;
+ uint8_t new_update_password[20];
+ std::string dissect() const {
+ std::stringstream ss;
+ print_to_ss( current_update_password );
+ print_to_ss( new_update_password );
+ return ss.str();
+ }
+ };
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+ };
+
+ class ExportFirmware : public PasswordCommand<CommandID::EXPORT_FIRMWARE_TO_FILE> {};
+
+ class CreateNewKeys :
+ public PasswordCommand<CommandID::GENERATE_NEW_KEYS, PasswordKind::AdminPrefixed, 30> {};
+
+
+ class FillSDCardWithRandomChars : Command<CommandID::FILL_SD_CARD_WITH_RANDOM_CHARS> {
+ public:
+ enum class ChosenVolumes : uint8_t {
+ all_volumes = 0,
+ encrypted_volume = 1
+ };
+
+ struct CommandPayload {
+ uint8_t volume_flag;
+ uint8_t kind;
+ uint8_t admin_pin[20];
+
+ std::string dissect() const {
+ std::stringstream ss;
+ print_to_ss( (int) volume_flag );
+ print_to_ss( kind );
+ print_to_ss(admin_pin);
+ return ss.str();
+ }
+ void set_kind_user() {
+ kind = (uint8_t) 'P';
+ }
+ void set_defaults(){
+ set_kind_user();
+ volume_flag = static_cast<uint8_t>(ChosenVolumes::encrypted_volume);
+ }
+
+ } __packed;
+
+ typedef Transaction<Command<CommandID::FILL_SD_CARD_WITH_RANDOM_CHARS>::command_id(),
+ struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+ };
+
+ namespace StorageCommandResponsePayload{
+ using namespace DeviceResponseConstants;
+ static constexpr auto padding_size =
+ storage_data_absolute_address - header_size;
+ struct TransmissionData{
+ uint8_t _padding[padding_size];
+
+ uint8_t SendCounter_u8;
+ uint8_t SendDataType_u8;
+ uint8_t FollowBytesFlag_u8;
+ uint8_t SendSize_u8;
+
+ std::string dissect() const {
+ std::stringstream ss;
+ ss << "_padding:" << std::endl
+ << ::nitrokey::misc::hexdump((const char *) (_padding),
+ sizeof _padding);
+ print_to_ss((int) SendCounter_u8);
+ print_to_ss((int) SendDataType_u8);
+ print_to_ss((int) FollowBytesFlag_u8);
+ print_to_ss((int) SendSize_u8);
+ return ss.str();
+ }
+
+ } __packed;
}
- } __packed;
-
- typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
- CommandTransaction;
- };
-
-
- class UnlockUserPassword : Command<CommandID::UNLOCK_USER_PASSWORD> {
- public:
- struct CommandPayload {
- uint8_t kind;
- uint8_t user_new_password[20];
- std::string dissect() const {
- std::stringstream ss;
- ss << " user_new_password:\t" << user_new_password<< std::endl;
- return ss.str();
- }
- void set_kind(PasswordKind k){
- kind = (uint8_t)k;
- }
- } __packed;
-
- typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
- CommandTransaction;
- };
-
-class EnableEncryptedPartition : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t password[30]; // TODO check w/ firmware
- };
-
- typedef Transaction<CommandID::ENABLE_CRYPTED_PARI, struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class DisableEncryptedPartition : semantics::non_constructible {
- public:
- typedef Transaction<CommandID::DISABLE_CRYPTED_PARI, struct EmptyPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class EnableHiddenEncryptedPartition : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t password[30]; // TODO check w/ firmware
- };
-
- typedef Transaction<CommandID::ENABLE_HIDDEN_CRYPTED_PARI,
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class DisableHiddenEncryptedPartition : semantics::non_constructible {
- public:
- typedef Transaction<CommandID::DISABLE_CRYPTED_PARI, struct EmptyPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class EnableFirmwareUpdate : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t password[30]; // TODO check w/ firmware
- };
-
- typedef Transaction<CommandID::ENABLE_FIRMWARE_UPDATE, struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class UpdatePassword : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t old_password[15];
- uint8_t new_password[15];
- };
-
- typedef Transaction<CommandID::CHANGE_UPDATE_PIN, struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class ExportFirmware : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t password[30];
- };
-
- typedef Transaction<CommandID::EXPORT_FIRMWARE_TO_FILE, struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
- class CreateNewKeys : Command<CommandID::GENERATE_NEW_KEYS> {
- public:
- struct CommandPayload {
- uint8_t kind;
- uint8_t admin_password[30]; //CS20_MAX_PASSWORD_LEN
- std::string dissect() const {
- std::stringstream ss;
- ss << " admin_password:\t" << admin_password<< std::endl;
- return ss.str();
- }
- void setKindPrefixed(){
- kind = 'P';
+ namespace DeviceConfigurationResponsePacket{
+
+ struct ResponsePayload {
+ StorageCommandResponsePayload::TransmissionData transmission_data;
+
+ uint16_t MagicNumber_StickConfig_u16;
+ uint8_t ReadWriteFlagUncryptedVolume_u8;
+ uint8_t ReadWriteFlagCryptedVolume_u8;
+ uint8_t VersionInfo_au8[4];
+ uint8_t ReadWriteFlagHiddenVolume_u8;
+ uint8_t FirmwareLocked_u8;
+ uint8_t NewSDCardFound_u8;
+ uint8_t SDFillWithRandomChars_u8;
+ uint32_t ActiveSD_CardID_u32;
+ uint8_t VolumeActiceFlag_u8;
+ uint8_t NewSmartCardFound_u8;
+ uint8_t UserPwRetryCount;
+ uint8_t AdminPwRetryCount;
+ uint32_t ActiveSmartCardID_u32;
+ uint8_t StickKeysNotInitiated;
+
+ bool isValid() const { return true; }
+
+ std::string dissect() const {
+ std::stringstream ss;
+
+ print_to_ss(transmission_data.dissect());
+ print_to_ss( MagicNumber_StickConfig_u16 );
+ print_to_ss((int) ReadWriteFlagUncryptedVolume_u8 );
+ print_to_ss((int) ReadWriteFlagCryptedVolume_u8 );
+ print_to_ss((int) VersionInfo_au8[1] );
+ print_to_ss((int) VersionInfo_au8[3] );
+ print_to_ss((int) ReadWriteFlagHiddenVolume_u8 );
+ print_to_ss((int) FirmwareLocked_u8 );
+ print_to_ss((int) NewSDCardFound_u8 );
+ print_to_ss((int) SDFillWithRandomChars_u8 );
+ print_to_ss( ActiveSD_CardID_u32 );
+ print_to_ss((int) VolumeActiceFlag_u8 );
+ print_to_ss((int) NewSmartCardFound_u8 );
+ print_to_ss((int) UserPwRetryCount );
+ print_to_ss((int) AdminPwRetryCount );
+ print_to_ss( ActiveSmartCardID_u32 );
+ print_to_ss((int) StickKeysNotInitiated );
+
+ return ss.str();
+ }
+ } __packed;
}
- } __packed;
-
- typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
- CommandTransaction;
- };
-
-
-class FillSDCardWithRandomChars : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t volume_flag;
- uint8_t password[30];
- };
-
- typedef Transaction<CommandID::FILL_SD_CARD_WITH_RANDOM_CHARS,
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class SetupHiddenVolume : semantics::non_constructible {
- public:
- typedef Transaction<CommandID::SEND_HIDDEN_VOLUME_SETUP, struct EmptyPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class SendPasswordMatrix : semantics::non_constructible {
- public:
- typedef Transaction<CommandID::SEND_PASSWORD_MATRIX, struct EmptyPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class SendPasswordMatrixPinData : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t pin_data[30]; // TODO how long actually can it be?
- };
-
- typedef Transaction<CommandID::SEND_PASSWORD_MATRIX_PINDATA,
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class SendPasswordMatrixSetup : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t setup_data[30]; // TODO how long actually can it be?
- };
-
- typedef Transaction<CommandID::SEND_PASSWORD_MATRIX_SETUP,
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-#define d(x) ss << " "#x":\t" << (int)x << std::endl;
-
- class GetDeviceStatus : Command<CommandID::GET_DEVICE_STATUS> {
- public:
- static const int OUTPUT_CMD_RESULT_STICK20_STATUS_START = 20 +1;
- static const int payload_absolute_begin = 8;
- static const int padding_size = OUTPUT_CMD_RESULT_STICK20_STATUS_START - payload_absolute_begin;
- struct ResponsePayload {
- uint8_t _padding[padding_size]; //TODO confirm padding in Storage firmware
- //data starts from 21st byte of packet -> 13th byte of payload
- uint8_t command_counter;
- uint8_t last_command;
- uint8_t status;
- uint8_t progress_bar_value;
- bool isValid() const { return true; }
-
- std::string dissect() const {
- std::stringstream ss;
- d(command_counter);
- d(last_command);
- d(status);
- d(progress_bar_value);
- ss << "_padding:\t"
- << ::nitrokey::misc::hexdump((const char *)(_padding),
- sizeof _padding);
- return ss.str();
- }
- } __packed;
-
- typedef Transaction<command_id(), struct EmptyPayload, struct ResponsePayload>
- CommandTransaction;
- };
-
-
-class SendPassword : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t password[30];
- };
- typedef Transaction<CommandID::SEND_PASSWORD, struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
+ class SendStartup : Command<CommandID::SEND_STARTUP> {
+ public:
+ struct CommandPayload {
+ uint64_t localtime; // POSIX seconds from epoch start, supports until year 2106
+ std::string dissect() const {
+ std::stringstream ss;
+ print_to_ss( localtime );
+ return ss.str();
+ }
+ void set_defaults(){
+ localtime =
+ std::chrono::duration_cast<std::chrono::seconds> (
+ std::chrono::system_clock::now().time_since_epoch()).count();
+ }
+ }__packed;
+
+ using ResponsePayload = DeviceConfigurationResponsePacket::ResponsePayload;
+
+ typedef Transaction<command_id(), struct CommandPayload, ResponsePayload>
+ CommandTransaction;
+ };
-class SendNewPassword : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t password[30];
- };
-
- typedef Transaction<CommandID::SEND_NEW_PASSWORD, struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
// TODO fix original nomenclature
-class SendSetReadonlyToUncryptedVolume : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t password[30];
- };
-
- typedef Transaction<CommandID::ENABLE_READWRITE_UNCRYPTED_LUN,
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class SendSetReadwriteToUncryptedVolume : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t password[30];
- };
-
- typedef Transaction<CommandID::ENABLE_READWRITE_UNCRYPTED_LUN,
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class SendClearNewSdCardFound : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t password[30];
- };
-
- typedef Transaction<CommandID::CLEAR_NEW_SD_CARD_FOUND, struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class SendStartup : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint64_t localtime; // POSIX
- };
-
- typedef Transaction<CommandID::SEND_STARTUP, struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class SendHiddenVolumeSetup : semantics::non_constructible {
- public:
- struct CommandPayload {
- // TODO HiddenVolumeSetup_tst type
- };
-
- typedef Transaction<CommandID::SEND_HIDDEN_VOLUME_SETUP,
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class LockFirmware : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t password[30];
- };
-
- typedef Transaction<CommandID::SEND_LOCK_STICK_HARDWARE,
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
-};
-
-class ProductionTest : semantics::non_constructible {
- public:
- typedef Transaction<CommandID::PRODUCTION_TEST, struct EmptyPayload,
- struct EmptyPayload> CommandTransaction;
-};
-}
-}
+ class SendSetReadonlyToUncryptedVolume : public PasswordCommand<CommandID::ENABLE_READONLY_UNCRYPTED_LUN> {};
+ class SendSetReadwriteToUncryptedVolume : public PasswordCommand<CommandID::ENABLE_READWRITE_UNCRYPTED_LUN> {};
+ class SendClearNewSdCardFound : public PasswordCommand<CommandID::CLEAR_NEW_SD_CARD_FOUND> {};
+
+ class GetDeviceStatus : Command<CommandID::GET_DEVICE_STATUS> {
+ public:
+ using ResponsePayload = DeviceConfigurationResponsePacket::ResponsePayload;
+
+ typedef Transaction<command_id(), struct EmptyPayload, ResponsePayload>
+ CommandTransaction;
+ };
+
+ class GetSDCardOccupancy : Command<CommandID::SD_CARD_HIGH_WATERMARK> {
+ public:
+ struct ResponsePayload {
+ uint8_t WriteLevelMin;
+ uint8_t WriteLevelMax;
+ uint8_t ReadLevelMin;
+ uint8_t ReadLevelMax;
+ std::string dissect() const {
+ std::stringstream ss;
+ print_to_ss((int) WriteLevelMin);
+ print_to_ss((int) WriteLevelMax);
+ print_to_ss((int) ReadLevelMin);
+ print_to_ss((int) ReadLevelMax);
+ return ss.str();
+ }
+ } __packed;
+
+ typedef Transaction<command_id(), struct EmptyPayload, struct ResponsePayload>
+ CommandTransaction;
+ };
+
+
+ class SetupHiddenVolume : Command<CommandID::SEND_HIDDEN_VOLUME_SETUP> {
+ public:
+ constexpr static int MAX_HIDDEN_VOLUME_PASSWORD_SIZE = 20;
+ struct CommandPayload {
+ uint8_t SlotNr_u8;
+ uint8_t StartBlockPercent_u8;
+ uint8_t EndBlockPercent_u8;
+ uint8_t HiddenVolumePassword_au8[MAX_HIDDEN_VOLUME_PASSWORD_SIZE];
+ std::string dissect() const {
+ std::stringstream ss;
+ print_to_ss((int) SlotNr_u8);
+ print_to_ss((int) StartBlockPercent_u8);
+ print_to_ss((int) EndBlockPercent_u8);
+ print_to_ss(HiddenVolumePassword_au8);
+ return ss.str();
+ }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+ };
+
+
+//disable this command for now
+// class LockFirmware : public PasswordCommand<CommandID::SEND_LOCK_STICK_HARDWARE> {};
+
+ class ProductionTest : Command<CommandID::PRODUCTION_TEST> {
+ public:
+ struct ResponsePayload {
+
+ StorageCommandResponsePayload::TransmissionData transmission_data;
+
+ uint8_t FirmwareVersion_au8[2]; // 2 byte // 2
+ uint8_t FirmwareVersionInternal_u8; // 1 byte // 3
+ uint8_t SD_Card_Size_u8; // 1 byte // 4
+ uint32_t CPU_CardID_u32; // 4 byte // 8
+ uint32_t SmartCardID_u32; // 4 byte // 12
+ uint32_t SD_CardID_u32; // 4 byte // 16
+ uint8_t SC_UserPwRetryCount; // User PIN retry count 1 byte // 17
+ uint8_t SC_AdminPwRetryCount; // Admin PIN retry count 1 byte // 18
+ uint8_t SD_Card_ManufacturingYear_u8; // 1 byte // 19
+ uint8_t SD_Card_ManufacturingMonth_u8; // 1 byte // 20
+ uint16_t SD_Card_OEM_u16; // 2 byte // 22
+ uint16_t SD_WriteSpeed_u16; // in kbyte / sec 2 byte // 24
+ uint8_t SD_Card_Manufacturer_u8; // 1 byte // 25
+
+ bool isValid() const { return true; }
+
+ std::string dissect() const {
+ std::stringstream ss;
+
+ print_to_ss(transmission_data.dissect());
+ print_to_ss((int) FirmwareVersion_au8[0]);
+ print_to_ss((int) FirmwareVersion_au8[1]);
+ print_to_ss((int) FirmwareVersionInternal_u8);
+ print_to_ss((int) SD_Card_Size_u8);
+ print_to_ss( CPU_CardID_u32);
+ print_to_ss( SmartCardID_u32);
+ print_to_ss( SD_CardID_u32);
+ print_to_ss((int) SC_UserPwRetryCount);
+ print_to_ss((int) SC_AdminPwRetryCount);
+ print_to_ss((int) SD_Card_ManufacturingYear_u8);
+ print_to_ss((int) SD_Card_ManufacturingMonth_u8);
+ print_to_ss( SD_Card_OEM_u16);
+ print_to_ss( SD_WriteSpeed_u16);
+ print_to_ss((int) SD_Card_Manufacturer_u8);
+ return ss.str();
+ }
+
+ } __packed;
+
+ typedef Transaction<command_id(), struct EmptyPayload, struct ResponsePayload>
+ CommandTransaction;
+ };
+ }
+ }
}
+#undef print_to_ss
+
#endif