Search in sources :

Example 31 with KeymasterArguments

use of android.security.keymaster.KeymasterArguments in project android_frameworks_base by crdroidandroid.

the class AndroidKeyStoreKeyPairGeneratorSpi method constructKeyGenerationArguments.

private KeymasterArguments constructKeyGenerationArguments() {
    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, mKeymasterEncryptionPaddings);
    args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterSignaturePaddings);
    args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
    KeymasterUtils.addUserAuthArgs(args, mSpec.isUserAuthenticationRequired(), mSpec.getUserAuthenticationValidityDurationSeconds(), mSpec.isUserAuthenticationValidWhileOnBody(), mSpec.isInvalidatedByBiometricEnrollment());
    args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, mSpec.getKeyValidityStart());
    args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, mSpec.getKeyValidityForOriginationEnd());
    args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, mSpec.getKeyValidityForConsumptionEnd());
    addAlgorithmSpecificParameters(args);
    if (mSpec.isUniqueIdIncluded())
        args.addBoolean(KeymasterDefs.KM_TAG_INCLUDE_UNIQUE_ID);
    return args;
}
Also used : KeymasterArguments(android.security.keymaster.KeymasterArguments)

Example 32 with KeymasterArguments

use of android.security.keymaster.KeymasterArguments in project android_frameworks_base by crdroidandroid.

the class AndroidKeyStoreSignatureSpiBase method ensureKeystoreOperationInitialized.

private void ensureKeystoreOperationInitialized() throws InvalidKeyException {
    if (mMessageStreamer != null) {
        return;
    }
    if (mCachedException != null) {
        return;
    }
    if (mKey == null) {
        throw new IllegalStateException("Not initialized");
    }
    KeymasterArguments keymasterInputArgs = new KeymasterArguments();
    addAlgorithmSpecificParametersToBegin(keymasterInputArgs);
    OperationResult opResult = mKeyStore.begin(mKey.getAlias(), mSigning ? KeymasterDefs.KM_PURPOSE_SIGN : KeymasterDefs.KM_PURPOSE_VERIFY, // permit aborting this operation if keystore runs out of resources
    true, keymasterInputArgs, // no additional entropy for begin -- only finish might need some
    null, mKey.getUid());
    if (opResult == null) {
        throw new KeyStoreConnectException();
    }
    // Store operation token and handle regardless of the error code returned by KeyStore to
    // ensure that the operation gets aborted immediately if the code below throws an exception.
    mOperationToken = opResult.token;
    mOperationHandle = opResult.operationHandle;
    // If necessary, throw an exception due to KeyStore operation having failed.
    InvalidKeyException e = KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(mKeyStore, mKey, opResult.resultCode);
    if (e != null) {
        throw e;
    }
    if (mOperationToken == null) {
        throw new ProviderException("Keystore returned null operation token");
    }
    if (mOperationHandle == 0) {
        throw new ProviderException("Keystore returned invalid operation handle");
    }
    mMessageStreamer = createMainDataStreamer(mKeyStore, opResult.token);
}
Also used : KeymasterArguments(android.security.keymaster.KeymasterArguments) ProviderException(java.security.ProviderException) OperationResult(android.security.keymaster.OperationResult) InvalidKeyException(java.security.InvalidKeyException)

Example 33 with KeymasterArguments

use of android.security.keymaster.KeymasterArguments in project android_frameworks_base by crdroidandroid.

the class AndroidKeyStoreSpi method setSecretKeyEntry.

