Search in sources :

Example 16 with KeyCharacteristics

use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by DirtyUnicorns.

the class AndroidKeyStoreKeyPairGeneratorSpi method generateKeystoreKeyPair.

private void generateKeystoreKeyPair(final String privateKeyAlias, KeymasterArguments args, byte[] additionalEntropy, final int flags) throws ProviderException {
    KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics();
    int errorCode = mKeyStore.generateKey(privateKeyAlias, args, additionalEntropy, mEntryUid, flags, resultingKeyCharacteristics);
    if (errorCode != KeyStore.NO_ERROR) {
        throw new ProviderException("Failed to generate key pair", KeyStore.getKeyStoreException(errorCode));
    }
}
Also used : ProviderException(java.security.ProviderException) KeyCharacteristics(android.security.keymaster.KeyCharacteristics)

Example 17 with KeyCharacteristics

use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by DirtyUnicorns.

the class AndroidKeyStoreProvider method loadAndroidKeyStorePublicKeyFromKeystore.

@NonNull
public static AndroidKeyStorePublicKey loadAndroidKeyStorePublicKeyFromKeystore(@NonNull KeyStore keyStore, @NonNull String privateKeyAlias, int uid) throws UnrecoverableKeyException {
    KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
    int errorCode = keyStore.getKeyCharacteristics(privateKeyAlias, null, null, uid, keyCharacteristics);
    if (errorCode != KeyStore.NO_ERROR) {
        throw (UnrecoverableKeyException) new UnrecoverableKeyException("Failed to obtain information about private key").initCause(KeyStore.getKeyStoreException(errorCode));
    }
    ExportResult exportResult = keyStore.exportKey(privateKeyAlias, KeymasterDefs.KM_KEY_FORMAT_X509, null, null, uid);
    if (exportResult.resultCode != KeyStore.NO_ERROR) {
        throw (UnrecoverableKeyException) new UnrecoverableKeyException("Failed to obtain X.509 form of public key").initCause(KeyStore.getKeyStoreException(exportResult.resultCode));
    }
    final byte[] x509EncodedPublicKey = exportResult.exportData;
    Integer keymasterAlgorithm = keyCharacteristics.getEnum(KeymasterDefs.KM_TAG_ALGORITHM);
    if (keymasterAlgorithm == null) {
        throw new UnrecoverableKeyException("Key algorithm unknown");
    }
    String jcaKeyAlgorithm;
    try {
        jcaKeyAlgorithm = KeyProperties.KeyAlgorithm.fromKeymasterAsymmetricKeyAlgorithm(keymasterAlgorithm);
    } catch (IllegalArgumentException e) {
        throw (UnrecoverableKeyException) new UnrecoverableKeyException("Failed to load private key").initCause(e);
    }
    return AndroidKeyStoreProvider.getAndroidKeyStorePublicKey(privateKeyAlias, uid, jcaKeyAlgorithm, x509EncodedPublicKey);
}
Also used : UnrecoverableKeyException(java.security.UnrecoverableKeyException) KeyCharacteristics(android.security.keymaster.KeyCharacteristics) ExportResult(android.security.keymaster.ExportResult) NonNull(android.annotation.NonNull)

Example 18 with KeyCharacteristics

use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by DirtyUnicorns.

the class AndroidKeyStoreProvider method loadAndroidKeyStoreSecretKeyFromKeystore.

