• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.security.keystore.KeyGenParameterSpec;
23 import android.security.keystore.KeyProperties;
24 
25 import java.security.KeyStore;
26 import java.security.PrivateKey;
27 import java.security.Signature;
28 
29 import javax.crypto.Cipher;
30 import javax.crypto.KeyGenerator;
31 import javax.crypto.Mac;
32 import javax.crypto.SecretKey;
33 
34 public class Utils {
35     private static final String TAG = "BiometricTestUtils";
36 
createBiometricBoundKey(String keyName, boolean useStrongBox)37     static void createBiometricBoundKey(String keyName, boolean useStrongBox) throws Exception {
38         KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
39         keyStore.load(null);
40         KeyGenerator keyGenerator = KeyGenerator.getInstance(
41                 KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
42 
43         // Set the alias of the entry in Android KeyStore where the key will appear
44         // and the constrains (purposes) in the constructor of the Builder
45         keyGenerator.init(new KeyGenParameterSpec.Builder(keyName,
46                 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
47                 .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
48                 .setUserAuthenticationRequired(true)
49                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
50                 .setIsStrongBoxBacked(useStrongBox)
51                 .setInvalidatedByBiometricEnrollment(true)
52                 .build());
53         keyGenerator.generateKey();
54     }
55 
createTimeBoundSecretKey_deprecated(String keyName, boolean useStrongBox)56     static void createTimeBoundSecretKey_deprecated(String keyName, boolean useStrongBox)
57             throws Exception {
58         KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
59         keyStore.load(null);
60         KeyGenerator keyGenerator = KeyGenerator.getInstance(
61                 KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
62 
63         // Set the alias of the entry in Android KeyStore where the key will appear
64         // and the constrains (purposes) in the constructor of the Builder
65         keyGenerator.init(new KeyGenParameterSpec.Builder(keyName,
66                 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
67                 .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
68                 .setUserAuthenticationRequired(true)
69                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
70                 .setIsStrongBoxBacked(useStrongBox)
71                 .setUserAuthenticationValidityDurationSeconds(5 /* seconds */)
72                 .build());
73         keyGenerator.generateKey();
74     }
75 
initCipher(String keyName)76     static Cipher initCipher(String keyName) throws Exception {
77         KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
78         keyStore.load(null);
79         SecretKey secretKey = (SecretKey) keyStore.getKey(keyName, null);
80 
81         Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
82                 + KeyProperties.BLOCK_MODE_CBC + "/"
83                 + KeyProperties.ENCRYPTION_PADDING_PKCS7);
84         cipher.init(Cipher.ENCRYPT_MODE, secretKey);
85         return cipher;
86     }
87 
initAeadCipher(String keyName)88     static Cipher initAeadCipher(String keyName) throws Exception {
89         KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
90         keyStore.load(null);
91         SecretKey secretKey = (SecretKey) keyStore.getKey(keyName, null);
92 
93         Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
94                 + KeyProperties.BLOCK_MODE_GCM + "/"
95                 + KeyProperties.ENCRYPTION_PADDING_NONE);
96         cipher.init(Cipher.ENCRYPT_MODE, secretKey);
97         return cipher;
98     }
99 
initSignature(String keyName)100     static Signature initSignature(String keyName) throws Exception {
101         KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
102         keyStore.load(null);
103 
104         KeyStore.Entry entry = keyStore.getEntry(keyName, null);
105 
106         PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
107 
108         // TODO: This can be used to verify signature
109         // PublicKey publicKey = keyStore.getCertificate(keyName).getPublicKey();
110 
111         Signature signature = Signature.getInstance("SHA256withECDSA");
112         signature.initSign(privateKey);
113         return signature;
114     }
115 
initMac(String keyName)116     static Mac initMac(String keyName) throws Exception {
117         KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
118         keyStore.load(null);
119 
120         SecretKey secretKey = (SecretKey) keyStore.getKey(keyName, null);
121 
122         Mac mac = Mac.getInstance("HmacSHA256");
123         mac.init(secretKey);
124         return mac;
125     }
126 
doEncrypt(Cipher cipher, byte[] data)127     static byte[] doEncrypt(Cipher cipher, byte[] data) throws Exception {
128         return cipher.doFinal(data);
129     }
130 
doSign(Signature signature, byte[] data)131     static byte[] doSign(Signature signature, byte[] data) throws Exception {
132         signature.update(data);
133         return signature.sign();
134     }
135 
showInstructionDialog(Context context, int titleRes, int messageRes, int positiveButtonRes, DialogInterface.OnClickListener listener)136     static void showInstructionDialog(Context context, int titleRes, int messageRes,
137             int positiveButtonRes, DialogInterface.OnClickListener listener) {
138         AlertDialog.Builder builder = new AlertDialog.Builder(context);
139         builder.setTitle(titleRes);
140         builder.setMessage(messageRes);
141         builder.setPositiveButton(positiveButtonRes, listener);
142         AlertDialog dialog = builder.create();
143         dialog.show();
144     }
145 }
146