1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
use failure::Error;
use serde::{
de::{Deserialize, Deserializer, Error as DeError},
ser::{Serialize, Serializer},
};
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[allow(missing_docs)]
#[repr(u8)]
pub enum CommandCode {
Unknown = 0x00,
Echo = 0x01,
CreateSession = 0x03,
AuthSession = 0x04,
SessionMessage = 0x05,
DeviceInfo = 0x06,
BSL = 0x07,
Reset = 0x08,
Command9 = 0x09,
CloseSession = 0x40,
StorageStatus = 0x41,
PutOpaqueObject = 0x42,
GetOpaqueObject = 0x43,
PutAuthKey = 0x44,
PutAsymmetricKey = 0x45,
GenerateAsymmetricKey = 0x46,
SignDataPKCS1 = 0x47,
ListObjects = 0x48,
DecryptPKCS1 = 0x49,
ExportWrapped = 0x4a,
ImportWrapped = 0x4b,
PutWrapKey = 0x4c,
GetLogs = 0x4d,
GetObjectInfo = 0x4e,
PutOption = 0x4f,
GetOption = 0x50,
GetPseudoRandom = 0x51,
PutHMACKey = 0x52,
HMACData = 0x53,
GetPubKey = 0x54,
SignDataPSS = 0x55,
SignDataECDSA = 0x56,
DecryptECDH = 0x57,
DeleteObject = 0x58,
DecryptOAEP = 0x59,
GenerateHMACKey = 0x5a,
GenerateWrapKey = 0x5b,
VerifyHMAC = 0x5c,
SSHCertify = 0x5d,
PutTemplate = 0x5e,
GetTemplate = 0x5f,
DecryptOTP = 0x60,
CreateOTPAEAD = 0x61,
RandomOTPAEAD = 0x62,
RewrapOTPAEAD = 0x63,
AttestAsymmetric = 0x64,
PutOTPAEAD = 0x65,
GenerateOTPAEAD = 0x66,
SetLogIndex = 0x67,
WrapData = 0x68,
UnwrapData = 0x69,
SignDataEdDSA = 0x6a,
Blink = 0x6b,
Error = 0x7f,
}
impl CommandCode {
pub fn from_u8(byte: u8) -> Result<Self, Error> {
Ok(match byte {
0x00 => CommandCode::Unknown,
0x01 => CommandCode::Echo,
0x03 => CommandCode::CreateSession,
0x04 => CommandCode::AuthSession,
0x05 => CommandCode::SessionMessage,
0x06 => CommandCode::DeviceInfo,
0x07 => CommandCode::BSL,
0x08 => CommandCode::Reset,
0x09 => CommandCode::Command9,
0x40 => CommandCode::CloseSession,
0x41 => CommandCode::StorageStatus,
0x42 => CommandCode::PutOpaqueObject,
0x43 => CommandCode::GetOpaqueObject,
0x44 => CommandCode::PutAuthKey,
0x45 => CommandCode::PutAsymmetricKey,
0x46 => CommandCode::GenerateAsymmetricKey,
0x47 => CommandCode::SignDataPKCS1,
0x48 => CommandCode::ListObjects,
0x49 => CommandCode::DecryptPKCS1,
0x4a => CommandCode::ExportWrapped,
0x4b => CommandCode::ImportWrapped,
0x4c => CommandCode::PutWrapKey,
0x4d => CommandCode::GetLogs,
0x4e => CommandCode::GetObjectInfo,
0x4f => CommandCode::PutOption,
0x50 => CommandCode::GetOption,
0x51 => CommandCode::GetPseudoRandom,
0x52 => CommandCode::PutHMACKey,
0x53 => CommandCode::HMACData,
0x54 => CommandCode::GetPubKey,
0x55 => CommandCode::SignDataPSS,
0x56 => CommandCode::SignDataECDSA,
0x57 => CommandCode::DecryptECDH,
0x58 => CommandCode::DeleteObject,
0x59 => CommandCode::DecryptOAEP,
0x5a => CommandCode::GenerateHMACKey,
0x5b => CommandCode::GenerateWrapKey,
0x5c => CommandCode::VerifyHMAC,
0x5d => CommandCode::SSHCertify,
0x5e => CommandCode::PutTemplate,
0x5f => CommandCode::GetTemplate,
0x60 => CommandCode::DecryptOTP,
0x61 => CommandCode::CreateOTPAEAD,
0x62 => CommandCode::RandomOTPAEAD,
0x63 => CommandCode::RewrapOTPAEAD,
0x64 => CommandCode::AttestAsymmetric,
0x65 => CommandCode::PutOTPAEAD,
0x66 => CommandCode::GenerateOTPAEAD,
0x67 => CommandCode::SetLogIndex,
0x68 => CommandCode::WrapData,
0x69 => CommandCode::UnwrapData,
0x6a => CommandCode::SignDataEdDSA,
0x6b => CommandCode::Blink,
0x7f => CommandCode::Error,
_ => bail!("invalid command type: {}", byte),
})
}
pub fn to_u8(self) -> u8 {
self as u8
}
}
impl Serialize for CommandCode {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_u8(self.to_u8())
}
}
impl<'de> Deserialize<'de> for CommandCode {
fn deserialize<D>(deserializer: D) -> Result<CommandCode, D::Error>
where
D: Deserializer<'de>,
{
CommandCode::from_u8(u8::deserialize(deserializer)?)
.or_else(|e| Err(D::Error::custom(format!("{}", e))))
}
}