From f76d08c19adb9d7a2445321a451d6fb8b09b2a82 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 9 Jan 2020 15:18:58 +0000 Subject: [PATCH] Use StrongBox on API 28+ if available. --- .../bramble/api/crypto/KeyStoreConfig.java | 7 ++++- .../bramble/crypto/CryptoComponentImpl.java | 22 +++++++++++---- .../briar/android/AndroidKeyStoreConfig.java | 28 +++++++++++++++---- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/KeyStoreConfig.java b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/KeyStoreConfig.java index 39f545f2f..5533e994d 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/KeyStoreConfig.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/KeyStoreConfig.java @@ -3,6 +3,7 @@ package org.briarproject.bramble.api.crypto; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import java.security.spec.AlgorithmParameterSpec; +import java.util.List; /** * Configures the use of a stored key to strengthen password-based encryption. @@ -23,5 +24,9 @@ public interface KeyStoreConfig { String getMacAlgorithmName(); - AlgorithmParameterSpec getParameterSpec(); + /** + * Returns a list of {@link AlgorithmParameterSpec AlgorithmParameterSpecs} + * to use for key generation, in order of preference. + */ + List getParameterSpecs(); } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java index 0ae209b1b..a634a0c8b 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java @@ -34,6 +34,7 @@ import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.SecureRandom; import java.security.Security; +import java.security.spec.AlgorithmParameterSpec; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -382,17 +383,28 @@ class CryptoComponentImpl implements CryptoComponent { KeyStore ks = KeyStore.getInstance(config.getKeyStoreType()); ks.load(null); // Load or generate the stored key - javax.crypto.SecretKey storedKey; + javax.crypto.SecretKey storedKey = null; Entry e = ks.getEntry(config.getKeyAlias(), null); if (e == null) { if (!generateIfMissing) { LOG.warning("Key not found in keystore"); return null; } - KeyGenerator kg = KeyGenerator.getInstance( - config.getMacAlgorithmName(), config.getProviderName()); - kg.init(config.getParameterSpec()); - storedKey = kg.generateKey(); + // Try the parameter specs in order of preference + for (AlgorithmParameterSpec spec : config.getParameterSpecs()) { + try { + KeyGenerator kg = KeyGenerator.getInstance( + config.getMacAlgorithmName(), + config.getProviderName()); + kg.init(spec); + storedKey = kg.generateKey(); + } catch (GeneralSecurityException e1) { + if (LOG.isLoggable(INFO)) + LOG.info("Could not generate key: " + e1); + // Fall back to next spec + } + } + if (storedKey == null) throw new IllegalArgumentException(); LOG.info("Stored key in keystore"); } else { if (!(e instanceof SecretKeyEntry)) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidKeyStoreConfig.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidKeyStoreConfig.java index e6aff2dad..5f9b4b1e8 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidKeyStoreConfig.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidKeyStoreConfig.java @@ -6,21 +6,37 @@ import org.briarproject.bramble.api.crypto.KeyStoreConfig; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import java.security.spec.AlgorithmParameterSpec; +import java.util.List; import androidx.annotation.RequiresApi; +import static android.os.Build.VERSION.SDK_INT; import static android.security.keystore.KeyProperties.PURPOSE_SIGN; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; @RequiresApi(23) @NotNullByDefault class AndroidKeyStoreConfig implements KeyStoreConfig { - private final KeyGenParameterSpec spec; + private final List specs; AndroidKeyStoreConfig() { - spec = new KeyGenParameterSpec.Builder("db", PURPOSE_SIGN) - .setKeySize(256) - .build(); + KeyGenParameterSpec noStrongBox = + new KeyGenParameterSpec.Builder("db", PURPOSE_SIGN) + .setKeySize(256) + .build(); + if (SDK_INT >= 28) { + // Prefer StrongBox if available + KeyGenParameterSpec strongBox = + new KeyGenParameterSpec.Builder("db", PURPOSE_SIGN) + .setIsStrongBoxBacked(true) + .setKeySize(256) + .build(); + specs = asList(strongBox, noStrongBox); + } else { + specs = singletonList(noStrongBox); + } } @Override @@ -44,7 +60,7 @@ class AndroidKeyStoreConfig implements KeyStoreConfig { } @Override - public AlgorithmParameterSpec getParameterSpec() { - return spec; + public List getParameterSpecs() { + return specs; } }