1#[cfg(test)]
2use cryptoauthlib_sys::atca_aes_cbc_ctx_t;
3#[cfg(test)]
4use cryptoauthlib_sys::atca_aes_ctr_ctx_t;
5#[cfg(test)]
6use std::mem::MaybeUninit;
7
8use super::{
9 AeadAlgorithm, AtcaDeviceType, AtcaIfaceCfg, AtcaIfaceType, AtcaSlot, AtcaStatus,
10 AteccDeviceTrait, CipherAlgorithm, EcdhParams, EcdhResult, InfoCmdType, KdfAlgorithm,
11 KdfParams, KdfResult, KeyType, MacAlgorithm, NonceTarget, OutputProtectionState, SignMode,
12 VerifyMode,
13};
14
15#[cfg(test)]
16use super::AtcaSlotCapacity;
17
18use super::{ATCA_AES_DATA_SIZE, ATCA_RANDOM_BUFFER_SIZE, ATCA_SERIAL_NUM_SIZE};
19use rand::{distributions::Standard, Rng};
20
21pub struct AteccDevice {
22 dev_type: AtcaDeviceType,
23}
24
25impl Default for AteccDevice {
33 fn default() -> AteccDevice {
34 AteccDevice {
35 dev_type: AtcaDeviceType::AtcaTestDevNone,
36 }
37 }
38}
39
40impl AteccDeviceTrait for AteccDevice {
41 fn random(&self, rand_out: &mut Vec<u8>) -> AtcaStatus {
42 let vector: Vec<u8> = rand::thread_rng()
43 .sample_iter(Standard)
44 .take(ATCA_RANDOM_BUFFER_SIZE)
45 .collect();
46 rand_out.resize(ATCA_RANDOM_BUFFER_SIZE, 0u8);
47 rand_out.copy_from_slice(&vector);
48 match self.dev_type {
49 AtcaDeviceType::AtcaTestDevFailUnimplemented | AtcaDeviceType::AtcaTestDevSuccess => {
50 AtcaStatus::AtcaSuccess
51 }
52 _ => AtcaStatus::AtcaUnimplemented,
53 }
54 }
55 fn sha(&self, _message: Vec<u8>, _digest: &mut Vec<u8>) -> AtcaStatus {
57 self.default_dev_status()
58 }
59 fn nonce(&self, _target: NonceTarget, _data: &[u8]) -> AtcaStatus {
65 self.default_dev_status()
66 }
67 fn nonce_rand(&self, _host_nonce: &[u8], _rand_out: &mut Vec<u8>) -> AtcaStatus {
70 self.default_dev_status()
71 }
72 fn gen_key(&self, _key_type: KeyType, _slot_id: u8) -> AtcaStatus {
74 self.default_dev_status()
75 }
76 fn import_key(&self, _key_type: KeyType, _key_data: &[u8], _slot_number: u8) -> AtcaStatus {
78 self.default_dev_status()
79 }
80 fn export_key(&self, _key_type: KeyType, _key_data: &mut Vec<u8>, _slot_id: u8) -> AtcaStatus {
82 self.default_dev_status()
83 }
84 fn get_public_key(&self, _slot_id: u8, _public_key: &mut Vec<u8>) -> AtcaStatus {
88 self.default_dev_status()
89 }
90 fn sign_hash(&self, _mode: SignMode, _slot_id: u8, _signature: &mut Vec<u8>) -> AtcaStatus {
92 self.default_dev_status()
93 }
94 fn verify_hash(
96 &self,
97 _mode: VerifyMode,
98 _hash: &[u8],
99 _signature: &[u8],
100 ) -> Result<bool, AtcaStatus> {
101 match self.dev_type {
102 AtcaDeviceType::AtcaTestDevSuccess => Ok(true),
103 _ => Err(self.default_dev_status()),
104 }
105 }
106 fn cipher_encrypt(
108 &self,
109 _algorithm: CipherAlgorithm,
110 _slot_id: u8,
111 _data: &mut Vec<u8>,
112 ) -> AtcaStatus {
113 self.default_dev_status()
114 }
115 fn cipher_decrypt(
117 &self,
118 _algorithm: CipherAlgorithm,
119 _slot_id: u8,
120 _data: &mut Vec<u8>,
121 ) -> AtcaStatus {
122 self.default_dev_status()
123 }
124 fn aead_encrypt(
126 &self,
127 _algorithm: AeadAlgorithm,
128 _slot_id: u8,
129 _data: &mut Vec<u8>,
130 ) -> Result<Vec<u8>, AtcaStatus> {
131 match self.dev_type {
132 AtcaDeviceType::AtcaTestDevSuccess => Ok(vec![0; ATCA_AES_DATA_SIZE]),
133 _ => Err(self.default_dev_status()),
134 }
135 }
136 fn aead_decrypt(
138 &self,
139 _algorithm: AeadAlgorithm,
140 _slot_id: u8,
141 _data: &mut Vec<u8>,
142 ) -> Result<bool, AtcaStatus> {
143 match self.dev_type {
144 AtcaDeviceType::AtcaTestDevSuccess => Ok(true),
145 _ => Err(self.default_dev_status()),
146 }
147 }
148 fn mac_compute(
150 &self,
151 _algorithm: MacAlgorithm,
152 _slot_id: u8,
153 _data: &[u8],
154 ) -> Result<Vec<u8>, AtcaStatus> {
155 match self.dev_type {
156 AtcaDeviceType::AtcaTestDevSuccess => Ok(vec![0; ATCA_AES_DATA_SIZE]),
157 _ => Err(self.default_dev_status()),
158 }
159 }
160 fn mac_verify(
162 &self,
163 _algorithm: MacAlgorithm,
164 _slot_id: u8,
165 _data: &[u8],
166 ) -> Result<bool, AtcaStatus> {
167 match self.dev_type {
168 AtcaDeviceType::AtcaTestDevSuccess => Ok(true),
169 _ => Err(self.default_dev_status()),
170 }
171 }
172 fn kdf(
174 &self,
175 _algorithm: KdfAlgorithm,
176 _parameters: KdfParams,
177 _message: Option<&[u8]>,
178 _message_length: usize,
179 ) -> Result<KdfResult, AtcaStatus> {
180 match self.dev_type {
181 AtcaDeviceType::AtcaTestDevSuccess => Ok(KdfResult {
182 out_data: None,
183 out_nonce: None,
184 }),
185 _ => Err(self.default_dev_status()),
186 }
187 }
188 fn ecdh(
190 &self,
191 _parameters: EcdhParams,
192 _peer_public_key: &[u8],
193 ) -> Result<EcdhResult, AtcaStatus> {
194 match self.dev_type {
195 AtcaDeviceType::AtcaTestDevSuccess => Ok(EcdhResult {
196 pms: None,
197 out_nonce: None,
198 }),
199 _ => Err(self.default_dev_status()),
200 }
201 }
202 fn lock_config_zone(&self) -> AtcaStatus {
204 self.default_dev_status()
205 } fn lock_data_zone(&self) -> AtcaStatus {
208 self.default_dev_status()
209 } fn lock_slot(&self, _slot_id: u8) -> AtcaStatus {
212 self.default_dev_status()
213 } fn load_config_into_chip(&self, _config: &[u8]) -> AtcaStatus {
216 self.default_dev_status()
217 } fn get_device_type(&self) -> AtcaDeviceType {
220 self.dev_type
221 }
222 fn is_configuration_locked(&self) -> bool {
225 match self.dev_type {
226 AtcaDeviceType::AtcaTestDevFailUnimplemented | AtcaDeviceType::AtcaTestDevSuccess => {
227 true
228 }
229 _ => false,
230 }
231 }
232 fn is_data_zone_locked(&self) -> bool {
235 matches!(self.default_dev_status(), AtcaStatus::AtcaSuccess)
236 }
237 fn get_config(&self, _atca_slots: &mut Vec<AtcaSlot>) -> AtcaStatus {
240 match self.dev_type {
241 AtcaDeviceType::AtcaTestDevSuccess | AtcaDeviceType::AtcaTestDevFailUnimplemented => {
242 AtcaStatus::AtcaSuccess
243 }
244 _ => AtcaStatus::AtcaUnimplemented,
245 }
246 }
247 fn info_cmd(&self, _command: InfoCmdType) -> Result<Vec<u8>, AtcaStatus> {
249 match self.dev_type {
250 AtcaDeviceType::AtcaTestDevSuccess => Ok(Vec::new()),
251 _ => Err(self.default_dev_status()),
252 }
253 }
254
255 fn add_access_key(&self, _slot_id: u8, _encryption_key: &[u8]) -> AtcaStatus {
256 self.default_dev_status()
257 }
258
259 fn flush_access_keys(&self) -> AtcaStatus {
260 self.default_dev_status()
261 }
262
263 fn get_serial_number(&self) -> [u8; ATCA_SERIAL_NUM_SIZE] {
264 let mut serial_number = [0; ATCA_SERIAL_NUM_SIZE];
265 if AtcaDeviceType::AtcaTestDevSuccess == self.dev_type {
266 serial_number[0] = 0x01;
267 serial_number[1] = 0x23;
268 }
269
270 serial_number
271 }
272
273 fn is_aes_enabled(&self) -> bool {
274 matches!(self.default_dev_status(), AtcaStatus::AtcaSuccess)
275 }
276
277 fn is_kdf_aes_enabled(&self) -> bool {
278 matches!(self.default_dev_status(), AtcaStatus::AtcaSuccess)
279 }
280
281 fn is_kdf_iv_enabled(&self) -> bool {
282 matches!(self.default_dev_status(), AtcaStatus::AtcaSuccess)
283 }
284
285 fn is_io_protection_key_enabled(&self) -> bool {
286 matches!(self.default_dev_status(), AtcaStatus::AtcaSuccess)
287 }
288
289 fn get_ecdh_output_protection_state(&self) -> OutputProtectionState {
290 OutputProtectionState::ClearTextAllowed
291 }
292
293 fn get_kdf_output_protection_state(&self) -> OutputProtectionState {
294 OutputProtectionState::ClearTextAllowed
295 }
296
297 fn sleep(&self) -> AtcaStatus {
299 match self.dev_type {
300 AtcaDeviceType::AtcaTestDevFailUnimplemented | AtcaDeviceType::AtcaTestDevSuccess => {
301 AtcaStatus::AtcaSuccess
302 }
303 _ => AtcaStatus::AtcaUnimplemented,
304 }
305 }
306
307 fn wakeup(&self) -> AtcaStatus {
308 match self.dev_type {
309 AtcaDeviceType::AtcaTestDevFailUnimplemented | AtcaDeviceType::AtcaTestDevSuccess => {
310 AtcaStatus::AtcaSuccess
311 }
312 _ => AtcaStatus::AtcaUnimplemented,
313 }
314 }
315
316 fn release(&self) -> AtcaStatus {
318 match self.dev_type {
319 AtcaDeviceType::AtcaTestDevFailUnimplemented | AtcaDeviceType::AtcaTestDevSuccess => {
320 AtcaStatus::AtcaSuccess
321 }
322 _ => AtcaStatus::AtcaUnimplemented,
323 }
324 }
325
326 #[cfg(test)]
334 fn read_zone(
335 &self,
336 _zone: u8,
337 _slot: u16,
338 _block: u8,
339 _offset: u8,
340 _data: &mut [u8],
341 ) -> AtcaStatus {
342 self.default_dev_status()
343 }
344 #[cfg(test)]
348 fn read_config_zone(&self, _config_data: &mut Vec<u8>) -> AtcaStatus {
349 self.default_dev_status()
350 }
351 #[cfg(test)]
354 fn cmp_config_zone(&self, _config_data: &mut [u8]) -> Result<bool, AtcaStatus> {
355 match self.dev_type {
356 AtcaDeviceType::AtcaTestDevSuccess => Ok(true),
357 _ => Err(self.default_dev_status()),
358 }
359 }
360 #[cfg(test)]
361 fn get_access_key(&self, _slot_id: u8, _key: &mut Vec<u8>) -> AtcaStatus {
362 self.default_dev_status()
363 }
364 #[cfg(test)]
365 fn aes_encrypt_block(
366 &self,
367 _key_id: u16,
368 _key_block: u8,
369 _input: &[u8],
370 ) -> Result<[u8; ATCA_AES_DATA_SIZE], AtcaStatus> {
371 match self.dev_type {
372 AtcaDeviceType::AtcaTestDevSuccess => Ok([0x00; ATCA_AES_DATA_SIZE]),
373 _ => Err(self.default_dev_status()),
374 }
375 }
376 #[cfg(test)]
377 fn aes_decrypt_block(
378 &self,
379 _key_id: u16,
380 _key_block: u8,
381 _input: &[u8],
382 ) -> Result<[u8; ATCA_AES_DATA_SIZE], AtcaStatus> {
383 match self.dev_type {
384 AtcaDeviceType::AtcaTestDevSuccess => Ok([0x00; ATCA_AES_DATA_SIZE]),
385 _ => Err(self.default_dev_status()),
386 }
387 }
388 #[cfg(test)]
389 fn aes_ctr_init(
390 &self,
391 _slot_id: u8,
392 _counter_size: u8,
393 _iv: &[u8],
394 ) -> Result<atca_aes_ctr_ctx_t, AtcaStatus> {
395 match self.dev_type {
396 AtcaDeviceType::AtcaTestDevSuccess => {
397 let ctx: atca_aes_ctr_ctx_t = {
398 let ctx = MaybeUninit::<atca_aes_ctr_ctx_t>::zeroed();
399 unsafe { ctx.assume_init() }
400 };
401 Ok(ctx)
402 }
403 _ => Err(self.default_dev_status()),
404 }
405 }
406 #[cfg(test)]
407 fn aes_ctr_increment(&self, ctx: atca_aes_ctr_ctx_t) -> Result<atca_aes_ctr_ctx_t, AtcaStatus> {
408 match self.dev_type {
409 AtcaDeviceType::AtcaTestDevSuccess => Ok(ctx),
410 _ => Err(self.default_dev_status()),
411 }
412 }
413 #[cfg(test)]
415 fn aes_cbc_init(&self, _slot_id: u8, _iv: &[u8]) -> Result<atca_aes_cbc_ctx_t, AtcaStatus> {
416 match self.dev_type {
417 AtcaDeviceType::AtcaTestDevSuccess => {
418 let ctx: atca_aes_cbc_ctx_t = {
419 let ctx = MaybeUninit::<atca_aes_cbc_ctx_t>::zeroed();
420 unsafe { ctx.assume_init() }
421 };
422 Ok(ctx)
423 }
424 _ => Err(self.default_dev_status()),
425 }
426 }
427 #[cfg(test)]
430 fn get_slot_capacity(&self, _slot_id: u8) -> AtcaSlotCapacity {
431 let result: AtcaSlotCapacity = { Default::default() };
432 result
433 }
434}
435
436impl AteccDevice {
437 pub fn new(r_iface_cfg: AtcaIfaceCfg) -> Result<AteccDevice, String> {
438 let mut device = AteccDevice::default();
439 match r_iface_cfg.iface_type {
440 AtcaIfaceType::AtcaTestIface => (),
441 _ => {
442 let err = format!(
443 "Software implementation of an AteccDevice does not support interface {}",
444 r_iface_cfg.iface_type
445 );
446 return Err(err);
447 }
448 }
449 device.dev_type = match r_iface_cfg.devtype {
450 AtcaDeviceType::AtcaTestDevFail => AtcaDeviceType::AtcaTestDevFail,
451 AtcaDeviceType::AtcaTestDevSuccess => AtcaDeviceType::AtcaTestDevSuccess,
452 AtcaDeviceType::AtcaTestDevFailUnimplemented => {
453 AtcaDeviceType::AtcaTestDevFailUnimplemented
454 }
455 _ => {
456 let err = format!(
457 "Software implementation of an AteccDevice does not support interface {}",
458 r_iface_cfg.devtype
459 );
460 return Err(err);
461 }
462 };
463 Ok(device)
464 }
465 fn default_dev_status(&self) -> AtcaStatus {
466 match self.dev_type {
467 AtcaDeviceType::AtcaTestDevSuccess => AtcaStatus::AtcaSuccess,
468 _ => AtcaStatus::AtcaUnimplemented,
469 }
470 }
471}