tasign 0.2.3

TA ELF signing utilities with CMS/PKCS#7 support
Documentation
//! Hash types and SM3 / SHA-256 digests via `tee_crypto`.

extern crate alloc;

use alloc::vec::Vec;

use tee_crypto::hash::{Digest as TeeDigest, Sha256, Sm3};

/// Hash algorithm identifier for [`Pk`] CMS signing (SM3 / SHA-256 only).
///
/// PKIX chain verification via [`tee_crypto::pkix`] supports additional digest
/// algorithms (RSA SHA-384/512, ECDSA P-384, etc.); this enum reflects the
/// historical tasign `Pk::sign` / `Pk::verify` surface.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MdType {
    SM3,
    Sha256,
}

/// Trait for cryptographic hash functions.
pub trait Digest {
    fn new() -> Self
    where
        Self: Sized;

    fn update(&mut self, data: &[u8]);

    fn finalize(self) -> Vec<u8>;

    fn output_size() -> usize;

    fn name() -> &'static str;
}

/// SM3 hash (32-byte output).
#[derive(Clone)]
pub struct Sm3Hasher {
    inner: Sm3,
}

impl Digest for Sm3Hasher {
    fn new() -> Self {
        Self {
            inner: Sm3::new(),
        }
    }

    fn update(&mut self, data: &[u8]) {
        self.inner.update(data);
    }

    fn finalize(self) -> Vec<u8> {
        self.inner.finalize().as_bytes().to_vec()
    }

    fn output_size() -> usize {
        32
    }

    fn name() -> &'static str {
        "SM3"
    }
}

/// Compute a 32-byte digest.
pub fn digest32(md: MdType, data: &[u8]) -> crate::crypto::Result<[u8; 32]> {
    match md {
        MdType::SM3 => {
            let mut h = Sm3Hasher::new();
            h.update(data);
            let v = h.finalize();
            let mut out = [0u8; 32];
            out.copy_from_slice(&v);
            Ok(out)
        }
        MdType::Sha256 => {
            let mut h = Sha256::new();
            h.update(data);
            let v = h.finalize();
            let mut out = [0u8; 32];
            out.copy_from_slice(v.as_bytes());
            Ok(out)
        }
    }
}