Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 46 additions & 15 deletions deps/verifier/src/hygon_tpm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ use eventlog_rs::{BiosEventlog, Eventlog};
use log::{debug, info};
use openssl::bn::{BigNum, BigNumContext};
use openssl::ec::{EcGroup, EcKey, EcPoint};
use openssl::ecdsa::EcdsaSig;
use openssl::hash::MessageDigest;
use openssl::nid::Nid;
use openssl::pkey::PKey;
use openssl::sign::Verifier as OpenSslVerifier;
use openssl::x509::X509;
use reqwest::Client;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -94,7 +91,7 @@ fn create_sm2_pkey(ak_pubkey: &HygonSm2PublicKey) -> Result<PKey<openssl::pkey::
Ok(PKey::from_ec_key(ec_key)?)
}

fn signature_to_der(sig_b64: &str) -> Result<Vec<u8>> {
fn extract_sm2_signature_components(sig_b64: &str) -> Result<(BigNum, BigNum)> {
let sig_bytes = base64::engine::general_purpose::STANDARD.decode(sig_b64)?;
let signature = Signature::unmarshall(&sig_bytes)?;
let Signature::Sm2(sm2_sig) = signature else {
Expand All @@ -103,8 +100,7 @@ fn signature_to_der(sig_b64: &str) -> Result<Vec<u8>> {

let r = BigNum::from_slice(sm2_sig.signature_r().value())?;
let s = BigNum::from_slice(sm2_sig.signature_s().value())?;
let sig = EcdsaSig::from_private_components(r, s)?;
Ok(sig.to_der()?)
Ok((r, s))
}

async fn verify_registrar_binding(evidence: &HygonTpmEvidence, uuid: &str) -> Result<()> {
Expand Down Expand Up @@ -420,17 +416,52 @@ fn parse_measurements_from_event(

impl HygonTpmQuote {
fn verify_signature(&self, ak_pubkey: &HygonSm2PublicKey) -> Result<()> {
let pkey = create_sm2_pkey(ak_pubkey)?;
let signature_der = signature_to_der(&self.attest_sig)?;
let (sig_r, sig_s) = extract_sm2_signature_components(&self.attest_sig)?;
let attest_body = base64::engine::general_purpose::STANDARD.decode(&self.attest_body)?;

// Reuse OpenSSL's current SM2-capable verification path that works with
// the crate version in this workspace. If real hardware shows a different
// distinguishing-ID requirement, we can narrow it on-device without
// changing the evidence schema or policy surface.
let mut verifier = OpenSslVerifier::new(MessageDigest::sm3(), &pkey)?;
verifier.update(&attest_body)?;
if !verifier.verify(&signature_der)? {
// TPM2 SM2 quotes sign SM3(attest_body) directly per the TPM2 spec —
// there is no GB/T 32918 ZA pre-processing. OpenSSL's EVP_DigestVerify
// path either applies ZA (digest mismatch) or, on a plain EC PKey,
// dispatches to ECDSA verify (wrong algorithm). Run the SM2 verify
// equation (GB/T 32918.2 §7.1) directly against e = SM3(attest_body).
let mut hasher = Sm3::new();
hasher.update(&attest_body);
let e_bytes = hasher.finalize();
let e = BigNum::from_slice(&e_bytes)?;

let nid = Nid::from_raw(openssl_sys::NID_sm2);
let group = EcGroup::from_curve_name(nid)?;
let mut ctx = BigNumContext::new()?;
let mut order = BigNum::new()?;
group.order(&mut order, &mut ctx)?;

let one = BigNum::from_u32(1)?;
if sig_r < one || sig_r >= order || sig_s < one || sig_s >= order {
bail!("Verify Hygon TPM quote signature failed");
}

let mut t = BigNum::new()?;
t.mod_add(&sig_r, &sig_s, &order, &mut ctx)?;
if t.num_bits() == 0 {
bail!("Verify Hygon TPM quote signature failed");
}

let bx = BigNum::from_hex_str(&ak_pubkey.x)?;
let by = BigNum::from_hex_str(&ak_pubkey.y)?;
let mut q = EcPoint::new(&group)?;
q.set_affine_coordinates_gfp(&group, &bx, &by, &mut ctx)?;

let mut p = EcPoint::new(&group)?;
p.mul_full(&group, &sig_s, &q, &t, &mut ctx)?;

let mut x1 = BigNum::new()?;
let mut y1 = BigNum::new()?;
p.affine_coordinates_gfp(&group, &mut x1, &mut y1, &mut ctx)?;

let mut r_check = BigNum::new()?;
r_check.mod_add(&e, &x1, &order, &mut ctx)?;

if r_check != sig_r {
bail!("Verify Hygon TPM quote signature failed");
}

Expand Down
14 changes: 13 additions & 1 deletion rpm/trustee.spec
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
%global __brp_mangle_shebangs %{nil}

Name: trustee
Version: 1.8.3
Version: 1.8.4
Release: %{alinux_release}%{?dist}
Summary: Daemon services for attestation and secret distribution
Group: Applications/System
Expand Down Expand Up @@ -148,6 +148,18 @@ fi
/var/lib/attestation/token/ear/policies/opa/default.rego

%changelog
* Mon May 18 2026 Jiale Zhang <xinjian.zjl@alibaba-inc.com> -1.8.4-1
- KBS: support private cloud Aliyun KMS endpoints
- AS: add signer transparency support
- Verifier: add Hygon TPM verifier with sm2/sm3 keylime support
- Verifier/TDX: expose TCB verification result and supplemental data in claims
- Verifier: make eventlog a required dependency
- RVPS: export types for external use, add release manifest Rekor support
- Gateway: prefer instance info IP in audit records
- Gateway: fix AA instance heartbeat deduplication
- Rekor v2: unify provenance metadata schema and add OCI-based RVPS verification path
- Release: keep SLSA provenance in release workflow

* Thu Mar 26 2026 Jiale Zhang <xinjian.zjl@alibaba-inc.com> -1.8.3-1
- fix(slsa): generate and upload DSSE envelope for Rekor intoto
- chore(slsa): upgrade cosign/rekor-cli and align generator with v3 APIs
Expand Down
4 changes: 3 additions & 1 deletion trustee-gateway/internal/persistence/storage/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,9 @@ func (d *Database) migrateAAInstanceHeartbeatIndexMySQL() error {
logrus.Info("Cleaned up duplicate instance_id records in aa_instance_heartbeats")
}

if err := d.DB.Exec("CREATE UNIQUE INDEX idx_aa_heartbeat_instance_id ON aa_instance_heartbeats(instance_id)").Error; err != nil {
// Use a 191-char prefix to stay under MySQL InnoDB's 767-byte index key
// limit when instance_id is VARCHAR(255) utf8mb4 (4 bytes/char → 1020 bytes).
if err := d.DB.Exec("CREATE UNIQUE INDEX idx_aa_heartbeat_instance_id ON aa_instance_heartbeats(instance_id(191))").Error; err != nil {
return fmt.Errorf("failed to create unique index on instance_id: %w", err)
}

Expand Down
Loading