Merge "Keystore: Included KM_TAG_RSA_OAEP_MGF_DIGEST tag"
This commit is contained in:
@@ -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_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_ORIGINATION_EXPIRE_DATETIME =
|
||||
|
||||
@@ -29,6 +29,8 @@ import libcore.util.EmptyArray;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.MGF1ParameterSpec;
|
||||
import java.util.Collection;
|
||||
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
|
||||
public static @DigestEnum String fromKeymasterToSignatureAlgorithmDigest(int digest) {
|
||||
switch (digest) {
|
||||
|
||||
@@ -69,6 +69,7 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
*/
|
||||
abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStoreCryptoOperation {
|
||||
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
|
||||
// doFinal finishes.
|
||||
@@ -133,24 +134,28 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
||||
if ("RSA/ECB/OAEPWithSHA-224AndMGF1Padding".equals(transform)) {
|
||||
OAEPParameterSpec spec =
|
||||
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);
|
||||
} else if ("RSA/ECB/OAEPWithSHA-256AndMGF1Padding".equals(transform)) {
|
||||
OAEPParameterSpec spec =
|
||||
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);
|
||||
|
||||
} else if ("RSA/ECB/OAEPWithSHA-384AndMGF1Padding".equals(transform)) {
|
||||
OAEPParameterSpec spec =
|
||||
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);
|
||||
|
||||
} else if ("RSA/ECB/OAEPWithSHA-512AndMGF1Padding".equals(transform)) {
|
||||
OAEPParameterSpec spec =
|
||||
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);
|
||||
} else {
|
||||
mCipher.init(opmode, key, random);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.security.keystore2;
|
||||
|
||||
import static android.security.keystore2.AndroidKeyStoreCipherSpiBase.DEFAULT_MGF1_DIGEST;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityThread;
|
||||
@@ -908,6 +910,26 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
|
||||
params.add(KeyStore2ParameterUtils.makeEnum(
|
||||
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) -> {
|
||||
params.add(KeyStore2ParameterUtils.makeEnum(
|
||||
|
||||
@@ -161,10 +161,11 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
|
||||
*/
|
||||
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 mDigestOutputSizeBytes;
|
||||
private int mKeymasterMgf1Digest = KeymasterDefs.KM_DIGEST_SHA1; // Default MGF1 digest
|
||||
|
||||
OAEPWithMGF1Padding(int keymasterDigest) {
|
||||
super(KeymasterDefs.KM_PAD_RSA_OAEP);
|
||||
@@ -189,10 +190,10 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
|
||||
+ ". Only OAEPParameterSpec supported");
|
||||
}
|
||||
OAEPParameterSpec spec = (OAEPParameterSpec) params;
|
||||
if (!MGF_ALGORITGM_MGF1.equalsIgnoreCase(spec.getMGFAlgorithm())) {
|
||||
if (!MGF_ALGORITHM_MGF1.equalsIgnoreCase(spec.getMGFAlgorithm())) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"Unsupported MGF: " + spec.getMGFAlgorithm()
|
||||
+ ". Only " + MGF_ALGORITGM_MGF1 + " supported");
|
||||
+ ". Only " + MGF_ALGORITHM_MGF1 + " supported");
|
||||
}
|
||||
String jcaDigest = spec.getDigestAlgorithm();
|
||||
int keymasterDigest;
|
||||
@@ -225,11 +226,6 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
|
||||
}
|
||||
MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec) mgfParams;
|
||||
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();
|
||||
if (!(pSource instanceof PSource.PSpecified)) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
@@ -244,6 +240,7 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
|
||||
+ ". Only pSpecifiedEmpty (PSource.PSpecified.DEFAULT) supported");
|
||||
}
|
||||
mKeymasterDigest = keymasterDigest;
|
||||
mKeymasterMgf1Digest = KeyProperties.Digest.toKeymaster(mgf1JcaDigest);
|
||||
mDigestOutputSizeBytes =
|
||||
(KeymasterUtils.getDigestOutputSizeBits(keymasterDigest) + 7) / 8;
|
||||
}
|
||||
@@ -273,10 +270,10 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
|
||||
protected final AlgorithmParameters engineGetParameters() {
|
||||
OAEPParameterSpec spec =
|
||||
new OAEPParameterSpec(
|
||||
KeyProperties.Digest.fromKeymaster(mKeymasterDigest),
|
||||
MGF_ALGORITGM_MGF1,
|
||||
MGF1ParameterSpec.SHA1,
|
||||
PSource.PSpecified.DEFAULT);
|
||||
KeyProperties.Digest.fromKeymaster(mKeymasterDigest),
|
||||
MGF_ALGORITHM_MGF1,
|
||||
KeyProperties.Digest.fromKeymasterToMGF1ParameterSpec(mKeymasterMgf1Digest),
|
||||
PSource.PSpecified.DEFAULT);
|
||||
try {
|
||||
AlgorithmParameters params = AlgorithmParameters.getInstance("OAEP");
|
||||
params.init(spec);
|
||||
@@ -298,6 +295,9 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
|
||||
parameters.add(KeyStore2ParameterUtils.makeEnum(
|
||||
KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest
|
||||
));
|
||||
parameters.add(KeyStore2ParameterUtils.makeEnum(
|
||||
KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, mKeymasterMgf1Digest
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.security.keystore2;
|
||||
|
||||
import static android.security.keystore2.AndroidKeyStoreCipherSpiBase.DEFAULT_MGF1_DIGEST;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.hardware.biometrics.BiometricManager;
|
||||
import android.hardware.security.keymint.HardwareAuthenticatorType;
|
||||
@@ -511,6 +513,28 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
|
||||
KeymasterDefs.KM_TAG_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()) {
|
||||
importArgs.add(KeyStore2ParameterUtils.makeEnum(
|
||||
|
||||
@@ -78,6 +78,7 @@ public abstract class KeyStore2ParameterUtils {
|
||||
kp.value = KeyParameterValue.blockMode(v);
|
||||
break;
|
||||
case Tag.DIGEST:
|
||||
case Tag.RSA_OAEP_MGF_DIGEST:
|
||||
kp.value = KeyParameterValue.digest(v);
|
||||
break;
|
||||
case Tag.EC_CURVE:
|
||||
|
||||
Reference in New Issue
Block a user