Merge "Keystore: Included KM_TAG_RSA_OAEP_MGF_DIGEST tag" am: eea63d6aa4 am: f42d5e8847 am: 72b1cc3e49 am: 3f20176ddf

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2167462

Change-Id: I0dcc2afa940a582e017420a9ddbe3d92674f07ed
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot
2022-09-20 15:24:24 +00:00
committed by Automerger Merge Worker
7 changed files with 92 additions and 16 deletions

View File

@@ -68,6 +68,8 @@ public final class KeymasterDefs {
public static final int KM_TAG_RSA_PUBLIC_EXPONENT = Tag.RSA_PUBLIC_EXPONENT; // KM_ULONG | 200; public static final int KM_TAG_RSA_PUBLIC_EXPONENT = Tag.RSA_PUBLIC_EXPONENT; // KM_ULONG | 200;
public static final int KM_TAG_INCLUDE_UNIQUE_ID = Tag.INCLUDE_UNIQUE_ID; // KM_BOOL | 202; public static final int KM_TAG_INCLUDE_UNIQUE_ID = Tag.INCLUDE_UNIQUE_ID; // KM_BOOL | 202;
public static final int KM_TAG_RSA_OAEP_MGF_DIGEST = Tag.RSA_OAEP_MGF_DIGEST;
// KM_ENUM_REP | 203;
public static final int KM_TAG_ACTIVE_DATETIME = Tag.ACTIVE_DATETIME; // KM_DATE | 400; public static final int KM_TAG_ACTIVE_DATETIME = Tag.ACTIVE_DATETIME; // KM_DATE | 400;
public static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME = public static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME =

View File

@@ -29,6 +29,8 @@ import libcore.util.EmptyArray;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.MGF1ParameterSpec;
import java.util.Collection; import java.util.Collection;
import java.util.Locale; import java.util.Locale;
@@ -675,6 +677,26 @@ public abstract class KeyProperties {
} }
} }
/**
* @hide
*/
@NonNull public static @DigestEnum
AlgorithmParameterSpec fromKeymasterToMGF1ParameterSpec(int digest) {
switch (digest) {
default:
case KeymasterDefs.KM_DIGEST_SHA1:
return MGF1ParameterSpec.SHA1;
case KeymasterDefs.KM_DIGEST_SHA_2_224:
return MGF1ParameterSpec.SHA224;
case KeymasterDefs.KM_DIGEST_SHA_2_256:
return MGF1ParameterSpec.SHA256;
case KeymasterDefs.KM_DIGEST_SHA_2_384:
return MGF1ParameterSpec.SHA384;
case KeymasterDefs.KM_DIGEST_SHA_2_512:
return MGF1ParameterSpec.SHA512;
}
}
@NonNull @NonNull
public static @DigestEnum String fromKeymasterToSignatureAlgorithmDigest(int digest) { public static @DigestEnum String fromKeymasterToSignatureAlgorithmDigest(int digest) {
switch (digest) { switch (digest) {

View File

@@ -69,6 +69,7 @@ import javax.crypto.spec.SecretKeySpec;
*/ */
abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStoreCryptoOperation { abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStoreCryptoOperation {
private static final String TAG = "AndroidKeyStoreCipherSpiBase"; private static final String TAG = "AndroidKeyStoreCipherSpiBase";
public static final String DEFAULT_MGF1_DIGEST = "SHA-1";
// Fields below are populated by Cipher.init and KeyStore.begin and should be preserved after // Fields below are populated by Cipher.init and KeyStore.begin and should be preserved after
// doFinal finishes. // doFinal finishes.
@@ -133,24 +134,28 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
if ("RSA/ECB/OAEPWithSHA-224AndMGF1Padding".equals(transform)) { if ("RSA/ECB/OAEPWithSHA-224AndMGF1Padding".equals(transform)) {
OAEPParameterSpec spec = OAEPParameterSpec spec =
new OAEPParameterSpec("SHA-224", "MGF1", new OAEPParameterSpec("SHA-224", "MGF1",
new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT); new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST),
PSource.PSpecified.DEFAULT);
mCipher.init(opmode, key, spec, random); mCipher.init(opmode, key, spec, random);
} else if ("RSA/ECB/OAEPWithSHA-256AndMGF1Padding".equals(transform)) { } else if ("RSA/ECB/OAEPWithSHA-256AndMGF1Padding".equals(transform)) {
OAEPParameterSpec spec = OAEPParameterSpec spec =
new OAEPParameterSpec("SHA-256", "MGF1", new OAEPParameterSpec("SHA-256", "MGF1",
new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT); new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST),
PSource.PSpecified.DEFAULT);
mCipher.init(opmode, key, spec, random); mCipher.init(opmode, key, spec, random);
} else if ("RSA/ECB/OAEPWithSHA-384AndMGF1Padding".equals(transform)) { } else if ("RSA/ECB/OAEPWithSHA-384AndMGF1Padding".equals(transform)) {
OAEPParameterSpec spec = OAEPParameterSpec spec =
new OAEPParameterSpec("SHA-384", "MGF1", new OAEPParameterSpec("SHA-384", "MGF1",
new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT); new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST),
PSource.PSpecified.DEFAULT);
mCipher.init(opmode, key, spec, random); mCipher.init(opmode, key, spec, random);
} else if ("RSA/ECB/OAEPWithSHA-512AndMGF1Padding".equals(transform)) { } else if ("RSA/ECB/OAEPWithSHA-512AndMGF1Padding".equals(transform)) {
OAEPParameterSpec spec = OAEPParameterSpec spec =
new OAEPParameterSpec("SHA-512", "MGF1", new OAEPParameterSpec("SHA-512", "MGF1",
new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT); new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST),
PSource.PSpecified.DEFAULT);
mCipher.init(opmode, key, spec, random); mCipher.init(opmode, key, spec, random);
} else { } else {
mCipher.init(opmode, key, random); mCipher.init(opmode, key, random);

View File

@@ -16,6 +16,8 @@
package android.security.keystore2; package android.security.keystore2;
import static android.security.keystore2.AndroidKeyStoreCipherSpiBase.DEFAULT_MGF1_DIGEST;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.ActivityThread; import android.app.ActivityThread;
@@ -908,6 +910,26 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
params.add(KeyStore2ParameterUtils.makeEnum( params.add(KeyStore2ParameterUtils.makeEnum(
KeymasterDefs.KM_TAG_PADDING, padding KeymasterDefs.KM_TAG_PADDING, padding
)); ));
if (padding == KeymasterDefs.KM_PAD_RSA_OAEP) {
final boolean[] hasDefaultMgf1DigestBeenAdded = {false};
ArrayUtils.forEach(mKeymasterDigests, (digest) -> {
params.add(KeyStore2ParameterUtils.makeEnum(
KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, digest
));
hasDefaultMgf1DigestBeenAdded[0] |=
digest.equals(KeyProperties.Digest.toKeymaster(DEFAULT_MGF1_DIGEST));
});
/* Because of default MGF1 digest is SHA-1. It has to be added in Key
* characteristics. Otherwise, crypto operations will fail with Incompatible
* MGF1 digest.
*/
if (!hasDefaultMgf1DigestBeenAdded[0]) {
params.add(KeyStore2ParameterUtils.makeEnum(
KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST,
KeyProperties.Digest.toKeymaster(DEFAULT_MGF1_DIGEST)
));
}
}
}); });
ArrayUtils.forEach(mKeymasterSignaturePaddings, (padding) -> { ArrayUtils.forEach(mKeymasterSignaturePaddings, (padding) -> {
params.add(KeyStore2ParameterUtils.makeEnum( params.add(KeyStore2ParameterUtils.makeEnum(

View File

@@ -161,10 +161,11 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
*/ */
abstract static class OAEPWithMGF1Padding extends AndroidKeyStoreRSACipherSpi { abstract static class OAEPWithMGF1Padding extends AndroidKeyStoreRSACipherSpi {
private static final String MGF_ALGORITGM_MGF1 = "MGF1"; private static final String MGF_ALGORITHM_MGF1 = "MGF1";
private int mKeymasterDigest = -1; private int mKeymasterDigest = -1;
private int mDigestOutputSizeBytes; private int mDigestOutputSizeBytes;
private int mKeymasterMgf1Digest = KeymasterDefs.KM_DIGEST_SHA1; // Default MGF1 digest
OAEPWithMGF1Padding(int keymasterDigest) { OAEPWithMGF1Padding(int keymasterDigest) {
super(KeymasterDefs.KM_PAD_RSA_OAEP); super(KeymasterDefs.KM_PAD_RSA_OAEP);
@@ -189,10 +190,10 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
+ ". Only OAEPParameterSpec supported"); + ". Only OAEPParameterSpec supported");
} }
OAEPParameterSpec spec = (OAEPParameterSpec) params; OAEPParameterSpec spec = (OAEPParameterSpec) params;
if (!MGF_ALGORITGM_MGF1.equalsIgnoreCase(spec.getMGFAlgorithm())) { if (!MGF_ALGORITHM_MGF1.equalsIgnoreCase(spec.getMGFAlgorithm())) {
throw new InvalidAlgorithmParameterException( throw new InvalidAlgorithmParameterException(
"Unsupported MGF: " + spec.getMGFAlgorithm() "Unsupported MGF: " + spec.getMGFAlgorithm()
+ ". Only " + MGF_ALGORITGM_MGF1 + " supported"); + ". Only " + MGF_ALGORITHM_MGF1 + " supported");
} }
String jcaDigest = spec.getDigestAlgorithm(); String jcaDigest = spec.getDigestAlgorithm();
int keymasterDigest; int keymasterDigest;
@@ -225,11 +226,6 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
} }
MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec) mgfParams; MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec) mgfParams;
String mgf1JcaDigest = mgfSpec.getDigestAlgorithm(); String mgf1JcaDigest = mgfSpec.getDigestAlgorithm();
if (!KeyProperties.DIGEST_SHA1.equalsIgnoreCase(mgf1JcaDigest)) {
throw new InvalidAlgorithmParameterException(
"Unsupported MGF1 digest: " + mgf1JcaDigest
+ ". Only " + KeyProperties.DIGEST_SHA1 + " supported");
}
PSource pSource = spec.getPSource(); PSource pSource = spec.getPSource();
if (!(pSource instanceof PSource.PSpecified)) { if (!(pSource instanceof PSource.PSpecified)) {
throw new InvalidAlgorithmParameterException( throw new InvalidAlgorithmParameterException(
@@ -244,6 +240,7 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
+ ". Only pSpecifiedEmpty (PSource.PSpecified.DEFAULT) supported"); + ". Only pSpecifiedEmpty (PSource.PSpecified.DEFAULT) supported");
} }
mKeymasterDigest = keymasterDigest; mKeymasterDigest = keymasterDigest;
mKeymasterMgf1Digest = KeyProperties.Digest.toKeymaster(mgf1JcaDigest);
mDigestOutputSizeBytes = mDigestOutputSizeBytes =
(KeymasterUtils.getDigestOutputSizeBits(keymasterDigest) + 7) / 8; (KeymasterUtils.getDigestOutputSizeBits(keymasterDigest) + 7) / 8;
} }
@@ -274,8 +271,8 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
OAEPParameterSpec spec = OAEPParameterSpec spec =
new OAEPParameterSpec( new OAEPParameterSpec(
KeyProperties.Digest.fromKeymaster(mKeymasterDigest), KeyProperties.Digest.fromKeymaster(mKeymasterDigest),
MGF_ALGORITGM_MGF1, MGF_ALGORITHM_MGF1,
MGF1ParameterSpec.SHA1, KeyProperties.Digest.fromKeymasterToMGF1ParameterSpec(mKeymasterMgf1Digest),
PSource.PSpecified.DEFAULT); PSource.PSpecified.DEFAULT);
try { try {
AlgorithmParameters params = AlgorithmParameters.getInstance("OAEP"); AlgorithmParameters params = AlgorithmParameters.getInstance("OAEP");
@@ -298,6 +295,9 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
parameters.add(KeyStore2ParameterUtils.makeEnum( parameters.add(KeyStore2ParameterUtils.makeEnum(
KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest
)); ));
parameters.add(KeyStore2ParameterUtils.makeEnum(
KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, mKeymasterMgf1Digest
));
} }
@Override @Override

View File

@@ -16,6 +16,8 @@
package android.security.keystore2; package android.security.keystore2;
import static android.security.keystore2.AndroidKeyStoreCipherSpiBase.DEFAULT_MGF1_DIGEST;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricManager;
import android.hardware.security.keymint.HardwareAuthenticatorType; import android.hardware.security.keymint.HardwareAuthenticatorType;
@@ -511,6 +513,28 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_TAG_PADDING,
padding padding
)); ));
if (padding == KeymasterDefs.KM_PAD_RSA_OAEP) {
if (spec.isDigestsSpecified()) {
boolean hasDefaultMgf1DigestBeenAdded = false;
for (String digest : spec.getDigests()) {
importArgs.add(KeyStore2ParameterUtils.makeEnum(
KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST,
KeyProperties.Digest.toKeymaster(digest)
));
hasDefaultMgf1DigestBeenAdded |= digest.equals(DEFAULT_MGF1_DIGEST);
}
/* Because of default MGF1 digest is SHA-1. It has to be added in Key
* characteristics. Otherwise, crypto operations will fail with Incompatible
* MGF1 digest.
*/
if (!hasDefaultMgf1DigestBeenAdded) {
importArgs.add(KeyStore2ParameterUtils.makeEnum(
KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST,
KeyProperties.Digest.toKeymaster(DEFAULT_MGF1_DIGEST)
));
}
}
}
} }
for (String padding : spec.getSignaturePaddings()) { for (String padding : spec.getSignaturePaddings()) {
importArgs.add(KeyStore2ParameterUtils.makeEnum( importArgs.add(KeyStore2ParameterUtils.makeEnum(

View File

@@ -78,6 +78,7 @@ public abstract class KeyStore2ParameterUtils {
kp.value = KeyParameterValue.blockMode(v); kp.value = KeyParameterValue.blockMode(v);
break; break;
case Tag.DIGEST: case Tag.DIGEST:
case Tag.RSA_OAEP_MGF_DIGEST:
kp.value = KeyParameterValue.digest(v); kp.value = KeyParameterValue.digest(v);
break; break;
case Tag.EC_CURVE: case Tag.EC_CURVE: