1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.cts.verifier.biometrics; 18 19 import android.app.AlertDialog; 20 import android.content.Context; 21 import android.content.DialogInterface; 22 import android.content.res.Resources; 23 import android.security.keystore.KeyGenParameterSpec; 24 import android.security.keystore.KeyProperties; 25 import android.util.Log; 26 import android.widget.Toast; 27 28 import java.security.KeyStore; 29 import java.security.PrivateKey; 30 import java.security.Signature; 31 32 import javax.crypto.Cipher; 33 import javax.crypto.KeyGenerator; 34 import javax.crypto.Mac; 35 import javax.crypto.SecretKey; 36 37 public class Utils { 38 private static final String TAG = "BiometricTestUtils"; 39 createBiometricBoundKey(String keyName, boolean useStrongBox)40 static void createBiometricBoundKey(String keyName, boolean useStrongBox) throws Exception { 41 KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 42 keyStore.load(null); 43 KeyGenerator keyGenerator = KeyGenerator.getInstance( 44 KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); 45 46 // Set the alias of the entry in Android KeyStore where the key will appear 47 // and the constrains (purposes) in the constructor of the Builder 48 keyGenerator.init(new KeyGenParameterSpec.Builder(keyName, 49 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) 50 .setBlockModes(KeyProperties.BLOCK_MODE_CBC) 51 .setUserAuthenticationRequired(true) 52 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) 53 .setIsStrongBoxBacked(useStrongBox) 54 .setInvalidatedByBiometricEnrollment(true) 55 .build()); 56 keyGenerator.generateKey(); 57 } 58 createTimeBoundSecretKey_deprecated(String keyName, boolean useStrongBox)59 static void createTimeBoundSecretKey_deprecated(String keyName, boolean useStrongBox) 60 throws Exception { 61 KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 62 keyStore.load(null); 63 KeyGenerator keyGenerator = KeyGenerator.getInstance( 64 KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); 65 66 // Set the alias of the entry in Android KeyStore where the key will appear 67 // and the constrains (purposes) in the constructor of the Builder 68 keyGenerator.init(new KeyGenParameterSpec.Builder(keyName, 69 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) 70 .setBlockModes(KeyProperties.BLOCK_MODE_CBC) 71 .setUserAuthenticationRequired(true) 72 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) 73 .setIsStrongBoxBacked(useStrongBox) 74 .setUserAuthenticationValidityDurationSeconds(5 /* seconds */) 75 .build()); 76 keyGenerator.generateKey(); 77 } 78 initCipher(String keyName)79 static Cipher initCipher(String keyName) throws Exception { 80 KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 81 keyStore.load(null); 82 SecretKey secretKey = (SecretKey) keyStore.getKey(keyName, null); 83 84 Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" 85 + KeyProperties.BLOCK_MODE_CBC + "/" 86 + KeyProperties.ENCRYPTION_PADDING_PKCS7); 87 cipher.init(Cipher.ENCRYPT_MODE, secretKey); 88 return cipher; 89 } 90 initSignature(String keyName)91 static Signature initSignature(String keyName) throws Exception { 92 KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 93 keyStore.load(null); 94 95 KeyStore.Entry entry = keyStore.getEntry(keyName, null); 96 97 PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); 98 99 // TODO: This can be used to verify signature 100 // PublicKey publicKey = keyStore.getCertificate(keyName).getPublicKey(); 101 102 Signature signature = Signature.getInstance("SHA256withECDSA"); 103 signature.initSign(privateKey); 104 return signature; 105 } 106 initMac(String keyName)107 static Mac initMac(String keyName) throws Exception { 108 KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 109 keyStore.load(null); 110 111 SecretKey secretKey = (SecretKey) keyStore.getKey(keyName, null); 112 113 Mac mac = Mac.getInstance("HmacSHA256"); 114 mac.init(secretKey); 115 return mac; 116 } 117 doEncrypt(Cipher cipher, byte[] data)118 static byte[] doEncrypt(Cipher cipher, byte[] data) throws Exception { 119 return cipher.doFinal(data); 120 } 121 doSign(Signature signature, byte[] data)122 static byte[] doSign(Signature signature, byte[] data) throws Exception { 123 signature.update(data); 124 return signature.sign(); 125 } 126 showInstructionDialog(Context context, int titleRes, int messageRes, int positiveButtonRes, DialogInterface.OnClickListener listener)127 static void showInstructionDialog(Context context, int titleRes, int messageRes, 128 int positiveButtonRes, DialogInterface.OnClickListener listener) { 129 AlertDialog.Builder builder = new AlertDialog.Builder(context); 130 builder.setTitle(titleRes); 131 builder.setMessage(messageRes); 132 builder.setPositiveButton(positiveButtonRes, listener); 133 AlertDialog dialog = builder.create(); 134 dialog.show(); 135 } 136 } 137