Keystore: EC_CURVE tag added import agruments
As per Keymint documentation EC key import has to provide EC_CURVE tag. This is required for Strongbox implementation test using wycheproof test cases. Also added a support to get KEY_SIZE based on EC_CURVE, if it is not included into Authorization list. Bug: 237634216 Test: run cts -m CtsKeystoreWycheproofTestCases Change-Id: Ie981721c38477e74da3cba6613dc0b34e453609c
This commit is contained in:
@@ -65,6 +65,7 @@ public final class KeymasterDefs {
|
||||
public static final int KM_TAG_PADDING = Tag.PADDING; // KM_ENUM_REP | 6;
|
||||
public static final int KM_TAG_CALLER_NONCE = Tag.CALLER_NONCE; // KM_BOOL | 7;
|
||||
public static final int KM_TAG_MIN_MAC_LENGTH = Tag.MIN_MAC_LENGTH; // KM_UINT | 8;
|
||||
public static final int KM_TAG_EC_CURVE = Tag.EC_CURVE; // KM_ENUM | 10;
|
||||
|
||||
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;
|
||||
|
||||
@@ -30,6 +30,7 @@ import libcore.util.EmptyArray;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.ECParameterSpec;
|
||||
import java.security.spec.MGF1ParameterSpec;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
@@ -913,6 +914,51 @@ public abstract class KeyProperties {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public abstract static class EcCurve {
|
||||
private EcCurve() {}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static int toKeymasterCurve(ECParameterSpec spec) {
|
||||
int keySize = spec.getCurve().getField().getFieldSize();
|
||||
switch (keySize) {
|
||||
case 224:
|
||||
return android.hardware.security.keymint.EcCurve.P_224;
|
||||
case 256:
|
||||
return android.hardware.security.keymint.EcCurve.P_256;
|
||||
case 384:
|
||||
return android.hardware.security.keymint.EcCurve.P_384;
|
||||
case 521:
|
||||
return android.hardware.security.keymint.EcCurve.P_521;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static int fromKeymasterCurve(int ecCurve) {
|
||||
switch (ecCurve) {
|
||||
case android.hardware.security.keymint.EcCurve.P_224:
|
||||
return 224;
|
||||
case android.hardware.security.keymint.EcCurve.P_256:
|
||||
case android.hardware.security.keymint.EcCurve.CURVE_25519:
|
||||
return 256;
|
||||
case android.hardware.security.keymint.EcCurve.P_384:
|
||||
return 384;
|
||||
case android.hardware.security.keymint.EcCurve.P_521:
|
||||
return 521;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Namespaces provide system developers and vendors with a way to use keystore without
|
||||
* requiring an applications uid. Namespaces can be configured using SEPolicy.
|
||||
|
||||
@@ -203,6 +203,11 @@ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignature
|
||||
for (Authorization a : key.getAuthorizations()) {
|
||||
if (a.keyParameter.tag == KeymasterDefs.KM_TAG_KEY_SIZE) {
|
||||
keySizeBits = KeyStore2ParameterUtils.getUnsignedInt(a);
|
||||
break;
|
||||
} else if (a.keyParameter.tag == KeymasterDefs.KM_TAG_EC_CURVE) {
|
||||
keySizeBits = KeyProperties.EcCurve.fromKeymasterCurve(
|
||||
a.keyParameter.value.getEcCurve());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.interfaces.ECKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -566,6 +567,22 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
|
||||
spec.getMaxUsageCount()
|
||||
));
|
||||
}
|
||||
if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(key.getAlgorithm())) {
|
||||
if (key instanceof ECKey) {
|
||||
ECKey ecKey = (ECKey) key;
|
||||
importArgs.add(KeyStore2ParameterUtils.makeEnum(
|
||||
KeymasterDefs.KM_TAG_EC_CURVE,
|
||||
KeyProperties.EcCurve.toKeymasterCurve(ecKey.getParams())
|
||||
));
|
||||
}
|
||||
}
|
||||
/* TODO: check for Ed25519(EdDSA) or X25519(XDH) key algorithm and
|
||||
* add import args for KM_TAG_EC_CURVE as EcCurve.CURVE_25519.
|
||||
* Currently conscrypt does not support EdDSA key import and XDH keys are not an
|
||||
* instance of XECKey, hence these conditions are not added, once it is fully
|
||||
* implemented by conscrypt, we can add CURVE_25519 argument for EdDSA and XDH
|
||||
* algorithms.
|
||||
*/
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
throw new KeyStoreException(e);
|
||||
}
|
||||
|
||||
@@ -22,8 +22,9 @@ import android.system.keystore2.Authorization;
|
||||
import android.system.keystore2.KeyDescriptor;
|
||||
|
||||
import java.security.PrivateKey;
|
||||
import java.security.interfaces.EdECKey;
|
||||
import java.security.interfaces.XECPrivateKey;
|
||||
import java.security.spec.NamedParameterSpec;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* X25519 Private Key backed by Keystore.
|
||||
@@ -31,7 +32,8 @@ import java.security.spec.NamedParameterSpec;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class AndroidKeyStoreXDHPrivateKey extends AndroidKeyStorePrivateKey implements EdECKey {
|
||||
public class AndroidKeyStoreXDHPrivateKey extends AndroidKeyStorePrivateKey
|
||||
implements XECPrivateKey {
|
||||
public AndroidKeyStoreXDHPrivateKey(
|
||||
@NonNull KeyDescriptor descriptor, long keyId,
|
||||
@NonNull Authorization[] authorizations,
|
||||
@@ -44,4 +46,12 @@ public class AndroidKeyStoreXDHPrivateKey extends AndroidKeyStorePrivateKey impl
|
||||
public NamedParameterSpec getParams() {
|
||||
return NamedParameterSpec.X25519;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<byte[]> getScalar() {
|
||||
/* An empty Optional if the scalar cannot be extracted (e.g. if the provider is a hardware
|
||||
* token and the private key is not allowed to leave the crypto boundary).
|
||||
*/
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user