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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
// Apparently bitflags isn't clippy-safe
#![cfg_attr(clippy, allow(clippy::redundant_field_names, clippy::suspicious_arithmetic_impl))]
use std::fmt;
use serde::de::{self, Deserialize, Deserializer, Visitor};
use serde::ser::{Serialize, Serializer};
bitflags! {
/// Object attributes specifying which operations are allowed to be performed
///
/// <https://developers.yubico.com/YubiHSM2/Concepts/Capability.html>
pub struct Capability: u64 {
/// asymmetric_decrypt_ecdh: perform ECDH operation
const ASYMMETRIC_DECRYPT_ECDH = 0x800;
/// asymmetric_decrypt_oaep: perform RSA-OAEP decryption
const ASYMMETRIC_DECRYPT_OAEP = 0x400;
/// asymmetric_decrypt_pkcs: perform RSA-PKCS1v1.5 decryption
const ASYMMETRIC_DECRYPT_PKCS = 0x200;
/// asymmetric_gen: generate asymmetric objects
const ASYMMETRIC_GEN = 0x10;
/// asymmetric_sign_ecdsa: compute ECDSA digital signature
const ASYMMETRIC_SIGN_ECDSA = 0x80;
/// asymmetric_sign_eddsa: compute EdDSA (i.e. Ed25519) digital signature
const ASYMMETRIC_SIGN_EDDSA = 0x100;
/// asymmetric_sign_pkcs: compute RSA-PKCS1v1.5 digital signature
const ASYMMETRIC_SIGN_PKCS = 0x20;
/// asymmetric_sign_pss: compute RSA-PSS digital signature
const ASYMMETRIC_SIGN_PSS = 0x40;
/// attest: create attestation (i.e. X.509 certificate) about an asymmetric object
const ATTEST = 0x4_0000_0000;
/// audit: read the log store
const AUDIT = 0x100_0000;
/// delete_asymmetric: delete asymmetric key objects
const DELETE_ASYMMETRIC = 0x200_0000_0000;
/// delete_auth_key: delete AuthKey objects
const DELETE_AUTHKEY = 0x100_0000_0000;
/// delete_hmac_key: delete HMACKey objects
const DELETE_HMACKEY = 0x800_0000_0000;
/// delete_opaque: delete opaque objects
const DELETE_OPAQUE = 0x80_0000_0000;
/// delete_otp_aead_key: delete OTPAEADKey objects
const DELETE_OTP_AEAD_KEY = 0x2000_0000_0000;
/// delete_template: delete template objects
const DELETE_TEMPLATE = 0x1000_0000_0000;
/// delete_wrap_key: delete WrapKey objects
const DELETE_WRAPKEY = 0x400_0000_0000;
/// export_under_wrap: mark an object as exportable under keywrap
const EXPORT_UNDER_WRAP = 0x1_0000;
/// export_wrapped: export objects under keywrap
const EXPORT_WRAPPED = 0x1000;
/// generate_otp_aead_key: generate OTPAEADKey objects
const GENERATE_OTP_AEAD_KEY = 0x10_0000_0000;
/// generate_wrapkey: generate wrapkey objects
const GENERATE_WRAPKEY = 0x8000;
/// get_opaque: read opaque objects
const GET_OPAQUE = 0x1;
/// get_option: read device-global options
const GET_OPTION = 0x4_0000;
/// get_randomness: extract random bytes
const GET_RANDOMNESS = 0x8_0000;
/// get_template: read template objects
const GET_TEMPLATE = 0x400_0000;
/// hmackey_generate: generate HMACKey objects
const HMACKEY_GENERATE = 0x20_0000;
/// hmac_data: compute HMAC for data
const HMAC_DATA = 0x40_0000;
/// hmac_verify: verify HMAC for data
const HMAC_VERIFY = 0x80_0000;
/// import_wrapped: import keywrapped objects
const IMPORT_WRAPPED = 0x2000;
/// otp_aead_create: create an OTP AEAD
const OTP_AEAD_CREATE = 0x4000_0000;
/// otp_aead_random: create an OTP AEAD from random data
const OTP_AEAD_RANDOM = 0x8000_0000;
/// otp_aead_rewrap_from: rewrap AEADs from one OTPAEADKey Object to another
const OTP_AEAD_REWRAP_FROM = 0x1_0000_0000;
/// otp_aead_rewrap_to: rewrap AEADs to one OTPAEADKey Object from another
const OTP_AEAD_REWRAP_TO = 0x2_0000_0000;
/// otp_decrypt: decrypt OTP
const OTP_DECRYPT = 0x2000_0000;
/// put_asymmetric_key: write asymmetric objects
const PUT_ASYMMETRIC = 0x8;
/// put_auth_key: write AuthKey objects
const PUT_AUTHKEY = 0x4;
/// put_hmac_key: write HMACKey objects
const PUT_HMACKEY = 0x10_0000;
/// put_opaque: Write Opaque Objects
const PUT_OPAQUE = 0x2;
/// put_option: write device-global options
const PUT_OPTION = 0x2_0000;
/// put_otp_aead_key: write OTPAEADKey objects
const PUT_OTP_AEAD_KEY = 0x8_0000_0000;
/// put_template: write template objects
const PUT_TEMPLATE = 0x800_0000;
/// put_wrapkey: write WrapKey objects
const PUT_WRAPKEY = 0x4000;
/// reset: factory reset the device
const RESET = 0x1000_0000;
/// ssh_certify: sign SSH certificates
const SSH_CERTIFY = 0x200_0000;
/// unwrap_data: unwrap user-provided data
const UNWRAP_DATA = 0x40_0000_0000;
/// wrap_data: wrap user-provided data
const WRAP_DATA = 0x20_0000_0000;
/// Unknown Capability (Bit 46)
const CAP46 = 0x4000_0000_0000;
/// Unknown Capability (Bit 47)
const CAP47 = 0x8000_0000_0000;
/// Unknown Capability (Bit 48)
const CAP48 = 0x1_0000_0000_0000;
/// Unknown Capability (Bit 49)
const CAP49 = 0x2_0000_0000_0000;
/// Unknown Capability (Bit 50)
const CAP50 = 0x4_0000_0000_0000;
/// Unknown Capability (Bit 51)
const CAP51 = 0x8_0000_0000_0000;
/// Unknown Capability (Bit 52)
const CAP52 = 0x10_0000_0000_0000;
/// Unknown Capability (Bit 53)
const CAP53 = 0x20_0000_0000_0000;
/// Unknown Capability (Bit 54)
const CAP54 = 0x40_0000_0000_0000;
/// Unknown Capability (Bit 55)
const CAP55 = 0x80_0000_0000_0000;
/// Unknown Capability (Bit 56)
const CAP56 = 0x100_0000_0000_0000;
/// Unknown Capability (Bit 57)
const CAP57 = 0x200_0000_0000_0000;
/// Unknown Capability (Bit 58)
const CAP58 = 0x400_0000_0000_0000;
/// Unknown Capability (Bit 59)
const CAP59 = 0x800_0000_0000_0000;
/// Unknown Capability (Bit 60)
const CAP60 = 0x1000_0000_0000_0000;
/// Unknown Capability (Bit 61)
const CAP61 = 0x2000_0000_0000_0000;
/// Unknown Capability (Bit 62)
const CAP62 = 0x4000_0000_0000_0000;
/// Unknown Capability (Bit 63)
const CAP63 = 0x8000_0000_0000_0000;
}
}
impl Default for Capability {
fn default() -> Self {
Capability::empty()
}
}
impl Serialize for Capability {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_u64(self.bits())
}
}
impl<'de> Deserialize<'de> for Capability {
fn deserialize<D>(deserializer: D) -> Result<Capability, D::Error>
where
D: Deserializer<'de>,
{
struct CapabilityVisitor;
impl<'de> Visitor<'de> for CapabilityVisitor {
type Value = Capability;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("8-bytes containing capability bitflags")
}
fn visit_u64<E>(self, value: u64) -> Result<Capability, E>
where
E: de::Error,
{
Capability::from_bits(value).ok_or_else(|| E::custom("invalid capability bitflags"))
}
}
deserializer.deserialize_u64(CapabilityVisitor)
}
}