Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Certify, CertifyEx, and CertifyCreation return partial signature data #236

Closed
chrisfenner opened this issue Mar 5, 2021 · 0 comments · Fixed by #235
Closed

Certify, CertifyEx, and CertifyCreation return partial signature data #236

chrisfenner opened this issue Mar 5, 2021 · 0 comments · Fixed by #235

Comments

@chrisfenner
Copy link
Member

Here is the response description from the TPM 2.0 spec for the parameters returned from Certify and CertifyCreation:

Type Name Description
TPM2B_ATTEST certifyInfo the structure that was signed
TPMT_SIGNATURE signature the asymmetric signature ...

Here is decodeCertify which is used by all 3 of Certify, CertifyEx, and CertifyCreation:

go-tpm/tpm2/tpm2.go

Lines 1747 to 1778 in 1ff48da

func decodeCertify(resp []byte) ([]byte, []byte, error) {
var paramSize uint32
var attest, signature tpmutil.U16Bytes
var sigAlg, hashAlg Algorithm
buf := bytes.NewBuffer(resp)
if err := tpmutil.UnpackBuf(buf, &paramSize); err != nil {
return nil, nil, err
}
buf.Truncate(int(paramSize))
if err := tpmutil.UnpackBuf(buf, &attest, &sigAlg); err != nil {
return nil, nil, err
}
// If sigAlg is AlgNull, there will be no hashAlg or signature.
// This will happen if AlgNull was passed in the Certify() as
// the signing key (no need to sign the response).
// See TPM2 spec part4 pg227 SignAttestInfo()
if sigAlg != AlgNull {
if sigAlg == AlgECDSA {
var r, s tpmutil.U16Bytes
if err := tpmutil.UnpackBuf(buf, &hashAlg, &r, &s); err != nil {
return nil, nil, err
}
signature = append(r, s...)
} else {
if err := tpmutil.UnpackBuf(buf, &hashAlg, &signature); err != nil {
return nil, nil, err
}
}
}
return attest, signature, nil
}

In particular, note that the second parameter is signature which is the parsed raw RSA signature (exponentiated plaintext modulo key's modulus) or ECDSA signature (r, s pair). This is a loss of the following data:

  • sigAlg from TPMT_SIGNATURE
  • hash from TPMS_SIGNATURE_ECC if sigAlg indicated an ECC signature, or from TPMS_SIGNATURE_RSA if sigAlg indicated an RSA signature.

This means that a consumer of the output of the Certify command (via Certify or CertifyEx) or CertifyCreation command has to remember or guess the signature algorithm, as well as the hash algorithm that was used.

  • Guessing the sigAlg parameter is not trivially "if it's small, it's ECC, else RSA" because TPM supports multiple schemes per algorithm family (e.g., either PSS or PKCS1.5 for RSA). So throwing this data away harms potential users of the API.
  • Guessing the hash is reasonably done in 2021 by assuming it's SHA2-256, but this is subject to change and should be expected to as more TPMs support SHA2-384 and users become interested in that algorithm.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant