Search in sources :

Example 1 with KeyGenParameterSpec

use of android.security.keystore.KeyGenParameterSpec in project platform_frameworks_base by android.

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);
    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 2 with KeyGenParameterSpec

use of android.security.keystore.KeyGenParameterSpec 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 3 with KeyGenParameterSpec

use of android.security.keystore.KeyGenParameterSpec in project android_frameworks_base by AOSPA.

the class AndroidKeyStoreKeyGeneratorSpi method engineInit.

@Override
protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException {
    resetAll();
    boolean success = false;
    try {
        if ((params == null) || (!(params instanceof KeyGenParameterSpec))) {
            throw new InvalidAlgorithmParameterException("Cannot initialize without a " + KeyGenParameterSpec.class.getName() + " parameter");
        }
        KeyGenParameterSpec spec = (KeyGenParameterSpec) params;
        if (spec.getKeystoreAlias() == null) {
            throw new InvalidAlgorithmParameterException("KeyStore entry alias not provided");
        }
        mRng = random;
        mSpec = spec;
        mKeySizeBits = (spec.getKeySize() != -1) ? spec.getKeySize() : mDefaultKeySizeBits;
        if (mKeySizeBits <= 0) {
            throw new InvalidAlgorithmParameterException("Key size must be positive: " + mKeySizeBits);
        } else if ((mKeySizeBits % 8) != 0) {
            throw new InvalidAlgorithmParameterException("Key size must be a multiple of 8: " + mKeySizeBits);
        }
        try {
            mKeymasterPurposes = KeyProperties.Purpose.allToKeymaster(spec.getPurposes());
            mKeymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(spec.getEncryptionPaddings());
            if (spec.getSignaturePaddings().length > 0) {
                throw new InvalidAlgorithmParameterException("Signature paddings not supported for symmetric key algorithms");
            }
            mKeymasterBlockModes = KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes());
            if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0) && (spec.isRandomizedEncryptionRequired())) {
                for (int keymasterBlockMode : mKeymasterBlockModes) {
                    if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto(keymasterBlockMode)) {
                        throw new InvalidAlgorithmParameterException("Randomized encryption (IND-CPA) required but may be violated" + " by block mode: " + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode) + ". See " + KeyGenParameterSpec.class.getName() + " documentation.");
                    }
                }
            }
            if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
                // JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm
                // implies SHA-256 digest). Because keymaster HMAC key is authorized only for
                // one digest, we don't let algorithm parameter spec override the digest implied
                // by the key. If the spec specifies digests at all, it must specify only one
                // digest, the only implied by key algorithm.
                mKeymasterDigests = new int[] { mKeymasterDigest };
                if (spec.isDigestsSpecified()) {
                    // Digest(s) explicitly specified in the spec. Check that the list
                    // consists of exactly one digest, the one implied by key algorithm.
                    int[] keymasterDigestsFromSpec = KeyProperties.Digest.allToKeymaster(spec.getDigests());
                    if ((keymasterDigestsFromSpec.length != 1) || (keymasterDigestsFromSpec[0] != mKeymasterDigest)) {
                        throw new InvalidAlgorithmParameterException("Unsupported digests specification: " + Arrays.asList(spec.getDigests()) + ". Only " + KeyProperties.Digest.fromKeymaster(mKeymasterDigest) + " supported for this HMAC key algorithm");
                    }
                }
            } else {
                // Key algorithm does not imply a digest.
                if (spec.isDigestsSpecified()) {
                    mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests());
                } else {
                    mKeymasterDigests = EmptyArray.INT;
                }
            }
            // Check that user authentication related parameters are acceptable. This method
            // will throw an IllegalStateException if there are issues (e.g., secure lock screen
            // not set up).
            KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), spec.isUserAuthenticationRequired(), spec.getUserAuthenticationValidityDurationSeconds(), spec.isUserAuthenticationValidWhileOnBody(), spec.isInvalidatedByBiometricEnrollment());
        } catch (IllegalStateException | IllegalArgumentException e) {
            throw new InvalidAlgorithmParameterException(e);
        }
        success = true;
    } finally {
        if (!success) {
            resetAll();
        }
    }
}
Also used : InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) KeymasterArguments(android.security.keymaster.KeymasterArguments) KeyGenParameterSpec(android.security.keystore.KeyGenParameterSpec)

Example 4 with KeyGenParameterSpec

use of android.security.keystore.KeyGenParameterSpec in project android_frameworks_base by ResurrectionRemix.

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);
    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 5 with KeyGenParameterSpec

