Loading keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java +34 −8 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.security.KeyStoreException; import android.security.KeyStoreOperation; import android.security.keymaster.KeymasterDefs; import android.security.keystore.KeyStoreCryptoOperation; import android.system.keystore2.Authorization; import libcore.util.EmptyArray; Loading Loading @@ -119,6 +120,14 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor mCipher = null; } private Authorization[] getKeyCharacteristics(Key key) { if (!(key instanceof AndroidKeyStoreKey)) { return new Authorization[] {}; } return ((AndroidKeyStoreKey) key).getAuthorizations(); } @Override protected final void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException { Loading Loading @@ -173,7 +182,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor init(opmode, key, random); initAlgorithmSpecificParameters(); try { ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized(getKeyCharacteristics(key)); } catch (InvalidAlgorithmParameterException e) { throw new InvalidKeyException(e); } Loading Loading @@ -206,7 +215,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor try { init(opmode, key, random); initAlgorithmSpecificParameters(params); ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized(getKeyCharacteristics(key)); success = true; } finally { if (!success) { Loading Loading @@ -236,7 +245,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor try { init(opmode, key, random); initAlgorithmSpecificParameters(params); ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized(getKeyCharacteristics(key)); success = true; } finally { if (!success) { Loading Loading @@ -310,7 +319,8 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor mCachedException = null; } private void ensureKeystoreOperationInitialized() throws InvalidKeyException, private void ensureKeystoreOperationInitialized(Authorization[] keyCharacteristics) throws InvalidKeyException, InvalidAlgorithmParameterException { if (mMainDataStreamer != null) { return; Loading @@ -323,7 +333,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor } List<KeyParameter> parameters = new ArrayList<>(); addAlgorithmSpecificParametersToBegin(parameters); addAlgorithmSpecificParametersToBegin(parameters, keyCharacteristics); int purpose; if (mKeymasterPurposeOverride != -1) { Loading Loading @@ -404,7 +414,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor return null; } try { ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized(getKeyCharacteristics(mKey)); } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { mCachedException = e; return null; Loading Loading @@ -520,7 +530,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor } try { ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized(getKeyCharacteristics(mKey)); } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { mCachedException = e; return; Loading Loading @@ -597,7 +607,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor } try { ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized(getKeyCharacteristics(mKey)); } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e); } Loading Loading @@ -1011,6 +1021,22 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor protected abstract void addAlgorithmSpecificParametersToBegin( @NonNull List<KeyParameter> parameters); /** * Invoked to add algorithm-specific parameters for the KeyStore's {@code begin} operation, * including the key characteristics. This is useful in case the parameters to {@code begin} * depend on how the key was generated. * The default implementation provided here simply ignores these key characteristics because * they are not be needed for most engines. * * @param parameters keystore/keymaster arguments to be populated with algorithm-specific * parameters. * @param keyCharacteristics The key's characteristics. */ protected void addAlgorithmSpecificParametersToBegin( @NonNull List<KeyParameter> parameters, Authorization[] keyCharacteristics) { addAlgorithmSpecificParametersToBegin(parameters); } /** * Invoked to obtain algorithm-specific parameters from the result of the KeyStore's * {@code begin} operation. Loading keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java +23 −5 Original line number Diff line number Diff line Loading @@ -288,17 +288,35 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase } } private static boolean isMgfDigestTagPresentInKeyProperties( Authorization[] keyCharacteristics) { for (Authorization authorization : keyCharacteristics) { if (authorization.keyParameter.tag == KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST) { return true; } } return false; } @Override protected final void addAlgorithmSpecificParametersToBegin( @NonNull List<KeyParameter> parameters) { super.addAlgorithmSpecificParametersToBegin(parameters); @NonNull List<KeyParameter> parameters, Authorization[] keyCharacteristics) { super.addAlgorithmSpecificParametersToBegin(parameters, keyCharacteristics); parameters.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest )); // Only add the KM_TAG_RSA_OAEP_MGF_DIGEST tag to begin() if the MGF Digest is // present in the key properties. Keys generated prior to Android 14 did not have // this tag (Keystore didn't add it) so specifying any MGF digest tag would cause // a begin() operation (on an Android 14 device) to fail (with a key that was generated // on Android 13 or below). if (isMgfDigestTagPresentInKeyProperties(keyCharacteristics)) { parameters.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, mKeymasterMgf1Digest )); } } @Override protected final void loadAlgorithmSpecificParametersFromBeginResult( Loading Loading
keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java +34 −8 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.security.KeyStoreException; import android.security.KeyStoreOperation; import android.security.keymaster.KeymasterDefs; import android.security.keystore.KeyStoreCryptoOperation; import android.system.keystore2.Authorization; import libcore.util.EmptyArray; Loading Loading @@ -119,6 +120,14 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor mCipher = null; } private Authorization[] getKeyCharacteristics(Key key) { if (!(key instanceof AndroidKeyStoreKey)) { return new Authorization[] {}; } return ((AndroidKeyStoreKey) key).getAuthorizations(); } @Override protected final void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException { Loading Loading @@ -173,7 +182,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor init(opmode, key, random); initAlgorithmSpecificParameters(); try { ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized(getKeyCharacteristics(key)); } catch (InvalidAlgorithmParameterException e) { throw new InvalidKeyException(e); } Loading Loading @@ -206,7 +215,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor try { init(opmode, key, random); initAlgorithmSpecificParameters(params); ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized(getKeyCharacteristics(key)); success = true; } finally { if (!success) { Loading Loading @@ -236,7 +245,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor try { init(opmode, key, random); initAlgorithmSpecificParameters(params); ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized(getKeyCharacteristics(key)); success = true; } finally { if (!success) { Loading Loading @@ -310,7 +319,8 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor mCachedException = null; } private void ensureKeystoreOperationInitialized() throws InvalidKeyException, private void ensureKeystoreOperationInitialized(Authorization[] keyCharacteristics) throws InvalidKeyException, InvalidAlgorithmParameterException { if (mMainDataStreamer != null) { return; Loading @@ -323,7 +333,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor } List<KeyParameter> parameters = new ArrayList<>(); addAlgorithmSpecificParametersToBegin(parameters); addAlgorithmSpecificParametersToBegin(parameters, keyCharacteristics); int purpose; if (mKeymasterPurposeOverride != -1) { Loading Loading @@ -404,7 +414,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor return null; } try { ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized(getKeyCharacteristics(mKey)); } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { mCachedException = e; return null; Loading Loading @@ -520,7 +530,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor } try { ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized(getKeyCharacteristics(mKey)); } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { mCachedException = e; return; Loading Loading @@ -597,7 +607,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor } try { ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized(getKeyCharacteristics(mKey)); } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e); } Loading Loading @@ -1011,6 +1021,22 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor protected abstract void addAlgorithmSpecificParametersToBegin( @NonNull List<KeyParameter> parameters); /** * Invoked to add algorithm-specific parameters for the KeyStore's {@code begin} operation, * including the key characteristics. This is useful in case the parameters to {@code begin} * depend on how the key was generated. * The default implementation provided here simply ignores these key characteristics because * they are not be needed for most engines. * * @param parameters keystore/keymaster arguments to be populated with algorithm-specific * parameters. * @param keyCharacteristics The key's characteristics. */ protected void addAlgorithmSpecificParametersToBegin( @NonNull List<KeyParameter> parameters, Authorization[] keyCharacteristics) { addAlgorithmSpecificParametersToBegin(parameters); } /** * Invoked to obtain algorithm-specific parameters from the result of the KeyStore's * {@code begin} operation. Loading
keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java +23 −5 Original line number Diff line number Diff line Loading @@ -288,17 +288,35 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase } } private static boolean isMgfDigestTagPresentInKeyProperties( Authorization[] keyCharacteristics) { for (Authorization authorization : keyCharacteristics) { if (authorization.keyParameter.tag == KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST) { return true; } } return false; } @Override protected final void addAlgorithmSpecificParametersToBegin( @NonNull List<KeyParameter> parameters) { super.addAlgorithmSpecificParametersToBegin(parameters); @NonNull List<KeyParameter> parameters, Authorization[] keyCharacteristics) { super.addAlgorithmSpecificParametersToBegin(parameters, keyCharacteristics); parameters.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest )); // Only add the KM_TAG_RSA_OAEP_MGF_DIGEST tag to begin() if the MGF Digest is // present in the key properties. Keys generated prior to Android 14 did not have // this tag (Keystore didn't add it) so specifying any MGF digest tag would cause // a begin() operation (on an Android 14 device) to fail (with a key that was generated // on Android 13 or below). if (isMgfDigestTagPresentInKeyProperties(keyCharacteristics)) { parameters.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, mKeymasterMgf1Digest )); } } @Override protected final void loadAlgorithmSpecificParametersFromBeginResult( Loading