From 3c41d9a9724d0539d99791e4f1560dd7a5285bc6 Mon Sep 17 00:00:00 2001 From: Chris Coulson Date: Wed, 10 Apr 2024 14:55:12 +0100 Subject: [PATCH] cryptutil,policyutil: avoid some panics in various places --- cryptutil/secret.go | 3 +++ cryptutil/signatures.go | 8 ++++++-- policyutil/auth.go | 7 +++---- policyutil/builder.go | 3 ++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/cryptutil/secret.go b/cryptutil/secret.go index 258e5ec..1ce83cb 100644 --- a/cryptutil/secret.go +++ b/cryptutil/secret.go @@ -28,6 +28,9 @@ import ( // The specified digest algorithm must match the name algorithm of the public area associated with // the supplied private key. func SecretDecrypt(priv crypto.PrivateKey, hashAlg tpm2.HashAlgorithmId, label, secret []byte) (seed []byte, err error) { + if !hashAlg.Available() { + return nil, errors.New("digest algorithm is not available") + } return internal_crypt.SecretDecrypt(priv, hashAlg.GetHash(), label, secret) } diff --git a/cryptutil/signatures.go b/cryptutil/signatures.go index 7970c2e..6e0a68e 100644 --- a/cryptutil/signatures.go +++ b/cryptutil/signatures.go @@ -62,8 +62,6 @@ func digestFromSignerOpts(opts crypto.SignerOpts) (tpm2.HashAlgorithmId, error) // Sign creates a signature of the supplied digest using the supplied signer and options. // Note that only RSA-SSA, RSA-PSS, ECDSA and HMAC signatures can be created. The returned // signature can be verified on a TPM using the associated public key. -// -// This may panic if the requested digest algorithm is not available. func Sign(rand io.Reader, signer crypto.Signer, digest []byte, opts crypto.SignerOpts) (*tpm2.Signature, error) { hashAlg, err := digestFromSignerOpts(opts) if err != nil { @@ -75,10 +73,16 @@ func Sign(rand io.Reader, signer crypto.Signer, digest []byte, opts crypto.Signe switch k := signer.Public().(type) { case *rsa.PublicKey: _ = k + if _, pss := opts.(*rsa.PSSOptions); pss && !hashAlg.Available() { + return nil, errors.New("digest algorithm is not available") + } case *ecdsa.PublicKey: _ = k case HMACKey: _ = k + if !hashAlg.Available() { + return nil, errors.New("digest algorithm is not available") + } default: return nil, errors.New("unsupported key type") } diff --git a/policyutil/auth.go b/policyutil/auth.go index 696975b..c6e09f7 100644 --- a/policyutil/auth.go +++ b/policyutil/auth.go @@ -43,9 +43,10 @@ type PolicyAuthorization struct { // approved policy digest. This can sign authorizations for TPM2_PolicySigned as well, but // [SignPolicySignedAuthorization] is preferred for that because it constructs the message // appropriately. -// -// This will panic if the specified digest algorithm is not available. func SignPolicyAuthorization(rand io.Reader, message []byte, authKey *tpm2.Public, policyRef tpm2.Nonce, signer crypto.Signer, opts crypto.SignerOpts) (*PolicyAuthorization, error) { + if !opts.HashFunc().Available() { + return nil, errors.New("digest algorithm is not available") + } digest := ComputePolicyAuthorizationTBSDigest(opts.HashFunc(), message, policyRef) sig, err := cryptutil.Sign(rand, signer, digest, opts) if err != nil { @@ -127,8 +128,6 @@ type PolicySignedParams struct { // sessions, and its validity period and scope are restricted by the expiration and cpHashA // arguments. If the authorization is not bound to a specific session, the ticket will expire on // the next TPM reset if this occurs before the calculated expiration time -// -// This will panic if the requested digest algorithm is not available. func SignPolicySignedAuthorization(rand io.Reader, params *PolicySignedParams, authKey *tpm2.Public, policyRef tpm2.Nonce, signer crypto.Signer, opts crypto.SignerOpts) (*PolicySignedAuthorization, error) { if params == nil { params = new(PolicySignedParams) diff --git a/policyutil/builder.go b/policyutil/builder.go index b7e4e39..cad6e10 100644 --- a/policyutil/builder.go +++ b/policyutil/builder.go @@ -716,7 +716,8 @@ type PolicyBuilder struct { err error } -// NewPolicyBuilder returns a new PolicyBuilder. +// NewPolicyBuilder returns a new PolicyBuilder. It will panic if the supplied algorithm +// is not available. func NewPolicyBuilder(alg tpm2.HashAlgorithmId) *PolicyBuilder { if !alg.Available() { panic("invalid algorithm")