use of android.security.keystore.KeyGenParameterSpec in project android_frameworks_base by crdroidandroid.

the class AndroidKeyStoreKeyGeneratorSpi method engineInit.

@Override
protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException {
    resetAll();
    boolean success = false;
    try {
        if ((params == null) || (!(params instanceof KeyGenParameterSpec))) {
            throw new InvalidAlgorithmParameterException("Cannot initialize without a " + KeyGenParameterSpec.class.getName() + " parameter");
        }
        KeyGenParameterSpec spec = (KeyGenParameterSpec) params;
        if (spec.getKeystoreAlias() == null) {
            throw new InvalidAlgorithmParameterException("KeyStore entry alias not provided");
        }
        mRng = random;
        mSpec = spec;
        mKeySizeBits = (spec.getKeySize() != -1) ? spec.getKeySize() : mDefaultKeySizeBits;
        if (mKeySizeBits <= 0) {
            throw new InvalidAlgorithmParameterException("Key size must be positive: " + mKeySizeBits);
        } else if ((mKeySizeBits % 8) != 0) {
            throw new InvalidAlgorithmParameterException("Key size must be a multiple of 8: " + mKeySizeBits);
        }
        try {
            mKeymasterPurposes = KeyProperties.Purpose.allToKeymaster(spec.getPurposes());
            mKeymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(spec.getEncryptionPaddings());
            if (spec.getSignaturePaddings().length > 0) {
                throw new InvalidAlgorithmParameterException("Signature paddings not supported for symmetric key algorithms");
            }
            mKeymasterBlockModes = KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes());
            if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0) && (spec.isRandomizedEncryptionRequired())) {
                for (int keymasterBlockMode : mKeymasterBlockModes) {
                    if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto(keymasterBlockMode)) {
                        throw new InvalidAlgorithmParameterException("Randomized encryption (IND-CPA) required but may be violated" + " by block mode: " + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode) + ". See " + KeyGenParameterSpec.class.getName() + " documentation.");
                    }
                }
            }
            if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
                // JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm
                // implies SHA-256 digest). Because keymaster HMAC key is authorized only for
                // one digest, we don't let algorithm parameter spec override the digest implied
                // by the key. If the spec specifies digests at all, it must specify only one
                // digest, the only implied by key algorithm.
                mKeymasterDigests = new int[] { mKeymasterDigest };
                if (spec.isDigestsSpecified()) {
                    // Digest(s) explicitly specified in the spec. Check that the list
                    // consists of exactly one digest, the one implied by key algorithm.
                    int[] keymasterDigestsFromSpec = KeyProperties.Digest.allToKeymaster(spec.getDigests());
                    if ((keymasterDigestsFromSpec.length != 1) || (keymasterDigestsFromSpec[0] != mKeymasterDigest)) {
                        throw new InvalidAlgorithmParameterException("Unsupported digests specification: " + Arrays.asList(spec.getDigests()) + ". Only " + KeyProperties.Digest.fromKeymaster(mKeymasterDigest) + " supported for this HMAC key algorithm");
                    }
                }
            } else {
                // Key algorithm does not imply a digest.
                if (spec.isDigestsSpecified()) {
                    mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests());
                } else {
                    mKeymasterDigests = EmptyArray.INT;
                }
            }
            // Check that user authentication related parameters are acceptable. This method
            // will throw an IllegalStateException if there are issues (e.g., secure lock screen
            // not set up).
            KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), spec.isUserAuthenticationRequired(), spec.getUserAuthenticationValidityDurationSeconds(), spec.isUserAuthenticationValidWhileOnBody(), spec.isInvalidatedByBiometricEnrollment());
        } catch (IllegalStateException | IllegalArgumentException e) {
            throw new InvalidAlgorithmParameterException(e);
        }
        success = true;
    } finally {
        if (!success) {
            resetAll();
        }
    }
}
Also used : InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) KeymasterArguments(android.security.keymaster.KeymasterArguments) KeyGenParameterSpec(android.security.keystore.KeyGenParameterSpec)

Aggregations

KeymasterArguments (android.security.keymaster.KeymasterArguments)10 KeyGenParameterSpec (android.security.keystore.KeyGenParameterSpec)10 KeyCharacteristics (android.security.keymaster.KeyCharacteristics)5 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)5 ProviderException (java.security.ProviderException)5 SecretKey (javax.crypto.SecretKey)5