Skip to main content

parsec_service/providers/cryptoauthlib/
hash.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use super::Provider;
4use log::error;
5use parsec_interface::operations::psa_algorithm::Hash;
6use parsec_interface::operations::psa_hash_compare;
7use parsec_interface::operations::psa_hash_compute;
8use parsec_interface::requests::{ResponseStatus, Result};
9
10impl Provider {
11    /// Calculate SHA2-256 digest for a given message using CALib.
12    /// Ensure proper return value type.
13    pub fn sha256(&self, msg: &[u8]) -> Result<psa_hash_compute::Result> {
14        let mut hash = vec![0u8; rust_cryptoauthlib::ATCA_SHA2_256_DIGEST_SIZE];
15        let result = self.device.sha(msg.to_vec(), &mut hash);
16        match result {
17            rust_cryptoauthlib::AtcaStatus::AtcaSuccess => {
18                Ok(psa_hash_compute::Result { hash: hash.into() })
19            }
20            _ => {
21                error!("Hash compute failed, hardware reported: {}.", result);
22                Err(ResponseStatus::PsaErrorHardwareFailure)
23            }
24        }
25    }
26
27    pub(super) fn psa_hash_compute_internal(
28        &self,
29        op: psa_hash_compute::Operation,
30    ) -> Result<psa_hash_compute::Result> {
31        match op.alg {
32            Hash::Sha256 => self.sha256(&op.input),
33            _ => Err(ResponseStatus::PsaErrorNotSupported),
34        }
35    }
36
37    pub(super) fn psa_hash_compare_internal(
38        &self,
39        op: psa_hash_compare::Operation,
40    ) -> Result<psa_hash_compare::Result> {
41        // check hash length
42        if op.hash.len() != Hash::Sha256.hash_length() {
43            error!("Invalid input hash length.");
44            return Err(ResponseStatus::PsaErrorInvalidArgument);
45        }
46        match op.alg {
47            Hash::Sha256 => {
48                // compute hash
49                let hash = self.sha256(&op.input)?.hash;
50                // compare input vs. computed hash
51                if op.hash != hash {
52                    error!("Hash comparison failed.");
53                    Err(ResponseStatus::PsaErrorInvalidSignature)
54                } else {
55                    Ok(psa_hash_compare::Result)
56                }
57            }
58            _ => Err(ResponseStatus::PsaErrorNotSupported),
59        }
60    }
61}