private void setSecretKeyEntry(String entryAlias, SecretKey key, java.security.KeyStore.ProtectionParameter param) throws KeyStoreException {
    if ((param != null) && (!(param instanceof KeyProtection))) {
        throw new KeyStoreException("Unsupported protection parameter class: " + param.getClass().getName() + ". Supported: " + KeyProtection.class.getName());
    }
    KeyProtection params = (KeyProtection) param;
    if (key instanceof AndroidKeyStoreSecretKey) {
        // KeyStore-backed secret key. It cannot be duplicated into another entry and cannot
        // overwrite its own entry.
        String keyAliasInKeystore = ((AndroidKeyStoreSecretKey) key).getAlias();
        if (keyAliasInKeystore == null) {
            throw new KeyStoreException("KeyStore-backed secret key does not have an alias");
        }
        if (!keyAliasInKeystore.startsWith(Credentials.USER_SECRET_KEY)) {
            throw new KeyStoreException("KeyStore-backed secret key has invalid alias: " + keyAliasInKeystore);
        }
        String keyEntryAlias = keyAliasInKeystore.substring(Credentials.USER_SECRET_KEY.length());
        if (!entryAlias.equals(keyEntryAlias)) {
            throw new KeyStoreException("Can only replace KeyStore-backed keys with same" + " alias: " + entryAlias + " != " + keyEntryAlias);
        }
        // This is the entry where this key is already stored. No need to do anything.
        if (params != null) {
            throw new KeyStoreException("Modifying KeyStore-backed key using protection" + " parameters not supported");
        }
        return;
    }
    if (params == null) {
        throw new KeyStoreException("Protection parameters must be specified when importing a symmetric key");
    }
    // Not a KeyStore-backed secret key -- import its key material into keystore.
    String keyExportFormat = key.getFormat();
    if (keyExportFormat == null) {
        throw new KeyStoreException("Only secret keys that export their key material are supported");
    } else if (!"RAW".equals(keyExportFormat)) {
        throw new KeyStoreException("Unsupported secret key material export format: " + keyExportFormat);
    }
    byte[] keyMaterial = key.getEncoded();
    if (keyMaterial == null) {
        throw new KeyStoreException("Key did not export its key material despite supporting" + " RAW format export");
    }
    KeymasterArguments args = new KeymasterArguments();
    try {
        int keymasterAlgorithm = KeyProperties.KeyAlgorithm.toKeymasterSecretKeyAlgorithm(key.getAlgorithm());
        args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm);
        int[] keymasterDigests;
        if (keymasterAlgorithm == 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 import parameters override the digest implied by the key.
            // If the parameters specify digests at all, they must specify only one digest, the
            // only implied by key algorithm.
            int keymasterImpliedDigest = KeyProperties.KeyAlgorithm.toKeymasterDigest(key.getAlgorithm());
            if (keymasterImpliedDigest == -1) {
                throw new ProviderException("HMAC key algorithm digest unknown for key algorithm " + key.getAlgorithm());
            }
            keymasterDigests = new int[] { keymasterImpliedDigest };
            if (params.isDigestsSpecified()) {
                // Digest(s) explicitly specified in params -- check that the list consists of
                // exactly one digest, the one implied by key algorithm.
                int[] keymasterDigestsFromParams = KeyProperties.Digest.allToKeymaster(params.getDigests());
                if ((keymasterDigestsFromParams.length != 1) || (keymasterDigestsFromParams[0] != keymasterImpliedDigest)) {
                    throw new KeyStoreException("Unsupported digests specification: " + Arrays.asList(params.getDigests()) + ". Only " + KeyProperties.Digest.fromKeymaster(keymasterImpliedDigest) + " supported for HMAC key algorithm " + key.getAlgorithm());
                }
            }
        } else {
            // Key algorithm does not imply a digest.
            if (params.isDigestsSpecified()) {
                keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests());
            } else {
                keymasterDigests = EmptyArray.INT;
            }
        }
        args.addEnums(KeymasterDefs.KM_TAG_DIGEST, keymasterDigests);
        @KeyProperties.PurposeEnum int purposes = params.getPurposes();
        int[] keymasterBlockModes = KeyProperties.BlockMode.allToKeymaster(params.getBlockModes());
        if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0) && (params.isRandomizedEncryptionRequired())) {
            for (int keymasterBlockMode : keymasterBlockModes) {
                if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto(keymasterBlockMode)) {
                    throw new KeyStoreException("Randomized encryption (IND-CPA) required but may be violated by" + " block mode: " + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode) + ". See KeyProtection documentation.");
                }
            }
        }
        args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, KeyProperties.Purpose.allToKeymaster(purposes));
        args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
        if (params.getSignaturePaddings().length > 0) {
            throw new KeyStoreException("Signature paddings not supported for symmetric keys");
        }
        int[] keymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(params.getEncryptionPaddings());
        args.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
        KeymasterUtils.addUserAuthArgs(args, params.isUserAuthenticationRequired(), params.getUserAuthenticationValidityDurationSeconds(), params.isUserAuthenticationValidWhileOnBody(), params.isInvalidatedByBiometricEnrollment());
        KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(args, keymasterAlgorithm, keymasterBlockModes, keymasterDigests);
        args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, params.getKeyValidityStart());
        args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, params.getKeyValidityForOriginationEnd());
        args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, params.getKeyValidityForConsumptionEnd());
        if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0) && (!params.isRandomizedEncryptionRequired())) {
            // Permit caller-provided IV when encrypting with this key
            args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE);
        }
    } catch (IllegalArgumentException | IllegalStateException e) {
        throw new KeyStoreException(e);
    }
    Credentials.deleteAllTypesForAlias(mKeyStore, entryAlias, mUid);
    String keyAliasInKeystore = Credentials.USER_SECRET_KEY + entryAlias;
    int errorCode = mKeyStore.importKey(keyAliasInKeystore, args, KeymasterDefs.KM_KEY_FORMAT_RAW, keyMaterial, mUid, // flags
    0, new KeyCharacteristics());
    if (errorCode != KeyStore.NO_ERROR) {
        throw new KeyStoreException("Failed to import secret key. Keystore error code: " + errorCode);
    }
}
Also used : KeymasterArguments(android.security.keymaster.KeymasterArguments) ProviderException(java.security.ProviderException) KeyStoreException(java.security.KeyStoreException) KeyProtection(android.security.keystore.KeyProtection) KeyCharacteristics(android.security.keymaster.KeyCharacteristics)