@NonNull
public static AndroidKeyStoreSecretKey loadAndroidKeyStoreSecretKeyFromKeystore(@NonNull KeyStore keyStore, @NonNull String secretKeyAlias, int uid) throws UnrecoverableKeyException {
    KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
    int errorCode = keyStore.getKeyCharacteristics(secretKeyAlias, null, null, uid, keyCharacteristics);
    if (errorCode != KeyStore.NO_ERROR) {
        throw (UnrecoverableKeyException) new UnrecoverableKeyException("Failed to obtain information about key").initCause(KeyStore.getKeyStoreException(errorCode));
    }
    Integer keymasterAlgorithm = keyCharacteristics.getEnum(KeymasterDefs.KM_TAG_ALGORITHM);
    if (keymasterAlgorithm == null) {
        throw new UnrecoverableKeyException("Key algorithm unknown");
    }
    List<Integer> keymasterDigests = keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_DIGEST);
    int keymasterDigest;
    if (keymasterDigests.isEmpty()) {
        keymasterDigest = -1;
    } else {
        // More than one digest can be permitted for this key. Use the first one to form the
        // JCA key algorithm name.
        keymasterDigest = keymasterDigests.get(0);
    }
    @KeyProperties.KeyAlgorithmEnum String keyAlgorithmString;
    try {
        keyAlgorithmString = KeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm(keymasterAlgorithm, keymasterDigest);
    } catch (IllegalArgumentException e) {
        throw (UnrecoverableKeyException) new UnrecoverableKeyException("Unsupported secret key type").initCause(e);
    }
    return new AndroidKeyStoreSecretKey(secretKeyAlias, uid, keyAlgorithmString);
}
Also used : UnrecoverableKeyException(java.security.UnrecoverableKeyException) KeyCharacteristics(android.security.keymaster.KeyCharacteristics) NonNull(android.annotation.NonNull)

Example 19 with KeyCharacteristics

use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by AOSPA.

the class AndroidKeyStoreKeyGeneratorSpi method engineGenerateKey.

@Override
protected SecretKey engineGenerateKey() {
    KeyGenParameterSpec spec = mSpec;
    if (spec == null) {
        throw new IllegalStateException("Not initialized");
    }
    KeymasterArguments args = new KeymasterArguments();
    args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits);
    args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
    args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, mKeymasterPurposes);
    args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
    args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterPaddings);
    args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
    if (spec.isUseSecureProcessor())
        args.addBoolean(KeymasterDefs.KM_TAG_USE_SECURE_PROCESSOR);
    KeymasterUtils.addUserAuthArgs(args, spec.isUserAuthenticationRequired(), spec.getUserAuthenticationValidityDurationSeconds(), spec.isUserAuthenticationValidWhileOnBody(), spec.isInvalidatedByBiometricEnrollment());
    KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(args, mKeymasterAlgorithm, mKeymasterBlockModes, mKeymasterDigests);
    args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, spec.getKeyValidityStart());
    args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, spec.getKeyValidityForOriginationEnd());
    args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, spec.getKeyValidityForConsumptionEnd());
    if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0) && (!spec.isRandomizedEncryptionRequired())) {
        // Permit caller-provided IV when encrypting with this key
        args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE);
    }
    byte[] additionalEntropy = KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(mRng, (mKeySizeBits + 7) / 8);
    int flags = 0;
    String keyAliasInKeystore = Credentials.USER_SECRET_KEY + spec.getKeystoreAlias();
    KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics();
    boolean success = false;
    try {
        Credentials.deleteAllTypesForAlias(mKeyStore, spec.getKeystoreAlias(), spec.getUid());
        int errorCode = mKeyStore.generateKey(keyAliasInKeystore, args, additionalEntropy, spec.getUid(), flags, resultingKeyCharacteristics);
        if (errorCode != KeyStore.NO_ERROR) {
            throw new ProviderException("Keystore operation failed", KeyStore.getKeyStoreException(errorCode));
        }
        @KeyProperties.KeyAlgorithmEnum String keyAlgorithmJCA;
        try {
            keyAlgorithmJCA = KeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm(mKeymasterAlgorithm, mKeymasterDigest);
        } catch (IllegalArgumentException e) {
            throw new ProviderException("Failed to obtain JCA secret key algorithm name", e);
        }
        SecretKey result = new AndroidKeyStoreSecretKey(keyAliasInKeystore, spec.getUid(), keyAlgorithmJCA);
        success = true;
        return result;
    } finally {
        if (!success) {
            Credentials.deleteAllTypesForAlias(mKeyStore, spec.getKeystoreAlias(), spec.getUid());
        }
    }
}
Also used : KeymasterArguments(android.security.keymaster.KeymasterArguments) KeyGenParameterSpec(android.security.keystore.KeyGenParameterSpec) ProviderException(java.security.ProviderException) SecretKey(javax.crypto.SecretKey) KeyCharacteristics(android.security.keymaster.KeyCharacteristics)

