tpm2: have CryptCreateObject handle nameAlg TPM_ALG_NULL

For symmetric objects (i.e. non-public key based objects),
name computation requires that a non NULL hash algorithm
be specified.

The hash algorithm is specified via direct user input,
and may hence be invalid.  The crash in bug chrome-os-partner:56767
was reached via CryptGenerateKeySymmetric, but a similar fix
applies to CryptGenerateKeyedHash (which also has a code-path
to the crash site).  Hence this change adds checks to both
CryptGenerateKeySymmetric and CryptGenerateKeyedHash, returning
error TPM_RC_VALUE if appropriate.

BRANCH=none
BUG=chrome-os-partner:56767
TEST=fuzz test no longer results in a crash; TCG tests pass

Change-Id: I8ed38bacd65368246b7f20cb4f76c803509165d3
Signed-off-by: nagendra modadugu <[email protected]>
Reviewed-on: https://chromium-review.googlesource.com/382864
Commit-Ready: Nagendra Modadugu <[email protected]>
Tested-by: Nagendra Modadugu <[email protected]>
Reviewed-by: Marius Schilder <[email protected]>
Reviewed-by: Bill Richardson <[email protected]>
Reviewed-by: Darren Krahn <[email protected]>
diff --git a/CryptUtil.c b/CryptUtil.c
index a60703c..5bb2158 100644
--- a/CryptUtil.c
+++ b/CryptUtil.c
@@ -688,6 +688,7 @@
 //      Error Returns                     Meaning
 //
 //      TPM_RC_SIZE                       sensitive data size is larger than allowed for the scheme
+//      TPM_RC_VALUE                      the publicArea nameAlg is invalid
 //
 static TPM_RC
 CryptGenerateKeyedHash(
@@ -703,6 +704,11 @@
    TPMT_KEYEDHASH_SCHEME          *scheme;
    TPM_ALG_ID                      hashAlg;
    UINT16                          hashBlockSize;
+   // Check parameter values
+   if(publicArea->nameAlg == TPM_ALG_NULL)
+   {
+       return TPM_RC_VALUE;
+   }
    scheme = &publicArea->parameters.keyedHashDetail.scheme;
    pAssert(publicArea->type == TPM_ALG_KEYEDHASH);
    // Pick the limiting hash algorithm
@@ -1927,6 +1933,7 @@
 //
 //       TPM_RC_KEY_SIZE                   key size in the public area does not match the size in the sensitive
 //                                         creation area
+//       TPM_RC_VALUE                      the publicArea nameAlg is invalid
 //
 static TPM_RC
 CryptGenerateKeySymmetric(
@@ -1939,6 +1946,11 @@
    TPM2B_NAME                     *name                      //   IN: name of the object
    )
 {
+   // Check parameter values
+   if(publicArea->nameAlg == TPM_ALG_NULL)
+   {
+       return TPM_RC_VALUE;
+   }
    // If this is not a new key, then the provided key data must be the right size
    if(publicArea->objectAttributes.sensitiveDataOrigin == CLEAR)
    {
@@ -2870,7 +2882,7 @@
 //                                         hash object
 //       TPM_RC_VALUE                      exponent is not prime or could not find a prime using the provided
 //                                         parameters for an RSA key; unsupported name algorithm for an ECC
-//                                         key
+//                                         key; unsupported name algorithm for symmetric algorithms
 //
 TPM_RC
 CryptCreateObject(