Example 34 with KeymasterArguments

use of android.security.keymaster.KeymasterArguments in project android_frameworks_base by crdroidandroid.

the class KeyStoreTest method testAppId.

public void testAppId() throws Exception {
    String name = "test";
    byte[] id = new byte[] { 0x01, 0x02, 0x03 };
    KeymasterArguments args = new KeymasterArguments();
    args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
    args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
    args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
    args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
    args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
    args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
    args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
    args.addBytes(KeymasterDefs.KM_TAG_APPLICATION_ID, id);
    args.addUnsignedLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, RSAKeyGenParameterSpec.F4);
    KeyCharacteristics outCharacteristics = new KeyCharacteristics();
    int result = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
    assertEquals("generateRsaKey should succeed", KeyStore.NO_ERROR, result);
    assertEquals("getKeyCharacteristics should fail without application ID", KeymasterDefs.KM_ERROR_INVALID_KEY_BLOB, mKeyStore.getKeyCharacteristics(name, null, null, outCharacteristics));
    assertEquals("getKeyCharacteristics should succeed with application ID", KeyStore.NO_ERROR, mKeyStore.getKeyCharacteristics(name, new KeymasterBlob(id), null, outCharacteristics));
}
Also used : KeymasterBlob(android.security.keymaster.KeymasterBlob) KeymasterArguments(android.security.keymaster.KeymasterArguments) KeyCharacteristics(android.security.keymaster.KeyCharacteristics)

Example 35 with KeymasterArguments

use of android.security.keymaster.KeymasterArguments in project android_frameworks_base by crdroidandroid.

the class KeyStoreTest method testOperationPruning.

// This is a very implementation specific test and should be thrown out eventually, however it
// is nice for now to test that keystore is properly pruning operations.
public void testOperationPruning() throws Exception {
    String name = "test";
    KeymasterArguments args = new KeymasterArguments();
    args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
    args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
    args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
    args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
    args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
    args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
    args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
    KeyCharacteristics outCharacteristics = new KeyCharacteristics();
    int rc = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
    assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
    args = new KeymasterArguments();
    args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
    args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
    args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
    OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT, true, args, null);
    assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
    IBinder first = result.token;
    // Implementation detail: softkeymaster supports 16 concurrent operations
    for (int i = 0; i < 16; i++) {
        result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT, true, args, null);
        assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
    }
    // At this point the first operation should be pruned.
    assertEquals("Operation should be pruned", KeymasterDefs.KM_ERROR_INVALID_OPERATION_HANDLE, mKeyStore.update(first, null, new byte[] { 0x01 }).resultCode);
}
Also used : IBinder(android.os.IBinder) KeymasterArguments(android.security.keymaster.KeymasterArguments) KeyCharacteristics(android.security.keymaster.KeyCharacteristics) OperationResult(android.security.keymaster.OperationResult)

Aggregations

KeymasterArguments (android.security.keymaster.KeymasterArguments)90 KeyCharacteristics (android.security.keymaster.KeyCharacteristics)50 OperationResult (android.security.keymaster.OperationResult)30 ProviderException (java.security.ProviderException)30 IBinder (android.os.IBinder)15 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)15 InvalidKeyException (java.security.InvalidKeyException)15 KeyGenParameterSpec (android.security.keystore.KeyGenParameterSpec)10 KeyProtection (android.security.keystore.KeyProtection)10 KeyStoreException (java.security.KeyStoreException)10 KeyPairGeneratorSpec (android.security.KeyPairGeneratorSpec)5 KeyStoreParameter (android.security.KeyStoreParameter)5 KeymasterBlob (android.security.keymaster.KeymasterBlob)5 DERBitString (com.android.org.bouncycastle.asn1.DERBitString)5 GeneralSecurityException (java.security.GeneralSecurityException)5 CertificateEncodingException (java.security.cert.CertificateEncodingException)5 X509Certificate (java.security.cert.X509Certificate)5 RSAKeyGenParameterSpec (java.security.spec.RSAKeyGenParameterSpec)5 SecretKey (javax.crypto.SecretKey)5