diff options
author | Alex Klyubin <klyubin@google.com> | 2015-07-22 15:24:27 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-07-22 15:24:27 +0000 |
commit | ada70be897fb7541129f1ab1f6faa94a80fca986 (patch) | |
tree | 4686db46b90b94925b7d73643a0616b0bba5354f /keystore | |
parent | ff21279e2cbe0bdd9c41350b7a204cabf9370377 (diff) | |
parent | a95550f8016bbb0dba086dbd73eec63e6cdbbe98 (diff) | |
download | frameworks_base-ada70be897fb7541129f1ab1f6faa94a80fca986.zip frameworks_base-ada70be897fb7541129f1ab1f6faa94a80fca986.tar.gz frameworks_base-ada70be897fb7541129f1ab1f6faa94a80fca986.tar.bz2 |
Merge "Add KM_MIN_MAC_LENGTH tag to HMAC and AES-GCM keys." into mnc-dev
Diffstat (limited to 'keystore')
4 files changed, 55 insertions, 2 deletions
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java index 5459bea..441ee66 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java @@ -51,7 +51,7 @@ import javax.crypto.spec.GCMParameterSpec; abstract class AndroidKeyStoreAuthenticatedAESCipherSpi extends AndroidKeyStoreCipherSpiBase { abstract static class GCM extends AndroidKeyStoreAuthenticatedAESCipherSpi { - private static final int MIN_SUPPORTED_TAG_LENGTH_BITS = 96; + static final int MIN_SUPPORTED_TAG_LENGTH_BITS = 96; private static final int MAX_SUPPORTED_TAG_LENGTH_BITS = 128; private static final int DEFAULT_TAG_LENGTH_BITS = 128; private static final int IV_LENGTH_BYTES = 12; diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java index fd014eb..4c174f1 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java @@ -171,7 +171,7 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { "Key size must be positive: " + mKeySizeBits); } else if ((mKeySizeBits % 8) != 0) { throw new InvalidAlgorithmParameterException( - "Key size in must be a multiple of 8: " + mKeySizeBits); + "Key size must be a multiple of 8: " + mKeySizeBits); } try { @@ -272,6 +272,11 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { KeymasterUtils.addUserAuthArgs(args, spec.isUserAuthenticationRequired(), spec.getUserAuthenticationValidityDurationSeconds()); + KeymasterUtils.addMinMacLengthAuthorizationIfNecessary( + args, + mKeymasterAlgorithm, + mKeymasterBlockModes, + mKeymasterDigests); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, spec.getKeyValidityStart()); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, spec.getKeyValidityForOriginationEnd()); diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java index 88858de..915d86f 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java @@ -672,6 +672,11 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { KeymasterUtils.addUserAuthArgs(args, params.isUserAuthenticationRequired(), params.getUserAuthenticationValidityDurationSeconds()); + KeymasterUtils.addMinMacLengthAuthorizationIfNecessary( + args, + keymasterAlgorithm, + keymasterBlockModes, + keymasterDigests); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, params.getKeyValidityStart()); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java index 92d636c..feafbfa 100644 --- a/keystore/java/android/security/keystore/KeymasterUtils.java +++ b/keystore/java/android/security/keystore/KeymasterUtils.java @@ -22,6 +22,8 @@ import android.security.KeyStore; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; +import java.security.ProviderException; + /** * @hide */ @@ -133,4 +135,45 @@ public abstract class KeymasterUtils { userAuthenticationValidityDurationSeconds); } } + + /** + * Adds {@code KM_TAG_MIN_MAC_LENGTH} tag, if necessary, to the keymaster arguments for + * generating or importing a key. This tag may only be needed for symmetric keys (e.g., HMAC, + * AES-GCM). + */ + public static void addMinMacLengthAuthorizationIfNecessary(KeymasterArguments args, + int keymasterAlgorithm, + int[] keymasterBlockModes, + int[] keymasterDigests) { + switch (keymasterAlgorithm) { + case KeymasterDefs.KM_ALGORITHM_AES: + if (com.android.internal.util.ArrayUtils.contains( + keymasterBlockModes, KeymasterDefs.KM_MODE_GCM)) { + // AES GCM key needs the minimum length of AEAD tag specified. + args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH, + AndroidKeyStoreAuthenticatedAESCipherSpi.GCM + .MIN_SUPPORTED_TAG_LENGTH_BITS); + } + break; + case KeymasterDefs.KM_ALGORITHM_HMAC: + // HMAC key needs the minimum length of MAC set to the output size of the associated + // digest. This is because we do not offer a way to generate shorter MACs and + // don't offer a way to verify MACs (other than by generating them). + if (keymasterDigests.length != 1) { + throw new ProviderException( + "Unsupported number of authorized digests for HMAC key: " + + keymasterDigests.length + + ". Exactly one digest must be authorized"); + } + int keymasterDigest = keymasterDigests[0]; + int digestOutputSizeBits = getDigestOutputSizeBits(keymasterDigest); + if (digestOutputSizeBits == -1) { + throw new ProviderException( + "HMAC key authorized for unsupported digest: " + + KeyProperties.Digest.fromKeymaster(keymasterDigest)); + } + args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH, digestOutputSizeBits); + break; + } + } } |