Loading core/java/android/security/keymaster/KeymasterDefs.java +6 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ public final class KeymasterDefs { public static final int KM_TAG_DIGEST = KM_ENUM_REP | 5; public static final int KM_TAG_PADDING = KM_ENUM_REP | 6; public static final int KM_TAG_CALLER_NONCE = KM_BOOL | 7; public static final int KM_TAG_MIN_MAC_LENGTH = KM_UINT | 8; public static final int KM_TAG_RESCOPING_ADD = KM_ENUM_REP | 101; public static final int KM_TAG_RESCOPING_DEL = KM_ENUM_REP | 102; Loading Loading @@ -194,6 +195,9 @@ public final class KeymasterDefs { public static final int KM_ERROR_KEY_RATE_LIMIT_EXCEEDED = -54; public static final int KM_ERROR_CALLER_NONCE_PROHIBITED = -55; public static final int KM_ERROR_KEY_MAX_OPS_EXCEEDED = -56; public static final int KM_ERROR_INVALID_MAC_LENGTH = -57; public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = -58; public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59; public static final int KM_ERROR_UNIMPLEMENTED = -100; public static final int KM_ERROR_VERSION_MISMATCH = -101; public static final int KM_ERROR_UNKNOWN_ERROR = -1000; Loading Loading @@ -237,6 +241,8 @@ public final class KeymasterDefs { sErrorCodeToString.put(KM_ERROR_INVALID_NONCE, "Invalid IV"); sErrorCodeToString.put(KM_ERROR_CALLER_NONCE_PROHIBITED, "Caller-provided IV not permitted"); sErrorCodeToString.put(KM_ERROR_INVALID_MAC_LENGTH, "Invalid MAC or authentication tag length"); sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented"); sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error"); } Loading keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java +6 −1 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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()); Loading keystore/java/android/security/keystore/AndroidKeyStoreSpi.java +5 −0 Original line number Diff line number Diff line Loading @@ -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, Loading keystore/java/android/security/keystore/KeymasterUtils.java +43 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.security.KeyStore; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; import java.security.ProviderException; /** * @hide */ Loading Loading @@ -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; } } } Loading
core/java/android/security/keymaster/KeymasterDefs.java +6 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ public final class KeymasterDefs { public static final int KM_TAG_DIGEST = KM_ENUM_REP | 5; public static final int KM_TAG_PADDING = KM_ENUM_REP | 6; public static final int KM_TAG_CALLER_NONCE = KM_BOOL | 7; public static final int KM_TAG_MIN_MAC_LENGTH = KM_UINT | 8; public static final int KM_TAG_RESCOPING_ADD = KM_ENUM_REP | 101; public static final int KM_TAG_RESCOPING_DEL = KM_ENUM_REP | 102; Loading Loading @@ -194,6 +195,9 @@ public final class KeymasterDefs { public static final int KM_ERROR_KEY_RATE_LIMIT_EXCEEDED = -54; public static final int KM_ERROR_CALLER_NONCE_PROHIBITED = -55; public static final int KM_ERROR_KEY_MAX_OPS_EXCEEDED = -56; public static final int KM_ERROR_INVALID_MAC_LENGTH = -57; public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = -58; public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59; public static final int KM_ERROR_UNIMPLEMENTED = -100; public static final int KM_ERROR_VERSION_MISMATCH = -101; public static final int KM_ERROR_UNKNOWN_ERROR = -1000; Loading Loading @@ -237,6 +241,8 @@ public final class KeymasterDefs { sErrorCodeToString.put(KM_ERROR_INVALID_NONCE, "Invalid IV"); sErrorCodeToString.put(KM_ERROR_CALLER_NONCE_PROHIBITED, "Caller-provided IV not permitted"); sErrorCodeToString.put(KM_ERROR_INVALID_MAC_LENGTH, "Invalid MAC or authentication tag length"); sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented"); sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error"); } Loading
keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java +6 −1 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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()); Loading
keystore/java/android/security/keystore/AndroidKeyStoreSpi.java +5 −0 Original line number Diff line number Diff line Loading @@ -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, Loading
keystore/java/android/security/keystore/KeymasterUtils.java +43 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.security.KeyStore; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; import java.security.ProviderException; /** * @hide */ Loading Loading @@ -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; } } }