KeyStoreTest.java revision ce7ad24b6337135fd7b6ed169bb5c517d044f041
1/*
2 * Copyright (C) 2009 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
17package android.security;
18
19import android.app.Activity;
20import android.os.Binder;
21import android.os.IBinder;
22import android.os.Process;
23import android.os.ServiceManager;
24import android.security.KeyStore;
25import android.security.keymaster.ExportResult;
26import android.security.keymaster.KeyCharacteristics;
27import android.security.keymaster.KeymasterArguments;
28import android.security.keymaster.KeymasterBlob;
29import android.security.keymaster.KeymasterDefs;
30import android.security.keymaster.OperationResult;
31import android.test.ActivityUnitTestCase;
32import android.test.AssertionFailedError;
33import android.test.MoreAsserts;
34import android.test.suitebuilder.annotation.MediumTest;
35import com.android.org.conscrypt.NativeCrypto;
36import java.nio.charset.StandardCharsets;
37import java.util.Arrays;
38import java.util.Date;
39import java.util.HashSet;
40import java.security.spec.RSAKeyGenParameterSpec;
41
42import android.util.Log;
43import android.util.Base64;
44
45/**
46 * Junit / Instrumentation test case for KeyStore class
47 *
48 * Running the test suite:
49 *
50 *  runtest keystore-unit
51 *
52 * Or this individual test case:
53 *
54 *  runtest --path frameworks/base/keystore/tests/src/android/security/KeyStoreTest.java
55 */
56@MediumTest
57public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
58    private static final String TEST_PASSWD = "12345678";
59    private static final String TEST_PASSWD2 = "87654321";
60    private static final String TEST_KEYNAME = "test-key";
61    private static final String TEST_KEYNAME1 = "test-key.1";
62    private static final String TEST_KEYNAME2 = "test-key\02";
63    private static final byte[] TEST_KEYVALUE = "test value".getBytes(StandardCharsets.UTF_8);
64
65    // "Hello, World" in Chinese
66    private static final String TEST_I18N_KEY = "\u4F60\u597D, \u4E16\u754C";
67    private static final byte[] TEST_I18N_VALUE = TEST_I18N_KEY.getBytes(StandardCharsets.UTF_8);
68
69    // Test vector data for signatures
70    private static final int RSA_KEY_SIZE = 1024;
71    private static final byte[] TEST_DATA =  new byte[RSA_KEY_SIZE / 8];
72    static {
73        for (int i = 0; i < TEST_DATA.length; i++) {
74            TEST_DATA[i] = (byte) i;
75        }
76    }
77
78    private KeyStore mKeyStore = null;
79
80    public KeyStoreTest() {
81        super(Activity.class);
82    }
83
84    private static final byte[] PRIVKEY_BYTES = hexToBytes(
85            "308204BE020100300D06092A864886F70D0101010500048204A8308204A4020100028201" +
86            "0100E0473E8AB8F2284FEB9E742FF9748FA118ED98633C92F52AEB7A2EBE0D3BE60329BE" +
87            "766AD10EB6A515D0D2CFD9BEA7930F0C306537899F7958CD3E85B01F8818524D312584A9" +
88            "4B251E3625B54141EDBFEE198808E1BB97FC7CB49B9EAAAF68E9C98D7D0EDC53BBC0FA00" +
89            "34356D6305FBBCC3C7001405386ABBC873CB0F3EF7425F3D33DF7B315AE036D2A0B66AFD" +
90            "47503B169BF36E3B5162515B715FDA83DEAF2C58AEB9ABFB3097C3CC9DD9DBE5EF296C17" +
91            "6139028E8A671E63056D45F40188D2C4133490845DE52C2534E9C6B2478C07BDAE928823" +
92            "B62D066C7770F9F63F3DBA247F530844747BE7AAA85D853B8BD244ACEC3DE3C89AB46453" +
93            "AB4D24C3AC6902030100010282010037784776A5F17698F5AC960DFB83A1B67564E648BD" +
94            "0597CF8AB8087186F2669C27A9ECBDD480F0197A80D07309E6C6A96F925331E57F8B4AC6" +
95            "F4D45EDA45A23269C09FC428C07A4E6EDF738A15DEC97FABD2F2BB47A14F20EA72FCFE4C" +
96            "36E01ADA77BD137CD8D4DA10BB162E94A4662971F175F985FA188F056CB97EE2816F43AB" +
97            "9D3747612486CDA8C16196C30818A995EC85D38467791267B3BF21F273710A6925862576" +
98            "841C5B6712C12D4BD20A2F3299ADB7C135DA5E9515ABDA76E7CAF2A3BE80551D073B78BF" +
99            "1162C48AD2B7F4743A0238EE4D252F7D5E7E6533CCAE64CCB39360075A2FD1E034EC3AE5" +
100            "CE9C408CCBF0E25E4114021687B3DD4754AE8102818100F541884BC3737B2922D4119EF4" +
101            "5E2DEE2CD4CBB75F45505A157AA5009F99C73A2DF0724AC46024306332EA898177634546" +
102            "5DC6DF1E0A6F140AFF3B7396E6A8994AC5DAA96873472FE37749D14EB3E075E629DBEB35" +
103            "83338A6F3649D0A2654A7A42FD9AB6BFA4AC4D481D390BB229B064BDC311CC1BE1B63189" +
104            "DA7C40CDECF2B102818100EA1A742DDB881CEDB7288C87E38D868DD7A409D15A43F445D5" +
105            "377A0B5731DDBFCA2DAF28A8E13CD5C0AFCEC3347D74A39E235A3CD9633F274DE2B94F92" +
106            "DF43833911D9E9F1CF58F27DE2E08FF45964C720D3EC2139DC7CAFC912953CDECB2F355A" +
107            "2E2C35A50FAD754CB3B23166424BA3B6E3112A2B898C38C5C15EDB238693390281805182" +
108            "8F1EC6FD996029901BAF1D7E337BA5F0AF27E984EAD895ACE62BD7DF4EE45A224089F2CC" +
109            "151AF3CD173FCE0474BCB04F386A2CDCC0E0036BA2419F54579262D47100BE931984A3EF" +
110            "A05BECF141574DC079B3A95C4A83E6C43F3214D6DF32D512DE198085E531E616B83FD7DD" +
111            "9D1F4E2607C3333D07C55D107D1D3893587102818100DB4FB50F50DE8EDB53FF34C80931" +
112            "88A0512867DA2CCA04897759E587C244010DAF8664D59E8083D16C164789301F67A9F078" +
113            "060D834A2ADBD367575B68A8A842C2B02A89B3F31FCCEC8A22FE395795C5C6C7422B4E5D" +
114            "74A1E9A8F30E7759B9FC2D639C1F15673E84E93A5EF1506F4315383C38D45CBD1B14048F" +
115            "4721DC82326102818100D8114593AF415FB612DBF1923710D54D07486205A76A3B431949" +
116            "68C0DFF1F11EF0F61A4A337D5FD3741BBC9640E447B8B6B6C47C3AC1204357D3B0C55BA9" +
117            "286BDA73F629296F5FA9146D8976357D3C751E75148696A40B74685C82CE30902D639D72" +
118            "4FF24D5E2E9407EE34EDED2E3B4DF65AA9BCFEB6DF28D07BA6903F165768");
119
120    private static final byte[] AES256_BYTES = hexToBytes(
121            "0CC175B9C0F1B6A831C399E269772661CEC520EA51EA0A47E87295FA3245A605");
122
123    private static byte[] hexToBytes(String s) {
124        int len = s.length();
125        byte[] data = new byte[len / 2];
126        for (int i = 0; i < len; i += 2) {
127            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(
128                    s.charAt(i + 1), 16));
129        }
130        return data;
131    }
132
133    @Override
134    protected void setUp() throws Exception {
135        mKeyStore = KeyStore.getInstance();
136        if (mKeyStore.state() != KeyStore.State.UNINITIALIZED) {
137            mKeyStore.reset();
138        }
139        assertEquals("KeyStore should be in an uninitialized state",
140                KeyStore.State.UNINITIALIZED, mKeyStore.state());
141        super.setUp();
142    }
143
144    @Override
145    protected void tearDown() throws Exception {
146        mKeyStore.reset();
147        super.tearDown();
148    }
149
150    public void testState() throws Exception {
151        assertEquals(KeyStore.State.UNINITIALIZED, mKeyStore.state());
152    }
153
154    public void testPassword() throws Exception {
155        assertTrue(mKeyStore.password(TEST_PASSWD));
156        assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
157    }
158
159    public void testGet() throws Exception {
160        assertNull(mKeyStore.get(TEST_KEYNAME));
161        mKeyStore.password(TEST_PASSWD);
162        assertNull(mKeyStore.get(TEST_KEYNAME));
163        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
164                KeyStore.FLAG_ENCRYPTED));
165        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
166    }
167
168    public void testPut() throws Exception {
169        assertNull(mKeyStore.get(TEST_KEYNAME));
170        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
171                KeyStore.FLAG_ENCRYPTED));
172        assertFalse(mKeyStore.contains(TEST_KEYNAME));
173        mKeyStore.password(TEST_PASSWD);
174        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
175                KeyStore.FLAG_ENCRYPTED));
176        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
177    }
178
179    public void testPut_grantedUid_Wifi() throws Exception {
180        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
181        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
182                KeyStore.FLAG_ENCRYPTED));
183        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
184        mKeyStore.password(TEST_PASSWD);
185        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
186                KeyStore.FLAG_ENCRYPTED));
187        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
188    }
189
190    public void testPut_ungrantedUid_Bluetooth() throws Exception {
191        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
192        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
193                KeyStore.FLAG_ENCRYPTED));
194        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
195        mKeyStore.password(TEST_PASSWD);
196        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
197                KeyStore.FLAG_ENCRYPTED));
198        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
199    }
200
201    public void testI18n() throws Exception {
202        assertFalse(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE, KeyStore.UID_SELF,
203                KeyStore.FLAG_ENCRYPTED));
204        assertFalse(mKeyStore.contains(TEST_I18N_KEY));
205        mKeyStore.password(TEST_I18N_KEY);
206        assertTrue(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE, KeyStore.UID_SELF,
207                KeyStore.FLAG_ENCRYPTED));
208        assertTrue(mKeyStore.contains(TEST_I18N_KEY));
209    }
210
211    public void testDelete() throws Exception {
212        assertFalse(mKeyStore.delete(TEST_KEYNAME));
213        mKeyStore.password(TEST_PASSWD);
214        assertFalse(mKeyStore.delete(TEST_KEYNAME));
215
216        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
217                KeyStore.FLAG_ENCRYPTED));
218        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
219        assertTrue(mKeyStore.delete(TEST_KEYNAME));
220        assertNull(mKeyStore.get(TEST_KEYNAME));
221    }
222
223    public void testDelete_grantedUid_Wifi() throws Exception {
224        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.WIFI_UID));
225        mKeyStore.password(TEST_PASSWD);
226        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.WIFI_UID));
227
228        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
229                KeyStore.FLAG_ENCRYPTED));
230        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
231        assertTrue(mKeyStore.delete(TEST_KEYNAME, Process.WIFI_UID));
232        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
233    }
234
235    public void testDelete_ungrantedUid_Bluetooth() throws Exception {
236        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.BLUETOOTH_UID));
237        mKeyStore.password(TEST_PASSWD);
238        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.BLUETOOTH_UID));
239
240        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
241                KeyStore.FLAG_ENCRYPTED));
242        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
243        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.BLUETOOTH_UID));
244        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
245    }
246
247    public void testContains() throws Exception {
248        assertFalse(mKeyStore.contains(TEST_KEYNAME));
249
250        assertTrue(mKeyStore.password(TEST_PASSWD));
251        assertFalse(mKeyStore.contains(TEST_KEYNAME));
252
253        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
254                KeyStore.FLAG_ENCRYPTED));
255        assertTrue(mKeyStore.contains(TEST_KEYNAME));
256    }
257
258    public void testContains_grantedUid_Wifi() throws Exception {
259        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
260
261        assertTrue(mKeyStore.password(TEST_PASSWD));
262        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
263
264        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
265                KeyStore.FLAG_ENCRYPTED));
266        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
267    }
268
269    public void testContains_grantedUid_Bluetooth() throws Exception {
270        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
271
272        assertTrue(mKeyStore.password(TEST_PASSWD));
273        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
274
275        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
276                KeyStore.FLAG_ENCRYPTED));
277        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
278    }
279
280    public void testSaw() throws Exception {
281        String[] emptyResult = mKeyStore.saw(TEST_KEYNAME);
282        assertNotNull(emptyResult);
283        assertEquals(0, emptyResult.length);
284
285        mKeyStore.password(TEST_PASSWD);
286        mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
287        mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
288
289        String[] results = mKeyStore.saw(TEST_KEYNAME);
290        assertEquals(new HashSet(Arrays.asList(TEST_KEYNAME1.substring(TEST_KEYNAME.length()),
291                                               TEST_KEYNAME2.substring(TEST_KEYNAME.length()))),
292                     new HashSet(Arrays.asList(results)));
293    }
294
295    public void testSaw_ungrantedUid_Bluetooth() throws Exception {
296        String[] results1 = mKeyStore.saw(TEST_KEYNAME, Process.BLUETOOTH_UID);
297        assertNull(results1);
298
299        mKeyStore.password(TEST_PASSWD);
300        mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
301        mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
302
303        String[] results2 = mKeyStore.saw(TEST_KEYNAME, Process.BLUETOOTH_UID);
304        assertNull(results2);
305    }
306
307    public void testSaw_grantedUid_Wifi() throws Exception {
308        String[] results1 = mKeyStore.saw(TEST_KEYNAME, Process.WIFI_UID);
309        assertNotNull(results1);
310        assertEquals(0, results1.length);
311
312        mKeyStore.password(TEST_PASSWD);
313        mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED);
314        mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED);
315
316        String[] results2 = mKeyStore.saw(TEST_KEYNAME, Process.WIFI_UID);
317        assertEquals(new HashSet(Arrays.asList(TEST_KEYNAME1.substring(TEST_KEYNAME.length()),
318                                               TEST_KEYNAME2.substring(TEST_KEYNAME.length()))),
319                     new HashSet(Arrays.asList(results2)));
320    }
321
322    public void testSaw_grantedUid_Vpn() throws Exception {
323        String[] results1 = mKeyStore.saw(TEST_KEYNAME, Process.VPN_UID);
324        assertNotNull(results1);
325        assertEquals(0, results1.length);
326
327        mKeyStore.password(TEST_PASSWD);
328        mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, Process.VPN_UID, KeyStore.FLAG_ENCRYPTED);
329        mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, Process.VPN_UID, KeyStore.FLAG_ENCRYPTED);
330
331        String[] results2 = mKeyStore.saw(TEST_KEYNAME, Process.VPN_UID);
332        assertEquals(new HashSet(Arrays.asList(TEST_KEYNAME1.substring(TEST_KEYNAME.length()),
333                                               TEST_KEYNAME2.substring(TEST_KEYNAME.length()))),
334                     new HashSet(Arrays.asList(results2)));
335    }
336
337    public void testLock() throws Exception {
338        assertFalse(mKeyStore.lock());
339
340        mKeyStore.password(TEST_PASSWD);
341        assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
342
343        assertTrue(mKeyStore.lock());
344        assertEquals(KeyStore.State.LOCKED, mKeyStore.state());
345    }
346
347    public void testUnlock() throws Exception {
348        mKeyStore.password(TEST_PASSWD);
349        assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
350        mKeyStore.lock();
351
352        assertFalse(mKeyStore.unlock(TEST_PASSWD2));
353        assertTrue(mKeyStore.unlock(TEST_PASSWD));
354    }
355
356    public void testIsEmpty() throws Exception {
357        assertTrue(mKeyStore.isEmpty());
358        mKeyStore.password(TEST_PASSWD);
359        assertTrue(mKeyStore.isEmpty());
360        mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
361        assertFalse(mKeyStore.isEmpty());
362        mKeyStore.reset();
363        assertTrue(mKeyStore.isEmpty());
364    }
365
366    public void testGenerate_NotInitialized_Fail() throws Exception {
367        assertFalse("Should fail when keystore is not initialized",
368                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
369                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
370    }
371
372    public void testGenerate_Locked_Fail() throws Exception {
373        mKeyStore.password(TEST_PASSWD);
374        mKeyStore.lock();
375        assertFalse("Should fail when keystore is locked",
376                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
377                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
378    }
379
380    public void testGenerate_Success() throws Exception {
381        assertTrue(mKeyStore.password(TEST_PASSWD));
382
383        assertTrue("Should be able to generate key when unlocked",
384                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
385                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
386        assertTrue(mKeyStore.contains(TEST_KEYNAME));
387        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
388    }
389
390    public void testGenerate_grantedUid_Wifi_Success() throws Exception {
391        assertTrue(mKeyStore.password(TEST_PASSWD));
392
393        assertTrue("Should be able to generate key when unlocked",
394                mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, NativeCrypto.EVP_PKEY_RSA,
395                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
396        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
397        assertFalse(mKeyStore.contains(TEST_KEYNAME));
398    }
399
400    public void testGenerate_ungrantedUid_Bluetooth_Failure() throws Exception {
401        assertTrue(mKeyStore.password(TEST_PASSWD));
402
403        assertFalse(mKeyStore.generate(TEST_KEYNAME, Process.BLUETOOTH_UID,
404                    NativeCrypto.EVP_PKEY_RSA, RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
405        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
406        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
407        assertFalse(mKeyStore.contains(TEST_KEYNAME));
408    }
409
410    public void testImport_Success() throws Exception {
411        assertTrue(mKeyStore.password(TEST_PASSWD));
412
413        assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
414                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
415        assertTrue(mKeyStore.contains(TEST_KEYNAME));
416        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
417    }
418
419    public void testImport_grantedUid_Wifi_Success() throws Exception {
420        assertTrue(mKeyStore.password(TEST_PASSWD));
421
422        assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
423                PRIVKEY_BYTES, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED));
424        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
425        assertFalse(mKeyStore.contains(TEST_KEYNAME));
426    }
427
428    public void testImport_ungrantedUid_Bluetooth_Failure() throws Exception {
429        assertTrue(mKeyStore.password(TEST_PASSWD));
430
431        assertFalse(mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES, Process.BLUETOOTH_UID,
432                KeyStore.FLAG_ENCRYPTED));
433        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
434        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
435        assertFalse(mKeyStore.contains(TEST_KEYNAME));
436    }
437
438    public void testImport_Failure_BadEncoding() throws Exception {
439        mKeyStore.password(TEST_PASSWD);
440
441        assertFalse("Invalid DER-encoded key should not be imported", mKeyStore.importKey(
442                TEST_KEYNAME, TEST_DATA, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
443        assertFalse(mKeyStore.contains(TEST_KEYNAME));
444        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
445    }
446
447    public void testSign_Success() throws Exception {
448        mKeyStore.password(TEST_PASSWD);
449
450        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
451                    RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
452        assertTrue(mKeyStore.contains(TEST_KEYNAME));
453        final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
454
455        assertNotNull("Signature should not be null", signature);
456    }
457
458    public void testVerify_Success() throws Exception {
459        mKeyStore.password(TEST_PASSWD);
460
461        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
462                    RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
463        assertTrue(mKeyStore.contains(TEST_KEYNAME));
464        final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
465
466        assertNotNull("Signature should not be null", signature);
467
468        assertTrue("Signature should verify with same data",
469                mKeyStore.verify(TEST_KEYNAME, TEST_DATA, signature));
470    }
471
472    public void testSign_NotInitialized_Failure() throws Exception {
473        assertNull("Should not be able to sign without first initializing the keystore",
474                mKeyStore.sign(TEST_KEYNAME, TEST_DATA));
475    }
476
477    public void testSign_NotGenerated_Failure() throws Exception {
478        mKeyStore.password(TEST_PASSWD);
479
480        assertNull("Should not be able to sign without first generating keys",
481                mKeyStore.sign(TEST_KEYNAME, TEST_DATA));
482    }
483
484    public void testGrant_Generated_Success() throws Exception {
485        assertTrue("Password should work for keystore",
486                mKeyStore.password(TEST_PASSWD));
487
488        assertTrue("Should be able to generate key for testcase",
489                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
490                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
491
492        assertTrue("Should be able to grant key to other user",
493                mKeyStore.grant(TEST_KEYNAME, 0));
494    }
495
496    public void testGrant_Imported_Success() throws Exception {
497        assertTrue("Password should work for keystore", mKeyStore.password(TEST_PASSWD));
498
499        assertTrue("Should be able to import key for testcase", mKeyStore.importKey(TEST_KEYNAME,
500                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
501
502        assertTrue("Should be able to grant key to other user", mKeyStore.grant(TEST_KEYNAME, 0));
503    }
504
505    public void testGrant_NoKey_Failure() throws Exception {
506        assertTrue("Should be able to unlock keystore for test",
507                mKeyStore.password(TEST_PASSWD));
508
509        assertFalse("Should not be able to grant without first initializing the keystore",
510                mKeyStore.grant(TEST_KEYNAME, 0));
511    }
512
513    public void testGrant_NotInitialized_Failure() throws Exception {
514        assertFalse("Should not be able to grant without first initializing the keystore",
515                mKeyStore.grant(TEST_KEYNAME, 0));
516    }
517
518    public void testUngrant_Generated_Success() throws Exception {
519        assertTrue("Password should work for keystore",
520                mKeyStore.password(TEST_PASSWD));
521
522        assertTrue("Should be able to generate key for testcase",
523                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
524                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
525
526        assertTrue("Should be able to grant key to other user",
527                mKeyStore.grant(TEST_KEYNAME, 0));
528
529        assertTrue("Should be able to ungrant key to other user",
530                mKeyStore.ungrant(TEST_KEYNAME, 0));
531    }
532
533    public void testUngrant_Imported_Success() throws Exception {
534        assertTrue("Password should work for keystore",
535                mKeyStore.password(TEST_PASSWD));
536
537        assertTrue("Should be able to import key for testcase", mKeyStore.importKey(TEST_KEYNAME,
538                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
539
540        assertTrue("Should be able to grant key to other user",
541                mKeyStore.grant(TEST_KEYNAME, 0));
542
543        assertTrue("Should be able to ungrant key to other user",
544                mKeyStore.ungrant(TEST_KEYNAME, 0));
545    }
546
547    public void testUngrant_NotInitialized_Failure() throws Exception {
548        assertFalse("Should fail to ungrant key when keystore not initialized",
549                mKeyStore.ungrant(TEST_KEYNAME, 0));
550    }
551
552    public void testUngrant_NoGrant_Failure() throws Exception {
553        assertTrue("Password should work for keystore",
554                mKeyStore.password(TEST_PASSWD));
555
556        assertTrue("Should be able to generate key for testcase",
557                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
558                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
559
560        assertFalse("Should not be able to revoke not existent grant",
561                mKeyStore.ungrant(TEST_KEYNAME, 0));
562    }
563
564    public void testUngrant_DoubleUngrant_Failure() throws Exception {
565        assertTrue("Password should work for keystore",
566                mKeyStore.password(TEST_PASSWD));
567
568        assertTrue("Should be able to generate key for testcase",
569                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
570                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
571
572        assertTrue("Should be able to grant key to other user",
573                mKeyStore.grant(TEST_KEYNAME, 0));
574
575        assertTrue("Should be able to ungrant key to other user",
576                mKeyStore.ungrant(TEST_KEYNAME, 0));
577
578        assertFalse("Should fail to ungrant key to other user second time",
579                mKeyStore.ungrant(TEST_KEYNAME, 0));
580    }
581
582    public void testUngrant_DoubleGrantUngrant_Failure() throws Exception {
583        assertTrue("Password should work for keystore",
584                mKeyStore.password(TEST_PASSWD));
585
586        assertTrue("Should be able to generate key for testcase",
587                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
588                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
589
590        assertTrue("Should be able to grant key to other user",
591                mKeyStore.grant(TEST_KEYNAME, 0));
592
593        assertTrue("Should be able to grant key to other user a second time",
594                mKeyStore.grant(TEST_KEYNAME, 0));
595
596        assertTrue("Should be able to ungrant key to other user",
597                mKeyStore.ungrant(TEST_KEYNAME, 0));
598
599        assertFalse("Should fail to ungrant key to other user second time",
600                mKeyStore.ungrant(TEST_KEYNAME, 0));
601    }
602
603    public void testDuplicate_grantedUid_Wifi_Success() throws Exception {
604        assertTrue(mKeyStore.password(TEST_PASSWD));
605
606        assertFalse(mKeyStore.contains(TEST_KEYNAME));
607
608        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
609                    RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
610
611        assertTrue(mKeyStore.contains(TEST_KEYNAME));
612        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
613
614        // source doesn't exist
615        assertFalse(mKeyStore.duplicate(TEST_KEYNAME1, -1, TEST_KEYNAME1, Process.WIFI_UID));
616        assertFalse(mKeyStore.contains(TEST_KEYNAME1, Process.WIFI_UID));
617
618        // Copy from current UID to granted UID
619        assertTrue(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME1, Process.WIFI_UID));
620        assertTrue(mKeyStore.contains(TEST_KEYNAME));
621        assertFalse(mKeyStore.contains(TEST_KEYNAME1));
622        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
623        assertTrue(mKeyStore.contains(TEST_KEYNAME1, Process.WIFI_UID));
624        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME1, Process.WIFI_UID));
625
626        // Copy from granted UID to same granted UID
627        assertTrue(mKeyStore.duplicate(TEST_KEYNAME1, Process.WIFI_UID, TEST_KEYNAME2,
628                Process.WIFI_UID));
629        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
630        assertTrue(mKeyStore.contains(TEST_KEYNAME1, Process.WIFI_UID));
631        assertTrue(mKeyStore.contains(TEST_KEYNAME2, Process.WIFI_UID));
632        assertFalse(mKeyStore.duplicate(TEST_KEYNAME1, Process.WIFI_UID, TEST_KEYNAME2,
633                Process.WIFI_UID));
634
635        assertTrue(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME2, -1));
636        assertTrue(mKeyStore.contains(TEST_KEYNAME));
637        assertFalse(mKeyStore.contains(TEST_KEYNAME1));
638        assertTrue(mKeyStore.contains(TEST_KEYNAME2));
639        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME2, -1));
640    }
641
642    public void testDuplicate_ungrantedUid_Bluetooth_Failure() throws Exception {
643        assertTrue(mKeyStore.password(TEST_PASSWD));
644
645        assertFalse(mKeyStore.contains(TEST_KEYNAME));
646
647        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
648                    RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
649
650        assertTrue(mKeyStore.contains(TEST_KEYNAME));
651        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
652
653        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME2, Process.BLUETOOTH_UID));
654        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, Process.BLUETOOTH_UID, TEST_KEYNAME2,
655                Process.BLUETOOTH_UID));
656
657        assertTrue(mKeyStore.contains(TEST_KEYNAME));
658        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
659    }
660
661    /**
662     * The amount of time to allow before and after expected time for variance
663     * in timing tests.
664     */
665    private static final long SLOP_TIME_MILLIS = 15000L;
666
667    public void testGetmtime_Success() throws Exception {
668        assertTrue("Password should work for keystore",
669                mKeyStore.password(TEST_PASSWD));
670
671        assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
672                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
673
674        long now = System.currentTimeMillis();
675        long actual = mKeyStore.getmtime(TEST_KEYNAME);
676
677        long expectedAfter = now - SLOP_TIME_MILLIS;
678        long expectedBefore = now + SLOP_TIME_MILLIS;
679
680        assertLessThan("Time should be close to current time", expectedBefore, actual);
681        assertGreaterThan("Time should be close to current time", expectedAfter, actual);
682    }
683
684    private static void assertLessThan(String explanation, long expectedBefore, long actual) {
685        if (actual >= expectedBefore) {
686            throw new AssertionFailedError(explanation + ": actual=" + actual
687                    + ", expected before: " + expectedBefore);
688        }
689    }
690
691    private static void assertGreaterThan(String explanation, long expectedAfter, long actual) {
692        if (actual <= expectedAfter) {
693            throw new AssertionFailedError(explanation + ": actual=" + actual
694                    + ", expected after: " + expectedAfter);
695        }
696    }
697
698    public void testGetmtime_NonExist_Failure() throws Exception {
699        assertTrue("Password should work for keystore",
700                mKeyStore.password(TEST_PASSWD));
701
702        assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
703                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
704
705        assertEquals("-1 should be returned for non-existent key",
706                -1L, mKeyStore.getmtime(TEST_KEYNAME2));
707    }
708
709    private KeyCharacteristics generateRsaKey(String name) throws Exception {
710        KeymasterArguments args = new KeymasterArguments();
711        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
712        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
713        args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
714        args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
715        args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
716        args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
717        args.addLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT,
718                RSAKeyGenParameterSpec.F4.longValue());
719
720        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
721        int result = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
722        assertEquals("generateRsaKey should succeed", KeyStore.NO_ERROR, result);
723        return outCharacteristics;
724    }
725
726    public void testGenerateKey() throws Exception {
727        generateRsaKey("test");
728        mKeyStore.delete("test");
729    }
730
731    public void testGenerateRsaWithEntropy() throws Exception {
732        byte[] entropy = new byte[] {1,2,3,4,5};
733        String name = "test";
734        KeymasterArguments args = new KeymasterArguments();
735        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
736        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
737        args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
738        args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
739        args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
740        args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
741        args.addLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT,
742                RSAKeyGenParameterSpec.F4.longValue());
743
744        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
745        int result = mKeyStore.generateKey(name, args, entropy, 0, outCharacteristics);
746        assertEquals("generateKey should succeed", KeyStore.NO_ERROR, result);
747    }
748
749    public void testGenerateAndDelete() throws Exception {
750        generateRsaKey("test");
751        assertTrue("delete should succeed", mKeyStore.delete("test"));
752    }
753
754    public void testGetKeyCharacteristicsSuccess() throws Exception {
755        mKeyStore.password(TEST_PASSWD);
756        String name = "test";
757        KeyCharacteristics gen = generateRsaKey(name);
758        KeyCharacteristics call = new KeyCharacteristics();
759        int result = mKeyStore.getKeyCharacteristics(name, null, null, call);
760        assertEquals("getKeyCharacteristics should succeed", KeyStore.NO_ERROR, result);
761        mKeyStore.delete("test");
762    }
763
764    public void testAppId() throws Exception {
765        String name = "test";
766        byte[] id = new byte[] {0x01, 0x02, 0x03};
767        KeymasterArguments args = new KeymasterArguments();
768        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
769        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
770        args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
771        args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
772        args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
773        args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
774        args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
775        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_ID, id);
776        args.addLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT,
777                RSAKeyGenParameterSpec.F4.longValue());
778
779        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
780        int result = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
781        assertEquals("generateRsaKey should succeed", KeyStore.NO_ERROR, result);
782        assertEquals("getKeyCharacteristics should fail without application ID",
783                KeymasterDefs.KM_ERROR_INVALID_KEY_BLOB,
784                mKeyStore.getKeyCharacteristics(name, null, null, outCharacteristics));
785        assertEquals("getKeyCharacteristics should succeed with application ID",
786                KeyStore.NO_ERROR,
787                mKeyStore.getKeyCharacteristics(name, new KeymasterBlob(id), null,
788                    outCharacteristics));
789    }
790
791
792    public void testExportRsa() throws Exception {
793        String name = "test";
794        generateRsaKey(name);
795        ExportResult result = mKeyStore.exportKey(name, KeymasterDefs.KM_KEY_FORMAT_X509, null,
796                null);
797        assertEquals("Export success", KeyStore.NO_ERROR, result.resultCode);
798        // TODO: Verify we have an RSA public key that's well formed.
799    }
800
801    public void testAesOcbEncryptSuccess() throws Exception {
802        String name = "test";
803        KeymasterArguments args = new KeymasterArguments();
804        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
805        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
806        args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
807        args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
808        args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
809        args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_OCB);
810        args.addInt(KeymasterDefs.KM_TAG_CHUNK_LENGTH, 4096);
811        args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, 16);
812        args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
813
814        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
815        int rc = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
816        assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
817
818        KeymasterArguments out = new KeymasterArguments();
819        args = new KeymasterArguments();
820        OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
821                true, args, null, out);
822        IBinder token = result.token;
823        assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
824        result = mKeyStore.update(token, null, new byte[] {0x01, 0x02, 0x03, 0x04});
825        assertEquals("Update should succeed", KeyStore.NO_ERROR, result.resultCode);
826        assertEquals("Finish should succeed", KeyStore.NO_ERROR,
827                mKeyStore.finish(token, null, null).resultCode);
828    }
829
830    public void testBadToken() throws Exception {
831        IBinder token = new Binder();
832        OperationResult result = mKeyStore.update(token, null, new byte[] {0x01});
833        assertEquals("Update with invalid token should fail",
834                KeymasterDefs.KM_ERROR_INVALID_OPERATION_HANDLE, result.resultCode);
835    }
836
837    private int importAesKey(String name, byte[] key, int size, int mode) {
838        KeymasterArguments args = new KeymasterArguments();
839        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
840        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
841        args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
842        args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
843        args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, mode);
844        args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, size);
845        args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
846        return mKeyStore.importKey(name, args, KeymasterDefs.KM_KEY_FORMAT_RAW, key, 0,
847                new KeyCharacteristics());
848    }
849    private byte[] doOperation(String name, int purpose, byte[] in, KeymasterArguments beginArgs) {
850        KeymasterArguments out = new KeymasterArguments();
851        OperationResult result = mKeyStore.begin(name, purpose,
852                true, beginArgs, null, out);
853        assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
854        IBinder token = result.token;
855        result = mKeyStore.update(token, null, in);
856        assertEquals("Update should succeed", KeyStore.NO_ERROR, result.resultCode);
857        assertEquals("All data should be consumed", in.length, result.inputConsumed);
858        assertEquals("Finish should succeed", KeyStore.NO_ERROR,
859                mKeyStore.finish(token, null, null).resultCode);
860        return result.output;
861    }
862
863    public void testImportAes() throws Exception {
864        int result = importAesKey("aes", AES256_BYTES, 256, KeymasterDefs.KM_MODE_ECB);
865        assertEquals("import should succeed", KeyStore.NO_ERROR, result);
866        mKeyStore.delete("aes");
867    }
868
869    public void testAes256Ecb() throws Exception {
870        byte[] key =
871                hexToBytes("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
872        String name = "aes";
873        assertEquals(KeyStore.NO_ERROR, importAesKey(name, key, 256, KeymasterDefs.KM_MODE_ECB));
874        byte[][] testVectors = new byte[][] {
875            hexToBytes("6bc1bee22e409f96e93d7e117393172a"),
876            hexToBytes("ae2d8a571e03ac9c9eb76fac45af8e51"),
877            hexToBytes("30c81c46a35ce411e5fbc1191a0a52ef"),
878            hexToBytes("f69f2445df4f9b17ad2b417be66c3710")};
879        byte[][] cipherVectors = new byte[][] {
880            hexToBytes("f3eed1bdb5d2a03c064b5a7e3db181f8"),
881            hexToBytes("591ccb10d410ed26dc5ba74a31362870"),
882            hexToBytes("b6ed21b99ca6f4f9f153e7b1beafed1d"),
883            hexToBytes("23304b7a39f9f3ff067d8d8f9e24ecc7")};
884        for (int i = 0; i < testVectors.length; i++) {
885            byte[] cipherText = doOperation(name, KeymasterDefs.KM_PURPOSE_ENCRYPT, testVectors[i],
886                    new KeymasterArguments());
887            MoreAsserts.assertEquals(cipherVectors[i], cipherText);
888        }
889        for (int i = 0; i < testVectors.length; i++) {
890            byte[] plainText = doOperation(name, KeymasterDefs.KM_PURPOSE_DECRYPT,
891                    cipherVectors[i], new KeymasterArguments());
892            MoreAsserts.assertEquals(testVectors[i], plainText);
893        }
894    }
895
896    // This is a very implementation specific test and should be thrown out eventually, however it
897    // is nice for now to test that keystore is properly pruning operations.
898    public void testOperationPruning() throws Exception {
899        String name = "test";
900        KeymasterArguments args = new KeymasterArguments();
901        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
902        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
903        args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
904        args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
905        args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
906        args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_OCB);
907        args.addInt(KeymasterDefs.KM_TAG_CHUNK_LENGTH, 4096);
908        args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, 16);
909        args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
910
911        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
912        int rc = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
913        assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
914
915        KeymasterArguments out = new KeymasterArguments();
916        args = new KeymasterArguments();
917        OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
918                true, args, null, out);
919        assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
920        IBinder first = result.token;
921        // Implementation detail: softkeymaster supports 16 concurrent operations
922        for (int i = 0; i < 16; i++) {
923            result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT, true, args, null,
924                    out);
925            assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
926        }
927        // At this point the first operation should be pruned.
928        assertEquals("Operation should be pruned", KeymasterDefs.KM_ERROR_INVALID_OPERATION_HANDLE,
929                mKeyStore.update(first, null, new byte[] {0x01}).resultCode);
930    }
931
932    public void testAuthNeeded() throws Exception {
933        String name = "test";
934        KeymasterArguments args = new KeymasterArguments();
935        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
936        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
937        args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
938        args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
939        args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
940        args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_OCB);
941        args.addInt(KeymasterDefs.KM_TAG_CHUNK_LENGTH, 4096);
942        args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, 16);
943        args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 1);
944
945        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
946        int rc = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
947        KeymasterArguments out = new KeymasterArguments();
948        assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
949        OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
950                true, args, null, out);
951        assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
952        IBinder token = result.token;
953        result = mKeyStore.update(token, null, new byte[] {0x01, 0x02, 0x03, 0x04});
954        assertEquals("Update should require authorization",
955                KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED, result.resultCode);
956    }
957}
958