Skip to content

Code assumes using ECDSA P-384 / SHA-384 #990

Description

@MichalTarnacki

Per ### TDX Migration TD Design Guide Rev 0.9.3 (2025-08-21)

Table 7-1: MigTD cryptography algorithm

cryptography options recommendation
digital signature rsa, ecdsa ecdsa-nist_p384
key exchange ecdhe ecdhe-secp384r1
aead aes-gcm, chacha20-poly1305 aes-256-gcm

For "digital signature", the permitted options are RSA and ECDSA; P-384
is only the recommendation

However code already hard-force ECDSA P-384 / SHA-384 even though the spec
allows more options.

verify_signature() in src/migtd/src/ratls/server_client.rs:

fn verify_signature(cert: &Certificate, verified_report: &[u8]) -> CryptoResult<()> {
    let public_key = cert
        .tbs_certificate
        .subject_public_key_info
        .subject_public_key
        .as_bytes()
        .ok_or_else(|| CryptoError::ParseCertificate)?;
    let tbs = cert.tbs_certificate.to_der()?;
    let signature = cert.signature_value.as_bytes().ok_or_else(|| CryptoError::ParseCertificate)?;
    verify_public_key(verified_report, public_key)?;
    ecdsa_verify(public_key, &tbs, signature) // <-- P-384 only
}

ecdsa_verify is hard-wired to ECDSA_P384_SHA384_ASN1 in
src/crypto/src/rustls_impl/ecdsa.rs:

pub fn ecdsa_verify(public_key: &[u8], data: &[u8], signature: &[u8]) -> Result<()> {
    let pk = UnparsedPublicKey::new(&signature::ECDSA_P384_SHA384_ASN1, public_key);
    pk.verify(data, signature).map_err(|_e| Error::EcdsaVerify)
}

verify_signature_with_algorithm() in src/crypto/src/lib.rs:

// ECDSA with SHA-384: 1.2.840.10045.4.3.3
const ECDSA_WITH_SHA384: &[u32] = &[1, 2, 840, 10045, 4, 3, 3];

// Only ECDSA-P384 with SHA384 signature is supported
match oid_arcs.as_slice() {
    ECDSA_WITH_SHA384 => ecdsa::ecdsa_verify_with_algorithm(
        public_key,
        message,
        signature,
        &ecdsa::ECDSA_P384_SHA384_ASN1,
    )
    .map_err(|_| Error::SignatureVerification),
    _ => {
        // Unsupported algorithm
        Err(Error::UnsupportedAlgorithm)
    }
}

EcdsaPk::new() in src/crypto/src/rustls_impl/ecdsa.rs:

pub fn new() -> Result<Self> {
    let rand = SystemRandom::new();
    EcdsaKeyPair::generate_pkcs8(&signature::ECDSA_P384_SHA384_ASN1_SIGNING, &rand)
        .map(|pk| Self { pk })
        .map_err(|_| Error::GenerateKeyPair)
}

Requester in src/migtd/src/spdm/spdm_req.rs and
responder in src/migtd/src/spdm/spdm_rsp.rs:

let config_info = common::SpdmConfigInfo {
    // ...
    base_asym_algo: SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384,
    base_hash_algo: SpdmBaseHashAlgo::TPM_ALG_SHA_384,
    dhe_algo: SpdmDheAlgo::SECP_384_R1,
    aead_algo: SpdmAeadAlgo::AES_256_GCM,
    req_asym_algo: SpdmReqAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384,
    // ...
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions