summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/command.h17
-rw-r--r--include/command_id.h127
-rw-r--r--include/cxx_semantics.h6
-rw-r--r--include/device.h74
-rw-r--r--include/device_proto.h302
-rw-r--r--include/dissect.h99
-rw-r--r--include/log.h53
-rw-r--r--include/misc.h1
-rw-r--r--include/stick10_commands.h1043
-rw-r--r--include/stick20_commands.h448
10 files changed, 1015 insertions, 1155 deletions
diff --git a/include/command.h b/include/command.h
index 6a3e8b4..715902d 100644
--- a/include/command.h
+++ b/include/command.h
@@ -7,19 +7,16 @@
namespace nitrokey {
namespace proto {
-template <CommandID cmd_id>
+template <CommandID cmd_id>
class Command : semantics::non_constructible {
-public:
- constexpr static CommandID command_id() {
- return cmd_id;
- }
+ 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");
- }
+ template <typename T>
+ static std::string dissect(const T &) {
+ return std::string("Payload dissection is unavailable");
+ }
};
-
}
}
diff --git a/include/command_id.h b/include/command_id.h
index 124855b..37aa5d2 100644
--- a/include/command_id.h
+++ b/include/command_id.h
@@ -6,81 +6,80 @@ namespace nitrokey {
namespace proto {
enum class CommandID : uint8_t {
- GET_STATUS = 0x00,
- WRITE_TO_SLOT = 0x01,
- READ_SLOT_NAME = 0x02,
- READ_SLOT = 0x03,
- GET_CODE = 0x04,
- WRITE_CONFIG = 0x05,
- ERASE_SLOT = 0x06,
- FIRST_AUTHENTICATE = 0x07,
- AUTHORIZE = 0x08,
- GET_PASSWORD_RETRY_COUNT = 0x09,
- CLEAR_WARNING = 0x0A,
- SET_TIME = 0x0B,
- TEST_COUNTER = 0x0C,
- TEST_TIME = 0x0D,
- USER_AUTHENTICATE = 0x0E,
- GET_USER_PASSWORD_RETRY_COUNT = 0x0F,
- USER_AUTHORIZE = 0x10,
- UNLOCK_USER_PASSWORD = 0x11,
- LOCK_DEVICE = 0x12,
- FACTORY_RESET = 0x13,
- CHANGE_USER_PIN = 0x14,
- CHANGE_ADMIN_PIN = 0x15,
+ GET_STATUS = 0x00,
+ WRITE_TO_SLOT = 0x01,
+ READ_SLOT_NAME = 0x02,
+ READ_SLOT = 0x03,
+ GET_CODE = 0x04,
+ WRITE_CONFIG = 0x05,
+ ERASE_SLOT = 0x06,
+ FIRST_AUTHENTICATE = 0x07,
+ AUTHORIZE = 0x08,
+ GET_PASSWORD_RETRY_COUNT = 0x09,
+ CLEAR_WARNING = 0x0A,
+ SET_TIME = 0x0B,
+ TEST_COUNTER = 0x0C,
+ TEST_TIME = 0x0D,
+ USER_AUTHENTICATE = 0x0E,
+ GET_USER_PASSWORD_RETRY_COUNT = 0x0F,
+ USER_AUTHORIZE = 0x10,
+ UNLOCK_USER_PASSWORD = 0x11,
+ LOCK_DEVICE = 0x12,
+ FACTORY_RESET = 0x13,
+ CHANGE_USER_PIN = 0x14,
+ CHANGE_ADMIN_PIN = 0x15,
- 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,
+ 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,
- WRITE_STATUS_DATA,
- ENABLE_READONLY_UNCRYPTED_LUN,
- ENABLE_READWRITE_UNCRYPTED_LUN,
+ WRITE_STATUS_DATA,
+ ENABLE_READONLY_UNCRYPTED_LUN,
+ ENABLE_READWRITE_UNCRYPTED_LUN,
- SEND_PASSWORD_MATRIX,
- SEND_PASSWORD_MATRIX_PINDATA,
- SEND_PASSWORD_MATRIX_SETUP,
+ SEND_PASSWORD_MATRIX,
+ SEND_PASSWORD_MATRIX_PINDATA,
+ SEND_PASSWORD_MATRIX_SETUP,
- GET_DEVICE_STATUS,
- SEND_DEVICE_STATUS,
+ GET_DEVICE_STATUS,
+ SEND_DEVICE_STATUS,
- SEND_HIDDEN_VOLUME_PASSWORD,
- SEND_HIDDEN_VOLUME_SETUP,
- SEND_PASSWORD,
- SEND_NEW_PASSWORD,
- CLEAR_NEW_SD_CARD_FOUND,
+ SEND_HIDDEN_VOLUME_PASSWORD,
+ SEND_HIDDEN_VOLUME_SETUP,
+ SEND_PASSWORD,
+ SEND_NEW_PASSWORD,
+ CLEAR_NEW_SD_CARD_FOUND,
- SEND_STARTUP,
- SEND_CLEAR_STICK_KEYS_NOT_INITIATED,
- SEND_LOCK_STICK_HARDWARE,
+ SEND_STARTUP,
+ SEND_CLEAR_STICK_KEYS_NOT_INITIATED,
+ SEND_LOCK_STICK_HARDWARE,
- PRODUCTION_TEST,
- SEND_DEBUG_DATA,
+ PRODUCTION_TEST,
+ SEND_DEBUG_DATA,
- CHANGE_UPDATE_PIN,
+ CHANGE_UPDATE_PIN,
- GET_PW_SAFE_SLOT_STATUS = 0x60,
- GET_PW_SAFE_SLOT_NAME = 0x61,
- GET_PW_SAFE_SLOT_PASSWORD = 0x62,
- GET_PW_SAFE_SLOT_LOGINNAME = 0x63,
- SET_PW_SAFE_SLOT_DATA_1 = 0x64,
- 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,
- SD_CARD_HIGH_WATERMARK = 0x70,
- DETECT_SC_AES = 0x6a,
- NEW_AES_KEY = 0x6b
+ GET_PW_SAFE_SLOT_STATUS = 0x60,
+ GET_PW_SAFE_SLOT_NAME = 0x61,
+ GET_PW_SAFE_SLOT_PASSWORD = 0x62,
+ GET_PW_SAFE_SLOT_LOGINNAME = 0x63,
+ SET_PW_SAFE_SLOT_DATA_1 = 0x64,
+ 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,
+ SD_CARD_HIGH_WATERMARK = 0x70,
+ DETECT_SC_AES = 0x6a,
+ NEW_AES_KEY = 0x6b
};
-const char * commandid_to_string(CommandID id);
-
+const char *commandid_to_string(CommandID id);
}
}
#endif
diff --git a/include/cxx_semantics.h b/include/cxx_semantics.h
index f5d3dca..b846317 100644
--- a/include/cxx_semantics.h
+++ b/include/cxx_semantics.h
@@ -7,9 +7,9 @@
* There's no need to include Boost for a simple subset this project needs.
*/
namespace semantics {
- class non_constructible {
- non_constructible() {}
- };
+class non_constructible {
+ non_constructible() {}
+};
}
#endif
diff --git a/include/device.h b/include/device.h
index 943fe1a..768ac32 100644
--- a/include/device.h
+++ b/include/device.h
@@ -11,60 +11,58 @@
namespace nitrokey {
namespace device {
-enum class CommError
-{
- ERR_NO_ERROR = 0,
- ERR_NOT_CONNECTED = -1,
- ERR_WRONG_RESPONSE_CRC = -2,
- ERR_SENDING = -3,
- ERR_STATUS_NOT_OK = -4
+enum class CommError {
+ ERR_NO_ERROR = 0,
+ ERR_NOT_CONNECTED = -1,
+ ERR_WRONG_RESPONSE_CRC = -2,
+ ERR_SENDING = -3,
+ ERR_STATUS_NOT_OK = -4
};
class Device {
-public:
- Device();
+ public:
+ Device();
- // lack of device is not actually an error,
- // so it doesn't throw
- virtual bool connect();
- virtual bool disconnect();
+ // lack of device is not actually an error,
+ // so it doesn't throw
+ virtual bool connect();
+ virtual bool disconnect();
- /*
- * Sends packet of HID_REPORT_SIZE.
- */
- virtual CommError send(const void *packet);
+ /*
+ * Sends packet of HID_REPORT_SIZE.
+ */
+ virtual CommError send(const void *packet);
- /*
- * Gets packet of HID_REPORT_SIZE.
- * Can sleep. See below.
- */
- virtual CommError recv(void *packet);
+ /*
+ * Gets packet of HID_REPORT_SIZE.
+ * Can sleep. See below.
+ */
+ virtual CommError recv(void *packet);
-protected:
- uint16_t m_vid;
- uint16_t m_pid;
+ protected:
+ uint16_t m_vid;
+ uint16_t m_pid;
- /*
- * While the project uses Signal11 portable HIDAPI
- * library, there's no way of doing it asynchronously,
- * hence polling.
- */
- int m_retry_count;
- std::chrono::milliseconds m_retry_timeout;
+ /*
+ * While the project uses Signal11 portable HIDAPI
+ * library, there's no way of doing it asynchronously,
+ * hence polling.
+ */
+ int m_retry_count;
+ std::chrono::milliseconds m_retry_timeout;
- hid_device *mp_devhandle;
+ hid_device *mp_devhandle;
};
class Stick10 : public Device {
-public:
- Stick10();
+ public:
+ Stick10();
};
class Stick20 : public Device {
-public:
- Stick20();
+ public:
+ Stick20();
};
-
}
}
#endif
diff --git a/include/device_proto.h b/include/device_proto.h
index c8f1ff2..142b45b 100644
--- a/include/device_proto.h
+++ b/include/device_proto.h
@@ -23,10 +23,10 @@
#define PWS_PASSWORD_LENGTH 20
#define PWS_LOGINNAME_LENGTH 32
-#define PWS_SEND_PASSWORD 0
-#define PWS_SEND_LOGINNAME 1
-#define PWS_SEND_TAB 2
-#define PWS_SEND_CR 3
+#define PWS_SEND_PASSWORD 0
+#define PWS_SEND_LOGINNAME 1
+#define PWS_SEND_TAB 2
+#define PWS_SEND_CR 3
namespace nitrokey {
namespace proto {
@@ -42,46 +42,42 @@ namespace proto {
*/
template <CommandID cmd_id, typename Payload>
struct HIDReport {
- uint8_t _zero;
- CommandID command_id; // uint8_t
- union {
- uint8_t _padding[HID_REPORT_SIZE - 6];
- Payload payload;
- } __packed;
- uint32_t crc;
-
- // POD types can't have non-default constructors
- // used in Transaction<>::run()
- void initialize() {
- bzero(this, sizeof *this);
- command_id = cmd_id;
- }
-
- uint32_t calculate_CRC() const {
- // w/o leading zero, a part of each HID packet
- // w/o 4-byte crc
- return misc::stm_crc32((const uint8_t *)(this) + 1,
- (size_t)(HID_REPORT_SIZE - 5));
- }
-
- void update_CRC() {
- crc = calculate_CRC();
- }
-
- bool isCRCcorrect() const {
- return crc == calculate_CRC();
- }
-
- bool isValid() const {
- return true;
-// return !_zero && payload.isValid() && isCRCcorrect();
- }
-
- operator std::string() const {
- // Packet type is known upfront in normal operation.
- // Can't be used to dissect random packets.
- return QueryDissector<cmd_id, decltype(*this)>::dissect(*this);
- }
+ uint8_t _zero;
+ CommandID command_id; // uint8_t
+ union {
+ uint8_t _padding[HID_REPORT_SIZE - 6];
+ Payload payload;
+ } __packed;
+ uint32_t crc;
+
+ // POD types can't have non-default constructors
+ // used in Transaction<>::run()
+ void initialize() {
+ bzero(this, sizeof *this);
+ command_id = cmd_id;
+ }
+
+ uint32_t calculate_CRC() const {
+ // w/o leading zero, a part of each HID packet
+ // w/o 4-byte crc
+ return misc::stm_crc32((const uint8_t *)(this) + 1,
+ (size_t)(HID_REPORT_SIZE - 5));
+ }
+
+ void update_CRC() { crc = calculate_CRC(); }
+
+ bool isCRCcorrect() const { return crc == calculate_CRC(); }
+
+ bool isValid() const {
+ return true;
+ // return !_zero && payload.isValid() && isCRCcorrect();
+ }
+
+ operator std::string() const {
+ // Packet type is known upfront in normal operation.
+ // Can't be used to dissect random packets.
+ return QueryDissector<cmd_id, decltype(*this)>::dissect(*this);
+ }
} __packed;
/*
@@ -92,131 +88,117 @@ struct HIDReport {
*/
template <CommandID cmd_id, typename ResponsePayload>
struct DeviceResponse {
- 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];
- ResponsePayload payload;
- } __packed;
- uint32_t crc;
-
- void initialize() {
- bzero(this, sizeof *this);
- }
-
- uint32_t calculate_CRC() const {
- // w/o leading zero, a part of each HID packet
- // w/o 4-byte crc
- return misc::stm_crc32((const uint8_t *)(this) + 1,
- (size_t)(HID_REPORT_SIZE - 5));
- }
-
- 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);
- return true;
- }
-
- operator std::string() const {
- return ResponseDissector<cmd_id, decltype(*this)>::dissect(*this);
- }
+ 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];
+ ResponsePayload payload;
+ } __packed;
+ uint32_t crc;
+
+ void initialize() { bzero(this, sizeof *this); }
+
+ uint32_t calculate_CRC() const {
+ // w/o leading zero, a part of each HID packet
+ // w/o 4-byte crc
+ return misc::stm_crc32((const uint8_t *)(this) + 1,
+ (size_t)(HID_REPORT_SIZE - 5));
+ }
+
+ 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);
+ return true;
+ }
+
+ operator std::string() const {
+ return ResponseDissector<cmd_id, decltype(*this)>::dissect(*this);
+ }
} __packed;
struct EmptyPayload {
- uint8_t _data[];
+ uint8_t _data[];
- bool isValid() const {
- return true;
- }
+ bool isValid() const { return true; }
- std::string dissect() const {
- return std::string("Empty Payload.");
- }
+ std::string dissect() const { return std::string("Empty Payload."); }
} __packed;
-template<CommandID cmd_id, typename command_payload,
- typename response_payload>
+template <CommandID cmd_id, typename command_payload, typename response_payload>
class Transaction : semantics::non_constructible {
-public:
- // Types declared in command class scope can't be reached from there.
- typedef command_payload CommandPayload;
- typedef response_payload ResponsePayload;
-
- typedef struct HIDReport<cmd_id, CommandPayload> OutgoingPacket;
- typedef struct DeviceResponse<cmd_id, ResponsePayload> ResponsePacket;
-
- static_assert(std::is_pod<OutgoingPacket>::value,
- "outgoingpacket must be a pod type");
- static_assert(std::is_pod<ResponsePacket>::value,
- "ResponsePacket must be a POD type");
- static_assert(sizeof(OutgoingPacket) == HID_REPORT_SIZE,
- "OutgoingPacket type is not the right size");
- static_assert(sizeof(ResponsePacket) == HID_REPORT_SIZE,
- "ResponsePacket type is not the right size");
-
- static response_payload run(device::Device &dev,
- const command_payload &payload) {
- using namespace ::nitrokey::device;
- using namespace ::nitrokey::log;
-
- Log::instance()(__PRETTY_FUNCTION__, Loglevel::DEBUG_L2);
-
- CommError status;
- OutgoingPacket outp;
- ResponsePacket resp;
-
- // POD types can't have non-default constructors
- outp.initialize();
- resp.initialize();
-
- outp.payload = payload;
- outp.update_CRC();
-
- Log::instance()("Outgoing HID packet:", Loglevel::DEBUG);
- Log::instance()((std::string)(outp), Loglevel::DEBUG);
-
- if (!outp.isValid())
- throw std::runtime_error("Invalid outgoing packet");
-
- status = dev.send(&outp);
- if ((int)(status) < 0 && status != CommError::ERR_NO_ERROR)
- throw std::runtime_error(
- std::string("Device error while sending command ") +
- std::to_string((int)(status)));
-
- status = dev.recv(&resp);
- if ((int)(status) < 0 && status != CommError::ERR_NO_ERROR)
- throw std::runtime_error(
- std::string("Device error while executing command ") +
- std::to_string((int)(status)));
-
- Log::instance()("Incoming HID packet:", Loglevel::DEBUG);
- Log::instance()((std::string)(resp), Loglevel::DEBUG);
-
- if (!resp.isValid())
- throw std::runtime_error("Invalid incoming packet");
-
- // See: DeviceResponse
- return resp.payload;
- }
-
- static response_payload run(device::Device &dev) {
- command_payload empty_payload;
- return run(dev, empty_payload);
- }
+ public:
+ // Types declared in command class scope can't be reached from there.
+ typedef command_payload CommandPayload;
+ typedef response_payload ResponsePayload;
+
+ typedef struct HIDReport<cmd_id, CommandPayload> OutgoingPacket;
+ typedef struct DeviceResponse<cmd_id, ResponsePayload> ResponsePacket;
+
+ static_assert(std::is_pod<OutgoingPacket>::value,
+ "outgoingpacket must be a pod type");
+ static_assert(std::is_pod<ResponsePacket>::value,
+ "ResponsePacket must be a POD type");
+ static_assert(sizeof(OutgoingPacket) == HID_REPORT_SIZE,
+ "OutgoingPacket type is not the right size");
+ static_assert(sizeof(ResponsePacket) == HID_REPORT_SIZE,
+ "ResponsePacket type is not the right size");
+
+ static response_payload run(device::Device &dev,
+ const command_payload &payload) {
+ using namespace ::nitrokey::device;
+ using namespace ::nitrokey::log;
+
+ Log::instance()(__PRETTY_FUNCTION__, Loglevel::DEBUG_L2);
+
+ CommError status;
+ OutgoingPacket outp;
+ ResponsePacket resp;
+
+ // POD types can't have non-default constructors
+ outp.initialize();
+ resp.initialize();
+
+ outp.payload = payload;
+ outp.update_CRC();
+
+ Log::instance()("Outgoing HID packet:", Loglevel::DEBUG);
+ Log::instance()((std::string)(outp), Loglevel::DEBUG);
+
+ if (!outp.isValid()) throw std::runtime_error("Invalid outgoing packet");
+
+ status = dev.send(&outp);
+ if ((int)(status) < 0 && status != CommError::ERR_NO_ERROR)
+ throw std::runtime_error(
+ std::string("Device error while sending command ") +
+ std::to_string((int)(status)));
+
+ status = dev.recv(&resp);
+ if ((int)(status) < 0 && status != CommError::ERR_NO_ERROR)
+ throw std::runtime_error(
+ std::string("Device error while executing command ") +
+ std::to_string((int)(status)));
+
+ Log::instance()("Incoming HID packet:", Loglevel::DEBUG);
+ Log::instance()((std::string)(resp), Loglevel::DEBUG);
+
+ if (!resp.isValid()) throw std::runtime_error("Invalid incoming packet");
+
+ // See: DeviceResponse
+ return resp.payload;
+ }
+
+ static response_payload run(device::Device &dev) {
+ command_payload empty_payload;
+ return run(dev, empty_payload);
+ }
};
-
}
}
#endif
diff --git a/include/dissect.h b/include/dissect.h
index e2ddc02..f552950 100644
--- a/include/dissect.h
+++ b/include/dissect.h
@@ -15,68 +15,67 @@ namespace proto {
template <CommandID id, class HIDPacket>
class QueryDissector : semantics::non_constructible {
-public:
- static std::string dissect(const HIDPacket &pod) {
- std::stringstream out;
+ public:
+ static std::string dissect(const HIDPacket &pod) {
+ std::stringstream out;
- out << "Raw HID packet:" << std::endl;
- out << ::nitrokey::misc::hexdump((const char *)(&pod), sizeof pod);
+ out << "Raw HID packet:" << std::endl;
+ out << ::nitrokey::misc::hexdump((const char *)(&pod), sizeof pod);
- out << "Contents:" << std::endl;
- out << "Command ID:\t" << commandid_to_string((CommandID)(pod.command_id)) << std::endl;
- out << "CRC:\t" << pod.crc << std::endl;
+ out << "Contents:" << std::endl;
+ out << "Command ID:\t" << commandid_to_string((CommandID)(pod.command_id))
+ << std::endl;
+ out << "CRC:\t" << pod.crc << std::endl;
- out << "Payload:" << std::endl;
- out << pod.payload.dissect();
- return out.str();
- }
+ out << "Payload:" << std::endl;
+ out << pod.payload.dissect();
+ return out.str();
+ }
};
-
template <CommandID id, class HIDPacket>
class ResponseDissector : semantics::non_constructible {
-public:
- static std::string dissect(const HIDPacket &pod) {
- std::stringstream out;
-
+ public:
+ static std::string dissect(const HIDPacket &pod) {
+ std::stringstream out;
- // FIXME use values from firmware (possibly generate separate
- // header automatically)
- std::string status[4];
- status[0] = " STATUS_READY";
- status[1]= " STATUS_BUSY";
- status[2]= " STATUS_ERROR";
- status[3]= " STATUS_RECEIVED_REPORT";
- std::string cmd[11];
- cmd[0]= " CMD_STATUS_OK";
- cmd[1]= " CMD_STATUS_WRONG_CRC";
- cmd[2]= " CMD_STATUS_WRONG_SLOT";
- cmd[3]= " CMD_STATUS_SLOT_NOT_PROGRAMMED";
- cmd[4]= " CMD_STATUS_WRONG_PASSWORD";
- cmd[5]= " CMD_STATUS_NOT_AUTHORIZED";
- cmd[6]= " CMD_STATUS_TIMESTAMP_WARNING";
- cmd[7]= " CMD_STATUS_NO_NAME_ERROR";
- cmd[8]= " CMD_STATUS_NOT_SUPPORTED";
- cmd[9]= " CMD_STATUS_UNKNOWN_COMMAND";
- cmd[10]= " CMD_STATUS_AES_DEC_FAILED";
-
+ // FIXME use values from firmware (possibly generate separate
+ // header automatically)
+ std::string status[4];
+ status[0] = " STATUS_READY";
+ status[1] = " STATUS_BUSY";
+ status[2] = " STATUS_ERROR";
+ status[3] = " STATUS_RECEIVED_REPORT";
+ std::string cmd[11];
+ cmd[0] = " CMD_STATUS_OK";
+ cmd[1] = " CMD_STATUS_WRONG_CRC";
+ cmd[2] = " CMD_STATUS_WRONG_SLOT";
+ cmd[3] = " CMD_STATUS_SLOT_NOT_PROGRAMMED";
+ cmd[4] = " CMD_STATUS_WRONG_PASSWORD";
+ cmd[5] = " CMD_STATUS_NOT_AUTHORIZED";
+ cmd[6] = " CMD_STATUS_TIMESTAMP_WARNING";
+ cmd[7] = " CMD_STATUS_NO_NAME_ERROR";
+ cmd[8] = " CMD_STATUS_NOT_SUPPORTED";
+ cmd[9] = " CMD_STATUS_UNKNOWN_COMMAND";
+ cmd[10] = " CMD_STATUS_AES_DEC_FAILED";
- out << "Raw HID packet:" << std::endl;
- out << ::nitrokey::misc::hexdump((const char *)(&pod), sizeof pod);
+ out << "Raw HID packet:" << std::endl;
+ out << ::nitrokey::misc::hexdump((const char *)(&pod), sizeof pod);
- out << "Device status:\t" << pod.device_status + 0<<" "<< cmd[ pod.device_status ] << std::endl;
- out << "Command ID:\t" << commandid_to_string((CommandID)(pod.command_id)) << std::endl;
- out << "Last command CRC:\t" << pod.last_command_crc << std::endl;
- out << "Last command status:\t" << pod.last_command_status + 0<<" "<<status[pod.last_command_status] << std::endl;
- out << "CRC:\t" << pod.crc << std::endl;
+ out << "Device status:\t" << pod.device_status + 0 << " "
+ << cmd[pod.device_status] << std::endl;
+ out << "Command ID:\t" << commandid_to_string((CommandID)(pod.command_id))
+ << std::endl;
+ out << "Last command CRC:\t" << pod.last_command_crc << std::endl;
+ out << "Last command status:\t" << pod.last_command_status + 0 << " "
+ << status[pod.last_command_status] << std::endl;
+ out << "CRC:\t" << pod.crc << std::endl;
- out << "Payload:" << std::endl;
- out << pod.payload.dissect();
- return out.str();
- }
+ out << "Payload:" << std::endl;
+ out << pod.payload.dissect();
+ return out.str();
+ }
};
-
-
}
}
diff --git a/include/log.h b/include/log.h
index f6f7193..8eda4fb 100644
--- a/include/log.h
+++ b/include/log.h
@@ -6,57 +6,44 @@
namespace nitrokey {
namespace log {
-enum class Loglevel : int {
- DEBUG_L2,
- DEBUG,
- INFO,
- WARNING,
- ERROR
-};
+enum class Loglevel : int { DEBUG_L2, DEBUG, INFO, WARNING, ERROR };
class LogHandler {
-public:
- virtual void print(const std::string &, Loglevel lvl) = 0;
+ public:
+ virtual void print(const std::string &, Loglevel lvl) = 0;
-protected:
- std::string loglevel_to_str(Loglevel);
+ protected:
+ std::string loglevel_to_str(Loglevel);
};
class StdlogHandler : public LogHandler {
-public:
- virtual void print(const std::string &, Loglevel lvl);
+ public:
+ virtual void print(const std::string &, Loglevel lvl);
};
extern StdlogHandler stdlog_handler;
class Log {
-public:
- Log()
- : mp_loghandler(&stdlog_handler), m_loglevel(Loglevel::WARNING) {}
+ public:
+ Log() : mp_loghandler(&stdlog_handler), m_loglevel(Loglevel::WARNING) {}
- static Log &instance() {
- if (mp_instance == NULL)
- mp_instance = new Log;
- return *mp_instance;
- }
+ static Log &instance() {
+ if (mp_instance == NULL) mp_instance = new Log;
+ return *mp_instance;
+ }
- void operator()(const std::string &, Loglevel);
+ void operator()(const std::string &, Loglevel);
- void set_loglevel(Loglevel lvl) {
- m_loglevel = lvl;
- }
+ void set_loglevel(Loglevel lvl) { m_loglevel = lvl; }
- void set_handler(LogHandler *handler) {
- mp_loghandler = handler;
- }
+ void set_handler(LogHandler *handler) { mp_loghandler = handler; }
-private:
- Loglevel m_loglevel;
- LogHandler *mp_loghandler;
+ private:
+ Loglevel m_loglevel;
+ LogHandler *mp_loghandler;
- static Log *mp_instance;
+ static Log *mp_instance;
};
-
}
}
diff --git a/include/misc.h b/include/misc.h
index bf68915..07f221c 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -8,7 +8,6 @@ namespace misc {
std::string hexdump(const char *p, size_t size);
uint32_t stm_crc32(const uint8_t *data, size_t size);
-
}
}
diff --git a/include/stick10_commands.h b/include/stick10_commands.h
index de31e95..b140e99 100644
--- a/include/stick10_commands.h
+++ b/include/stick10_commands.h
@@ -12,571 +12,486 @@ namespace proto {
* Stick10 protocol definition
*/
namespace stick10 {
- class GetSlotName : public Command<CommandID::READ_SLOT_NAME> {
- public:
- // reachable as a typedef in Transaction
- struct CommandPayload {
- uint8_t slot_number;
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
- } __packed;
-
- struct ResponsePayload {
- uint8_t slot_name[15];
-
- bool isValid() const {
- return true;
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct ResponsePayload> CommandTransaction;
- };
-
- class EraseSlot : Command<CommandID::ERASE_SLOT> {
- public:
- struct CommandPayload {
- uint8_t slot_number;
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class SetTime : Command<CommandID::SET_TIME> {
- public:
- struct CommandPayload {
- uint8_t reset; // 0 - get time, 1 - set time
- uint64_t time; // posix time
-
- bool isValid() const {
- return reset && reset != 1;
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- // TODO duplicate TOTP
- class WriteToHOTPSlot : Command<CommandID::WRITE_TO_SLOT> {
- public:
- struct CommandPayload {
- uint8_t slot_number;
- uint8_t slot_name[15];
- uint8_t slot_secret[20];
- uint8_t slot_config;
- uint8_t slot_token_id[13];
- uint8_t slot_counter[8];
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class WriteToTOTPSlot : Command<CommandID::WRITE_TO_SLOT> {
- public:
- struct CommandPayload {
- uint8_t slot_number;
- uint8_t slot_name[15];
- uint8_t slot_secret[20];
- uint8_t slot_config;
- uint8_t slot_token_id[13];
- uint16_t slot_interval;
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class GetCode : Command<CommandID::GET_CODE> {
- public:
- struct CommandPayload {
- uint8_t slot_number;
- uint64_t challenge;
- uint64_t last_totp_time;
- uint8_t last_interval;
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
- } __packed;
-
- struct ResponsePayload {
- uint8_t code[18];
-
- bool isValid() const {
- return true;
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct ResponsePayload> CommandTransaction;
- };
-
- class GetHOTP : Command<CommandID::GET_CODE> {
- public:
- struct CommandPayload {
- uint8_t slot_number;
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class ReadSlot : Command<CommandID::READ_SLOT> {
- public:
- struct CommandPayload {
- uint8_t slot_number;
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
-
- std::string dissect() const {
- std::stringstream ss;
- ss << "slot_number:\t" << (int)(slot_number) << std::endl;
- return ss.str();
- }
- } __packed;
-
- struct ResponsePayload {
- uint8_t slot_name[15];
- uint8_t config;
- uint8_t token_id[13];
- uint64_t counter;
-
- bool isValid() const {
- return true;
- }
-
- std::string dissect() const {
- std::stringstream ss;
- ss << "slot_name:\t" << slot_name << std::endl;
- ss << "config:\t" << config << std::endl;
- ss << "token_id:\t" << token_id << std::endl;
- ss << "counter:\t" << counter << std::endl;
- return ss.str();
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct ResponsePayload> CommandTransaction;
- };
-
- class GetStatus : Command<CommandID::GET_STATUS> {
- public:
- struct ResponsePayload {
- uint16_t firmware_version;
- uint8_t card_serial[4];
- uint8_t general_config[3];
- uint8_t otp_password_config[2];
-
- bool isValid() const {
- return true;
- }
-
- std::string dissect() const {
- std::stringstream ss;
- ss << "firmware_version:\t" << firmware_version << std::endl;
- ss << "card_serial:\t"
- << ::nitrokey::misc::hexdump((const char *)(card_serial), sizeof card_serial);
- ss << "general_config:\t"
- << ::nitrokey::misc::hexdump((const char *)(general_config), sizeof general_config);
- ss << "otp_password_config:\t"
- << ::nitrokey::misc::hexdump((const char *)(otp_password_config), sizeof otp_password_config);
- return ss.str();
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct EmptyPayload,
- struct ResponsePayload> CommandTransaction;
- };
-
- class GetPasswordRetryCount : Command<CommandID::GET_PASSWORD_RETRY_COUNT> {
- public:
- struct ResponsePayload {
- uint8_t password_retry_count;
-
- bool isValid() const {
- return true;
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct EmptyPayload,
- struct ResponsePayload> CommandTransaction;
- };
-
- class GetUserPasswordRetryCount : Command<CommandID::GET_USER_PASSWORD_RETRY_COUNT> {
- public:
- struct ResponsePayload {
- uint8_t password_retry_count;
-
- bool isValid() const {
- return true;
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct EmptyPayload,
- struct ResponsePayload> CommandTransaction;
- };
-
- class GetPasswordSafeSlotStatus : Command<CommandID::GET_PW_SAFE_SLOT_STATUS> {
- public:
- struct ResponsePayload {
- uint8_t password_safe_status[PWS_SLOT_COUNT];
-
- bool isValid() const {
- return true;
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct EmptyPayload,
- struct ResponsePayload> CommandTransaction;
- };
-
- class GetPasswordSafeSlotName : Command<CommandID::GET_PW_SAFE_SLOT_NAME> {
- public:
- struct CommandPayload {
- uint8_t slot_number;
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
- } __packed;
-
- struct ResponsePayload {
- uint8_t slot_name[PWS_SLOTNAME_LENGTH];
-
- bool isValid() const {
- return true;
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct ResponsePayload> CommandTransaction;
- };
-
- class GetPasswordSafeSlotPassword : Command<CommandID::GET_PW_SAFE_SLOT_PASSWORD> {
- public:
- struct CommandPayload {
- uint8_t slot_number;
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
- } __packed;
-
- struct ResponsePayload {
- uint8_t slot_password[PWS_PASSWORD_LENGTH];
-
- bool isValid() const {
- return true;
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct ResponsePayload> CommandTransaction;
- };
-
- class GetPasswordSafeSlotLogin : Command<CommandID::GET_PW_SAFE_SLOT_LOGINNAME> {
- public:
- struct CommandPayload {
- uint8_t slot_number;
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
- } __packed;
-
- struct ResponsePayload {
- uint8_t slot_login[PWS_LOGINNAME_LENGTH];
-
- bool isValid() const {
- return true;
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct ResponsePayload> CommandTransaction;
- };
-
- class SetPasswordSafeSlotData : Command<CommandID::SET_PW_SAFE_SLOT_DATA_1> {
- public:
- struct CommandPayload {
- uint8_t slot_number;
- uint8_t slot_name[PWS_SLOTNAME_LENGTH];
- uint8_t slot_password[PWS_PASSWORD_LENGTH];
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class SetPasswordSafeSlotData2 : Command<CommandID::SET_PW_SAFE_SLOT_DATA_2> {
- public:
- struct CommandPayload {
- uint8_t slot_number;
- uint8_t slot_name[PWS_SLOTNAME_LENGTH];
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class ErasePasswordSafeSlot : Command<CommandID::PW_SAFE_ERASE_SLOT> {
- public:
- struct CommandPayload {
- uint8_t slot_number;
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class EnablePasswordSafe : Command<CommandID::PW_SAFE_ENABLE> {
- public:
- struct CommandPayload {
- uint8_t password[30];
-
- bool isValid() const {
- return true;
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class PasswordSafeInitKey : Command<CommandID::PW_SAFE_INIT_KEY> {
- public:
- typedef Transaction<command_id(),
- struct EmptyPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- // TODO naming screwed up, see above
- class PasswordSafeSendSlotViaHID: Command<CommandID::PW_SAFE_SEND_DATA> {
- public:
- struct CommandPayload {
- uint8_t slot_number;
- uint8_t slot_kind;
-
- bool isValid() const {
- return !(slot_number & 0xF0);
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
-
- // TODO "Device::passwordSafeSendSlotDataViaHID"
-
- class WriteGeneralConfig : Command<CommandID::WRITE_CONFIG> {
- public:
- struct CommandPayload {
- uint8_t config[5];
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class FirstAuthenticate : Command<CommandID::FIRST_AUTHENTICATE> {
- public:
- struct CommandPayload {
- uint8_t card_password[25];
- uint8_t temporary_password[25];
-
- bool isValid() const {
- return true;
- }
-
- std::string dissect() const {
- std::stringstream ss;
- ss << "card_password:\t" << card_password << std::endl;
- ss << "temporary_password:\t" << temporary_password << std::endl;
- return ss.str();
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class UserAuthenticate : Command<CommandID::USER_AUTHENTICATE> {
- public:
- struct CommandPayload {
- uint8_t card_password[25];
- uint8_t temporary_password[25];
-
- bool isValid() const {
- return true;
- }
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class Authorize : Command<CommandID::AUTHORIZE> {
- public:
- struct CommandPayload {
- uint8_t crc[4];
- uint8_t password[25];
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class UserAuthorize : Command<CommandID::USER_AUTHORIZE> {
- public:
- struct CommandPayload {
- uint8_t crc[4];
- uint8_t password[25];
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class UnlockUserPassword : Command<CommandID::UNLOCK_USER_PASSWORD> {
- public:
- struct CommandPayload {
- uint8_t admin_password[20]; // TODO
- } __packed;
-
- // TODO could we get the stick to return the retry count?
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class ChangeUserPin : Command<CommandID::CHANGE_USER_PIN> {
- public:
- struct CommandPayload {
- uint8_t old_pin[25];
- uint8_t new_pin[25];
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- // TODO why is it needed?
- class IsAESSupported : Command<CommandID::DETECT_SC_AES> {
- public:
- struct CommandPayload {
- uint8_t password[20];
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class ChangeAdminPin : Command<CommandID::CHANGE_ADMIN_PIN> {
- public:
- struct CommandPayload {
- uint8_t old_pin[25];
- uint8_t new_pin[25];
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class LockDevice : Command<CommandID::LOCK_DEVICE> {
- public:
- typedef Transaction<command_id(),
- struct EmptyPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class FactoryReset : Command<CommandID::FACTORY_RESET> {
- public:
- struct CommandPayload {
- uint8_t password[20];
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class BuildAESKey : Command<CommandID::NEW_AES_KEY> {
- public:
- struct CommandPayload {
- uint8_t password[20];
- } __packed;
-
- typedef Transaction<command_id(),
- struct CommandPayload,
- struct EmptyPayload> CommandTransaction;
- };
+class GetSlotName : public Command<CommandID::READ_SLOT_NAME> {
+ public:
+ // reachable as a typedef in Transaction
+ struct CommandPayload {
+ uint8_t slot_number;
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+ } __packed;
+
+ struct ResponsePayload {
+ uint8_t slot_name[15];
+
+ bool isValid() const { return true; }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload,
+ struct ResponsePayload> CommandTransaction;
+};
+
+class EraseSlot : Command<CommandID::ERASE_SLOT> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class SetTime : Command<CommandID::SET_TIME> {
+ public:
+ struct CommandPayload {
+ uint8_t reset; // 0 - get time, 1 - set time
+ uint64_t time; // posix time
+
+ bool isValid() const { return reset && reset != 1; }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+// TODO duplicate TOTP
+class WriteToHOTPSlot : Command<CommandID::WRITE_TO_SLOT> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+ uint8_t slot_name[15];
+ uint8_t slot_secret[20];
+ uint8_t slot_config;
+ uint8_t slot_token_id[13];
+ uint8_t slot_counter[8];
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class WriteToTOTPSlot : Command<CommandID::WRITE_TO_SLOT> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+ uint8_t slot_name[15];
+ uint8_t slot_secret[20];
+ uint8_t slot_config;
+ uint8_t slot_token_id[13];
+ uint16_t slot_interval;
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class GetCode : Command<CommandID::GET_CODE> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+ uint64_t challenge;
+ uint64_t last_totp_time;
+ uint8_t last_interval;
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+ } __packed;
+
+ struct ResponsePayload {
+ uint8_t code[18];
+
+ bool isValid() const { return true; }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload,
+ struct ResponsePayload> CommandTransaction;
+};
+
+class GetHOTP : Command<CommandID::GET_CODE> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class ReadSlot : Command<CommandID::READ_SLOT> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+
+ std::string dissect() const {
+ std::stringstream ss;
+ ss << "slot_number:\t" << (int)(slot_number) << std::endl;
+ return ss.str();
+ }
+ } __packed;
+
+ struct ResponsePayload {
+ uint8_t slot_name[15];
+ uint8_t config;
+ uint8_t token_id[13];
+ uint64_t counter;
+
+ bool isValid() const { return true; }
+
+ std::string dissect() const {
+ std::stringstream ss;
+ ss << "slot_name:\t" << slot_name << std::endl;
+ ss << "config:\t" << config << std::endl;
+ ss << "token_id:\t" << token_id << std::endl;
+ ss << "counter:\t" << counter << std::endl;
+ return ss.str();
+ }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload,
+ struct ResponsePayload> CommandTransaction;
+};
+
+class GetStatus : Command<CommandID::GET_STATUS> {
+ public:
+ struct ResponsePayload {
+ uint16_t firmware_version;
+ uint8_t card_serial[4];
+ uint8_t general_config[3];
+ uint8_t otp_password_config[2];
+
+ bool isValid() const { return true; }
+
+ std::string dissect() const {
+ std::stringstream ss;
+ ss << "firmware_version:\t" << firmware_version << std::endl;
+ ss << "card_serial:\t"
+ << ::nitrokey::misc::hexdump((const char *)(card_serial),
+ sizeof card_serial);
+ ss << "general_config:\t"
+ << ::nitrokey::misc::hexdump((const char *)(general_config),
+ sizeof general_config);
+ ss << "otp_password_config:\t"
+ << ::nitrokey::misc::hexdump((const char *)(otp_password_config),
+ sizeof otp_password_config);
+ return ss.str();
+ }
+ } __packed;
+
+ typedef Transaction<command_id(), struct EmptyPayload, struct ResponsePayload>
+ CommandTransaction;
+};
+
+class GetPasswordRetryCount : Command<CommandID::GET_PASSWORD_RETRY_COUNT> {
+ public:
+ struct ResponsePayload {
+ uint8_t password_retry_count;
+
+ bool isValid() const { return true; }
+ } __packed;
+
+ typedef Transaction<command_id(), struct EmptyPayload, struct ResponsePayload>
+ CommandTransaction;
+};
+
+class GetUserPasswordRetryCount
+ : Command<CommandID::GET_USER_PASSWORD_RETRY_COUNT> {
+ public:
+ struct ResponsePayload {
+ uint8_t password_retry_count;
+
+ bool isValid() const { return true; }
+ } __packed;
+
+ typedef Transaction<command_id(), struct EmptyPayload, struct ResponsePayload>
+ CommandTransaction;
+};
+
+class GetPasswordSafeSlotStatus : Command<CommandID::GET_PW_SAFE_SLOT_STATUS> {
+ public:
+ struct ResponsePayload {
+ uint8_t password_safe_status[PWS_SLOT_COUNT];
+
+ bool isValid() const { return true; }
+ } __packed;
+
+ typedef Transaction<command_id(), struct EmptyPayload, struct ResponsePayload>
+ CommandTransaction;
+};
+
+class GetPasswordSafeSlotName : Command<CommandID::GET_PW_SAFE_SLOT_NAME> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+ } __packed;
+
+ struct ResponsePayload {
+ uint8_t slot_name[PWS_SLOTNAME_LENGTH];
+
+ bool isValid() const { return true; }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload,
+ struct ResponsePayload> CommandTransaction;
+};
+
+class GetPasswordSafeSlotPassword
+ : Command<CommandID::GET_PW_SAFE_SLOT_PASSWORD> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+ } __packed;
+
+ struct ResponsePayload {
+ uint8_t slot_password[PWS_PASSWORD_LENGTH];
+
+ bool isValid() const { return true; }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload,
+ struct ResponsePayload> CommandTransaction;
+};
+
+class GetPasswordSafeSlotLogin
+ : Command<CommandID::GET_PW_SAFE_SLOT_LOGINNAME> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+ } __packed;
+
+ struct ResponsePayload {
+ uint8_t slot_login[PWS_LOGINNAME_LENGTH];
+
+ bool isValid() const { return true; }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload,
+ struct ResponsePayload> CommandTransaction;
+};
+
+class SetPasswordSafeSlotData : Command<CommandID::SET_PW_SAFE_SLOT_DATA_1> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+ uint8_t slot_name[PWS_SLOTNAME_LENGTH];
+ uint8_t slot_password[PWS_PASSWORD_LENGTH];
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class SetPasswordSafeSlotData2 : Command<CommandID::SET_PW_SAFE_SLOT_DATA_2> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+ uint8_t slot_name[PWS_SLOTNAME_LENGTH];
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class ErasePasswordSafeSlot : Command<CommandID::PW_SAFE_ERASE_SLOT> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class EnablePasswordSafe : Command<CommandID::PW_SAFE_ENABLE> {
+ public:
+ struct CommandPayload {
+ uint8_t password[30];
+
+ bool isValid() const { return true; }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class PasswordSafeInitKey : Command<CommandID::PW_SAFE_INIT_KEY> {
+ public:
+ typedef Transaction<command_id(), struct EmptyPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+// TODO naming screwed up, see above
+class PasswordSafeSendSlotViaHID : Command<CommandID::PW_SAFE_SEND_DATA> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+ uint8_t slot_kind;
+
+ bool isValid() const { return !(slot_number & 0xF0); }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+// TODO "Device::passwordSafeSendSlotDataViaHID"
+
+class WriteGeneralConfig : Command<CommandID::WRITE_CONFIG> {
+ public:
+ struct CommandPayload {
+ uint8_t config[5];
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class FirstAuthenticate : Command<CommandID::FIRST_AUTHENTICATE> {
+ public:
+ struct CommandPayload {
+ uint8_t card_password[25];
+ uint8_t temporary_password[25];
+
+ bool isValid() const { return true; }
+
+ std::string dissect() const {
+ std::stringstream ss;
+ ss << "card_password:\t" << card_password << std::endl;
+ ss << "temporary_password:\t" << temporary_password << std::endl;
+ return ss.str();
+ }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class UserAuthenticate : Command<CommandID::USER_AUTHENTICATE> {
+ public:
+ struct CommandPayload {
+ uint8_t card_password[25];
+ uint8_t temporary_password[25];
+
+ bool isValid() const { return true; }
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class Authorize : Command<CommandID::AUTHORIZE> {
+ public:
+ struct CommandPayload {
+ uint8_t crc[4];
+ uint8_t password[25];
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class UserAuthorize : Command<CommandID::USER_AUTHORIZE> {
+ public:
+ struct CommandPayload {
+ uint8_t crc[4];
+ uint8_t password[25];
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class UnlockUserPassword : Command<CommandID::UNLOCK_USER_PASSWORD> {
+ public:
+ struct CommandPayload {
+ uint8_t admin_password[20]; // TODO
+ } __packed;
+
+ // TODO could we get the stick to return the retry count?
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class ChangeUserPin : Command<CommandID::CHANGE_USER_PIN> {
+ public:
+ struct CommandPayload {
+ uint8_t old_pin[25];
+ uint8_t new_pin[25];
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+// TODO why is it needed?
+class IsAESSupported : Command<CommandID::DETECT_SC_AES> {
+ public:
+ struct CommandPayload {
+ uint8_t password[20];
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class ChangeAdminPin : Command<CommandID::CHANGE_ADMIN_PIN> {
+ public:
+ struct CommandPayload {
+ uint8_t old_pin[25];
+ uint8_t new_pin[25];
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class LockDevice : Command<CommandID::LOCK_DEVICE> {
+ public:
+ typedef Transaction<command_id(), struct EmptyPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class FactoryReset : Command<CommandID::FACTORY_RESET> {
+ public:
+ struct CommandPayload {
+ uint8_t password[20];
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
+
+class BuildAESKey : Command<CommandID::NEW_AES_KEY> {
+ public:
+ struct CommandPayload {
+ uint8_t password[20];
+ } __packed;
+
+ typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>
+ CommandTransaction;
+};
}
-
}
}
#endif
diff --git a/include/stick20_commands.h b/include/stick20_commands.h
index 22b7e9a..b84d436 100644
--- a/include/stick20_commands.h
+++ b/include/stick20_commands.h
@@ -10,238 +10,222 @@ namespace proto {
* a superset of STICK10
*/
namespace stick20 {
- 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 : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t password[30];
- };
-
- typedef Transaction<CommandID::GENERATE_NEW_KEYS,
- 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;
- };
-
- class GetDeviceStatus : semantics::non_constructible {
- public:
- typedef Transaction<CommandID::GET_DEVICE_STATUS,
- struct EmptyPayload,
- struct EmptyPayload> CommandTransaction;
- };
-
- class SendPassword : semantics::non_constructible {
- public:
- struct CommandPayload {
- uint8_t password[30];
- };
-
- typedef Transaction<CommandID::SEND_PASSWORD,
- struct CommandPayload,
- struct EmptyPayload> 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 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 : semantics::non_constructible {
+ public:
+ struct CommandPayload {
+ uint8_t password[30];
+ };
+
+ typedef Transaction<CommandID::GENERATE_NEW_KEYS, 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;
+};
+
+class GetDeviceStatus : semantics::non_constructible {
+ public:
+ typedef Transaction<CommandID::GET_DEVICE_STATUS, struct EmptyPayload,
+ struct EmptyPayload> CommandTransaction;
+};
+
+class SendPassword : semantics::non_constructible {
+ public:
+ struct CommandPayload {
+ uint8_t password[30];
+ };
+
+ typedef Transaction<CommandID::SEND_PASSWORD, struct CommandPayload,
+ struct EmptyPayload> 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;
+};
}
}
}