diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/command.h | 17 | ||||
| -rw-r--r-- | include/command_id.h | 127 | ||||
| -rw-r--r-- | include/cxx_semantics.h | 6 | ||||
| -rw-r--r-- | include/device.h | 74 | ||||
| -rw-r--r-- | include/device_proto.h | 302 | ||||
| -rw-r--r-- | include/dissect.h | 99 | ||||
| -rw-r--r-- | include/log.h | 53 | ||||
| -rw-r--r-- | include/misc.h | 1 | ||||
| -rw-r--r-- | include/stick10_commands.h | 1043 | ||||
| -rw-r--r-- | include/stick20_commands.h | 448 | 
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; +};  }  }  } | 
