Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ad84795 authored by Alex Klyubin's avatar Alex Klyubin Committed by Android Git Automerger
Browse files

am b1d68c90: am 568e67a3: am ada70be8: Merge "Add KM_MIN_MAC_LENGTH tag to...

am b1d68c90: am 568e67a3: am ada70be8: Merge "Add KM_MIN_MAC_LENGTH tag to HMAC and AES-GCM keys." into mnc-dev

* commit 'b1d68c90':
  Add KM_MIN_MAC_LENGTH tag to HMAC and AES-GCM keys.
parents 6cd07625 b1d68c90
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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");
    }
+1 −1
Original line number Diff line number Diff line
@@ -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;
+6 −1
Original line number Diff line number Diff line
@@ -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());
+5 −0
Original line number Diff line number Diff line
@@ -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,
+43 −0
Original line number Diff line number Diff line
@@ -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;
        }
    }
}