parsec_service/providers/
mod.rs

1// Copyright 2019 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3//! Core inter-op with underlying hardware
4//!
5//! [Providers](https://parallaxsecond.github.io/parsec-book/parsec_service/providers.html)
6//! are the real implementors of the operations that Parsec claims to support. They map to
7//! functionality in the underlying hardware which allows the PSA Crypto operations to be
8//! backed by a hardware root of trust.
9use log::trace;
10use parsec_interface::requests::Opcode;
11use std::collections::HashSet;
12use std::convert::TryFrom;
13use std::fmt;
14
15pub mod core;
16
17pub mod crypto_capability;
18
19#[cfg(feature = "pkcs11-provider")]
20//TODO: To remove when #301 is merged
21#[allow(clippy::all)]
22pub mod pkcs11;
23
24#[cfg(feature = "mbed-crypto-provider")]
25pub mod mbed_crypto;
26
27#[cfg(feature = "tpm-provider")]
28pub mod tpm;
29
30#[cfg(feature = "cryptoauthlib-provider")]
31pub mod cryptoauthlib;
32
33#[cfg(feature = "trusted-service-provider")]
34pub mod trusted_service;
35
36use crate::authenticators::ApplicationIdentity;
37use parsec_interface::operations::{
38    attest_key, can_do_crypto, delete_client, list_authenticators, list_clients, list_keys,
39    list_opcodes, list_providers, ping, prepare_key_attestation, psa_aead_decrypt,
40    psa_aead_encrypt, psa_asymmetric_decrypt, psa_asymmetric_encrypt, psa_cipher_decrypt,
41    psa_cipher_encrypt, psa_destroy_key, psa_export_key, psa_export_public_key, psa_generate_key,
42    psa_generate_random, psa_hash_compare, psa_hash_compute, psa_import_key, psa_raw_key_agreement,
43    psa_sign_hash, psa_sign_message, psa_verify_hash, psa_verify_message,
44};
45use parsec_interface::requests::{ResponseStatus, Result};
46
47use parsec_interface::requests::ProviderId;
48
49/// The ProviderIdentity struct specifies a unique uuid-name
50/// combination to form a unique provider identity.
51#[derive(Debug, Clone, PartialEq, Eq, Hash)]
52pub struct ProviderIdentity {
53    /// The uuid of the provider
54    uuid: String,
55    /// The name of the provider set in the config, defaults to a suitable name.
56    name: String,
57}
58
59impl fmt::Display for ProviderIdentity {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        write!(
62            f,
63            "ProviderIdentity: [uuid=\"{}\", name=\"{}\"]",
64            self.uuid, self.name
65        )
66    }
67}
68
69impl ProviderIdentity {
70    /// Creates a new instance of ProviderIdentity.
71    pub fn new(uuid: String, name: String) -> ProviderIdentity {
72        ProviderIdentity { uuid, name }
73    }
74
75    /// Get the uuid of the provider
76    pub fn uuid(&self) -> &String {
77        &self.uuid
78    }
79
80    /// Get the name of the provider
81    pub fn name(&self) -> &String {
82        &self.name
83    }
84}
85
86impl TryFrom<ProviderIdentity> for ProviderId {
87    type Error = String;
88
89    fn try_from(provider_identity: ProviderIdentity) -> std::result::Result<Self, Self::Error> {
90        let provider_id = match provider_identity.uuid.as_str() {
91            core::Provider::PROVIDER_UUID => Ok(ProviderId::Core),
92            #[cfg(feature = "cryptoauthlib-provider")]
93            cryptoauthlib::Provider::PROVIDER_UUID => Ok(ProviderId::CryptoAuthLib),
94            #[cfg(feature = "mbed-crypto-provider")]
95            mbed_crypto::Provider::PROVIDER_UUID => Ok(ProviderId::MbedCrypto),
96            #[cfg(feature = "pkcs11-provider")]
97            pkcs11::Provider::PROVIDER_UUID => Ok(ProviderId::Pkcs11),
98            #[cfg(feature = "tpm-provider")]
99            tpm::Provider::PROVIDER_UUID => Ok(ProviderId::Tpm),
100            #[cfg(feature = "trusted-service-provider")]
101            trusted_service::Provider::PROVIDER_UUID => Ok(ProviderId::TrustedService),
102            _ => Err(format!("Cannot convert from ProviderIdentity to ProviderId.\nProvider \"{}\" is not recognised.\nCould be it does not exist, or Parsec was not compiled with the required provider feature flags.", provider_identity.uuid)),
103        }?;
104
105        Ok(provider_id)
106    }
107}
108
109/// Provider interface for servicing client operations
110///
111/// Definition of the interface that a provider must implement to
112/// be linked into the service through a backend handler.
113///
114/// The methods with no default are used on a service-level by the
115/// core provider and so must be supported by all providers.
116pub trait Provide {
117    /// Return a description of the current provider.
118    ///
119    /// The descriptions are gathered in the Core Provider and returned for a ListProviders operation.
120    fn describe(&self) -> Result<(list_providers::ProviderInfo, HashSet<Opcode>)>;
121
122    /// List the providers running in the service.
123    fn list_providers(&self, _op: list_providers::Operation) -> Result<list_providers::Result> {
124        trace!("list_providers ingress");
125        Err(ResponseStatus::PsaErrorNotSupported)
126    }
127
128    /// List the opcodes supported by the given provider.
129    fn list_opcodes(&self, _op: list_opcodes::Operation) -> Result<list_opcodes::Result> {
130        trace!("list_opcodes ingress");
131        Err(ResponseStatus::PsaErrorNotSupported)
132    }
133
134    /// List the authenticators supported by the given provider.
135    fn list_authenticators(
136        &self,
137        _op: list_authenticators::Operation,
138    ) -> Result<list_authenticators::Result> {
139        trace!("list_authenticators ingress");
140        Err(ResponseStatus::PsaErrorNotSupported)
141    }
142
143    /// Lists all keys belonging to the application.
144    fn list_keys(
145        &self,
146        _application_identity: &ApplicationIdentity,
147        _op: list_keys::Operation,
148    ) -> Result<list_keys::Result>;
149
150    /// Lists all clients currently having data in the service.
151    fn list_clients(&self, _op: list_clients::Operation) -> Result<list_clients::Result>;
152
153    /// Delete all data a client has in the service..
154    fn delete_client(
155        &self,
156        _application_identity: &ApplicationIdentity,
157        _op: delete_client::Operation,
158    ) -> Result<delete_client::Result> {
159        trace!("delete_client ingress");
160        Err(ResponseStatus::PsaErrorNotSupported)
161    }
162
163    /// Execute a Ping operation to get the wire protocol version major and minor information.
164    ///
165    /// # Errors
166    ///
167    /// This operation will only fail if not implemented. It will never fail when being called on
168    /// the `CoreProvider`.
169    fn ping(&self, _op: ping::Operation) -> Result<ping::Result> {
170        trace!("ping ingress");
171        Err(ResponseStatus::PsaErrorNotSupported)
172    }
173
174    /// Execute a GenerateKey operation.
175    ///
176    /// Providers should try, in a best-effort way, to handle failures in a way that it is possible
177    /// to create a key with the same name later on.
178    ///
179    /// For providers using a Key Info Manager to map a key name with a provider-specific key
180    /// identification, the following algorithm can be followed:
181    /// 1. generate unique key ID
182    /// 2. try key creation with it. If successfull go to 3 else return an error.
183    /// 3. store the mappings between key name and key ID. If successfull return success, else go to 4.
184    /// 4. try to delete the key created. If failed, log it and return the error from 3.
185    fn psa_generate_key(
186        &self,
187        _application_identity: &ApplicationIdentity,
188        _op: psa_generate_key::Operation,
189    ) -> Result<psa_generate_key::Result> {
190        trace!("psa_generate_key ingress");
191        Err(ResponseStatus::PsaErrorNotSupported)
192    }
193
194    /// Execute an ImportKey operation.
195    ///
196    /// Providers should try, in a best-effort way, to handle failures in a way that it is possible
197    /// to import a key with the same name later on.
198    ///
199    /// For providers using a Key Info Manager to map a key name with a provider-specific key
200    /// identification, the following algorithm can be followed:
201    /// 1. generate unique key ID
202    /// 2. try key import with it. If successfull go to 3 else return an error.
203    /// 3. store the mappings between key name and key ID. If successfull return success, else go to 4.
204    /// 4. try to delete the key imported. If failed, log it and return the error from 3.
205    fn psa_import_key(
206        &self,
207        _application_identity: &ApplicationIdentity,
208        _op: psa_import_key::Operation,
209    ) -> Result<psa_import_key::Result> {
210        trace!("psa_import_key ingress");
211        Err(ResponseStatus::PsaErrorNotSupported)
212    }
213
214    /// Execute an ExportPublicKey operation.
215    fn psa_export_public_key(
216        &self,
217        _application_identity: &ApplicationIdentity,
218        _op: psa_export_public_key::Operation,
219    ) -> Result<psa_export_public_key::Result> {
220        trace!("psa_export_public_key ingress");
221        Err(ResponseStatus::PsaErrorNotSupported)
222    }
223
224    /// Execute an ExportKey operation.
225    fn psa_export_key(
226        &self,
227        _application_identity: &ApplicationIdentity,
228        _op: psa_export_key::Operation,
229    ) -> Result<psa_export_key::Result> {
230        trace!("psa_export_key ingress");
231        Err(ResponseStatus::PsaErrorNotSupported)
232    }
233
234    /// Execute a DestroyKey operation.
235    ///
236    /// Providers should try, in a best-effort way, to handle failures in a way that it is possible
237    /// to generate or create a key with the same name than the one destroyed later on.
238    ///
239    /// For providers using a Key Info Manager to map a key name with a provider-specific key
240    /// identification, the following algorithm can be followed:
241    /// 1. get the key ID from the key name using the KIM
242    /// 2. destroy the key mappings
243    /// 3. try to destroy the key
244    fn psa_destroy_key(
245        &self,
246        _application_identity: &ApplicationIdentity,
247        _op: psa_destroy_key::Operation,
248    ) -> Result<psa_destroy_key::Result> {
249        trace!("psa_destroy_key ingress");
250        Err(ResponseStatus::PsaErrorNotSupported)
251    }
252
253    /// Execute a SignHash operation. This operation only signs the short digest given but does not
254    /// hash it.
255    fn psa_sign_hash(
256        &self,
257        _application_identity: &ApplicationIdentity,
258        _op: psa_sign_hash::Operation,
259    ) -> Result<psa_sign_hash::Result> {
260        trace!("psa_sign_hash ingress");
261        Err(ResponseStatus::PsaErrorNotSupported)
262    }
263
264    /// Execute a VerifyHash operation.
265    fn psa_verify_hash(
266        &self,
267        _application_identity: &ApplicationIdentity,
268        _op: psa_verify_hash::Operation,
269    ) -> Result<psa_verify_hash::Result> {
270        trace!("psa_verify_hash ingress");
271        Err(ResponseStatus::PsaErrorNotSupported)
272    }
273
274    /// Execute an AsymmetricEncrypt operation.
275    fn psa_asymmetric_encrypt(
276        &self,
277        _application_identity: &ApplicationIdentity,
278        _op: psa_asymmetric_encrypt::Operation,
279    ) -> Result<psa_asymmetric_encrypt::Result> {
280        trace!("psa_asymmetric_encrypt ingress");
281        Err(ResponseStatus::PsaErrorNotSupported)
282    }
283
284    /// Execute an AsymmetricDecrypt operation.
285    fn psa_asymmetric_decrypt(
286        &self,
287        _application_identity: &ApplicationIdentity,
288        _op: psa_asymmetric_decrypt::Operation,
289    ) -> Result<psa_asymmetric_decrypt::Result> {
290        trace!("psa_asymmetric_decrypt ingress");
291        Err(ResponseStatus::PsaErrorNotSupported)
292    }
293
294    /// Execute an AeadEncrypt operation.
295    fn psa_aead_encrypt(
296        &self,
297        _application_identity: &ApplicationIdentity,
298        _op: psa_aead_encrypt::Operation,
299    ) -> Result<psa_aead_encrypt::Result> {
300        trace!("psa_aead_encrypt ingress");
301        Err(ResponseStatus::PsaErrorNotSupported)
302    }
303
304    /// Execute an AeadDecrypt operation.
305    fn psa_aead_decrypt(
306        &self,
307        _application_identity: &ApplicationIdentity,
308        _op: psa_aead_decrypt::Operation,
309    ) -> Result<psa_aead_decrypt::Result> {
310        trace!("psa_aead_decrypt ingress");
311        Err(ResponseStatus::PsaErrorNotSupported)
312    }
313
314    /// Execute a HashCompute operation.
315    fn psa_hash_compute(
316        &self,
317        _op: psa_hash_compute::Operation,
318    ) -> Result<psa_hash_compute::Result> {
319        trace!("psa_hash_compute ingress");
320        Err(ResponseStatus::PsaErrorNotSupported)
321    }
322
323    /// Execute a HashCompare operation.
324    fn psa_hash_compare(
325        &self,
326        _op: psa_hash_compare::Operation,
327    ) -> Result<psa_hash_compare::Result> {
328        trace!("psa_hash_compare ingress");
329        Err(ResponseStatus::PsaErrorNotSupported)
330    }
331
332    /// Execute a RawKeyAgreement operation.
333    fn psa_raw_key_agreement(
334        &self,
335        _application_identity: &ApplicationIdentity,
336        _op: psa_raw_key_agreement::Operation,
337    ) -> Result<psa_raw_key_agreement::Result> {
338        trace!("psa_raw_key_agreement ingress");
339        Err(ResponseStatus::PsaErrorNotSupported)
340    }
341
342    /// Execute a GenerateRandom operation.
343    fn psa_generate_random(
344        &self,
345        _op: psa_generate_random::Operation,
346    ) -> Result<psa_generate_random::Result> {
347        trace!("psa_generate_random ingress");
348        Err(ResponseStatus::PsaErrorNotSupported)
349    }
350
351    /// Encrypt a short message with a symmetric cipher.
352    fn psa_cipher_encrypt(
353        &self,
354        _application_identity: &ApplicationIdentity,
355        _op: psa_cipher_encrypt::Operation,
356    ) -> Result<psa_cipher_encrypt::Result> {
357        trace!("psa_cipher_encrypt ingress");
358        Err(ResponseStatus::PsaErrorNotSupported)
359    }
360
361    /// Decrypt a short message with a symmetric cipher.
362    fn psa_cipher_decrypt(
363        &self,
364        _application_identity: &ApplicationIdentity,
365        _op: psa_cipher_decrypt::Operation,
366    ) -> Result<psa_cipher_decrypt::Result> {
367        trace!("psa_cipher_decrypt ingress");
368        Err(ResponseStatus::PsaErrorNotSupported)
369    }
370
371    /// Sign a message with a private key.
372    fn psa_sign_message(
373        &self,
374        _application_identity: &ApplicationIdentity,
375        _op: psa_sign_message::Operation,
376    ) -> Result<psa_sign_message::Result> {
377        trace!("psa_sign_message ingress");
378        Err(ResponseStatus::PsaErrorNotSupported)
379    }
380
381    /// Verify the signature of a message using a public key.
382    fn psa_verify_message(
383        &self,
384        _application_identity: &ApplicationIdentity,
385        _op: psa_verify_message::Operation,
386    ) -> Result<psa_verify_message::Result> {
387        trace!("psa_verify_message ingress");
388        Err(ResponseStatus::PsaErrorNotSupported)
389    }
390
391    ///Check if the crypto operation is supported by provider.
392    fn can_do_crypto(
393        &self,
394        _application_identity: &ApplicationIdentity,
395        _op: can_do_crypto::Operation,
396    ) -> Result<can_do_crypto::Result> {
397        trace!("can_do_crypto main ingress");
398        Err(ResponseStatus::PsaErrorNotSupported)
399    }
400
401    /// Prepare a key attestation operation.
402    fn prepare_key_attestation(
403        &self,
404        _application_identity: &ApplicationIdentity,
405        _op: prepare_key_attestation::Operation,
406    ) -> Result<prepare_key_attestation::Result> {
407        trace!("prepare_key_attestation ingress");
408        Err(ResponseStatus::PsaErrorNotSupported)
409    }
410
411    /// Attest a key.
412    fn attest_key(
413        &self,
414        _application_identity: &ApplicationIdentity,
415        _op: attest_key::Operation,
416    ) -> Result<attest_key::Result> {
417        trace!("attest_key ingress");
418        Err(ResponseStatus::PsaErrorNotSupported)
419    }
420}