Loading keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java +21 −33 Original line number Diff line number Diff line Loading @@ -197,48 +197,36 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { } } } if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { // JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm // implies SHA-256 digest). Because keymaster HMAC key is authorized only for // one digest, we don't let algorithm parameter spec override the digest implied // by the key. If the spec specifies digests at all, it must specify only one // digest, the only implied by key algorithm. mKeymasterDigests = new int[] {mKeymasterDigest}; if (spec.isDigestsSpecified()) { // Digest(s) explicitly specified in the spec mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests()); if (mKeymasterDigest != -1) { // Key algorithm implies a digest -- ensure it's specified in the spec as // first digest. if (!com.android.internal.util.ArrayUtils.contains( mKeymasterDigests, mKeymasterDigest)) { // Digest(s) explicitly specified in the spec. Check that the list // consists of exactly one digest, the one implied by key algorithm. int[] keymasterDigestsFromSpec = KeyProperties.Digest.allToKeymaster(spec.getDigests()); if ((keymasterDigestsFromSpec.length != 1) || (keymasterDigestsFromSpec[0] != mKeymasterDigest)) { throw new InvalidAlgorithmParameterException( "Digests specified in algorithm parameters (" + Arrays.asList(spec.getDigests()) + ") must include " + " the digest " "Unsupported digests specification: " + Arrays.asList(spec.getDigests()) + ". Only " + KeyProperties.Digest.fromKeymaster(mKeymasterDigest) + " implied by key algorithm"); } if (mKeymasterDigests[0] != mKeymasterDigest) { // The first digest is not the one implied by the key algorithm. // Swap the implied digest with the first one. for (int i = 0; i < mKeymasterDigests.length; i++) { if (mKeymasterDigests[i] == mKeymasterDigest) { mKeymasterDigests[i] = mKeymasterDigests[0]; mKeymasterDigests[0] = mKeymasterDigest; break; } } + " supported for this HMAC key algorithm"); } } } else { // No digest specified in the spec if (mKeymasterDigest != -1) { // Key algorithm implies a digest -- use that digest mKeymasterDigests = new int[] {mKeymasterDigest}; // Key algorithm does not imply a digest. if (spec.isDigestsSpecified()) { mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests()); } else { mKeymasterDigests = EmptyArray.INT; } } if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { if (mKeymasterDigests.length == 0) { throw new InvalidAlgorithmParameterException( "At least one digest algorithm must be specified"); } } // Check that user authentication related parameters are acceptable. This method // will throw an IllegalStateException if there are issues (e.g., secure lock screen Loading keystore/java/android/security/keystore/AndroidKeyStoreSpi.java +30 −36 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import java.security.KeyStoreException; import java.security.KeyStoreSpi; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.ProviderException; import java.security.PublicKey; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; Loading Loading @@ -605,50 +606,43 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm); int[] keymasterDigests; int keymasterDigest = KeyProperties.KeyAlgorithm.toKeymasterDigest(key.getAlgorithm()); if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { // JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm // implies SHA-256 digest). Because keymaster HMAC key is authorized only for one // digest, we don't let import parameters override the digest implied by the key. // If the parameters specify digests at all, they must specify only one digest, the // only implied by key algorithm. int keymasterImpliedDigest = KeyProperties.KeyAlgorithm.toKeymasterDigest(key.getAlgorithm()); if (keymasterImpliedDigest == -1) { throw new ProviderException( "HMAC key algorithm digest unknown for key algorithm " + key.getAlgorithm()); } keymasterDigests = new int[] {keymasterImpliedDigest}; if (params.isDigestsSpecified()) { // Digest(s) specified in parameters keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests()); if (keymasterDigest != -1) { // Digest also specified in the JCA key algorithm name. if (!com.android.internal.util.ArrayUtils.contains( keymasterDigests, keymasterDigest)) { throw new KeyStoreException("Digest specified in key algorithm " + key.getAlgorithm() + " not specified in protection parameters: " + Arrays.asList(params.getDigests())); } // When the key is read back from keystore we reconstruct the JCA key algorithm // name from the KM_TAG_ALGORITHM and the first KM_TAG_DIGEST. Thus we need to // ensure that the digest reflected in the JCA key algorithm name is the first // KM_TAG_DIGEST tag. if (keymasterDigests[0] != keymasterDigest) { // The first digest is not the one implied by the JCA key algorithm name. // Swap the implied digest with the first one. for (int i = 0; i < keymasterDigests.length; i++) { if (keymasterDigests[i] == keymasterDigest) { keymasterDigests[i] = keymasterDigests[0]; keymasterDigests[0] = keymasterDigest; break; } } // Digest(s) explicitly specified in params -- check that the list consists of // exactly one digest, the one implied by key algorithm. int[] keymasterDigestsFromParams = KeyProperties.Digest.allToKeymaster(params.getDigests()); if ((keymasterDigestsFromParams.length != 1) || (keymasterDigestsFromParams[0] != keymasterImpliedDigest)) { throw new KeyStoreException( "Unsupported digests specification: " + Arrays.asList(params.getDigests()) + ". Only " + KeyProperties.Digest.fromKeymaster(keymasterImpliedDigest) + " supported for HMAC key algorithm " + key.getAlgorithm()); } } } else { // No digest specified in parameters if (keymasterDigest != -1) { // Digest specified in the JCA key algorithm name. keymasterDigests = new int[] {keymasterDigest}; // Key algorithm does not imply a digest. if (params.isDigestsSpecified()) { keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests()); } else { keymasterDigests = EmptyArray.INT; } } args.addEnums(KeymasterDefs.KM_TAG_DIGEST, keymasterDigests); if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { if (keymasterDigests.length == 0) { throw new KeyStoreException("At least one digest algorithm must be specified" + " for key algorithm " + key.getAlgorithm()); } } @KeyProperties.PurposeEnum int purposes = params.getPurposes(); int[] keymasterBlockModes = Loading keystore/java/android/security/keystore/KeyGenParameterSpec.java +2 −1 Original line number Diff line number Diff line Loading @@ -642,7 +642,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec { * <p>This must be specified for signing/verification keys and RSA encryption/decryption * keys used with RSA OAEP padding scheme because these operations involve a digest. For * HMAC keys, the default is the digest associated with the key algorithm (e.g., * {@code SHA-256} for key algorithm {@code HmacSHA256}). * {@code SHA-256} for key algorithm {@code HmacSHA256}). HMAC keys cannot be authorized * for more than one digest. * * <p>For private keys used for TLS/SSL client or server authentication it is usually * necessary to authorize the use of no digest ({@link KeyProperties#DIGEST_NONE}). This is Loading keystore/java/android/security/keystore/KeyProtection.java +2 −1 Original line number Diff line number Diff line Loading @@ -423,7 +423,8 @@ public final class KeyProtection implements ProtectionParameter { * <p>This must be specified for signing/verification keys and RSA encryption/decryption * keys used with RSA OAEP padding scheme because these operations involve a digest. For * HMAC keys, the default is the digest specified in {@link Key#getAlgorithm()} (e.g., * {@code SHA-256} for key algorithm {@code HmacSHA256}). * {@code SHA-256} for key algorithm {@code HmacSHA256}). HMAC keys cannot be authorized * for more than one digest. * * <p>For private keys used for TLS/SSL client or server authentication it is usually * necessary to authorize the use of no digest ({@link KeyProperties#DIGEST_NONE}). This is Loading Loading
keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java +21 −33 Original line number Diff line number Diff line Loading @@ -197,48 +197,36 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { } } } if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { // JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm // implies SHA-256 digest). Because keymaster HMAC key is authorized only for // one digest, we don't let algorithm parameter spec override the digest implied // by the key. If the spec specifies digests at all, it must specify only one // digest, the only implied by key algorithm. mKeymasterDigests = new int[] {mKeymasterDigest}; if (spec.isDigestsSpecified()) { // Digest(s) explicitly specified in the spec mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests()); if (mKeymasterDigest != -1) { // Key algorithm implies a digest -- ensure it's specified in the spec as // first digest. if (!com.android.internal.util.ArrayUtils.contains( mKeymasterDigests, mKeymasterDigest)) { // Digest(s) explicitly specified in the spec. Check that the list // consists of exactly one digest, the one implied by key algorithm. int[] keymasterDigestsFromSpec = KeyProperties.Digest.allToKeymaster(spec.getDigests()); if ((keymasterDigestsFromSpec.length != 1) || (keymasterDigestsFromSpec[0] != mKeymasterDigest)) { throw new InvalidAlgorithmParameterException( "Digests specified in algorithm parameters (" + Arrays.asList(spec.getDigests()) + ") must include " + " the digest " "Unsupported digests specification: " + Arrays.asList(spec.getDigests()) + ". Only " + KeyProperties.Digest.fromKeymaster(mKeymasterDigest) + " implied by key algorithm"); } if (mKeymasterDigests[0] != mKeymasterDigest) { // The first digest is not the one implied by the key algorithm. // Swap the implied digest with the first one. for (int i = 0; i < mKeymasterDigests.length; i++) { if (mKeymasterDigests[i] == mKeymasterDigest) { mKeymasterDigests[i] = mKeymasterDigests[0]; mKeymasterDigests[0] = mKeymasterDigest; break; } } + " supported for this HMAC key algorithm"); } } } else { // No digest specified in the spec if (mKeymasterDigest != -1) { // Key algorithm implies a digest -- use that digest mKeymasterDigests = new int[] {mKeymasterDigest}; // Key algorithm does not imply a digest. if (spec.isDigestsSpecified()) { mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests()); } else { mKeymasterDigests = EmptyArray.INT; } } if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { if (mKeymasterDigests.length == 0) { throw new InvalidAlgorithmParameterException( "At least one digest algorithm must be specified"); } } // Check that user authentication related parameters are acceptable. This method // will throw an IllegalStateException if there are issues (e.g., secure lock screen Loading
keystore/java/android/security/keystore/AndroidKeyStoreSpi.java +30 −36 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import java.security.KeyStoreException; import java.security.KeyStoreSpi; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.ProviderException; import java.security.PublicKey; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; Loading Loading @@ -605,50 +606,43 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm); int[] keymasterDigests; int keymasterDigest = KeyProperties.KeyAlgorithm.toKeymasterDigest(key.getAlgorithm()); if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { // JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm // implies SHA-256 digest). Because keymaster HMAC key is authorized only for one // digest, we don't let import parameters override the digest implied by the key. // If the parameters specify digests at all, they must specify only one digest, the // only implied by key algorithm. int keymasterImpliedDigest = KeyProperties.KeyAlgorithm.toKeymasterDigest(key.getAlgorithm()); if (keymasterImpliedDigest == -1) { throw new ProviderException( "HMAC key algorithm digest unknown for key algorithm " + key.getAlgorithm()); } keymasterDigests = new int[] {keymasterImpliedDigest}; if (params.isDigestsSpecified()) { // Digest(s) specified in parameters keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests()); if (keymasterDigest != -1) { // Digest also specified in the JCA key algorithm name. if (!com.android.internal.util.ArrayUtils.contains( keymasterDigests, keymasterDigest)) { throw new KeyStoreException("Digest specified in key algorithm " + key.getAlgorithm() + " not specified in protection parameters: " + Arrays.asList(params.getDigests())); } // When the key is read back from keystore we reconstruct the JCA key algorithm // name from the KM_TAG_ALGORITHM and the first KM_TAG_DIGEST. Thus we need to // ensure that the digest reflected in the JCA key algorithm name is the first // KM_TAG_DIGEST tag. if (keymasterDigests[0] != keymasterDigest) { // The first digest is not the one implied by the JCA key algorithm name. // Swap the implied digest with the first one. for (int i = 0; i < keymasterDigests.length; i++) { if (keymasterDigests[i] == keymasterDigest) { keymasterDigests[i] = keymasterDigests[0]; keymasterDigests[0] = keymasterDigest; break; } } // Digest(s) explicitly specified in params -- check that the list consists of // exactly one digest, the one implied by key algorithm. int[] keymasterDigestsFromParams = KeyProperties.Digest.allToKeymaster(params.getDigests()); if ((keymasterDigestsFromParams.length != 1) || (keymasterDigestsFromParams[0] != keymasterImpliedDigest)) { throw new KeyStoreException( "Unsupported digests specification: " + Arrays.asList(params.getDigests()) + ". Only " + KeyProperties.Digest.fromKeymaster(keymasterImpliedDigest) + " supported for HMAC key algorithm " + key.getAlgorithm()); } } } else { // No digest specified in parameters if (keymasterDigest != -1) { // Digest specified in the JCA key algorithm name. keymasterDigests = new int[] {keymasterDigest}; // Key algorithm does not imply a digest. if (params.isDigestsSpecified()) { keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests()); } else { keymasterDigests = EmptyArray.INT; } } args.addEnums(KeymasterDefs.KM_TAG_DIGEST, keymasterDigests); if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { if (keymasterDigests.length == 0) { throw new KeyStoreException("At least one digest algorithm must be specified" + " for key algorithm " + key.getAlgorithm()); } } @KeyProperties.PurposeEnum int purposes = params.getPurposes(); int[] keymasterBlockModes = Loading
keystore/java/android/security/keystore/KeyGenParameterSpec.java +2 −1 Original line number Diff line number Diff line Loading @@ -642,7 +642,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec { * <p>This must be specified for signing/verification keys and RSA encryption/decryption * keys used with RSA OAEP padding scheme because these operations involve a digest. For * HMAC keys, the default is the digest associated with the key algorithm (e.g., * {@code SHA-256} for key algorithm {@code HmacSHA256}). * {@code SHA-256} for key algorithm {@code HmacSHA256}). HMAC keys cannot be authorized * for more than one digest. * * <p>For private keys used for TLS/SSL client or server authentication it is usually * necessary to authorize the use of no digest ({@link KeyProperties#DIGEST_NONE}). This is Loading
keystore/java/android/security/keystore/KeyProtection.java +2 −1 Original line number Diff line number Diff line Loading @@ -423,7 +423,8 @@ public final class KeyProtection implements ProtectionParameter { * <p>This must be specified for signing/verification keys and RSA encryption/decryption * keys used with RSA OAEP padding scheme because these operations involve a digest. For * HMAC keys, the default is the digest specified in {@link Key#getAlgorithm()} (e.g., * {@code SHA-256} for key algorithm {@code HmacSHA256}). * {@code SHA-256} for key algorithm {@code HmacSHA256}). HMAC keys cannot be authorized * for more than one digest. * * <p>For private keys used for TLS/SSL client or server authentication it is usually * necessary to authorize the use of no digest ({@link KeyProperties#DIGEST_NONE}). This is Loading