Track Keymaster changes.

* MAC length is now specified as a parameters to the begin operation
  instead of as a parameter at key generation/import time.
* KM_TAG_MAC_LENGTH is now in bits instead of in bytes.

Change-Id: I752fe232d11d3ac39a575a48948215d84ded8fb9
diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java
index ed91d70..72cb062 100644
--- a/keystore/java/android/security/AndroidKeyStore.java
+++ b/keystore/java/android/security/AndroidKeyStore.java
@@ -486,16 +486,6 @@
             }
         }
         args.addInts(KeymasterDefs.KM_TAG_DIGEST, keymasterDigests);
-        if (keymasterDigests.length > 0) {
-            // TODO: Remove MAC length constraint once Keymaster API no longer requires it.
-            // This code will blow up if mode than one digest is specified.
-            int digestOutputSizeBytes =
-                    KeymasterUtils.getDigestOutputSizeBytes(keymasterDigests[0]);
-            if (digestOutputSizeBytes != -1) {
-                // TODO: Switch to bits instead of bytes, once this is fixed in Keymaster
-                args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, digestOutputSizeBytes);
-            }
-        }
         if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
             if (keymasterDigests.length == 0) {
                 throw new KeyStoreException("At least one digest algorithm must be specified"
diff --git a/keystore/java/android/security/KeyStoreHmacSpi.java b/keystore/java/android/security/KeyStoreHmacSpi.java
index 4590b9c..c52f61b 100644
--- a/keystore/java/android/security/KeyStoreHmacSpi.java
+++ b/keystore/java/android/security/KeyStoreHmacSpi.java
@@ -67,7 +67,7 @@
 
     private final KeyStore mKeyStore = KeyStore.getInstance();
     private final int mKeymasterDigest;
-    private final int mMacSizeBytes;
+    private final int mMacSizeBits;
 
     // Fields below are populated by engineInit and should be preserved after engineDoFinal.
     private KeyStoreSecretKey mKey;
@@ -79,12 +79,12 @@
 
     protected KeyStoreHmacSpi(int keymasterDigest) {
         mKeymasterDigest = keymasterDigest;
-        mMacSizeBytes = KeymasterUtils.getDigestOutputSizeBytes(keymasterDigest);
+        mMacSizeBits = KeymasterUtils.getDigestOutputSizeBits(keymasterDigest);
     }
 
     @Override
     protected int engineGetMacLength() {
-        return mMacSizeBytes;
+        return (mMacSizeBits + 7) / 8;
     }
 
     @Override
@@ -158,14 +158,16 @@
         KeymasterArguments keymasterArgs = new KeymasterArguments();
         keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_HMAC);
         keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
+        keymasterArgs.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mMacSizeBits);
 
+        KeymasterArguments keymasterOutputArgs = new KeymasterArguments();
         OperationResult opResult = mKeyStore.begin(
                 mKey.getAlias(),
                 KeymasterDefs.KM_PURPOSE_SIGN,
                 true,
                 keymasterArgs,
-                null,
-                new KeymasterArguments());
+                null, // no additional entropy needed for HMAC because it's deterministic
+                keymasterOutputArgs);
         if (opResult == null) {
             throw new KeyStoreConnectException();
         } else if ((opResult.resultCode != KeyStore.NO_ERROR)
diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
index 20f6042..68b5751 100644
--- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
@@ -45,7 +45,7 @@
         protected HmacBase(int keymasterDigest) {
             super(KeymasterDefs.KM_ALGORITHM_HMAC,
                     keymasterDigest,
-                    KeymasterUtils.getDigestOutputSizeBytes(keymasterDigest) * 8);
+                    KeymasterUtils.getDigestOutputSizeBits(keymasterDigest));
         }
     }
 
@@ -120,13 +120,6 @@
         args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
         if (mKeymasterDigest != -1) {
             args.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
-            int digestOutputSizeBytes =
-                    KeymasterUtils.getDigestOutputSizeBytes(mKeymasterDigest);
-            if (digestOutputSizeBytes != -1) {
-                // TODO: Remove MAC length constraint once Keymaster API no longer requires it.
-                // TODO: Switch to bits instead of bytes, once this is fixed in Keymaster
-                args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, digestOutputSizeBytes);
-            }
         }
         if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
             if (mKeymasterDigest == -1) {
diff --git a/keystore/java/android/security/KeymasterUtils.java b/keystore/java/android/security/KeymasterUtils.java
index 3ccb588..aa44ecd 100644
--- a/keystore/java/android/security/KeymasterUtils.java
+++ b/keystore/java/android/security/KeymasterUtils.java
@@ -179,22 +179,22 @@
         return result;
     }
 
-    public static int getDigestOutputSizeBytes(int keymasterDigest) {
+    public static int getDigestOutputSizeBits(int keymasterDigest) {
         switch (keymasterDigest) {
             case KeymasterDefs.KM_DIGEST_NONE:
                 return -1;
             case KeymasterDefs.KM_DIGEST_MD5:
-                return 128 / 8;
+                return 128;
             case KeymasterDefs.KM_DIGEST_SHA1:
-                return 160 / 8;
+                return 160;
             case KeymasterDefs.KM_DIGEST_SHA_2_224:
-                return 224 / 8;
+                return 224;
             case KeymasterDefs.KM_DIGEST_SHA_2_256:
-                return 256 / 8;
+                return 256;
             case KeymasterDefs.KM_DIGEST_SHA_2_384:
-                return 384 / 8;
+                return 384;
             case KeymasterDefs.KM_DIGEST_SHA_2_512:
-                return 512 / 8;
+                return 512;
             default:
                 throw new IllegalArgumentException("Unknown digest: " + keymasterDigest);
         }