Merge "Define String constants for AndroidKeyStore crypto." into mnc-dev
This commit is contained in:
@@ -28506,6 +28506,53 @@ package android.security {
|
|||||||
public abstract class KeyStoreKeyProperties {
|
public abstract class KeyStoreKeyProperties {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.Algorithm {
|
||||||
|
field public static final java.lang.String AES = "AES";
|
||||||
|
field public static final java.lang.String EC = "EC";
|
||||||
|
field public static final java.lang.String HMAC_SHA1 = "HmacSHA1";
|
||||||
|
field public static final java.lang.String HMAC_SHA224 = "HmacSHA224";
|
||||||
|
field public static final java.lang.String HMAC_SHA256 = "HmacSHA256";
|
||||||
|
field public static final java.lang.String HMAC_SHA384 = "HmacSHA384";
|
||||||
|
field public static final java.lang.String HMAC_SHA512 = "HmacSHA512";
|
||||||
|
field public static final java.lang.String RSA = "RSA";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.AlgorithmEnum implements java.lang.annotation.Annotation {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.BlockMode {
|
||||||
|
field public static final java.lang.String CBC = "CBC";
|
||||||
|
field public static final java.lang.String CTR = "CTR";
|
||||||
|
field public static final java.lang.String ECB = "ECB";
|
||||||
|
field public static final java.lang.String GCM = "GCM";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.BlockModeEnum implements java.lang.annotation.Annotation {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.Digest {
|
||||||
|
field public static final java.lang.String MD5 = "MD5";
|
||||||
|
field public static final java.lang.String NONE = "NONE";
|
||||||
|
field public static final java.lang.String SHA1 = "SHA-1";
|
||||||
|
field public static final java.lang.String SHA224 = "SHA-224";
|
||||||
|
field public static final java.lang.String SHA256 = "SHA-256";
|
||||||
|
field public static final java.lang.String SHA384 = "SHA-384";
|
||||||
|
field public static final java.lang.String SHA512 = "SHA-512";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.DigestEnum implements java.lang.annotation.Annotation {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.EncryptionPadding {
|
||||||
|
field public static final java.lang.String NONE = "NoPadding";
|
||||||
|
field public static final java.lang.String PKCS7 = "PKCS7Padding";
|
||||||
|
field public static final java.lang.String RSA_OAEP = "OAEPPadding";
|
||||||
|
field public static final java.lang.String RSA_PKCS1 = "PKCS1Padding";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.EncryptionPaddingEnum implements java.lang.annotation.Annotation {
|
||||||
|
}
|
||||||
|
|
||||||
public static abstract class KeyStoreKeyProperties.Origin {
|
public static abstract class KeyStoreKeyProperties.Origin {
|
||||||
field public static final int GENERATED = 1; // 0x1
|
field public static final int GENERATED = 1; // 0x1
|
||||||
field public static final int IMPORTED = 2; // 0x2
|
field public static final int IMPORTED = 2; // 0x2
|
||||||
@@ -28525,6 +28572,14 @@ package android.security {
|
|||||||
public static abstract class KeyStoreKeyProperties.PurposeEnum implements java.lang.annotation.Annotation {
|
public static abstract class KeyStoreKeyProperties.PurposeEnum implements java.lang.annotation.Annotation {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.SignaturePadding {
|
||||||
|
field public static final java.lang.String RSA_PKCS1 = "PKCS1";
|
||||||
|
field public static final java.lang.String RSA_PSS = "PSS";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.SignaturePaddingEnum implements java.lang.annotation.Annotation {
|
||||||
|
}
|
||||||
|
|
||||||
public class KeyStoreKeySpec implements java.security.spec.KeySpec {
|
public class KeyStoreKeySpec implements java.security.spec.KeySpec {
|
||||||
method public java.lang.String[] getBlockModes();
|
method public java.lang.String[] getBlockModes();
|
||||||
method public java.lang.String[] getDigests();
|
method public java.lang.String[] getDigests();
|
||||||
|
|||||||
@@ -30520,6 +30520,53 @@ package android.security {
|
|||||||
public abstract class KeyStoreKeyProperties {
|
public abstract class KeyStoreKeyProperties {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.Algorithm {
|
||||||
|
field public static final java.lang.String AES = "AES";
|
||||||
|
field public static final java.lang.String EC = "EC";
|
||||||
|
field public static final java.lang.String HMAC_SHA1 = "HmacSHA1";
|
||||||
|
field public static final java.lang.String HMAC_SHA224 = "HmacSHA224";
|
||||||
|
field public static final java.lang.String HMAC_SHA256 = "HmacSHA256";
|
||||||
|
field public static final java.lang.String HMAC_SHA384 = "HmacSHA384";
|
||||||
|
field public static final java.lang.String HMAC_SHA512 = "HmacSHA512";
|
||||||
|
field public static final java.lang.String RSA = "RSA";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.AlgorithmEnum implements java.lang.annotation.Annotation {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.BlockMode {
|
||||||
|
field public static final java.lang.String CBC = "CBC";
|
||||||
|
field public static final java.lang.String CTR = "CTR";
|
||||||
|
field public static final java.lang.String ECB = "ECB";
|
||||||
|
field public static final java.lang.String GCM = "GCM";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.BlockModeEnum implements java.lang.annotation.Annotation {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.Digest {
|
||||||
|
field public static final java.lang.String MD5 = "MD5";
|
||||||
|
field public static final java.lang.String NONE = "NONE";
|
||||||
|
field public static final java.lang.String SHA1 = "SHA-1";
|
||||||
|
field public static final java.lang.String SHA224 = "SHA-224";
|
||||||
|
field public static final java.lang.String SHA256 = "SHA-256";
|
||||||
|
field public static final java.lang.String SHA384 = "SHA-384";
|
||||||
|
field public static final java.lang.String SHA512 = "SHA-512";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.DigestEnum implements java.lang.annotation.Annotation {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.EncryptionPadding {
|
||||||
|
field public static final java.lang.String NONE = "NoPadding";
|
||||||
|
field public static final java.lang.String PKCS7 = "PKCS7Padding";
|
||||||
|
field public static final java.lang.String RSA_OAEP = "OAEPPadding";
|
||||||
|
field public static final java.lang.String RSA_PKCS1 = "PKCS1Padding";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.EncryptionPaddingEnum implements java.lang.annotation.Annotation {
|
||||||
|
}
|
||||||
|
|
||||||
public static abstract class KeyStoreKeyProperties.Origin {
|
public static abstract class KeyStoreKeyProperties.Origin {
|
||||||
field public static final int GENERATED = 1; // 0x1
|
field public static final int GENERATED = 1; // 0x1
|
||||||
field public static final int IMPORTED = 2; // 0x2
|
field public static final int IMPORTED = 2; // 0x2
|
||||||
@@ -30539,6 +30586,14 @@ package android.security {
|
|||||||
public static abstract class KeyStoreKeyProperties.PurposeEnum implements java.lang.annotation.Annotation {
|
public static abstract class KeyStoreKeyProperties.PurposeEnum implements java.lang.annotation.Annotation {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.SignaturePadding {
|
||||||
|
field public static final java.lang.String RSA_PKCS1 = "PKCS1";
|
||||||
|
field public static final java.lang.String RSA_PSS = "PSS";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class KeyStoreKeyProperties.SignaturePaddingEnum implements java.lang.annotation.Annotation {
|
||||||
|
}
|
||||||
|
|
||||||
public class KeyStoreKeySpec implements java.security.spec.KeySpec {
|
public class KeyStoreKeySpec implements java.security.spec.KeySpec {
|
||||||
method public java.lang.String[] getBlockModes();
|
method public java.lang.String[] getBlockModes();
|
||||||
method public java.lang.String[] getDigests();
|
method public java.lang.String[] getDigests();
|
||||||
|
|||||||
@@ -54,13 +54,13 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
|
|||||||
|
|
||||||
public static class RSA extends AndroidKeyPairGenerator {
|
public static class RSA extends AndroidKeyPairGenerator {
|
||||||
public RSA() {
|
public RSA() {
|
||||||
super("RSA");
|
super(KeyStoreKeyProperties.Algorithm.RSA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EC extends AndroidKeyPairGenerator {
|
public static class EC extends AndroidKeyPairGenerator {
|
||||||
public EC() {
|
public EC() {
|
||||||
super("EC");
|
super(KeyStoreKeyProperties.Algorithm.EC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,15 +83,15 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
|
|||||||
private android.security.KeyStore mKeyStore;
|
private android.security.KeyStore mKeyStore;
|
||||||
|
|
||||||
private KeyPairGeneratorSpec mSpec;
|
private KeyPairGeneratorSpec mSpec;
|
||||||
private String mKeyAlgorithm;
|
private @KeyStoreKeyProperties.AlgorithmEnum String mKeyAlgorithm;
|
||||||
private int mKeyType;
|
private int mKeyType;
|
||||||
private int mKeySize;
|
private int mKeySize;
|
||||||
|
|
||||||
protected AndroidKeyPairGenerator(String algorithm) {
|
protected AndroidKeyPairGenerator(@KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
|
||||||
mAlgorithm = algorithm;
|
mAlgorithm = algorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAlgorithm() {
|
public @KeyStoreKeyProperties.AlgorithmEnum String getAlgorithm() {
|
||||||
return mAlgorithm;
|
return mAlgorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
|
|||||||
return certGen.generate(privateKey);
|
return certGen.generate(privateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getKeyAlgorithm(KeyPairGeneratorSpec spec) {
|
private @KeyStoreKeyProperties.AlgorithmEnum String getKeyAlgorithm(KeyPairGeneratorSpec spec) {
|
||||||
String result = spec.getKeyType();
|
String result = spec.getKeyType();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
return result;
|
return result;
|
||||||
@@ -248,10 +248,11 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getDefaultSignatureAlgorithmForKeyAlgorithm(String algorithm) {
|
private static String getDefaultSignatureAlgorithmForKeyAlgorithm(
|
||||||
if ("RSA".equalsIgnoreCase(algorithm)) {
|
@KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
|
||||||
|
if (KeyStoreKeyProperties.Algorithm.RSA.equalsIgnoreCase(algorithm)) {
|
||||||
return "sha256WithRSA";
|
return "sha256WithRSA";
|
||||||
} else if ("EC".equalsIgnoreCase(algorithm)) {
|
} else if (KeyStoreKeyProperties.Algorithm.EC.equalsIgnoreCase(algorithm)) {
|
||||||
return "sha256WithECDSA";
|
return "sha256WithECDSA";
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unsupported key type " + algorithm);
|
throw new IllegalArgumentException("Unsupported key type " + algorithm);
|
||||||
@@ -287,7 +288,7 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
KeyPairGeneratorSpec spec = (KeyPairGeneratorSpec) params;
|
KeyPairGeneratorSpec spec = (KeyPairGeneratorSpec) params;
|
||||||
String keyAlgorithm = getKeyAlgorithm(spec);
|
@KeyStoreKeyProperties.AlgorithmEnum String keyAlgorithm = getKeyAlgorithm(spec);
|
||||||
int keyType = KeyStore.getKeyTypeForAlgorithm(keyAlgorithm);
|
int keyType = KeyStore.getKeyTypeForAlgorithm(keyAlgorithm);
|
||||||
if (keyType == -1) {
|
if (keyType == -1) {
|
||||||
throw new InvalidAlgorithmParameterException(
|
throw new InvalidAlgorithmParameterException(
|
||||||
|
|||||||
@@ -128,10 +128,11 @@ public class AndroidKeyStore extends KeyStoreSpi {
|
|||||||
keymasterDigest = keymasterDigests.get(0);
|
keymasterDigest = keymasterDigests.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
String keyAlgorithmString;
|
@KeyStoreKeyProperties.AlgorithmEnum String keyAlgorithmString;
|
||||||
try {
|
try {
|
||||||
keyAlgorithmString = KeymasterUtils.getJcaSecretKeyAlgorithm(
|
keyAlgorithmString =
|
||||||
keymasterAlgorithm, keymasterDigest);
|
KeyStoreKeyProperties.Algorithm.fromKeymasterSecretKeyAlgorithm(
|
||||||
|
keymasterAlgorithm, keymasterDigest);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw (UnrecoverableKeyException)
|
throw (UnrecoverableKeyException)
|
||||||
new UnrecoverableKeyException("Unsupported secret key type").initCause(e);
|
new UnrecoverableKeyException("Unsupported secret key type").initCause(e);
|
||||||
@@ -451,10 +452,10 @@ public class AndroidKeyStore extends KeyStoreSpi {
|
|||||||
int keymasterAlgorithm;
|
int keymasterAlgorithm;
|
||||||
int keymasterDigest;
|
int keymasterDigest;
|
||||||
try {
|
try {
|
||||||
keymasterAlgorithm = KeymasterUtils.getKeymasterAlgorithmFromJcaSecretKeyAlgorithm(
|
keymasterAlgorithm = KeyStoreKeyProperties.Algorithm.toKeymasterSecretKeyAlgorithm(
|
||||||
keyAlgorithmString);
|
keyAlgorithmString);
|
||||||
keymasterDigest =
|
keymasterDigest =
|
||||||
KeymasterUtils.getKeymasterDigestfromJcaSecretKeyAlgorithm(keyAlgorithmString);
|
KeyStoreKeyProperties.Algorithm.toKeymasterDigest(keyAlgorithmString);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new KeyStoreException("Unsupported secret key algorithm: " + keyAlgorithmString);
|
throw new KeyStoreException("Unsupported secret key algorithm: " + keyAlgorithmString);
|
||||||
}
|
}
|
||||||
@@ -465,8 +466,7 @@ public class AndroidKeyStore extends KeyStoreSpi {
|
|||||||
int[] keymasterDigests;
|
int[] keymasterDigests;
|
||||||
if (params.isDigestsSpecified()) {
|
if (params.isDigestsSpecified()) {
|
||||||
// Digest(s) specified in parameters
|
// Digest(s) specified in parameters
|
||||||
keymasterDigests =
|
keymasterDigests = KeyStoreKeyProperties.Digest.allToKeymaster(params.getDigests());
|
||||||
KeymasterUtils.getKeymasterDigestsFromJcaDigestAlgorithms(params.getDigests());
|
|
||||||
if (keymasterDigest != -1) {
|
if (keymasterDigest != -1) {
|
||||||
// Digest also specified in the JCA key algorithm name.
|
// Digest also specified in the JCA key algorithm name.
|
||||||
if (!com.android.internal.util.ArrayUtils.contains(
|
if (!com.android.internal.util.ArrayUtils.contains(
|
||||||
@@ -494,8 +494,8 @@ public class AndroidKeyStore extends KeyStoreSpi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@KeyStoreKeyProperties.PurposeEnum int purposes = params.getPurposes();
|
@KeyStoreKeyProperties.PurposeEnum int purposes = params.getPurposes();
|
||||||
int[] keymasterBlockModes = KeymasterUtils.getKeymasterBlockModesFromJcaBlockModes(
|
int[] keymasterBlockModes =
|
||||||
params.getBlockModes());
|
KeyStoreKeyProperties.BlockMode.allToKeymaster(params.getBlockModes());
|
||||||
if (((purposes & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
|
if (((purposes & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
|
||||||
&& (params.isRandomizedEncryptionRequired())) {
|
&& (params.isRandomizedEncryptionRequired())) {
|
||||||
for (int keymasterBlockMode : keymasterBlockModes) {
|
for (int keymasterBlockMode : keymasterBlockModes) {
|
||||||
@@ -503,8 +503,7 @@ public class AndroidKeyStore extends KeyStoreSpi {
|
|||||||
throw new KeyStoreException(
|
throw new KeyStoreException(
|
||||||
"Randomized encryption (IND-CPA) required but may be violated by block"
|
"Randomized encryption (IND-CPA) required but may be violated by block"
|
||||||
+ " mode: "
|
+ " mode: "
|
||||||
+ KeymasterUtils.getJcaBlockModeFromKeymasterBlockMode(
|
+ KeyStoreKeyProperties.BlockMode.fromKeymaster(keymasterBlockMode)
|
||||||
keymasterBlockMode)
|
|
||||||
+ ". See KeyStoreParameter documentation.");
|
+ ". See KeyStoreParameter documentation.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -513,11 +512,11 @@ public class AndroidKeyStore extends KeyStoreSpi {
|
|||||||
args.addInt(KeymasterDefs.KM_TAG_PURPOSE, keymasterPurpose);
|
args.addInt(KeymasterDefs.KM_TAG_PURPOSE, keymasterPurpose);
|
||||||
}
|
}
|
||||||
args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
|
args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
|
||||||
int[] keymasterPaddings = ArrayUtils.concat(
|
if (params.getSignaturePaddings().length > 0) {
|
||||||
KeymasterUtils.getKeymasterPaddingsFromJcaEncryptionPaddings(
|
throw new KeyStoreException("Signature paddings not supported for symmetric keys");
|
||||||
params.getEncryptionPaddings()),
|
}
|
||||||
KeymasterUtils.getKeymasterPaddingsFromJcaSignaturePaddings(
|
int[] keymasterPaddings = KeyStoreKeyProperties.EncryptionPadding.allToKeymaster(
|
||||||
params.getSignaturePaddings()));
|
params.getEncryptionPaddings());
|
||||||
args.addInts(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
|
args.addInts(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
|
||||||
KeymasterUtils.addUserAuthArgs(args,
|
KeymasterUtils.addUserAuthArgs(args,
|
||||||
params.getContext(),
|
params.getContext(),
|
||||||
|
|||||||
@@ -262,7 +262,8 @@ public final class KeyChain {
|
|||||||
* unavailable.
|
* unavailable.
|
||||||
*/
|
*/
|
||||||
public static void choosePrivateKeyAlias(Activity activity, KeyChainAliasCallback response,
|
public static void choosePrivateKeyAlias(Activity activity, KeyChainAliasCallback response,
|
||||||
String[] keyTypes, Principal[] issuers, String host, int port, String alias) {
|
@KeyStoreKeyProperties.AlgorithmEnum String[] keyTypes, Principal[] issuers,
|
||||||
|
String host, int port, String alias) {
|
||||||
choosePrivateKeyAlias(activity, response, keyTypes, issuers, host, port, null, alias);
|
choosePrivateKeyAlias(activity, response, keyTypes, issuers, host, port, null, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,9 +307,8 @@ public final class KeyChain {
|
|||||||
* unavailable.
|
* unavailable.
|
||||||
*/
|
*/
|
||||||
public static void choosePrivateKeyAlias(Activity activity, KeyChainAliasCallback response,
|
public static void choosePrivateKeyAlias(Activity activity, KeyChainAliasCallback response,
|
||||||
String[] keyTypes, Principal[] issuers,
|
@KeyStoreKeyProperties.AlgorithmEnum String[] keyTypes, Principal[] issuers,
|
||||||
String host, int port, String url,
|
String host, int port, String url, String alias) {
|
||||||
String alias) {
|
|
||||||
/*
|
/*
|
||||||
* TODO currently keyTypes, issuers are unused. They are meant
|
* TODO currently keyTypes, issuers are unused. They are meant
|
||||||
* to follow the semantics and purpose of X509KeyManager
|
* to follow the semantics and purpose of X509KeyManager
|
||||||
@@ -431,9 +431,11 @@ public final class KeyChain {
|
|||||||
* specific {@code PrivateKey} type indicated by {@code algorithm} (e.g.,
|
* specific {@code PrivateKey} type indicated by {@code algorithm} (e.g.,
|
||||||
* "RSA").
|
* "RSA").
|
||||||
*/
|
*/
|
||||||
public static boolean isKeyAlgorithmSupported(String algorithm) {
|
public static boolean isKeyAlgorithmSupported(
|
||||||
|
@KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
|
||||||
final String algUpper = algorithm.toUpperCase(Locale.US);
|
final String algUpper = algorithm.toUpperCase(Locale.US);
|
||||||
return "EC".equals(algUpper) || "RSA".equals(algUpper);
|
return KeyStoreKeyProperties.Algorithm.EC.equals(algUpper)
|
||||||
|
|| KeyStoreKeyProperties.Algorithm.RSA.equals(algUpper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -443,7 +445,8 @@ public final class KeyChain {
|
|||||||
* hardware support that can be used to bind keys to the device in a way
|
* hardware support that can be used to bind keys to the device in a way
|
||||||
* that makes it non-exportable.
|
* that makes it non-exportable.
|
||||||
*/
|
*/
|
||||||
public static boolean isBoundKeyAlgorithm(String algorithm) {
|
public static boolean isBoundKeyAlgorithm(
|
||||||
|
@KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
|
||||||
if (!isKeyAlgorithmSupported(algorithm)) {
|
if (!isKeyAlgorithmSupported(algorithm)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
private final Date mKeyValidityForOriginationEnd;
|
private final Date mKeyValidityForOriginationEnd;
|
||||||
private final Date mKeyValidityForConsumptionEnd;
|
private final Date mKeyValidityForConsumptionEnd;
|
||||||
private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
||||||
private final String[] mEncryptionPaddings;
|
private final @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
|
||||||
private final String[] mBlockModes;
|
private final @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
|
||||||
private final boolean mRandomizedEncryptionRequired;
|
private final boolean mRandomizedEncryptionRequired;
|
||||||
private final boolean mUserAuthenticationRequired;
|
private final boolean mUserAuthenticationRequired;
|
||||||
private final int mUserAuthenticationValidityDurationSeconds;
|
private final int mUserAuthenticationValidityDurationSeconds;
|
||||||
@@ -63,8 +63,8 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
Date keyValidityForOriginationEnd,
|
Date keyValidityForOriginationEnd,
|
||||||
Date keyValidityForConsumptionEnd,
|
Date keyValidityForConsumptionEnd,
|
||||||
@KeyStoreKeyProperties.PurposeEnum int purposes,
|
@KeyStoreKeyProperties.PurposeEnum int purposes,
|
||||||
String[] encryptionPaddings,
|
@KeyStoreKeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
|
||||||
String[] blockModes,
|
@KeyStoreKeyProperties.BlockModeEnum String[] blockModes,
|
||||||
boolean randomizedEncryptionRequired,
|
boolean randomizedEncryptionRequired,
|
||||||
boolean userAuthenticationRequired,
|
boolean userAuthenticationRequired,
|
||||||
int userAuthenticationValidityDurationSeconds) {
|
int userAuthenticationValidityDurationSeconds) {
|
||||||
@@ -160,14 +160,14 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
/**
|
/**
|
||||||
* Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
|
* Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
|
||||||
*/
|
*/
|
||||||
public String[] getEncryptionPaddings() {
|
public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
|
||||||
return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
|
return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the set of block modes with which the key can be used.
|
* Gets the set of block modes with which the key can be used.
|
||||||
*/
|
*/
|
||||||
public String[] getBlockModes() {
|
public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
|
||||||
return ArrayUtils.cloneIfNotEmpty(mBlockModes);
|
return ArrayUtils.cloneIfNotEmpty(mBlockModes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,8 +220,8 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
private Date mKeyValidityForOriginationEnd;
|
private Date mKeyValidityForOriginationEnd;
|
||||||
private Date mKeyValidityForConsumptionEnd;
|
private Date mKeyValidityForConsumptionEnd;
|
||||||
private @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
private @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
||||||
private String[] mEncryptionPaddings;
|
private @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
|
||||||
private String[] mBlockModes;
|
private @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
|
||||||
private boolean mRandomizedEncryptionRequired = true;
|
private boolean mRandomizedEncryptionRequired = true;
|
||||||
private boolean mUserAuthenticationRequired;
|
private boolean mUserAuthenticationRequired;
|
||||||
private int mUserAuthenticationValidityDurationSeconds = -1;
|
private int mUserAuthenticationValidityDurationSeconds = -1;
|
||||||
@@ -346,7 +346,8 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
*
|
*
|
||||||
* <p>This must be specified for keys which are used for encryption/decryption.
|
* <p>This must be specified for keys which are used for encryption/decryption.
|
||||||
*/
|
*/
|
||||||
public Builder setEncryptionPaddings(String... paddings) {
|
public Builder setEncryptionPaddings(
|
||||||
|
@KeyStoreKeyProperties.EncryptionPaddingEnum String... paddings) {
|
||||||
mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
|
mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -357,7 +358,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
*
|
*
|
||||||
* <p>This must be specified for encryption/decryption keys.
|
* <p>This must be specified for encryption/decryption keys.
|
||||||
*/
|
*/
|
||||||
public Builder setBlockModes(String... blockModes) {
|
public Builder setBlockModes(@KeyStoreKeyProperties.BlockModeEnum String... blockModes) {
|
||||||
mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
|
mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,13 +85,13 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
|
|
||||||
private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
||||||
|
|
||||||
private final String[] mDigests;
|
private final @KeyStoreKeyProperties.DigestEnum String[] mDigests;
|
||||||
|
|
||||||
private final String[] mEncryptionPaddings;
|
private final @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
|
||||||
|
|
||||||
private final String[] mSignaturePaddings;
|
private final @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
|
||||||
|
|
||||||
private final String[] mBlockModes;
|
private final @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
|
||||||
|
|
||||||
private final boolean mRandomizedEncryptionRequired;
|
private final boolean mRandomizedEncryptionRequired;
|
||||||
|
|
||||||
@@ -138,10 +138,10 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
Date keyValidityForOriginationEnd,
|
Date keyValidityForOriginationEnd,
|
||||||
Date keyValidityForConsumptionEnd,
|
Date keyValidityForConsumptionEnd,
|
||||||
@KeyStoreKeyProperties.PurposeEnum int purposes,
|
@KeyStoreKeyProperties.PurposeEnum int purposes,
|
||||||
String[] digests,
|
@KeyStoreKeyProperties.DigestEnum String[] digests,
|
||||||
String[] encryptionPaddings,
|
@KeyStoreKeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
|
||||||
String[] signaturePaddings,
|
@KeyStoreKeyProperties.SignaturePaddingEnum String[] signaturePaddings,
|
||||||
String[] blockModes,
|
@KeyStoreKeyProperties.BlockModeEnum String[] blockModes,
|
||||||
boolean randomizedEncryptionRequired,
|
boolean randomizedEncryptionRequired,
|
||||||
boolean userAuthenticationRequired,
|
boolean userAuthenticationRequired,
|
||||||
int userAuthenticationValidityDurationSeconds) {
|
int userAuthenticationValidityDurationSeconds) {
|
||||||
@@ -246,7 +246,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
/**
|
/**
|
||||||
* Returns the key type (e.g., "EC", "RSA") specified by this parameter.
|
* Returns the key type (e.g., "EC", "RSA") specified by this parameter.
|
||||||
*/
|
*/
|
||||||
public String getKeyType() {
|
public @KeyStoreKeyProperties.AlgorithmEnum String getKeyType() {
|
||||||
return mKeyType;
|
return mKeyType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,28 +352,28 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
/**
|
/**
|
||||||
* Gets the set of digest algorithms with which the key can be used.
|
* Gets the set of digest algorithms with which the key can be used.
|
||||||
*/
|
*/
|
||||||
public String[] getDigests() {
|
public @KeyStoreKeyProperties.DigestEnum String[] getDigests() {
|
||||||
return ArrayUtils.cloneIfNotEmpty(mDigests);
|
return ArrayUtils.cloneIfNotEmpty(mDigests);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
|
* Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
|
||||||
*/
|
*/
|
||||||
public String[] getEncryptionPaddings() {
|
public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
|
||||||
return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
|
return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the set of padding schemes with which the key can be used when signing/verifying.
|
* Gets the set of padding schemes with which the key can be used when signing/verifying.
|
||||||
*/
|
*/
|
||||||
public String[] getSignaturePaddings() {
|
public @KeyStoreKeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
|
||||||
return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
|
return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the set of block modes with which the key can be used.
|
* Gets the set of block modes with which the key can be used.
|
||||||
*/
|
*/
|
||||||
public String[] getBlockModes() {
|
public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
|
||||||
return ArrayUtils.cloneIfNotEmpty(mBlockModes);
|
return ArrayUtils.cloneIfNotEmpty(mBlockModes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,13 +468,13 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
|
|
||||||
private @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
private @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
||||||
|
|
||||||
private String[] mDigests;
|
private @KeyStoreKeyProperties.DigestEnum String[] mDigests;
|
||||||
|
|
||||||
private String[] mEncryptionPaddings;
|
private @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
|
||||||
|
|
||||||
private String[] mSignaturePaddings;
|
private @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
|
||||||
|
|
||||||
private String[] mBlockModes;
|
private @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
|
||||||
|
|
||||||
private boolean mRandomizedEncryptionRequired = true;
|
private boolean mRandomizedEncryptionRequired = true;
|
||||||
|
|
||||||
@@ -511,7 +511,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
/**
|
/**
|
||||||
* Sets the key type (e.g., EC, RSA) of the keypair to be created.
|
* Sets the key type (e.g., EC, RSA) of the keypair to be created.
|
||||||
*/
|
*/
|
||||||
public Builder setKeyType(String keyType) throws NoSuchAlgorithmException {
|
public Builder setKeyType(@KeyStoreKeyProperties.AlgorithmEnum String keyType)
|
||||||
|
throws NoSuchAlgorithmException {
|
||||||
if (keyType == null) {
|
if (keyType == null) {
|
||||||
throw new NullPointerException("keyType == null");
|
throw new NullPointerException("keyType == null");
|
||||||
} else {
|
} else {
|
||||||
@@ -691,7 +692,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
*
|
*
|
||||||
* <p>This must be specified for keys which are used for signing/verification.
|
* <p>This must be specified for keys which are used for signing/verification.
|
||||||
*/
|
*/
|
||||||
public Builder setDigests(String... digests) {
|
public Builder setDigests(@KeyStoreKeyProperties.DigestEnum String... digests) {
|
||||||
mDigests = ArrayUtils.cloneIfNotEmpty(digests);
|
mDigests = ArrayUtils.cloneIfNotEmpty(digests);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -703,7 +704,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
*
|
*
|
||||||
* <p>This must be specified for keys which are used for encryption/decryption.
|
* <p>This must be specified for keys which are used for encryption/decryption.
|
||||||
*/
|
*/
|
||||||
public Builder setEncryptionPaddings(String... paddings) {
|
public Builder setEncryptionPaddings(
|
||||||
|
@KeyStoreKeyProperties.EncryptionPaddingEnum String... paddings) {
|
||||||
mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
|
mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -715,7 +717,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
*
|
*
|
||||||
* <p>This must be specified for RSA keys which are used for signing/verification.
|
* <p>This must be specified for RSA keys which are used for signing/verification.
|
||||||
*/
|
*/
|
||||||
public Builder setSignaturePaddings(String... paddings) {
|
public Builder setSignaturePaddings(
|
||||||
|
@KeyStoreKeyProperties.SignaturePaddingEnum String... paddings) {
|
||||||
mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
|
mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -726,7 +729,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
*
|
*
|
||||||
* <p>This must be specified for encryption/decryption keys.
|
* <p>This must be specified for encryption/decryption keys.
|
||||||
*/
|
*/
|
||||||
public Builder setBlockModes(String... blockModes) {
|
public Builder setBlockModes(@KeyStoreKeyProperties.BlockModeEnum String... blockModes) {
|
||||||
mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
|
mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,10 +115,10 @@ public class KeyStore {
|
|||||||
return mToken;
|
return mToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getKeyTypeForAlgorithm(String keyType) {
|
static int getKeyTypeForAlgorithm(@KeyStoreKeyProperties.AlgorithmEnum String keyType) {
|
||||||
if ("RSA".equalsIgnoreCase(keyType)) {
|
if (KeyStoreKeyProperties.Algorithm.RSA.equalsIgnoreCase(keyType)) {
|
||||||
return NativeConstants.EVP_PKEY_RSA;
|
return NativeConstants.EVP_PKEY_RSA;
|
||||||
} else if ("EC".equalsIgnoreCase(keyType)) {
|
} else if (KeyStoreKeyProperties.Algorithm.EC.equalsIgnoreCase(keyType)) {
|
||||||
return NativeConstants.EVP_PKEY_EC;
|
return NativeConstants.EVP_PKEY_EC;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -494,7 +494,8 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
|
|||||||
}
|
}
|
||||||
if ((mIv != null) && (mIv.length > 0)) {
|
if ((mIv != null) && (mIv.length > 0)) {
|
||||||
try {
|
try {
|
||||||
AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
|
AlgorithmParameters params =
|
||||||
|
AlgorithmParameters.getInstance(KeyStoreKeyProperties.Algorithm.AES);
|
||||||
params.init(new IvParameterSpec(mIv));
|
params.init(new IvParameterSpec(mIv));
|
||||||
return params;
|
return params;
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
|||||||
@@ -129,8 +129,8 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
|
|||||||
int keySizeBits = (spec.getKeySize() != -1) ? spec.getKeySize() : mDefaultKeySizeBits;
|
int keySizeBits = (spec.getKeySize() != -1) ? spec.getKeySize() : mDefaultKeySizeBits;
|
||||||
args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, keySizeBits);
|
args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, keySizeBits);
|
||||||
@KeyStoreKeyProperties.PurposeEnum int purposes = spec.getPurposes();
|
@KeyStoreKeyProperties.PurposeEnum int purposes = spec.getPurposes();
|
||||||
int[] keymasterBlockModes = KeymasterUtils.getKeymasterBlockModesFromJcaBlockModes(
|
int[] keymasterBlockModes =
|
||||||
spec.getBlockModes());
|
KeyStoreKeyProperties.BlockMode.allToKeymaster(spec.getBlockModes());
|
||||||
if (((purposes & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
|
if (((purposes & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
|
||||||
&& (spec.isRandomizedEncryptionRequired())) {
|
&& (spec.isRandomizedEncryptionRequired())) {
|
||||||
for (int keymasterBlockMode : keymasterBlockModes) {
|
for (int keymasterBlockMode : keymasterBlockModes) {
|
||||||
@@ -138,8 +138,7 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
|
|||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Randomized encryption (IND-CPA) required but may be violated by block"
|
"Randomized encryption (IND-CPA) required but may be violated by block"
|
||||||
+ " mode: "
|
+ " mode: "
|
||||||
+ KeymasterUtils.getJcaBlockModeFromKeymasterBlockMode(
|
+ KeyStoreKeyProperties.BlockMode.fromKeymaster(keymasterBlockMode)
|
||||||
keymasterBlockMode)
|
|
||||||
+ ". See KeyGeneratorSpec documentation.");
|
+ ". See KeyGeneratorSpec documentation.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,7 +151,7 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
|
|||||||
args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
|
args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
|
||||||
args.addInts(
|
args.addInts(
|
||||||
KeymasterDefs.KM_TAG_PADDING,
|
KeymasterDefs.KM_TAG_PADDING,
|
||||||
KeymasterUtils.getKeymasterPaddingsFromJcaEncryptionPaddings(
|
KeyStoreKeyProperties.EncryptionPadding.allToKeymaster(
|
||||||
spec.getEncryptionPaddings()));
|
spec.getEncryptionPaddings()));
|
||||||
KeymasterUtils.addUserAuthArgs(args,
|
KeymasterUtils.addUserAuthArgs(args,
|
||||||
spec.getContext(),
|
spec.getContext(),
|
||||||
@@ -189,8 +188,9 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
|
|||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Keystore operation failed", KeyStore.getKeyStoreException(errorCode));
|
"Keystore operation failed", KeyStore.getKeyStoreException(errorCode));
|
||||||
}
|
}
|
||||||
String keyAlgorithmJCA =
|
@KeyStoreKeyProperties.AlgorithmEnum String keyAlgorithmJCA =
|
||||||
KeymasterUtils.getJcaSecretKeyAlgorithm(mKeymasterAlgorithm, mKeymasterDigest);
|
KeyStoreKeyProperties.Algorithm.fromKeymasterSecretKeyAlgorithm(
|
||||||
|
mKeymasterAlgorithm, mKeymasterDigest);
|
||||||
return new KeyStoreSecretKey(keyAliasInKeystore, keyAlgorithmJCA);
|
return new KeyStoreSecretKey(keyAliasInKeystore, keyAlgorithmJCA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,13 +17,23 @@
|
|||||||
package android.security;
|
package android.security;
|
||||||
|
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
|
import android.annotation.StringDef;
|
||||||
import android.security.keymaster.KeymasterDefs;
|
import android.security.keymaster.KeymasterDefs;
|
||||||
|
|
||||||
import libcore.util.EmptyArray;
|
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.Key;
|
||||||
|
import java.security.KeyFactory;
|
||||||
|
import java.security.KeyPairGenerator;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.KeyGenerator;
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.SecretKeyFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties of {@code AndroidKeyStore} keys.
|
* Properties of {@code AndroidKeyStore} keys.
|
||||||
@@ -37,7 +47,7 @@ public abstract class KeyStoreKeyProperties {
|
|||||||
public @interface PurposeEnum {}
|
public @interface PurposeEnum {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Purpose of key.
|
* Purposes of key.
|
||||||
*/
|
*/
|
||||||
public static abstract class Purpose {
|
public static abstract class Purpose {
|
||||||
private Purpose() {}
|
private Purpose() {}
|
||||||
@@ -121,6 +131,514 @@ public abstract class KeyStoreKeyProperties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@StringDef({
|
||||||
|
Algorithm.RSA,
|
||||||
|
Algorithm.EC,
|
||||||
|
Algorithm.AES,
|
||||||
|
Algorithm.HMAC_SHA1,
|
||||||
|
Algorithm.HMAC_SHA224,
|
||||||
|
Algorithm.HMAC_SHA256,
|
||||||
|
Algorithm.HMAC_SHA384,
|
||||||
|
Algorithm.HMAC_SHA512,
|
||||||
|
})
|
||||||
|
public @interface AlgorithmEnum {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key algorithms.
|
||||||
|
*
|
||||||
|
* <p>These are standard names which can be used to obtain instances of {@link KeyGenerator},
|
||||||
|
* {@link KeyPairGenerator}, {@link Cipher} (as part of the transformation string), {@link Mac},
|
||||||
|
* {@link KeyFactory}, {@link SecretKeyFactory}. These are also the names used by
|
||||||
|
* {@link Key#getAlgorithm()}.
|
||||||
|
*/
|
||||||
|
public static abstract class Algorithm {
|
||||||
|
private Algorithm() {}
|
||||||
|
|
||||||
|
/** Rivest Shamir Adleman (RSA) key. */
|
||||||
|
public static final String RSA = "RSA";
|
||||||
|
|
||||||
|
/** Elliptic Curve (EC) key. */
|
||||||
|
public static final String EC = "EC";
|
||||||
|
|
||||||
|
/** Advanced Encryption Standard (AES) key. */
|
||||||
|
public static final String AES = "AES";
|
||||||
|
|
||||||
|
/** Keyed-Hash Message Authentication Code (HMAC) key using SHA-1 as the hash. */
|
||||||
|
public static final String HMAC_SHA1 = "HmacSHA1";
|
||||||
|
|
||||||
|
/** Keyed-Hash Message Authentication Code (HMAC) key using SHA-224 as the hash. */
|
||||||
|
public static final String HMAC_SHA224 = "HmacSHA224";
|
||||||
|
|
||||||
|
/** Keyed-Hash Message Authentication Code (HMAC) key using SHA-256 as the hash. */
|
||||||
|
public static final String HMAC_SHA256 = "HmacSHA256";
|
||||||
|
|
||||||
|
/** Keyed-Hash Message Authentication Code (HMAC) key using SHA-384 as the hash. */
|
||||||
|
public static final String HMAC_SHA384 = "HmacSHA384";
|
||||||
|
|
||||||
|
/** Keyed-Hash Message Authentication Code (HMAC) key using SHA-512 as the hash. */
|
||||||
|
public static final String HMAC_SHA512 = "HmacSHA512";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static int toKeymasterSecretKeyAlgorithm(@AlgorithmEnum String algorithm) {
|
||||||
|
if (AES.equalsIgnoreCase(algorithm)) {
|
||||||
|
return KeymasterDefs.KM_ALGORITHM_AES;
|
||||||
|
} else if (algorithm.toUpperCase(Locale.US).startsWith("HMAC")) {
|
||||||
|
return KeymasterDefs.KM_ALGORITHM_HMAC;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unsupported secret key algorithm: " + algorithm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static @AlgorithmEnum String fromKeymasterSecretKeyAlgorithm(
|
||||||
|
int keymasterAlgorithm, int keymasterDigest) {
|
||||||
|
switch (keymasterAlgorithm) {
|
||||||
|
case KeymasterDefs.KM_ALGORITHM_AES:
|
||||||
|
if (keymasterDigest != -1) {
|
||||||
|
throw new IllegalArgumentException("Digest not supported for AES key: "
|
||||||
|
+ Digest.fromKeymaster(keymasterDigest));
|
||||||
|
}
|
||||||
|
return AES;
|
||||||
|
case KeymasterDefs.KM_ALGORITHM_HMAC:
|
||||||
|
switch (keymasterDigest) {
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA1:
|
||||||
|
return HMAC_SHA1;
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA_2_224:
|
||||||
|
return HMAC_SHA224;
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA_2_256:
|
||||||
|
return HMAC_SHA256;
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA_2_384:
|
||||||
|
return HMAC_SHA384;
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA_2_512:
|
||||||
|
return HMAC_SHA512;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unsupported HMAC digest: "
|
||||||
|
+ Digest.fromKeymaster(keymasterDigest));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unsupported algorithm: " + keymasterAlgorithm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*
|
||||||
|
* @return keymaster digest or {@code -1} if the algorithm does not involve a digest.
|
||||||
|
*/
|
||||||
|
static int toKeymasterDigest(@AlgorithmEnum String algorithm) {
|
||||||
|
String algorithmUpper = algorithm.toUpperCase(Locale.US);
|
||||||
|
if (algorithmUpper.startsWith("HMAC")) {
|
||||||
|
String digestUpper = algorithmUpper.substring("HMAC".length());
|
||||||
|
switch (digestUpper) {
|
||||||
|
case "SHA1":
|
||||||
|
return KeymasterDefs.KM_DIGEST_SHA1;
|
||||||
|
case "SHA224":
|
||||||
|
return KeymasterDefs.KM_DIGEST_SHA_2_224;
|
||||||
|
case "SHA256":
|
||||||
|
return KeymasterDefs.KM_DIGEST_SHA_2_256;
|
||||||
|
case "SHA384":
|
||||||
|
return KeymasterDefs.KM_DIGEST_SHA_2_384;
|
||||||
|
case "SHA512":
|
||||||
|
return KeymasterDefs.KM_DIGEST_SHA_2_512;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unsupported HMAC digest: " + digestUpper);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@StringDef({
|
||||||
|
BlockMode.ECB,
|
||||||
|
BlockMode.CBC,
|
||||||
|
BlockMode.CTR,
|
||||||
|
BlockMode.GCM,
|
||||||
|
})
|
||||||
|
public @interface BlockModeEnum {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Block modes that can be used when encrypting/decrypting using a key.
|
||||||
|
*/
|
||||||
|
public static abstract class BlockMode {
|
||||||
|
private BlockMode() {}
|
||||||
|
|
||||||
|
/** Electronic Codebook (ECB) block mode. */
|
||||||
|
public static final String ECB = "ECB";
|
||||||
|
|
||||||
|
/** Cipher Block Chaining (CBC) block mode. */
|
||||||
|
public static final String CBC = "CBC";
|
||||||
|
|
||||||
|
/** Counter (CTR) block mode. */
|
||||||
|
public static final String CTR = "CTR";
|
||||||
|
|
||||||
|
/** Galois/Counter Mode (GCM) block mode. */
|
||||||
|
public static final String GCM = "GCM";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static int toKeymaster(@BlockModeEnum String blockMode) {
|
||||||
|
if (ECB.equalsIgnoreCase(blockMode)) {
|
||||||
|
return KeymasterDefs.KM_MODE_ECB;
|
||||||
|
} else if (CBC.equalsIgnoreCase(blockMode)) {
|
||||||
|
return KeymasterDefs.KM_MODE_CBC;
|
||||||
|
} else if (CTR.equalsIgnoreCase(blockMode)) {
|
||||||
|
return KeymasterDefs.KM_MODE_CTR;
|
||||||
|
} else if (GCM.equalsIgnoreCase(blockMode)) {
|
||||||
|
return KeymasterDefs.KM_MODE_GCM;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unsupported block mode: " + blockMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static @BlockModeEnum String fromKeymaster(int blockMode) {
|
||||||
|
switch (blockMode) {
|
||||||
|
case KeymasterDefs.KM_MODE_ECB:
|
||||||
|
return ECB;
|
||||||
|
case KeymasterDefs.KM_MODE_CBC:
|
||||||
|
return CBC;
|
||||||
|
case KeymasterDefs.KM_MODE_CTR:
|
||||||
|
return CTR;
|
||||||
|
case KeymasterDefs.KM_MODE_GCM:
|
||||||
|
return GCM;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unsupported block mode: " + blockMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static @BlockModeEnum String[] allFromKeymaster(Collection<Integer> blockModes) {
|
||||||
|
if ((blockModes == null) || (blockModes.isEmpty())) {
|
||||||
|
return EmptyArray.STRING;
|
||||||
|
}
|
||||||
|
@BlockModeEnum String[] result = new String[blockModes.size()];
|
||||||
|
int offset = 0;
|
||||||
|
for (int blockMode : blockModes) {
|
||||||
|
result[offset] = fromKeymaster(blockMode);
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static int[] allToKeymaster(@BlockModeEnum String[] blockModes) {
|
||||||
|
if ((blockModes == null) || (blockModes.length == 0)) {
|
||||||
|
return EmptyArray.INT;
|
||||||
|
}
|
||||||
|
int[] result = new int[blockModes.length];
|
||||||
|
for (int i = 0; i < blockModes.length; i++) {
|
||||||
|
result[i] = toKeymaster(blockModes[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@StringDef({
|
||||||
|
EncryptionPadding.NONE,
|
||||||
|
EncryptionPadding.PKCS7,
|
||||||
|
EncryptionPadding.RSA_PKCS1,
|
||||||
|
EncryptionPadding.RSA_OAEP,
|
||||||
|
})
|
||||||
|
public @interface EncryptionPaddingEnum {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Padding schemes for encryption/decryption.
|
||||||
|
*/
|
||||||
|
public static abstract class EncryptionPadding {
|
||||||
|
private EncryptionPadding() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No padding.
|
||||||
|
*/
|
||||||
|
public static final String NONE = "NoPadding";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PKCS#7 padding.
|
||||||
|
*/
|
||||||
|
public static final String PKCS7 = "PKCS7Padding";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSA PKCS#1 v1.5 padding for encryption/decryption.
|
||||||
|
*/
|
||||||
|
public static final String RSA_PKCS1 = "PKCS1Padding";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSA Optimal Asymmetric Encryption Padding (OAEP).
|
||||||
|
*/
|
||||||
|
public static final String RSA_OAEP = "OAEPPadding";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static int toKeymaster(@EncryptionPaddingEnum String padding) {
|
||||||
|
if (NONE.equalsIgnoreCase(padding)) {
|
||||||
|
return KeymasterDefs.KM_PAD_NONE;
|
||||||
|
} else if (PKCS7.equalsIgnoreCase(padding)) {
|
||||||
|
return KeymasterDefs.KM_PAD_PKCS7;
|
||||||
|
} else if (RSA_PKCS1.equalsIgnoreCase(padding)) {
|
||||||
|
return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT;
|
||||||
|
} else if (RSA_OAEP.equalsIgnoreCase(padding)) {
|
||||||
|
return KeymasterDefs.KM_PAD_RSA_OAEP;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unsupported encryption padding scheme: " + padding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static @EncryptionPaddingEnum String fromKeymaster(int padding) {
|
||||||
|
switch (padding) {
|
||||||
|
case KeymasterDefs.KM_PAD_NONE:
|
||||||
|
return NONE;
|
||||||
|
case KeymasterDefs.KM_PAD_PKCS7:
|
||||||
|
return PKCS7;
|
||||||
|
case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
|
||||||
|
return RSA_PKCS1;
|
||||||
|
case KeymasterDefs.KM_PAD_RSA_OAEP:
|
||||||
|
return RSA_OAEP;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unsupported encryption padding: " + padding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static int[] allToKeymaster(@EncryptionPaddingEnum String[] paddings) {
|
||||||
|
if ((paddings == null) || (paddings.length == 0)) {
|
||||||
|
return EmptyArray.INT;
|
||||||
|
}
|
||||||
|
int[] result = new int[paddings.length];
|
||||||
|
for (int i = 0; i < paddings.length; i++) {
|
||||||
|
result[i] = toKeymaster(paddings[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@StringDef({
|
||||||
|
SignaturePadding.RSA_PKCS1,
|
||||||
|
SignaturePadding.RSA_PSS,
|
||||||
|
})
|
||||||
|
public @interface SignaturePaddingEnum {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Padding schemes for signing/verification.
|
||||||
|
*/
|
||||||
|
public static abstract class SignaturePadding {
|
||||||
|
private SignaturePadding() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSA PKCS#1 v1.5 padding for signatures.
|
||||||
|
*/
|
||||||
|
public static final String RSA_PKCS1 = "PKCS1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSA PKCS#1 v2.1 Probabilistic Signature Scheme (PSS) padding.
|
||||||
|
*/
|
||||||
|
public static final String RSA_PSS = "PSS";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static int toKeymaster(@SignaturePaddingEnum String padding) {
|
||||||
|
switch (padding.toUpperCase(Locale.US)) {
|
||||||
|
case RSA_PKCS1:
|
||||||
|
return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN;
|
||||||
|
case RSA_PSS:
|
||||||
|
return KeymasterDefs.KM_PAD_RSA_PSS;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unsupported signature padding scheme: " + padding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static @SignaturePaddingEnum String fromKeymaster(int padding) {
|
||||||
|
switch (padding) {
|
||||||
|
case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN:
|
||||||
|
return RSA_PKCS1;
|
||||||
|
case KeymasterDefs.KM_PAD_RSA_PSS:
|
||||||
|
return RSA_PSS;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unsupported signature padding: " + padding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static int[] allToKeymaster(@SignaturePaddingEnum String[] paddings) {
|
||||||
|
if ((paddings == null) || (paddings.length == 0)) {
|
||||||
|
return EmptyArray.INT;
|
||||||
|
}
|
||||||
|
int[] result = new int[paddings.length];
|
||||||
|
for (int i = 0; i < paddings.length; i++) {
|
||||||
|
result[i] = toKeymaster(paddings[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@StringDef({
|
||||||
|
Digest.NONE,
|
||||||
|
Digest.MD5,
|
||||||
|
Digest.SHA1,
|
||||||
|
Digest.SHA224,
|
||||||
|
Digest.SHA256,
|
||||||
|
Digest.SHA384,
|
||||||
|
Digest.SHA512,
|
||||||
|
})
|
||||||
|
public @interface DigestEnum {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Digests that can be used with a key when signing or generating Message Authentication
|
||||||
|
* Codes (MACs).
|
||||||
|
*/
|
||||||
|
public static abstract class Digest {
|
||||||
|
private Digest() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No digest: sign/authenticate the raw message.
|
||||||
|
*/
|
||||||
|
public static final String NONE = "NONE";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MD5 digest.
|
||||||
|
*/
|
||||||
|
public static final String MD5 = "MD5";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA-1 digest.
|
||||||
|
*/
|
||||||
|
public static final String SHA1 = "SHA-1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA-2 224 (aka SHA-224) digest.
|
||||||
|
*/
|
||||||
|
public static final String SHA224 = "SHA-224";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA-2 256 (aka SHA-256) digest.
|
||||||
|
*/
|
||||||
|
public static final String SHA256 = "SHA-256";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA-2 384 (aka SHA-384) digest.
|
||||||
|
*/
|
||||||
|
public static final String SHA384 = "SHA-384";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA-2 512 (aka SHA-512) digest.
|
||||||
|
*/
|
||||||
|
public static final String SHA512 = "SHA-512";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static int toKeymaster(@DigestEnum String digest) {
|
||||||
|
switch (digest.toUpperCase(Locale.US)) {
|
||||||
|
case SHA1:
|
||||||
|
return KeymasterDefs.KM_DIGEST_SHA1;
|
||||||
|
case SHA224:
|
||||||
|
return KeymasterDefs.KM_DIGEST_SHA_2_224;
|
||||||
|
case SHA256:
|
||||||
|
return KeymasterDefs.KM_DIGEST_SHA_2_256;
|
||||||
|
case SHA384:
|
||||||
|
return KeymasterDefs.KM_DIGEST_SHA_2_384;
|
||||||
|
case SHA512:
|
||||||
|
return KeymasterDefs.KM_DIGEST_SHA_2_512;
|
||||||
|
case NONE:
|
||||||
|
return KeymasterDefs.KM_DIGEST_NONE;
|
||||||
|
case MD5:
|
||||||
|
return KeymasterDefs.KM_DIGEST_MD5;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unsupported digest algorithm: " + digest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static @DigestEnum String fromKeymaster(int digest) {
|
||||||
|
switch (digest) {
|
||||||
|
case KeymasterDefs.KM_DIGEST_NONE:
|
||||||
|
return NONE;
|
||||||
|
case KeymasterDefs.KM_DIGEST_MD5:
|
||||||
|
return MD5;
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA1:
|
||||||
|
return SHA1;
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA_2_224:
|
||||||
|
return SHA224;
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA_2_256:
|
||||||
|
return SHA256;
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA_2_384:
|
||||||
|
return SHA384;
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA_2_512:
|
||||||
|
return SHA512;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unsupported digest algorithm: " + digest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static @DigestEnum String[] allFromKeymaster(Collection<Integer> digests) {
|
||||||
|
if (digests.isEmpty()) {
|
||||||
|
return EmptyArray.STRING;
|
||||||
|
}
|
||||||
|
String[] result = new String[digests.size()];
|
||||||
|
int offset = 0;
|
||||||
|
for (int digest : digests) {
|
||||||
|
result[offset] = fromKeymaster(digest);
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static int[] allToKeymaster(@DigestEnum String[] digests) {
|
||||||
|
if ((digests == null) || (digests.length == 0)) {
|
||||||
|
return EmptyArray.INT;
|
||||||
|
}
|
||||||
|
int[] result = new int[digests.length];
|
||||||
|
int offset = 0;
|
||||||
|
for (@DigestEnum String digest : digests) {
|
||||||
|
result[offset] = toKeymaster(digest);
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({Origin.GENERATED, Origin.IMPORTED, Origin.UNKNOWN})
|
@IntDef({Origin.GENERATED, Origin.IMPORTED, Origin.UNKNOWN})
|
||||||
public @interface OriginEnum {}
|
public @interface OriginEnum {}
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ public class KeyStoreKeySpec implements KeySpec {
|
|||||||
private final Date mKeyValidityForOriginationEnd;
|
private final Date mKeyValidityForOriginationEnd;
|
||||||
private final Date mKeyValidityForConsumptionEnd;
|
private final Date mKeyValidityForConsumptionEnd;
|
||||||
private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
||||||
private final String[] mEncryptionPaddings;
|
private final @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
|
||||||
private final String[] mSignaturePaddings;
|
private final @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
|
||||||
private final String[] mDigests;
|
private final @KeyStoreKeyProperties.DigestEnum String[] mDigests;
|
||||||
private final String[] mBlockModes;
|
private final @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
|
||||||
private final boolean mUserAuthenticationRequired;
|
private final boolean mUserAuthenticationRequired;
|
||||||
private final int mUserAuthenticationValidityDurationSeconds;
|
private final int mUserAuthenticationValidityDurationSeconds;
|
||||||
private final boolean mUserAuthenticationRequirementTeeEnforced;
|
private final boolean mUserAuthenticationRequirementTeeEnforced;
|
||||||
@@ -51,10 +51,10 @@ public class KeyStoreKeySpec implements KeySpec {
|
|||||||
Date keyValidityForOriginationEnd,
|
Date keyValidityForOriginationEnd,
|
||||||
Date keyValidityForConsumptionEnd,
|
Date keyValidityForConsumptionEnd,
|
||||||
@KeyStoreKeyProperties.PurposeEnum int purposes,
|
@KeyStoreKeyProperties.PurposeEnum int purposes,
|
||||||
String[] encryptionPaddings,
|
@KeyStoreKeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
|
||||||
String[] signaturePaddings,
|
@KeyStoreKeyProperties.SignaturePaddingEnum String[] signaturePaddings,
|
||||||
String[] digests,
|
@KeyStoreKeyProperties.DigestEnum String[] digests,
|
||||||
String[] blockModes,
|
@KeyStoreKeyProperties.BlockModeEnum String[] blockModes,
|
||||||
boolean userAuthenticationRequired,
|
boolean userAuthenticationRequired,
|
||||||
int userAuthenticationValidityDurationSeconds,
|
int userAuthenticationValidityDurationSeconds,
|
||||||
boolean userAuthenticationRequirementTeeEnforced) {
|
boolean userAuthenticationRequirementTeeEnforced) {
|
||||||
@@ -143,28 +143,28 @@ public class KeyStoreKeySpec implements KeySpec {
|
|||||||
/**
|
/**
|
||||||
* Gets the set of block modes with which the key can be used.
|
* Gets the set of block modes with which the key can be used.
|
||||||
*/
|
*/
|
||||||
public String[] getBlockModes() {
|
public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
|
||||||
return ArrayUtils.cloneIfNotEmpty(mBlockModes);
|
return ArrayUtils.cloneIfNotEmpty(mBlockModes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the set of padding modes with which the key can be used when encrypting/decrypting.
|
* Gets the set of padding modes with which the key can be used when encrypting/decrypting.
|
||||||
*/
|
*/
|
||||||
public String[] getEncryptionPaddings() {
|
public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
|
||||||
return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
|
return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the set of padding modes with which the key can be used when signing/verifying.
|
* Gets the set of padding modes with which the key can be used when signing/verifying.
|
||||||
*/
|
*/
|
||||||
public String[] getSignaturePaddings() {
|
public @KeyStoreKeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
|
||||||
return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
|
return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the set of digest algorithms with which the key can be used.
|
* Gets the set of digest algorithms with which the key can be used.
|
||||||
*/
|
*/
|
||||||
public String[] getDigests() {
|
public @KeyStoreKeyProperties.DigestEnum String[] getDigests() {
|
||||||
return ArrayUtils.cloneIfNotEmpty(mDigests);
|
return ArrayUtils.cloneIfNotEmpty(mDigests);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,10 +45,10 @@ public final class KeyStoreParameter implements ProtectionParameter {
|
|||||||
private final Date mKeyValidityForOriginationEnd;
|
private final Date mKeyValidityForOriginationEnd;
|
||||||
private final Date mKeyValidityForConsumptionEnd;
|
private final Date mKeyValidityForConsumptionEnd;
|
||||||
private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
||||||
private final String[] mEncryptionPaddings;
|
private final @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
|
||||||
private final String[] mSignaturePaddings;
|
private final @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
|
||||||
private final String[] mDigests;
|
private final @KeyStoreKeyProperties.DigestEnum String[] mDigests;
|
||||||
private final String[] mBlockModes;
|
private final @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
|
||||||
private final boolean mRandomizedEncryptionRequired;
|
private final boolean mRandomizedEncryptionRequired;
|
||||||
private final boolean mUserAuthenticationRequired;
|
private final boolean mUserAuthenticationRequired;
|
||||||
private final int mUserAuthenticationValidityDurationSeconds;
|
private final int mUserAuthenticationValidityDurationSeconds;
|
||||||
@@ -60,10 +60,10 @@ public final class KeyStoreParameter implements ProtectionParameter {
|
|||||||
Date keyValidityForOriginationEnd,
|
Date keyValidityForOriginationEnd,
|
||||||
Date keyValidityForConsumptionEnd,
|
Date keyValidityForConsumptionEnd,
|
||||||
@KeyStoreKeyProperties.PurposeEnum int purposes,
|
@KeyStoreKeyProperties.PurposeEnum int purposes,
|
||||||
String[] encryptionPaddings,
|
@KeyStoreKeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
|
||||||
String[] signaturePaddings,
|
@KeyStoreKeyProperties.SignaturePaddingEnum String[] signaturePaddings,
|
||||||
String[] digests,
|
@KeyStoreKeyProperties.DigestEnum String[] digests,
|
||||||
String[] blockModes,
|
@KeyStoreKeyProperties.BlockModeEnum String[] blockModes,
|
||||||
boolean randomizedEncryptionRequired,
|
boolean randomizedEncryptionRequired,
|
||||||
boolean userAuthenticationRequired,
|
boolean userAuthenticationRequired,
|
||||||
int userAuthenticationValidityDurationSeconds) {
|
int userAuthenticationValidityDurationSeconds) {
|
||||||
@@ -151,7 +151,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
|
|||||||
/**
|
/**
|
||||||
* Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
|
* Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
|
||||||
*/
|
*/
|
||||||
public String[] getEncryptionPaddings() {
|
public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
|
||||||
return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
|
return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
|
|||||||
* Gets the set of padding schemes with which the key can be used when signing or verifying
|
* Gets the set of padding schemes with which the key can be used when signing or verifying
|
||||||
* signatures.
|
* signatures.
|
||||||
*/
|
*/
|
||||||
public String[] getSignaturePaddings() {
|
public @KeyStoreKeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
|
||||||
return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
|
return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
|
|||||||
*
|
*
|
||||||
* @see #isDigestsSpecified()
|
* @see #isDigestsSpecified()
|
||||||
*/
|
*/
|
||||||
public String[] getDigests() {
|
public @KeyStoreKeyProperties.DigestEnum String[] getDigests() {
|
||||||
if (mDigests == null) {
|
if (mDigests == null) {
|
||||||
throw new IllegalStateException("Digests not specified");
|
throw new IllegalStateException("Digests not specified");
|
||||||
}
|
}
|
||||||
@@ -190,7 +190,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
|
|||||||
/**
|
/**
|
||||||
* Gets the set of block modes with which the key can be used.
|
* Gets the set of block modes with which the key can be used.
|
||||||
*/
|
*/
|
||||||
public String[] getBlockModes() {
|
public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
|
||||||
return ArrayUtils.cloneIfNotEmpty(mBlockModes);
|
return ArrayUtils.cloneIfNotEmpty(mBlockModes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,10 +251,10 @@ public final class KeyStoreParameter implements ProtectionParameter {
|
|||||||
private Date mKeyValidityForOriginationEnd;
|
private Date mKeyValidityForOriginationEnd;
|
||||||
private Date mKeyValidityForConsumptionEnd;
|
private Date mKeyValidityForConsumptionEnd;
|
||||||
private @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
private @KeyStoreKeyProperties.PurposeEnum int mPurposes;
|
||||||
private String[] mEncryptionPaddings;
|
private @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
|
||||||
private String[] mSignaturePaddings;
|
private @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
|
||||||
private String[] mDigests;
|
private @KeyStoreKeyProperties.DigestEnum String[] mDigests;
|
||||||
private String[] mBlockModes;
|
private @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
|
||||||
private boolean mRandomizedEncryptionRequired = true;
|
private boolean mRandomizedEncryptionRequired = true;
|
||||||
private boolean mUserAuthenticationRequired;
|
private boolean mUserAuthenticationRequired;
|
||||||
private int mUserAuthenticationValidityDurationSeconds = -1;
|
private int mUserAuthenticationValidityDurationSeconds = -1;
|
||||||
@@ -356,7 +356,8 @@ public final class KeyStoreParameter implements ProtectionParameter {
|
|||||||
*
|
*
|
||||||
* <p>This must be specified for keys which are used for encryption/decryption.
|
* <p>This must be specified for keys which are used for encryption/decryption.
|
||||||
*/
|
*/
|
||||||
public Builder setEncryptionPaddings(String... paddings) {
|
public Builder setEncryptionPaddings(
|
||||||
|
@KeyStoreKeyProperties.EncryptionPaddingEnum String... paddings) {
|
||||||
mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
|
mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -368,7 +369,8 @@ public final class KeyStoreParameter implements ProtectionParameter {
|
|||||||
*
|
*
|
||||||
* <p>This must be specified for RSA keys which are used for signing/verification.
|
* <p>This must be specified for RSA keys which are used for signing/verification.
|
||||||
*/
|
*/
|
||||||
public Builder setSignaturePaddings(String... paddings) {
|
public Builder setSignaturePaddings(
|
||||||
|
@KeyStoreKeyProperties.SignaturePaddingEnum String... paddings) {
|
||||||
mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
|
mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -381,7 +383,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
|
|||||||
* <p>For HMAC keys, the default is the digest specified in {@link Key#getAlgorithm()}. For
|
* <p>For HMAC keys, the default is the digest specified in {@link Key#getAlgorithm()}. For
|
||||||
* asymmetric signing keys this constraint must be specified.
|
* asymmetric signing keys this constraint must be specified.
|
||||||
*/
|
*/
|
||||||
public Builder setDigests(String... digests) {
|
public Builder setDigests(@KeyStoreKeyProperties.DigestEnum String... digests) {
|
||||||
mDigests = ArrayUtils.cloneIfNotEmpty(digests);
|
mDigests = ArrayUtils.cloneIfNotEmpty(digests);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -392,7 +394,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
|
|||||||
*
|
*
|
||||||
* <p>This must be specified for encryption/decryption keys.
|
* <p>This must be specified for encryption/decryption keys.
|
||||||
*/
|
*/
|
||||||
public Builder setBlockModes(String... blockModes) {
|
public Builder setBlockModes(@KeyStoreKeyProperties.BlockModeEnum String... blockModes) {
|
||||||
mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
|
mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,8 +79,8 @@ public class KeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
|
|||||||
int keySize;
|
int keySize;
|
||||||
@KeyStoreKeyProperties.PurposeEnum int purposes;
|
@KeyStoreKeyProperties.PurposeEnum int purposes;
|
||||||
String[] encryptionPaddings;
|
String[] encryptionPaddings;
|
||||||
String[] digests;
|
@KeyStoreKeyProperties.DigestEnum String[] digests;
|
||||||
String[] blockModes;
|
@KeyStoreKeyProperties.BlockModeEnum String[] blockModes;
|
||||||
int keymasterSwEnforcedUserAuthenticators;
|
int keymasterSwEnforcedUserAuthenticators;
|
||||||
int keymasterHwEnforcedUserAuthenticators;
|
int keymasterHwEnforcedUserAuthenticators;
|
||||||
try {
|
try {
|
||||||
@@ -105,10 +105,10 @@ public class KeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
|
|||||||
|
|
||||||
List<String> encryptionPaddingsList = new ArrayList<String>();
|
List<String> encryptionPaddingsList = new ArrayList<String>();
|
||||||
for (int keymasterPadding : keyCharacteristics.getInts(KeymasterDefs.KM_TAG_PADDING)) {
|
for (int keymasterPadding : keyCharacteristics.getInts(KeymasterDefs.KM_TAG_PADDING)) {
|
||||||
String jcaPadding;
|
@KeyStoreKeyProperties.EncryptionPaddingEnum String jcaPadding;
|
||||||
try {
|
try {
|
||||||
jcaPadding = KeymasterUtils.getJcaEncryptionPaddingFromKeymasterPadding(
|
jcaPadding =
|
||||||
keymasterPadding);
|
KeyStoreKeyProperties.EncryptionPadding.fromKeymaster(keymasterPadding);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new InvalidKeySpecException(
|
throw new InvalidKeySpecException(
|
||||||
"Unsupported encryption padding: " + keymasterPadding);
|
"Unsupported encryption padding: " + keymasterPadding);
|
||||||
@@ -118,9 +118,9 @@ public class KeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
|
|||||||
encryptionPaddings =
|
encryptionPaddings =
|
||||||
encryptionPaddingsList.toArray(new String[encryptionPaddingsList.size()]);
|
encryptionPaddingsList.toArray(new String[encryptionPaddingsList.size()]);
|
||||||
|
|
||||||
digests = KeymasterUtils.getJcaDigestAlgorithmsFromKeymasterDigests(
|
digests = KeyStoreKeyProperties.Digest.allFromKeymaster(
|
||||||
keyCharacteristics.getInts(KeymasterDefs.KM_TAG_DIGEST));
|
keyCharacteristics.getInts(KeymasterDefs.KM_TAG_DIGEST));
|
||||||
blockModes = KeymasterUtils.getJcaBlockModesFromKeymasterBlockModes(
|
blockModes = KeyStoreKeyProperties.BlockMode.allFromKeymaster(
|
||||||
keyCharacteristics.getInts(KeymasterDefs.KM_TAG_BLOCK_MODE));
|
keyCharacteristics.getInts(KeymasterDefs.KM_TAG_BLOCK_MODE));
|
||||||
keymasterSwEnforcedUserAuthenticators =
|
keymasterSwEnforcedUserAuthenticators =
|
||||||
keyCharacteristics.swEnforced.getInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
|
keyCharacteristics.swEnforced.getInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
|
||||||
|
|||||||
@@ -21,11 +21,6 @@ import android.hardware.fingerprint.FingerprintManager;
|
|||||||
import android.security.keymaster.KeymasterArguments;
|
import android.security.keymaster.KeymasterArguments;
|
||||||
import android.security.keymaster.KeymasterDefs;
|
import android.security.keymaster.KeymasterDefs;
|
||||||
|
|
||||||
import libcore.util.EmptyArray;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@@ -33,152 +28,6 @@ public abstract class KeymasterUtils {
|
|||||||
|
|
||||||
private KeymasterUtils() {}
|
private KeymasterUtils() {}
|
||||||
|
|
||||||
public static int getKeymasterAlgorithmFromJcaSecretKeyAlgorithm(String jcaKeyAlgorithm) {
|
|
||||||
if ("AES".equalsIgnoreCase(jcaKeyAlgorithm)) {
|
|
||||||
return KeymasterDefs.KM_ALGORITHM_AES;
|
|
||||||
} else if (jcaKeyAlgorithm.toUpperCase(Locale.US).startsWith("HMAC")) {
|
|
||||||
return KeymasterDefs.KM_ALGORITHM_HMAC;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unsupported secret key algorithm: " + jcaKeyAlgorithm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getJcaSecretKeyAlgorithm(int keymasterAlgorithm, int keymasterDigest) {
|
|
||||||
switch (keymasterAlgorithm) {
|
|
||||||
case KeymasterDefs.KM_ALGORITHM_AES:
|
|
||||||
if (keymasterDigest != -1) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Digest not supported for AES key: " + keymasterDigest);
|
|
||||||
}
|
|
||||||
return "AES";
|
|
||||||
case KeymasterDefs.KM_ALGORITHM_HMAC:
|
|
||||||
switch (keymasterDigest) {
|
|
||||||
case KeymasterDefs.KM_DIGEST_SHA1:
|
|
||||||
return "HmacSHA1";
|
|
||||||
case KeymasterDefs.KM_DIGEST_SHA_2_224:
|
|
||||||
return "HmacSHA224";
|
|
||||||
case KeymasterDefs.KM_DIGEST_SHA_2_256:
|
|
||||||
return "HmacSHA256";
|
|
||||||
case KeymasterDefs.KM_DIGEST_SHA_2_384:
|
|
||||||
return "HmacSHA384";
|
|
||||||
case KeymasterDefs.KM_DIGEST_SHA_2_512:
|
|
||||||
return "HmacSHA512";
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unsupported HMAC digest: " + keymasterDigest);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unsupported algorithm: " + keymasterAlgorithm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getJcaKeyPairAlgorithmFromKeymasterAlgorithm(int keymasterAlgorithm) {
|
|
||||||
switch (keymasterAlgorithm) {
|
|
||||||
case KeymasterDefs.KM_ALGORITHM_RSA:
|
|
||||||
return "RSA";
|
|
||||||
case KeymasterDefs.KM_ALGORITHM_EC:
|
|
||||||
return "EC";
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unsupported algorithm: " + keymasterAlgorithm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getKeymasterDigestfromJcaSecretKeyAlgorithm(String jcaKeyAlgorithm) {
|
|
||||||
String algorithmUpper = jcaKeyAlgorithm.toUpperCase(Locale.US);
|
|
||||||
if (algorithmUpper.startsWith("HMAC")) {
|
|
||||||
String digestUpper = algorithmUpper.substring("HMAC".length());
|
|
||||||
switch (digestUpper) {
|
|
||||||
case "MD5":
|
|
||||||
return KeymasterDefs.KM_DIGEST_MD5;
|
|
||||||
case "SHA1":
|
|
||||||
return KeymasterDefs.KM_DIGEST_SHA1;
|
|
||||||
case "SHA224":
|
|
||||||
return KeymasterDefs.KM_DIGEST_SHA_2_224;
|
|
||||||
case "SHA256":
|
|
||||||
return KeymasterDefs.KM_DIGEST_SHA_2_256;
|
|
||||||
case "SHA384":
|
|
||||||
return KeymasterDefs.KM_DIGEST_SHA_2_384;
|
|
||||||
case "SHA512":
|
|
||||||
return KeymasterDefs.KM_DIGEST_SHA_2_512;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unsupported HMAC digest: " + digestUpper);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getKeymasterDigestFromJcaDigestAlgorithm(String jcaDigestAlgorithm) {
|
|
||||||
if (jcaDigestAlgorithm.equalsIgnoreCase("SHA-1")) {
|
|
||||||
return KeymasterDefs.KM_DIGEST_SHA1;
|
|
||||||
} else if (jcaDigestAlgorithm.equalsIgnoreCase("SHA-224")) {
|
|
||||||
return KeymasterDefs.KM_DIGEST_SHA_2_224;
|
|
||||||
} else if (jcaDigestAlgorithm.equalsIgnoreCase("SHA-256")) {
|
|
||||||
return KeymasterDefs.KM_DIGEST_SHA_2_256;
|
|
||||||
} else if (jcaDigestAlgorithm.equalsIgnoreCase("SHA-384")) {
|
|
||||||
return KeymasterDefs.KM_DIGEST_SHA_2_384;
|
|
||||||
} else if (jcaDigestAlgorithm.equalsIgnoreCase("SHA-512")) {
|
|
||||||
return KeymasterDefs.KM_DIGEST_SHA_2_512;
|
|
||||||
} else if (jcaDigestAlgorithm.equalsIgnoreCase("NONE")) {
|
|
||||||
return KeymasterDefs.KM_DIGEST_NONE;
|
|
||||||
} else if (jcaDigestAlgorithm.equalsIgnoreCase("MD5")) {
|
|
||||||
return KeymasterDefs.KM_DIGEST_MD5;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unsupported digest algorithm: " + jcaDigestAlgorithm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getJcaDigestAlgorithmFromKeymasterDigest(int keymasterDigest) {
|
|
||||||
switch (keymasterDigest) {
|
|
||||||
case KeymasterDefs.KM_DIGEST_NONE:
|
|
||||||
return "NONE";
|
|
||||||
case KeymasterDefs.KM_DIGEST_MD5:
|
|
||||||
return "MD5";
|
|
||||||
case KeymasterDefs.KM_DIGEST_SHA1:
|
|
||||||
return "SHA-1";
|
|
||||||
case KeymasterDefs.KM_DIGEST_SHA_2_224:
|
|
||||||
return "SHA-224";
|
|
||||||
case KeymasterDefs.KM_DIGEST_SHA_2_256:
|
|
||||||
return "SHA-256";
|
|
||||||
case KeymasterDefs.KM_DIGEST_SHA_2_384:
|
|
||||||
return "SHA-384";
|
|
||||||
case KeymasterDefs.KM_DIGEST_SHA_2_512:
|
|
||||||
return "SHA-512";
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unsupported digest algorithm: " + keymasterDigest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String[] getJcaDigestAlgorithmsFromKeymasterDigests(
|
|
||||||
Collection<Integer> keymasterDigests) {
|
|
||||||
if (keymasterDigests.isEmpty()) {
|
|
||||||
return EmptyArray.STRING;
|
|
||||||
}
|
|
||||||
String[] result = new String[keymasterDigests.size()];
|
|
||||||
int offset = 0;
|
|
||||||
for (int keymasterDigest : keymasterDigests) {
|
|
||||||
result[offset] = getJcaDigestAlgorithmFromKeymasterDigest(keymasterDigest);
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int[] getKeymasterDigestsFromJcaDigestAlgorithms(String[] jcaDigestAlgorithms) {
|
|
||||||
if ((jcaDigestAlgorithms == null) || (jcaDigestAlgorithms.length == 0)) {
|
|
||||||
return EmptyArray.INT;
|
|
||||||
}
|
|
||||||
int[] result = new int[jcaDigestAlgorithms.length];
|
|
||||||
int offset = 0;
|
|
||||||
for (String jcaDigestAlgorithm : jcaDigestAlgorithms) {
|
|
||||||
result[offset] = getKeymasterDigestFromJcaDigestAlgorithm(jcaDigestAlgorithm);
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getDigestOutputSizeBits(int keymasterDigest) {
|
public static int getDigestOutputSizeBits(int keymasterDigest) {
|
||||||
switch (keymasterDigest) {
|
switch (keymasterDigest) {
|
||||||
case KeymasterDefs.KM_DIGEST_NONE:
|
case KeymasterDefs.KM_DIGEST_NONE:
|
||||||
@@ -200,60 +49,6 @@ public abstract class KeymasterUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getKeymasterBlockModeFromJcaBlockMode(String jcaBlockMode) {
|
|
||||||
if ("ECB".equalsIgnoreCase(jcaBlockMode)) {
|
|
||||||
return KeymasterDefs.KM_MODE_ECB;
|
|
||||||
} else if ("CBC".equalsIgnoreCase(jcaBlockMode)) {
|
|
||||||
return KeymasterDefs.KM_MODE_CBC;
|
|
||||||
} else if ("CTR".equalsIgnoreCase(jcaBlockMode)) {
|
|
||||||
return KeymasterDefs.KM_MODE_CTR;
|
|
||||||
} else if ("GCM".equalsIgnoreCase(jcaBlockMode)) {
|
|
||||||
return KeymasterDefs.KM_MODE_GCM;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unsupported block mode: " + jcaBlockMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getJcaBlockModeFromKeymasterBlockMode(int keymasterBlockMode) {
|
|
||||||
switch (keymasterBlockMode) {
|
|
||||||
case KeymasterDefs.KM_MODE_ECB:
|
|
||||||
return "ECB";
|
|
||||||
case KeymasterDefs.KM_MODE_CBC:
|
|
||||||
return "CBC";
|
|
||||||
case KeymasterDefs.KM_MODE_CTR:
|
|
||||||
return "CTR";
|
|
||||||
case KeymasterDefs.KM_MODE_GCM:
|
|
||||||
return "GCM";
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unsupported block mode: " + keymasterBlockMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String[] getJcaBlockModesFromKeymasterBlockModes(
|
|
||||||
Collection<Integer> keymasterBlockModes) {
|
|
||||||
if ((keymasterBlockModes == null) || (keymasterBlockModes.isEmpty())) {
|
|
||||||
return EmptyArray.STRING;
|
|
||||||
}
|
|
||||||
String[] result = new String[keymasterBlockModes.size()];
|
|
||||||
int offset = 0;
|
|
||||||
for (int keymasterBlockMode : keymasterBlockModes) {
|
|
||||||
result[offset] = getJcaBlockModeFromKeymasterBlockMode(keymasterBlockMode);
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int[] getKeymasterBlockModesFromJcaBlockModes(String[] jcaBlockModes) {
|
|
||||||
if ((jcaBlockModes == null) || (jcaBlockModes.length == 0)) {
|
|
||||||
return EmptyArray.INT;
|
|
||||||
}
|
|
||||||
int[] result = new int[jcaBlockModes.length];
|
|
||||||
for (int i = 0; i < jcaBlockModes.length; i++) {
|
|
||||||
result[i] = getKeymasterBlockModeFromJcaBlockMode(jcaBlockModes[i]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isKeymasterBlockModeIndCpaCompatible(int keymasterBlockMode) {
|
public static boolean isKeymasterBlockModeIndCpaCompatible(int keymasterBlockMode) {
|
||||||
switch (keymasterBlockMode) {
|
switch (keymasterBlockMode) {
|
||||||
case KeymasterDefs.KM_MODE_ECB:
|
case KeymasterDefs.KM_MODE_ECB:
|
||||||
@@ -267,82 +62,6 @@ public abstract class KeymasterUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getKeymasterPaddingFromJcaEncryptionPadding(String jcaPadding) {
|
|
||||||
if ("NoPadding".equalsIgnoreCase(jcaPadding)) {
|
|
||||||
return KeymasterDefs.KM_PAD_NONE;
|
|
||||||
} else if ("PKCS7Padding".equalsIgnoreCase(jcaPadding)) {
|
|
||||||
return KeymasterDefs.KM_PAD_PKCS7;
|
|
||||||
} else if ("PKCS1Padding".equalsIgnoreCase(jcaPadding)) {
|
|
||||||
return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT;
|
|
||||||
} else if ("OEAPPadding".equalsIgnoreCase(jcaPadding)) {
|
|
||||||
return KeymasterDefs.KM_PAD_RSA_OAEP;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unsupported encryption padding scheme: " + jcaPadding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getJcaEncryptionPaddingFromKeymasterPadding(int keymasterPadding) {
|
|
||||||
switch (keymasterPadding) {
|
|
||||||
case KeymasterDefs.KM_PAD_NONE:
|
|
||||||
return "NoPadding";
|
|
||||||
case KeymasterDefs.KM_PAD_PKCS7:
|
|
||||||
return "PKCS7Padding";
|
|
||||||
case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
|
|
||||||
return "PKCS1Padding";
|
|
||||||
case KeymasterDefs.KM_PAD_RSA_OAEP:
|
|
||||||
return "OEAPPadding";
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unsupported encryption padding: " + keymasterPadding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getKeymasterPaddingFromJcaSignaturePadding(String jcaPadding) {
|
|
||||||
if ("PKCS#1".equalsIgnoreCase(jcaPadding)) {
|
|
||||||
return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN;
|
|
||||||
} if ("PSS".equalsIgnoreCase(jcaPadding)) {
|
|
||||||
return KeymasterDefs.KM_PAD_RSA_PSS;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unsupported signature padding scheme: " + jcaPadding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getJcaSignaturePaddingFromKeymasterPadding(int keymasterPadding) {
|
|
||||||
switch (keymasterPadding) {
|
|
||||||
case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN:
|
|
||||||
return "PKCS#1";
|
|
||||||
case KeymasterDefs.KM_PAD_RSA_PSS:
|
|
||||||
return "PSS";
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unsupported signature padding: " + keymasterPadding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int[] getKeymasterPaddingsFromJcaEncryptionPaddings(String[] jcaPaddings) {
|
|
||||||
if ((jcaPaddings == null) || (jcaPaddings.length == 0)) {
|
|
||||||
return EmptyArray.INT;
|
|
||||||
}
|
|
||||||
int[] result = new int[jcaPaddings.length];
|
|
||||||
for (int i = 0; i < jcaPaddings.length; i++) {
|
|
||||||
result[i] = getKeymasterPaddingFromJcaEncryptionPadding(jcaPaddings[i]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int[] getKeymasterPaddingsFromJcaSignaturePaddings(String[] jcaPaddings) {
|
|
||||||
if ((jcaPaddings == null) || (jcaPaddings.length == 0)) {
|
|
||||||
return EmptyArray.INT;
|
|
||||||
}
|
|
||||||
int[] result = new int[jcaPaddings.length];
|
|
||||||
for (int i = 0; i < jcaPaddings.length; i++) {
|
|
||||||
result[i] = getKeymasterPaddingFromJcaSignaturePadding(jcaPaddings[i]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds keymaster arguments to express the key's authorization policy supported by user
|
* Adds keymaster arguments to express the key's authorization policy supported by user
|
||||||
* authentication.
|
* authentication.
|
||||||
|
|||||||
Reference in New Issue
Block a user