Example 20 with KeyCharacteristics

use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by AOSPA.

the class AndroidKeyStoreSecretKeyFactorySpi method getKeyInfo.

static KeyInfo getKeyInfo(KeyStore keyStore, String entryAlias, String keyAliasInKeystore, int keyUid) {
    KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
    int errorCode = keyStore.getKeyCharacteristics(keyAliasInKeystore, null, null, keyUid, keyCharacteristics);
    if (errorCode != KeyStore.NO_ERROR) {
        throw new ProviderException("Failed to obtain information about key." + " Keystore error: " + errorCode);
    }
    boolean insideSecureHardware;
    @KeyProperties.OriginEnum int origin;
    int keySize;
    @KeyProperties.PurposeEnum int purposes;
    String[] encryptionPaddings;
    String[] signaturePaddings;
    @KeyProperties.DigestEnum String[] digests;
    @KeyProperties.BlockModeEnum String[] blockModes;
    int keymasterSwEnforcedUserAuthenticators;
    int keymasterHwEnforcedUserAuthenticators;
    List<BigInteger> keymasterSecureUserIds;
    try {
        if (keyCharacteristics.hwEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
            insideSecureHardware = true;
            origin = KeyProperties.Origin.fromKeymaster(keyCharacteristics.hwEnforced.getEnum(KeymasterDefs.KM_TAG_ORIGIN, -1));
        } else if (keyCharacteristics.swEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
            insideSecureHardware = false;
            origin = KeyProperties.Origin.fromKeymaster(keyCharacteristics.swEnforced.getEnum(KeymasterDefs.KM_TAG_ORIGIN, -1));
        } else {
            throw new ProviderException("Key origin not available");
        }
        long keySizeUnsigned = keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
        if (keySizeUnsigned == -1) {
            throw new ProviderException("Key size not available");
        } else if (keySizeUnsigned > Integer.MAX_VALUE) {
            throw new ProviderException("Key too large: " + keySizeUnsigned + " bits");
        }
        keySize = (int) keySizeUnsigned;
        purposes = KeyProperties.Purpose.allFromKeymaster(keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_PURPOSE));
        List<String> encryptionPaddingsList = new ArrayList<String>();
        List<String> signaturePaddingsList = new ArrayList<String>();
        // Keymaster stores both types of paddings in the same array -- we split it into two.
        for (int keymasterPadding : keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_PADDING)) {
            try {
                @KeyProperties.EncryptionPaddingEnum String jcaPadding = KeyProperties.EncryptionPadding.fromKeymaster(keymasterPadding);
                encryptionPaddingsList.add(jcaPadding);
            } catch (IllegalArgumentException e) {
                try {
                    @KeyProperties.SignaturePaddingEnum String padding = KeyProperties.SignaturePadding.fromKeymaster(keymasterPadding);
                    signaturePaddingsList.add(padding);
                } catch (IllegalArgumentException e2) {
                    throw new ProviderException("Unsupported encryption padding: " + keymasterPadding);
                }
            }
        }
        encryptionPaddings = encryptionPaddingsList.toArray(new String[encryptionPaddingsList.size()]);
        signaturePaddings = signaturePaddingsList.toArray(new String[signaturePaddingsList.size()]);
        digests = KeyProperties.Digest.allFromKeymaster(keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_DIGEST));
        blockModes = KeyProperties.BlockMode.allFromKeymaster(keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_BLOCK_MODE));
        keymasterSwEnforcedUserAuthenticators = keyCharacteristics.swEnforced.getEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
        keymasterHwEnforcedUserAuthenticators = keyCharacteristics.hwEnforced.getEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
        keymasterSecureUserIds = keyCharacteristics.getUnsignedLongs(KeymasterDefs.KM_TAG_USER_SECURE_ID);
    } catch (IllegalArgumentException e) {
        throw new ProviderException("Unsupported key characteristic", e);
    }
    Date keyValidityStart = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME);
    Date keyValidityForOriginationEnd = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME);
    Date keyValidityForConsumptionEnd = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME);
    boolean userAuthenticationRequired = !keyCharacteristics.getBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
    long userAuthenticationValidityDurationSeconds = keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, -1);
    if (userAuthenticationValidityDurationSeconds > Integer.MAX_VALUE) {
        throw new ProviderException("User authentication timeout validity too long: " + userAuthenticationValidityDurationSeconds + " seconds");
    }
    boolean userAuthenticationRequirementEnforcedBySecureHardware = (userAuthenticationRequired) && (keymasterHwEnforcedUserAuthenticators != 0) && (keymasterSwEnforcedUserAuthenticators == 0);
    boolean userAuthenticationValidWhileOnBody = keyCharacteristics.hwEnforced.getBoolean(KeymasterDefs.KM_TAG_ALLOW_WHILE_ON_BODY);
    boolean invalidatedByBiometricEnrollment = false;
    if (keymasterSwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_FINGERPRINT || keymasterHwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_FINGERPRINT) {
        // Fingerprint-only key; will be invalidated if the root SID isn't in the SID list.
        invalidatedByBiometricEnrollment = keymasterSecureUserIds != null && !keymasterSecureUserIds.isEmpty() && !keymasterSecureUserIds.contains(getGateKeeperSecureUserId());
    }
    return new KeyInfo(entryAlias, insideSecureHardware, origin, keySize, keyValidityStart, keyValidityForOriginationEnd, keyValidityForConsumptionEnd, purposes, encryptionPaddings, signaturePaddings, digests, blockModes, userAuthenticationRequired, (int) userAuthenticationValidityDurationSeconds, userAuthenticationRequirementEnforcedBySecureHardware, userAuthenticationValidWhileOnBody, invalidatedByBiometricEnrollment);
}
Also used : ProviderException(java.security.ProviderException) ArrayList(java.util.ArrayList) Date(java.util.Date) KeyCharacteristics(android.security.keymaster.KeyCharacteristics) BigInteger(java.math.BigInteger)

Aggregations

KeyCharacteristics (android.security.keymaster.KeyCharacteristics)85 KeymasterArguments (android.security.keymaster.KeymasterArguments)50 ProviderException (java.security.ProviderException)20 IBinder (android.os.IBinder)15 OperationResult (android.security.keymaster.OperationResult)15 NonNull (android.annotation.NonNull)10 KeyProtection (android.security.keystore.KeyProtection)10 InvalidKeyException (java.security.InvalidKeyException)10 KeyStoreException (java.security.KeyStoreException)10 UnrecoverableKeyException (java.security.UnrecoverableKeyException)10 KeyStoreParameter (android.security.KeyStoreParameter)5 ExportResult (android.security.keymaster.ExportResult)5 KeymasterBlob (android.security.keymaster.KeymasterBlob)5 KeyGenParameterSpec (android.security.keystore.KeyGenParameterSpec)5 BigInteger (java.math.BigInteger)5 PrivateKey (java.security.PrivateKey)5 CertificateEncodingException (java.security.cert.CertificateEncodingException)5 X509Certificate (java.security.cert.X509Certificate)5 ArrayList (java.util.ArrayList)5 Date (java.util.Date)5