Skip to main content

parsec_service/providers/cryptoauthlib/
mod.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3//! Microchip CryptoAuthentication Library provider
4//!
5//! This provider implements Parsec operations using CryptoAuthentication
6//! Library backed by the ATECCx08 cryptochip.
7use super::Provide;
8use crate::authenticators::ApplicationIdentity;
9use crate::key_info_managers::{KeyIdentity, KeyInfoManagerClient};
10use crate::providers::ProviderIdentity;
11use crate::providers::cryptoauthlib::key_slot_storage::KeySlotStorage;
12use derivative::Derivative;
13use log::{error, trace, warn};
14use parsec_interface::operations::list_providers::ProviderInfo;
15use parsec_interface::operations::list_providers::Uuid;
16use parsec_interface::operations::{list_clients, list_keys};
17use parsec_interface::requests::{Opcode, ProviderId, ResponseStatus, Result};
18use std::collections::HashSet;
19use std::io::{Error, ErrorKind};
20
21use parsec_interface::operations::{
22    psa_aead_decrypt, psa_aead_encrypt, psa_cipher_decrypt, psa_cipher_encrypt, psa_destroy_key,
23    psa_export_key, psa_export_public_key, psa_generate_key, psa_generate_random, psa_hash_compare,
24    psa_hash_compute, psa_import_key, psa_raw_key_agreement, psa_sign_hash, psa_sign_message,
25    psa_verify_hash, psa_verify_message,
26};
27
28mod access_keys;
29mod aead;
30mod asym_sign;
31mod cipher;
32mod generate_random;
33mod hash;
34mod key_agreement;
35mod key_management;
36mod key_slot;
37mod key_slot_storage;
38
39/// CryptoAuthLib provider structure
40#[derive(Derivative)]
41#[derivative(Debug)]
42pub struct Provider {
43    #[derivative(Debug = "ignore")]
44    device: rust_cryptoauthlib::AteccDevice,
45    provider_id: ProviderId,
46    // The identity of the provider including uuid & name.
47    provider_identity: ProviderIdentity,
48    #[derivative(Debug = "ignore")]
49    key_info_store: KeyInfoManagerClient,
50    key_slots: KeySlotStorage,
51    supported_opcodes: HashSet<Opcode>,
52}
53
54impl Provider {
55    /// The default provider name for cryptoauthlib provider
56    pub const DEFAULT_PROVIDER_NAME: &'static str = "cryptoauthlib-provider";
57
58    /// The UUID for this provider
59    pub const PROVIDER_UUID: &'static str = "b8ba81e2-e9f7-4bdd-b096-a29d0019960c";
60
61    /// Creates and initialises an instance of CryptoAuthLibProvider
62    fn new(
63        provider_name: String,
64        key_info_store: KeyInfoManagerClient,
65        atca_iface: rust_cryptoauthlib::AtcaIfaceCfg,
66        access_key_file_name: Option<String>,
67    ) -> Option<Provider> {
68        // First define communication channel with the device then set it up
69        let device = match rust_cryptoauthlib::setup_atecc_device(atca_iface) {
70            Ok(dev) => dev,
71            Err(err) => {
72                error!("ATECC device initialization failed: {}", err);
73                return None;
74            }
75        };
76
77        // ATECC is useful for non-trivial usage only when its configuration is locked
78        if !device.is_configuration_locked() {
79            error!("Error: configuration is not locked.");
80            return None;
81        }
82
83        let mut cryptoauthlib_provider = Provider {
84            device,
85            provider_id: ProviderId::CryptoAuthLib,
86            provider_identity: ProviderIdentity {
87                name: provider_name,
88                uuid: String::from(Self::PROVIDER_UUID),
89            },
90            key_info_store,
91            key_slots: KeySlotStorage::new(),
92            supported_opcodes: HashSet::new(),
93        };
94
95        // Get the configuration from ATECC...
96        let mut atecc_config_vec = Vec::<rust_cryptoauthlib::AtcaSlot>::new();
97        let err = cryptoauthlib_provider
98            .device
99            .get_config(&mut atecc_config_vec);
100        if rust_cryptoauthlib::AtcaStatus::AtcaSuccess != err {
101            error!("atecc_get_config failed: {}", err);
102            return None;
103        }
104
105        // ... and set the key slots configuration as read from hardware
106        if let Err(err) = cryptoauthlib_provider
107            .key_slots
108            .set_hw_config(&atecc_config_vec)
109        {
110            error!("Applying hardware configuration failed: {}", err);
111            return None;
112        }
113
114        // Validate key info store against hardware configuration.
115        // Delete invalid entries or invalid mappings.
116        // Mark the slots free/busy appropriately.
117        let mut to_remove: Vec<KeyIdentity> = Vec::new();
118        match cryptoauthlib_provider.key_info_store.get_all() {
119            Ok(key_identities) => {
120                for key_identity in key_identities.iter() {
121                    match cryptoauthlib_provider
122                        .key_info_store
123                        .does_not_exist(key_identity)
124                    {
125                        Ok(x) => x,
126                        Err(err) => {
127                            warn!(
128                                "Error getting the Key ID for KeyIdentity:\n{}\n(error: {}), continuing...",
129                                key_identity, err
130                            );
131                            to_remove.push(key_identity.clone());
132                            continue;
133                        }
134                    };
135                    let key_info_id = match cryptoauthlib_provider
136                        .key_info_store
137                        .get_key_id::<u8>(key_identity)
138                    {
139                        Ok(x) => x,
140                        Err(err) => {
141                            warn!(
142                                "Could not get key info id for KeyIdentity {:?} because {}",
143                                key_identity, err
144                            );
145                            to_remove.push(key_identity.clone());
146                            continue;
147                        }
148                    };
149                    let key_info_attributes = match cryptoauthlib_provider
150                        .key_info_store
151                        .get_key_attributes(key_identity)
152                    {
153                        Ok(x) => x,
154                        Err(err) => {
155                            warn!(
156                                "Could not get key attributes for KeyIdentity {:?} because {}",
157                                key_identity, err
158                            );
159                            to_remove.push(key_identity.clone());
160                            continue;
161                        }
162                    };
163                    match cryptoauthlib_provider
164                        .key_slots
165                        .key_validate_and_mark_busy(key_info_id, &key_info_attributes)
166                    {
167                        Ok(None) => (),
168                        Ok(Some(warning)) => {
169                            warn!("{} for KeyIdentity {:?}", warning, key_identity)
170                        }
171                        Err(err) => {
172                            warn!("{} for KeyIdentity {:?}", err, key_identity);
173                            to_remove.push(key_identity.clone());
174                            continue;
175                        }
176                    }
177                }
178            }
179            Err(err) => {
180                error!("Key Info Manager error: {}", err);
181                return None;
182            }
183        };
184        for key_identity in to_remove.iter() {
185            if let Err(err) = cryptoauthlib_provider
186                .key_info_store
187                .remove_key_info(key_identity)
188            {
189                error!("Key Info Manager error: {}", err);
190                return None;
191            }
192        }
193
194        if cryptoauthlib_provider.set_opcodes().is_none() {
195            warn!("Failed to setup opcodes for cryptoauthlib_provider");
196        }
197
198        let err = cryptoauthlib_provider.set_access_keys(access_key_file_name);
199        match err {
200            Some(rust_cryptoauthlib::AtcaStatus::AtcaSuccess) => (),
201            _ => {
202                warn!("Unable to set access keys. This is dangerous for a hardware interface.");
203            }
204        }
205
206        Some(cryptoauthlib_provider)
207    }
208
209    fn set_opcodes(&mut self) -> Option<()> {
210        match self.device.get_device_type() {
211            rust_cryptoauthlib::AtcaDeviceType::ATECC508A
212            | rust_cryptoauthlib::AtcaDeviceType::ATECC608A
213            | rust_cryptoauthlib::AtcaDeviceType::ATECC108A => {
214                if self.supported_opcodes.insert(Opcode::PsaGenerateKey)
215                    && self.supported_opcodes.insert(Opcode::PsaDestroyKey)
216                    && self.supported_opcodes.insert(Opcode::PsaHashCompute)
217                    && self.supported_opcodes.insert(Opcode::PsaHashCompare)
218                    && self.supported_opcodes.insert(Opcode::PsaGenerateRandom)
219                    && self.supported_opcodes.insert(Opcode::PsaImportKey)
220                    && self.supported_opcodes.insert(Opcode::PsaSignHash)
221                    && self.supported_opcodes.insert(Opcode::PsaVerifyHash)
222                    && self.supported_opcodes.insert(Opcode::PsaCipherEncrypt)
223                    && self.supported_opcodes.insert(Opcode::PsaCipherDecrypt)
224                    && self.supported_opcodes.insert(Opcode::PsaSignMessage)
225                    && self.supported_opcodes.insert(Opcode::PsaVerifyMessage)
226                    && self.supported_opcodes.insert(Opcode::PsaExportPublicKey)
227                    && self.supported_opcodes.insert(Opcode::PsaExportKey)
228                    && self.supported_opcodes.insert(Opcode::PsaAeadEncrypt)
229                    && self.supported_opcodes.insert(Opcode::PsaAeadDecrypt)
230                    && self.supported_opcodes.insert(Opcode::PsaRawKeyAgreement)
231                {
232                    Some(())
233                } else {
234                    None
235                }
236            }
237            rust_cryptoauthlib::AtcaDeviceType::AtcaTestDevSuccess
238            | rust_cryptoauthlib::AtcaDeviceType::AtcaTestDevFail
239            | rust_cryptoauthlib::AtcaDeviceType::AtcaTestDevFailUnimplemented => {
240                let _ = self.supported_opcodes.insert(Opcode::PsaGenerateRandom);
241                Some(())
242            }
243            _ => None,
244        }
245    }
246}
247
248impl Provide for Provider {
249    fn describe(&self) -> Result<(ProviderInfo, HashSet<Opcode>)> {
250        trace!("describe ingress");
251        Ok((
252            ProviderInfo {
253                // Assigned UUID for this provider: b8ba81e2-e9f7-4bdd-b096-a29d0019960c
254                uuid: Uuid::parse_str(Provider::PROVIDER_UUID)
255                    .or(Err(ResponseStatus::InvalidEncoding))?,
256                description: String::from(
257                    "User space hardware provider, utilizing MicrochipTech CryptoAuthentication Library for ATECCx08 chips",
258                ),
259                vendor: String::from("Arm"),
260                version_maj: 0,
261                version_min: 1,
262                version_rev: 0,
263                id: ProviderId::CryptoAuthLib,
264            },
265            self.supported_opcodes.iter().copied().collect(),
266        ))
267    }
268
269    fn list_keys(
270        &self,
271        application_identity: &ApplicationIdentity,
272        _op: list_keys::Operation,
273    ) -> Result<list_keys::Result> {
274        Ok(list_keys::Result {
275            keys: self.key_info_store.list_keys(application_identity)?,
276        })
277    }
278
279    fn list_clients(&self, _op: list_clients::Operation) -> Result<list_clients::Result> {
280        Ok(list_clients::Result {
281            clients: self
282                .key_info_store
283                .list_clients()?
284                .into_iter()
285                .map(|application_identity| application_identity.name().clone())
286                .collect(),
287        })
288    }
289
290    fn psa_hash_compute(
291        &self,
292        op: psa_hash_compute::Operation,
293    ) -> Result<psa_hash_compute::Result> {
294        trace!("psa_hash_compute ingress");
295        if !self.supported_opcodes.contains(&Opcode::PsaHashCompute) {
296            Err(ResponseStatus::PsaErrorNotSupported)
297        } else {
298            self.psa_hash_compute_internal(op)
299        }
300    }
301
302    fn psa_hash_compare(
303        &self,
304        op: psa_hash_compare::Operation,
305    ) -> Result<psa_hash_compare::Result> {
306        trace!("psa_hash_compare ingress");
307        if !self.supported_opcodes.contains(&Opcode::PsaHashCompare) {
308            Err(ResponseStatus::PsaErrorNotSupported)
309        } else {
310            self.psa_hash_compare_internal(op)
311        }
312    }
313
314    fn psa_generate_random(
315        &self,
316        op: psa_generate_random::Operation,
317    ) -> Result<psa_generate_random::Result> {
318        trace!("psa_generate_random ingress");
319        if !self.supported_opcodes.contains(&Opcode::PsaGenerateRandom) {
320            Err(ResponseStatus::PsaErrorNotSupported)
321        } else {
322            self.psa_generate_random_internal(op)
323        }
324    }
325
326    fn psa_generate_key(
327        &self,
328        application_identity: &ApplicationIdentity,
329        op: psa_generate_key::Operation,
330    ) -> Result<psa_generate_key::Result> {
331        trace!("psa_generate_key ingress");
332        if !self.supported_opcodes.contains(&Opcode::PsaGenerateKey) {
333            Err(ResponseStatus::PsaErrorNotSupported)
334        } else {
335            self.psa_generate_key_internal(application_identity, op)
336        }
337    }
338
339    fn psa_destroy_key(
340        &self,
341        application_identity: &ApplicationIdentity,
342        op: psa_destroy_key::Operation,
343    ) -> Result<psa_destroy_key::Result> {
344        trace!("psa_destroy_key ingress");
345        if !self.supported_opcodes.contains(&Opcode::PsaDestroyKey) {
346            Err(ResponseStatus::PsaErrorNotSupported)
347        } else {
348            self.psa_destroy_key_internal(application_identity, op)
349        }
350    }
351
352    fn psa_import_key(
353        &self,
354        application_identity: &ApplicationIdentity,
355        op: psa_import_key::Operation,
356    ) -> Result<psa_import_key::Result> {
357        trace!("psa_import_key ingress");
358        if !self.supported_opcodes.contains(&Opcode::PsaImportKey) {
359            Err(ResponseStatus::PsaErrorNotSupported)
360        } else {
361            self.psa_import_key_internal(application_identity, op)
362        }
363    }
364
365    fn psa_sign_hash(
366        &self,
367        application_identity: &ApplicationIdentity,
368        op: psa_sign_hash::Operation,
369    ) -> Result<psa_sign_hash::Result> {
370        trace!("psa_sign_hash ingress");
371        if !self.supported_opcodes.contains(&Opcode::PsaSignHash) {
372            Err(ResponseStatus::PsaErrorNotSupported)
373        } else {
374            self.psa_sign_hash_internal(application_identity, op)
375        }
376    }
377
378    fn psa_verify_hash(
379        &self,
380        application_identity: &ApplicationIdentity,
381        op: psa_verify_hash::Operation,
382    ) -> Result<psa_verify_hash::Result> {
383        trace!("psa_verify_hash ingress");
384        if !self.supported_opcodes.contains(&Opcode::PsaVerifyHash) {
385            Err(ResponseStatus::PsaErrorNotSupported)
386        } else {
387            self.psa_verify_hash_internal(application_identity, op)
388        }
389    }
390
391    fn psa_cipher_encrypt(
392        &self,
393        application_identity: &ApplicationIdentity,
394        op: psa_cipher_encrypt::Operation,
395    ) -> Result<psa_cipher_encrypt::Result> {
396        trace!("psa_cipher_encrypt ingress");
397        if !self.supported_opcodes.contains(&Opcode::PsaCipherEncrypt) {
398            Err(ResponseStatus::PsaErrorNotSupported)
399        } else {
400            self.psa_cipher_encrypt_internal(application_identity, op)
401        }
402    }
403
404    fn psa_cipher_decrypt(
405        &self,
406        application_identity: &ApplicationIdentity,
407        op: psa_cipher_decrypt::Operation,
408    ) -> Result<psa_cipher_decrypt::Result> {
409        trace!("psa_cipher_decrypt ingress");
410        if !self.supported_opcodes.contains(&Opcode::PsaCipherDecrypt) {
411            Err(ResponseStatus::PsaErrorNotSupported)
412        } else {
413            self.psa_cipher_decrypt_internal(application_identity, op)
414        }
415    }
416
417    fn psa_sign_message(
418        &self,
419        application_identity: &ApplicationIdentity,
420        op: psa_sign_message::Operation,
421    ) -> Result<psa_sign_message::Result> {
422        trace!("psa_sign_message ingress");
423        if !self.supported_opcodes.contains(&Opcode::PsaSignMessage) {
424            Err(ResponseStatus::PsaErrorNotSupported)
425        } else {
426            self.psa_sign_message_internal(application_identity, op)
427        }
428    }
429
430    fn psa_verify_message(
431        &self,
432        application_identity: &ApplicationIdentity,
433        op: psa_verify_message::Operation,
434    ) -> Result<psa_verify_message::Result> {
435        trace!("psa_verify_message ingress");
436        if !self.supported_opcodes.contains(&Opcode::PsaVerifyMessage) {
437            Err(ResponseStatus::PsaErrorNotSupported)
438        } else {
439            self.psa_verify_message_internal(application_identity, op)
440        }
441    }
442
443    fn psa_export_public_key(
444        &self,
445        application_identity: &ApplicationIdentity,
446        op: psa_export_public_key::Operation,
447    ) -> Result<psa_export_public_key::Result> {
448        trace!("psa_export_public_key ingress");
449        if !self.supported_opcodes.contains(&Opcode::PsaExportPublicKey) {
450            Err(ResponseStatus::PsaErrorNotSupported)
451        } else {
452            self.psa_export_public_key_internal(application_identity, op)
453        }
454    }
455
456    fn psa_export_key(
457        &self,
458        application_identity: &ApplicationIdentity,
459        op: psa_export_key::Operation,
460    ) -> Result<psa_export_key::Result> {
461        trace!("psa_export_key ingress");
462        if !self.supported_opcodes.contains(&Opcode::PsaExportKey) {
463            Err(ResponseStatus::PsaErrorNotSupported)
464        } else {
465            self.psa_export_key_internal(application_identity, op)
466        }
467    }
468
469    fn psa_aead_encrypt(
470        &self,
471        application_identity: &ApplicationIdentity,
472        op: psa_aead_encrypt::Operation,
473    ) -> Result<psa_aead_encrypt::Result> {
474        trace!("psa_aead_encrypt ingress");
475        if !self.supported_opcodes.contains(&Opcode::PsaAeadEncrypt) {
476            Err(ResponseStatus::PsaErrorNotSupported)
477        } else {
478            self.psa_aead_encrypt_internal(application_identity, op)
479        }
480    }
481
482    fn psa_aead_decrypt(
483        &self,
484        application_identity: &ApplicationIdentity,
485        op: psa_aead_decrypt::Operation,
486    ) -> Result<psa_aead_decrypt::Result> {
487        trace!("psa_aead_decrypt ingress");
488        if !self.supported_opcodes.contains(&Opcode::PsaAeadDecrypt) {
489            Err(ResponseStatus::PsaErrorNotSupported)
490        } else {
491            self.psa_aead_decrypt_internal(application_identity, op)
492        }
493    }
494
495    fn psa_raw_key_agreement(
496        &self,
497        application_identity: &ApplicationIdentity,
498        op: psa_raw_key_agreement::Operation,
499    ) -> Result<psa_raw_key_agreement::Result> {
500        trace!("psa_raw_key_agreement ingress");
501        if !self.supported_opcodes.contains(&Opcode::PsaRawKeyAgreement) {
502            Err(ResponseStatus::PsaErrorNotSupported)
503        } else {
504            self.psa_raw_key_agreement_internal(application_identity, op)
505        }
506    }
507}
508
509/// CryptoAuthentication Library Provider builder
510#[derive(Default, Derivative)]
511#[derivative(Debug)]
512pub struct ProviderBuilder {
513    provider_name: Option<String>,
514    #[derivative(Debug = "ignore")]
515    key_info_store: Option<KeyInfoManagerClient>,
516    device_type: Option<String>,
517    iface_type: Option<String>,
518    wake_delay: Option<u16>,
519    rx_retries: Option<i32>,
520    slave_address: Option<u8>,
521    bus: Option<u8>,
522    baud: Option<u32>,
523    access_key_file_name: Option<String>,
524}
525
526impl ProviderBuilder {
527    /// Create a new CryptoAuthLib builder
528    pub fn new() -> ProviderBuilder {
529        ProviderBuilder {
530            provider_name: None,
531            key_info_store: None,
532            device_type: None,
533            iface_type: None,
534            wake_delay: None,
535            rx_retries: None,
536            slave_address: None,
537            bus: None,
538            baud: None,
539            access_key_file_name: None,
540        }
541    }
542
543    /// Add a provider name
544    pub fn with_provider_name(mut self, provider_name: String) -> ProviderBuilder {
545        self.provider_name = Some(provider_name);
546
547        self
548    }
549
550    /// Add a KeyInfo manager
551    pub fn with_key_info_store(mut self, key_info_store: KeyInfoManagerClient) -> ProviderBuilder {
552        self.key_info_store = Some(key_info_store);
553
554        self
555    }
556
557    /// Specify the ATECC device to be used
558    pub fn with_device_type(mut self, device_type: String) -> ProviderBuilder {
559        self.device_type = Some(device_type);
560
561        self
562    }
563
564    /// Specify an interface type (expected: "i2c")
565    pub fn with_iface_type(mut self, iface_type: String) -> ProviderBuilder {
566        self.iface_type = Some(iface_type);
567
568        self
569    }
570
571    /// Specify a wake delay
572    pub fn with_wake_delay(mut self, wake_delay: Option<u16>) -> ProviderBuilder {
573        self.wake_delay = wake_delay;
574
575        self
576    }
577
578    /// Specify number of rx retries
579    pub fn with_rx_retries(mut self, rx_retries: Option<i32>) -> ProviderBuilder {
580        self.rx_retries = rx_retries;
581
582        self
583    }
584
585    /// Specify i2c slave address of ATECC device
586    pub fn with_slave_address(mut self, slave_address: Option<u8>) -> ProviderBuilder {
587        self.slave_address = slave_address;
588
589        self
590    }
591
592    /// Specify i2c bus for ATECC device
593    pub fn with_bus(mut self, bus: Option<u8>) -> ProviderBuilder {
594        self.bus = bus;
595
596        self
597    }
598
599    /// Specify i2c baudrate
600    pub fn with_baud(mut self, baud: Option<u32>) -> ProviderBuilder {
601        self.baud = baud;
602
603        self
604    }
605
606    /// Specify access key file name
607    pub fn with_access_key_file(mut self, access_key_file_name: Option<String>) -> ProviderBuilder {
608        self.access_key_file_name = access_key_file_name;
609
610        self
611    }
612
613    /// Attempt to build CryptoAuthLib Provider
614    pub fn build(self) -> std::io::Result<Provider> {
615        let iface_cfg = match self.iface_type {
616            Some(x) => match x.as_str() {
617                "i2c" => {
618                    let atcai2c_iface_cfg = rust_cryptoauthlib::AtcaIfaceI2c::default()
619                        .set_slave_address(self.slave_address.ok_or_else(|| {
620                            Error::new(ErrorKind::InvalidData, "missing atecc i2c slave address")
621                        })?)
622                        .set_bus(self.bus.ok_or_else(|| {
623                            Error::new(ErrorKind::InvalidData, "missing atecc i2c bus")
624                        })?)
625                        .set_baud(self.baud.ok_or_else(|| {
626                            Error::new(ErrorKind::InvalidData, "missing atecc i2c baud rate")
627                        })?);
628                    rust_cryptoauthlib::AtcaIfaceCfg::default()
629                        .set_iface_type("i2c".to_owned())
630                        .set_devtype(self.device_type.ok_or_else(|| {
631                            Error::new(ErrorKind::InvalidData, "missing atecc device type")
632                        })?)
633                        .set_wake_delay(self.wake_delay.ok_or_else(|| {
634                            Error::new(ErrorKind::InvalidData, "missing atecc wake delay")
635                        })?)
636                        .set_rx_retries(self.rx_retries.ok_or_else(|| {
637                            Error::new(
638                                ErrorKind::InvalidData,
639                                "missing rx retries number for atecc",
640                            )
641                        })?)
642                        .set_iface(
643                            rust_cryptoauthlib::AtcaIface::default().set_atcai2c(atcai2c_iface_cfg),
644                        )
645                }
646                "test-interface" => rust_cryptoauthlib::AtcaIfaceCfg::default()
647                    .set_iface_type("test-interface".to_owned())
648                    .set_devtype(self.device_type.ok_or_else(|| {
649                        Error::new(ErrorKind::InvalidData, "missing atecc device type")
650                    })?),
651                _ => {
652                    return Err(Error::new(
653                        ErrorKind::InvalidData,
654                        "Unsupported inteface type",
655                    ));
656                }
657            },
658            None => return Err(Error::new(ErrorKind::InvalidData, "Missing inteface type")),
659        };
660        Provider::new(
661            self.provider_name
662                .ok_or_else(|| Error::new(ErrorKind::InvalidData, "missing provider name"))?,
663            self.key_info_store
664                .ok_or_else(|| Error::new(ErrorKind::InvalidData, "missing key info store"))?,
665            iface_cfg,
666            self.access_key_file_name,
667        )
668        .ok_or_else(|| {
669            Error::new(
670                ErrorKind::InvalidData,
671                "CryptoAuthLib Provider initialization failed",
672            )
673        })
674    }
675}