/*
* Copyright (c) 2015-2018 Nitrokey UG
*
* This file is part of libnitrokey.
*
* libnitrokey is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* libnitrokey is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libnitrokey. If not, see .
*
* SPDX-License-Identifier: LGPL-3.0
*/
#ifndef STICK20_COMMANDS_H
#define STICK20_COMMANDS_H
#include
#include "command.h"
#include
#include
#include "device_proto.h"
#pragma pack (push,1)
namespace nitrokey {
namespace proto {
/*
* STICK20 protocol command ids
* a superset (almost) of STICK10
*/
namespace stick20 {
class ChangeAdminUserPin20Current :
public PasswordCommand {};
class ChangeAdminUserPin20New :
public PasswordCommand {};
class UnlockUserPin :
public PasswordCommand {};
class EnableEncryptedPartition : public PasswordCommand {};
class EnableHiddenEncryptedPartition : public PasswordCommand {};
class SetUnencryptedVolumeReadOnlyAdmin :
public PasswordCommand {};
class SetUnencryptedVolumeReadWriteAdmin :
public PasswordCommand {};
class SetEncryptedVolumeReadOnly :
public PasswordCommand {};
class SetEncryptedVolumeReadWrite :
public PasswordCommand {};
//FIXME the volume disabling commands do not need password
class DisableEncryptedPartition : public PasswordCommand {};
class DisableHiddenEncryptedPartition : public PasswordCommand {};
class EnableFirmwareUpdate : public PasswordCommand {};
class ChangeUpdatePassword : Command {
public:
struct CommandPayload {
uint8_t __gap;
uint8_t current_update_password[20];
uint8_t __gap2;
uint8_t new_update_password[20];
std::string dissect() const {
std::stringstream ss;
print_to_ss_volatile( current_update_password );
print_to_ss_volatile( new_update_password );
return ss.str();
}
};
typedef Transaction
CommandTransaction;
};
class ExportFirmware : public PasswordCommand {};
class CreateNewKeys :
public PasswordCommand {};
class FillSDCardWithRandomChars : Command {
public:
enum class ChosenVolumes : uint8_t {
all_volumes = 0,
encrypted_volume = 1
};
struct CommandPayload {
uint8_t volume_flag;
uint8_t kind;
uint8_t admin_pin[20];
std::string dissect() const {
std::stringstream ss;
print_to_ss( (int) volume_flag );
print_to_ss( kind );
print_to_ss_volatile(admin_pin);
return ss.str();
}
void set_kind_user() {
kind = (uint8_t) 'P';
}
void set_defaults(){
set_kind_user();
volume_flag = static_cast(ChosenVolumes::encrypted_volume);
}
} __packed;
typedef Transaction::command_id(),
struct CommandPayload, struct EmptyPayload>
CommandTransaction;
};
namespace StorageCommandResponsePayload{
using namespace DeviceResponseConstants;
static constexpr auto padding_size =
storage_data_absolute_address - header_size;
struct TransmissionData{
uint8_t _padding[padding_size];
uint8_t SendCounter_u8;
uint8_t SendDataType_u8;
uint8_t FollowBytesFlag_u8;
uint8_t SendSize_u8;
std::string dissect() const {
std::stringstream ss;
ss << "_padding:" << std::endl
<< ::nitrokey::misc::hexdump((const uint8_t *) (_padding),
sizeof _padding);
print_to_ss((int) SendCounter_u8);
print_to_ss((int) SendDataType_u8);
print_to_ss((int) FollowBytesFlag_u8);
print_to_ss((int) SendSize_u8);
return ss.str();
}
} __packed;
}
namespace DeviceConfigurationResponsePacket{
struct ResponsePayload {
StorageCommandResponsePayload::TransmissionData transmission_data;
uint16_t MagicNumber_StickConfig_u16;
/**
* READ_WRITE_ACTIVE = ReadWriteFlagUncryptedVolume_u8 == 0;
*/
uint8_t ReadWriteFlagUncryptedVolume_u8;
uint8_t ReadWriteFlagCryptedVolume_u8;
union{
uint8_t VersionInfo_au8[4];
struct {
uint8_t _reserved;
uint8_t minor;
uint8_t _reserved2;
uint8_t major;
} __packed versionInfo;
} __packed;
uint8_t ReadWriteFlagHiddenVolume_u8;
uint8_t FirmwareLocked_u8;
union{
uint8_t NewSDCardFound_u8;
struct {
bool NewCard :1;
uint8_t Counter :7;
} __packed NewSDCardFound_st;
} __packed;
/**
* SD card FILLED with random chars
*/
uint8_t SDFillWithRandomChars_u8;
uint32_t ActiveSD_CardID_u32;
union{
uint8_t VolumeActiceFlag_u8;
struct {
bool unencrypted :1;
bool encrypted :1;
bool hidden :1;
} __packed VolumeActiceFlag_st;
} __packed;
uint8_t NewSmartCardFound_u8;
uint8_t UserPwRetryCount;
uint8_t AdminPwRetryCount;
uint32_t ActiveSmartCardID_u32;
uint8_t StickKeysNotInitiated;
bool isValid() const { return true; }
std::string dissect() const {
std::stringstream ss;
print_to_ss(transmission_data.dissect());
print_to_ss( MagicNumber_StickConfig_u16 );
print_to_ss((int) ReadWriteFlagUncryptedVolume_u8 );
print_to_ss((int) ReadWriteFlagCryptedVolume_u8 );
print_to_ss((int) ReadWriteFlagHiddenVolume_u8 );
print_to_ss((int) VersionInfo_au8[1] );
print_to_ss((int) VersionInfo_au8[3] );
print_to_ss((int) FirmwareLocked_u8 );
print_to_ss((int) NewSDCardFound_u8 );
print_to_ss((int) NewSDCardFound_st.NewCard );
print_to_ss((int) NewSDCardFound_st.Counter );
print_to_ss((int) SDFillWithRandomChars_u8 );
print_to_ss( ActiveSD_CardID_u32 );
print_to_ss((int) VolumeActiceFlag_u8 );
print_to_ss((int) VolumeActiceFlag_st.unencrypted );
print_to_ss((int) VolumeActiceFlag_st.encrypted );
print_to_ss((int) VolumeActiceFlag_st.hidden);
print_to_ss((int) NewSmartCardFound_u8 );
print_to_ss((int) UserPwRetryCount );
print_to_ss((int) AdminPwRetryCount );
print_to_ss( ActiveSmartCardID_u32 );
print_to_ss((int) StickKeysNotInitiated );
return ss.str();
}
} __packed;
}
class SendStartup : Command {
public:
struct CommandPayload {
uint64_t localtime; // POSIX seconds from epoch start, supports until year 2106
std::string dissect() const {
std::stringstream ss;
print_to_ss( localtime );
return ss.str();
}
void set_defaults(){
localtime =
std::chrono::duration_cast (
std::chrono::system_clock::now().time_since_epoch()).count();
}
}__packed;
using ResponsePayload = DeviceConfigurationResponsePacket::ResponsePayload;
typedef Transaction
CommandTransaction;
};
// TODO fix original nomenclature
class SendSetReadonlyToUncryptedVolume : public PasswordCommand {};
class SendSetReadwriteToUncryptedVolume : public PasswordCommand {};
class SendClearNewSdCardFound : public PasswordCommand {};
class GetDeviceStatus : Command {
public:
using ResponsePayload = DeviceConfigurationResponsePacket::ResponsePayload;
typedef Transaction
CommandTransaction;
};
class CheckSmartcardUsage : Command {
public:
typedef Transaction
CommandTransaction;
};
class GetSDCardOccupancy : Command {
public:
struct ResponsePayload {
uint8_t WriteLevelMin;
uint8_t WriteLevelMax;
uint8_t ReadLevelMin;
uint8_t ReadLevelMax;
std::string dissect() const {
std::stringstream ss;
print_to_ss((int) WriteLevelMin);
print_to_ss((int) WriteLevelMax);
print_to_ss((int) ReadLevelMin);
print_to_ss((int) ReadLevelMax);
return ss.str();
}
} __packed;
typedef Transaction
CommandTransaction;
};
class SetupHiddenVolume : Command {
public:
constexpr static int MAX_HIDDEN_VOLUME_PASSWORD_SIZE = 20;
struct CommandPayload {
uint8_t SlotNr_u8;
uint8_t StartBlockPercent_u8;
uint8_t EndBlockPercent_u8;
uint8_t HiddenVolumePassword_au8[MAX_HIDDEN_VOLUME_PASSWORD_SIZE];
std::string dissect() const {
std::stringstream ss;
print_to_ss((int) SlotNr_u8);
print_to_ss((int) StartBlockPercent_u8);
print_to_ss((int) EndBlockPercent_u8);
print_to_ss_volatile(HiddenVolumePassword_au8);
return ss.str();
}
} __packed;
typedef Transaction
CommandTransaction;
};
//disable this command for now
// class LockFirmware : public PasswordCommand {};
class ProductionTest : Command {
public:
struct ResponsePayload {
StorageCommandResponsePayload::TransmissionData transmission_data;
uint8_t FirmwareVersion_au8[2]; // 2 byte // 2
uint8_t FirmwareVersionInternal_u8; // 1 byte // 3
uint8_t SD_Card_Size_u8; // 1 byte // 4
uint32_t CPU_CardID_u32; // 4 byte // 8
uint32_t SmartCardID_u32; // 4 byte // 12
uint32_t SD_CardID_u32; // 4 byte // 16
uint8_t SC_UserPwRetryCount; // User PIN retry count 1 byte // 17
uint8_t SC_AdminPwRetryCount; // Admin PIN retry count 1 byte // 18
uint8_t SD_Card_ManufacturingYear_u8; // 1 byte // 19
uint8_t SD_Card_ManufacturingMonth_u8; // 1 byte // 20
uint16_t SD_Card_OEM_u16; // 2 byte // 22
uint16_t SD_WriteSpeed_u16; // in kbyte / sec 2 byte // 24
uint8_t SD_Card_Manufacturer_u8; // 1 byte // 25
bool isValid() const { return true; }
std::string dissect() const {
std::stringstream ss;
print_to_ss(transmission_data.dissect());
print_to_ss((int) FirmwareVersion_au8[0]);
print_to_ss((int) FirmwareVersion_au8[1]);
print_to_ss((int) FirmwareVersionInternal_u8);
print_to_ss((int) SD_Card_Size_u8);
print_to_ss( CPU_CardID_u32);
print_to_ss( SmartCardID_u32);
print_to_ss( SD_CardID_u32);
print_to_ss((int) SC_UserPwRetryCount);
print_to_ss((int) SC_AdminPwRetryCount);
print_to_ss((int) SD_Card_ManufacturingYear_u8);
print_to_ss((int) SD_Card_ManufacturingMonth_u8);
print_to_ss( SD_Card_OEM_u16);
print_to_ss( SD_WriteSpeed_u16);
print_to_ss((int) SD_Card_Manufacturer_u8);
return ss.str();
}
} __packed;
typedef Transaction
CommandTransaction;
};
}
}
}
#undef print_to_ss
#pragma pack (pop)
#endif