15927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin/* 25927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin * Copyright (C) 2015 The Android Open Source Project 35927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin * 45927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin * Licensed under the Apache License, Version 2.0 (the "License"); 55927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin * you may not use this file except in compliance with the License. 65927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin * You may obtain a copy of the License at 75927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin * 85927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin * http://www.apache.org/licenses/LICENSE-2.0 95927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin * 105927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin * Unless required by applicable law or agreed to in writing, software 115927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin * distributed under the License is distributed on an "AS IS" BASIS, 125927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin * See the License for the specific language governing permissions and 145927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin * limitations under the License. 155927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin */ 165927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinpackage android.security.keystore; 185927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 195927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubinimport android.annotation.IntDef; 2054bb1596e470144932943046ec7a99551d020ba0Alex Klyubinimport android.annotation.NonNull; 2154bb1596e470144932943046ec7a99551d020ba0Alex Klyubinimport android.annotation.Nullable; 224d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubinimport android.annotation.StringDef; 235927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubinimport android.security.keymaster.KeymasterDefs; 245927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 255927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubinimport libcore.util.EmptyArray; 265927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 275927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubinimport java.lang.annotation.Retention; 285927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubinimport java.lang.annotation.RetentionPolicy; 295927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubinimport java.util.Collection; 304d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubinimport java.util.Locale; 314d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 325927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin/** 333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Properties of <a href="{@docRoot}training/articles/keystore.html">Android Keystore</a> keys. 345927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin */ 353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinpublic abstract class KeyProperties { 363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private KeyProperties() {} 375927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 38dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin /** 39dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin * @hide 40dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin */ 415927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin @Retention(RetentionPolicy.SOURCE) 425927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin @IntDef(flag = true, 43622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin value = { 44622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin PURPOSE_ENCRYPT, 45622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin PURPOSE_DECRYPT, 46622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin PURPOSE_SIGN, 47622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin PURPOSE_VERIFY, 48622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin }) 495927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin public @interface PurposeEnum {} 505927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 515927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin /** 52622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * Purpose of key: encryption. 535927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin */ 54622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final int PURPOSE_ENCRYPT = 1 << 0; 555927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 56622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 57622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * Purpose of key: decryption. 58622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 59622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final int PURPOSE_DECRYPT = 1 << 1; 605927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 61622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 62622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * Purpose of key: signing or generating a Message Authentication Code (MAC). 63622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 64622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final int PURPOSE_SIGN = 1 << 2; 655927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 66622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 67622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * Purpose of key: signature or Message Authentication Code (MAC) verification. 68622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 69622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final int PURPOSE_VERIFY = 1 << 3; 705927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @hide 733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static abstract class Purpose { 75622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin private Purpose() {} 765927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static int toKeymaster(@PurposeEnum int purpose) { 785927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin switch (purpose) { 79622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin case PURPOSE_ENCRYPT: 805927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin return KeymasterDefs.KM_PURPOSE_ENCRYPT; 81622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin case PURPOSE_DECRYPT: 825927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin return KeymasterDefs.KM_PURPOSE_DECRYPT; 83622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin case PURPOSE_SIGN: 845927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin return KeymasterDefs.KM_PURPOSE_SIGN; 85622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin case PURPOSE_VERIFY: 865927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin return KeymasterDefs.KM_PURPOSE_VERIFY; 875927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin default: 885927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin throw new IllegalArgumentException("Unknown purpose: " + purpose); 895927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 905927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 915927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static @PurposeEnum int fromKeymaster(int purpose) { 935927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin switch (purpose) { 945927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin case KeymasterDefs.KM_PURPOSE_ENCRYPT: 95622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return PURPOSE_ENCRYPT; 965927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin case KeymasterDefs.KM_PURPOSE_DECRYPT: 97622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return PURPOSE_DECRYPT; 985927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin case KeymasterDefs.KM_PURPOSE_SIGN: 99622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return PURPOSE_SIGN; 1005927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin case KeymasterDefs.KM_PURPOSE_VERIFY: 101622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return PURPOSE_VERIFY; 1025927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin default: 1035927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin throw new IllegalArgumentException("Unknown purpose: " + purpose); 1045927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 1055927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 1065927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 10754bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 1083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static int[] allToKeymaster(@PurposeEnum int purposes) { 1095927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin int[] result = getSetFlags(purposes); 1105927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin for (int i = 0; i < result.length; i++) { 1115927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin result[i] = toKeymaster(result[i]); 1125927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 1135927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin return result; 1145927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 1155927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 1163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static @PurposeEnum int allFromKeymaster(@NonNull Collection<Integer> purposes) { 1175927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin @PurposeEnum int result = 0; 1185927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin for (int keymasterPurpose : purposes) { 1195927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin result |= fromKeymaster(keymasterPurpose); 1205927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 1215927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin return result; 1225927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 1234d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 1244d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 125dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin /** 126dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin * @hide 127dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin */ 1284d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin @Retention(RetentionPolicy.SOURCE) 1294d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin @StringDef({ 130622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin KEY_ALGORITHM_RSA, 131622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin KEY_ALGORITHM_EC, 132622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin KEY_ALGORITHM_AES, 133622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin KEY_ALGORITHM_HMAC_SHA1, 134622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin KEY_ALGORITHM_HMAC_SHA224, 135622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin KEY_ALGORITHM_HMAC_SHA256, 136622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin KEY_ALGORITHM_HMAC_SHA384, 137622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin KEY_ALGORITHM_HMAC_SHA512, 1384d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin }) 139622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public @interface KeyAlgorithmEnum {} 1404d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 141622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Rivest Shamir Adleman (RSA) key. */ 142622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String KEY_ALGORITHM_RSA = "RSA"; 1434d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 144622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Elliptic Curve (EC) Cryptography key. */ 145622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String KEY_ALGORITHM_EC = "EC"; 1464d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 147622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Advanced Encryption Standard (AES) key. */ 148622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String KEY_ALGORITHM_AES = "AES"; 1494d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 150622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-1 as the hash. */ 151622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String KEY_ALGORITHM_HMAC_SHA1 = "HmacSHA1"; 1524d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 153622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-224 as the hash. */ 154622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String KEY_ALGORITHM_HMAC_SHA224 = "HmacSHA224"; 1554d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 156622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-256 as the hash. */ 157622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String KEY_ALGORITHM_HMAC_SHA256 = "HmacSHA256"; 1584d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 159622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-384 as the hash. */ 160622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String KEY_ALGORITHM_HMAC_SHA384 = "HmacSHA384"; 1614d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 162622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-512 as the hash. */ 163622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String KEY_ALGORITHM_HMAC_SHA512 = "HmacSHA512"; 1644d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 1653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 1663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @hide 1673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 1683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static abstract class KeyAlgorithm { 169622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin private KeyAlgorithm() {} 1704d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 1713ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin public static int toKeymasterAsymmetricKeyAlgorithm( 1723ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin @NonNull @KeyAlgorithmEnum String algorithm) { 1733ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin if (KEY_ALGORITHM_EC.equalsIgnoreCase(algorithm)) { 1743ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return KeymasterDefs.KM_ALGORITHM_EC; 1753ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin } else if (KEY_ALGORITHM_RSA.equalsIgnoreCase(algorithm)) { 1763ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return KeymasterDefs.KM_ALGORITHM_RSA; 1773ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin } else { 1783ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin throw new IllegalArgumentException("Unsupported key algorithm: " + algorithm); 1793ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin } 1803ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin } 1813ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin 1823ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin @NonNull 1833ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin public static @KeyAlgorithmEnum String fromKeymasterAsymmetricKeyAlgorithm( 1843ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin int keymasterAlgorithm) { 1853ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin switch (keymasterAlgorithm) { 1863ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin case KeymasterDefs.KM_ALGORITHM_EC: 1873ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return KEY_ALGORITHM_EC; 1883ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin case KeymasterDefs.KM_ALGORITHM_RSA: 1893ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return KEY_ALGORITHM_RSA; 1903ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin default: 1913ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin throw new IllegalArgumentException( 1923ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin "Unsupported key algorithm: " + keymasterAlgorithm); 1933ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin } 1943ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin } 1953ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin 1963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static int toKeymasterSecretKeyAlgorithm( 1973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull @KeyAlgorithmEnum String algorithm) { 198622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin if (KEY_ALGORITHM_AES.equalsIgnoreCase(algorithm)) { 1994d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_ALGORITHM_AES; 2004d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } else if (algorithm.toUpperCase(Locale.US).startsWith("HMAC")) { 2014d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_ALGORITHM_HMAC; 2024d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } else { 2034d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin throw new IllegalArgumentException( 2044d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin "Unsupported secret key algorithm: " + algorithm); 2054d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 2064d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 2074d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 20854bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 2093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static @KeyAlgorithmEnum String fromKeymasterSecretKeyAlgorithm( 2104d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin int keymasterAlgorithm, int keymasterDigest) { 2114d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin switch (keymasterAlgorithm) { 2124d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_ALGORITHM_AES: 213622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return KEY_ALGORITHM_AES; 2144d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_ALGORITHM_HMAC: 2154d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin switch (keymasterDigest) { 2164d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_DIGEST_SHA1: 217622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return KEY_ALGORITHM_HMAC_SHA1; 2184d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_DIGEST_SHA_2_224: 219622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return KEY_ALGORITHM_HMAC_SHA224; 2204d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_DIGEST_SHA_2_256: 221622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return KEY_ALGORITHM_HMAC_SHA256; 2224d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_DIGEST_SHA_2_384: 223622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return KEY_ALGORITHM_HMAC_SHA384; 2244d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_DIGEST_SHA_2_512: 225622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return KEY_ALGORITHM_HMAC_SHA512; 2264d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin default: 2274d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin throw new IllegalArgumentException("Unsupported HMAC digest: " 2284d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin + Digest.fromKeymaster(keymasterDigest)); 2294d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 2304d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin default: 2314d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin throw new IllegalArgumentException( 232622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin "Unsupported key algorithm: " + keymasterAlgorithm); 2334d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 2344d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 2354d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 2364d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin /** 2374d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin * @hide 2384d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin * 2394d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin * @return keymaster digest or {@code -1} if the algorithm does not involve a digest. 2404d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin */ 2413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static int toKeymasterDigest(@NonNull @KeyAlgorithmEnum String algorithm) { 2424d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin String algorithmUpper = algorithm.toUpperCase(Locale.US); 2434d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin if (algorithmUpper.startsWith("HMAC")) { 2444d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin String digestUpper = algorithmUpper.substring("HMAC".length()); 2454d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin switch (digestUpper) { 2464d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case "SHA1": 2474d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_DIGEST_SHA1; 2484d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case "SHA224": 2494d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_DIGEST_SHA_2_224; 2504d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case "SHA256": 2514d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_DIGEST_SHA_2_256; 2524d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case "SHA384": 2534d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_DIGEST_SHA_2_384; 2544d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case "SHA512": 2554d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_DIGEST_SHA_2_512; 2564d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin default: 2574d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin throw new IllegalArgumentException( 2584d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin "Unsupported HMAC digest: " + digestUpper); 2594d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 2604d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } else { 2614d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return -1; 2624d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 2634d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 2644d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 2654d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 266dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin /** 267dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin * @hide 268dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin */ 2694d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin @Retention(RetentionPolicy.SOURCE) 2704d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin @StringDef({ 271622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin BLOCK_MODE_ECB, 272622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin BLOCK_MODE_CBC, 273622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin BLOCK_MODE_CTR, 274622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin BLOCK_MODE_GCM, 2754d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin }) 2764d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin public @interface BlockModeEnum {} 2774d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 278622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Electronic Codebook (ECB) block mode. */ 279622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String BLOCK_MODE_ECB = "ECB"; 2804d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 281622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Cipher Block Chaining (CBC) block mode. */ 282622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String BLOCK_MODE_CBC = "CBC"; 2834d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 284622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Counter (CTR) block mode. */ 285622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String BLOCK_MODE_CTR = "CTR"; 2864d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 287622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Galois/Counter Mode (GCM) block mode. */ 288622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String BLOCK_MODE_GCM = "GCM"; 2894d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 2903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 2913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @hide 2923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 2933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static abstract class BlockMode { 294622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin private BlockMode() {} 2954d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 2963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static int toKeymaster(@NonNull @BlockModeEnum String blockMode) { 297622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin if (BLOCK_MODE_ECB.equalsIgnoreCase(blockMode)) { 2984d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_MODE_ECB; 299622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin } else if (BLOCK_MODE_CBC.equalsIgnoreCase(blockMode)) { 3004d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_MODE_CBC; 301622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin } else if (BLOCK_MODE_CTR.equalsIgnoreCase(blockMode)) { 3024d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_MODE_CTR; 303622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin } else if (BLOCK_MODE_GCM.equalsIgnoreCase(blockMode)) { 3044d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_MODE_GCM; 3054d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } else { 3064d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin throw new IllegalArgumentException("Unsupported block mode: " + blockMode); 3074d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 3084d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 3094d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 31054bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 3113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static @BlockModeEnum String fromKeymaster(int blockMode) { 3124d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin switch (blockMode) { 3134d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_MODE_ECB: 314622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return BLOCK_MODE_ECB; 3154d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_MODE_CBC: 316622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return BLOCK_MODE_CBC; 3174d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_MODE_CTR: 318622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return BLOCK_MODE_CTR; 3194d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_MODE_GCM: 320622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return BLOCK_MODE_GCM; 3214d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin default: 3224d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin throw new IllegalArgumentException("Unsupported block mode: " + blockMode); 3234d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 3244d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 3254d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 32654bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 3273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static @BlockModeEnum String[] allFromKeymaster( 3283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull Collection<Integer> blockModes) { 3294d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin if ((blockModes == null) || (blockModes.isEmpty())) { 3304d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return EmptyArray.STRING; 3314d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 3324d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin @BlockModeEnum String[] result = new String[blockModes.size()]; 3334d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin int offset = 0; 3344d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin for (int blockMode : blockModes) { 3354d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin result[offset] = fromKeymaster(blockMode); 3364d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin offset++; 3374d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 3384d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return result; 3394d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 3404d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 3413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static int[] allToKeymaster(@Nullable @BlockModeEnum String[] blockModes) { 3424d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin if ((blockModes == null) || (blockModes.length == 0)) { 3434d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return EmptyArray.INT; 3444d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 3454d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin int[] result = new int[blockModes.length]; 3464d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin for (int i = 0; i < blockModes.length; i++) { 3474d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin result[i] = toKeymaster(blockModes[i]); 3484d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 3494d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return result; 3504d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 3514d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 3524d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 353dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin /** 354dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin * @hide 355dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin */ 3564d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin @Retention(RetentionPolicy.SOURCE) 3574d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin @StringDef({ 358622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin ENCRYPTION_PADDING_NONE, 359622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin ENCRYPTION_PADDING_PKCS7, 360622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin ENCRYPTION_PADDING_RSA_PKCS1, 361622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin ENCRYPTION_PADDING_RSA_OAEP, 3624d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin }) 3634d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin public @interface EncryptionPaddingEnum {} 3644d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 3654d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin /** 366622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * No encryption padding. 3674d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin */ 368622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String ENCRYPTION_PADDING_NONE = "NoPadding"; 3694d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 370622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 371622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * PKCS#7 encryption padding scheme. 372622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 373622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String ENCRYPTION_PADDING_PKCS7 = "PKCS7Padding"; 3744d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 375622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 376622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * RSA PKCS#1 v1.5 padding scheme for encryption. 377622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 378622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String ENCRYPTION_PADDING_RSA_PKCS1 = "PKCS1Padding"; 3794d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 380622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 381622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * RSA Optimal Asymmetric Encryption Padding (OAEP) scheme. 382622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 383622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String ENCRYPTION_PADDING_RSA_OAEP = "OAEPPadding"; 3844d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 3853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @hide 3873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static abstract class EncryptionPadding { 389622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin private EncryptionPadding() {} 3904d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 3913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static int toKeymaster(@NonNull @EncryptionPaddingEnum String padding) { 392622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin if (ENCRYPTION_PADDING_NONE.equalsIgnoreCase(padding)) { 3934d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_PAD_NONE; 394622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin } else if (ENCRYPTION_PADDING_PKCS7.equalsIgnoreCase(padding)) { 3954d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_PAD_PKCS7; 396622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin } else if (ENCRYPTION_PADDING_RSA_PKCS1.equalsIgnoreCase(padding)) { 3974d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT; 398622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin } else if (ENCRYPTION_PADDING_RSA_OAEP.equalsIgnoreCase(padding)) { 3994d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_PAD_RSA_OAEP; 4004d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } else { 4014d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin throw new IllegalArgumentException( 4024d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin "Unsupported encryption padding scheme: " + padding); 4034d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4044d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4054d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 40654bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 4073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static @EncryptionPaddingEnum String fromKeymaster(int padding) { 4084d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin switch (padding) { 4094d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_PAD_NONE: 410622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return ENCRYPTION_PADDING_NONE; 4114d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_PAD_PKCS7: 412622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return ENCRYPTION_PADDING_PKCS7; 4134d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT: 414622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return ENCRYPTION_PADDING_RSA_PKCS1; 4154d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_PAD_RSA_OAEP: 416622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return ENCRYPTION_PADDING_RSA_OAEP; 4174d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin default: 4184d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin throw new IllegalArgumentException( 4194d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin "Unsupported encryption padding: " + padding); 4204d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4214d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4224d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 42354bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 4243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static int[] allToKeymaster(@Nullable @EncryptionPaddingEnum String[] paddings) { 4254d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin if ((paddings == null) || (paddings.length == 0)) { 4264d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return EmptyArray.INT; 4274d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4284d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin int[] result = new int[paddings.length]; 4294d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin for (int i = 0; i < paddings.length; i++) { 4304d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin result[i] = toKeymaster(paddings[i]); 4314d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4324d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return result; 4334d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4344d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4354d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 436dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin /** 437dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin * @hide 438dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin */ 4394d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin @Retention(RetentionPolicy.SOURCE) 4404d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin @StringDef({ 441622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin SIGNATURE_PADDING_RSA_PKCS1, 442622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin SIGNATURE_PADDING_RSA_PSS, 4434d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin }) 4444d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin public @interface SignaturePaddingEnum {} 4454d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 4464d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin /** 447622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * RSA PKCS#1 v1.5 padding for signatures. 4484d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin */ 449622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String SIGNATURE_PADDING_RSA_PKCS1 = "PKCS1"; 4504d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 451622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 452622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * RSA PKCS#1 v2.1 Probabilistic Signature Scheme (PSS) padding. 453622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 454622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String SIGNATURE_PADDING_RSA_PSS = "PSS"; 4554d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 456622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin static abstract class SignaturePadding { 457622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin private SignaturePadding() {} 4584d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 45954bb1596e470144932943046ec7a99551d020ba0Alex Klyubin static int toKeymaster(@NonNull @SignaturePaddingEnum String padding) { 4604d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin switch (padding.toUpperCase(Locale.US)) { 461622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin case SIGNATURE_PADDING_RSA_PKCS1: 4624d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN; 463622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin case SIGNATURE_PADDING_RSA_PSS: 4644d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_PAD_RSA_PSS; 4654d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin default: 4664d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin throw new IllegalArgumentException( 4674d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin "Unsupported signature padding scheme: " + padding); 4684d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4694d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4704d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 47154bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 4724d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin static @SignaturePaddingEnum String fromKeymaster(int padding) { 4734d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin switch (padding) { 4744d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN: 475622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return SIGNATURE_PADDING_RSA_PKCS1; 4764d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_PAD_RSA_PSS: 477622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return SIGNATURE_PADDING_RSA_PSS; 4784d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin default: 4794d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin throw new IllegalArgumentException("Unsupported signature padding: " + padding); 4804d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4814d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4824d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 48354bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 48454bb1596e470144932943046ec7a99551d020ba0Alex Klyubin static int[] allToKeymaster(@Nullable @SignaturePaddingEnum String[] paddings) { 4854d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin if ((paddings == null) || (paddings.length == 0)) { 4864d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return EmptyArray.INT; 4874d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4884d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin int[] result = new int[paddings.length]; 4894d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin for (int i = 0; i < paddings.length; i++) { 4904d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin result[i] = toKeymaster(paddings[i]); 4914d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4924d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return result; 4934d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4944d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 4954d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 496dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin /** 497dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin * @hide 498dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin */ 4994d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin @Retention(RetentionPolicy.SOURCE) 5004d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin @StringDef({ 501622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin DIGEST_NONE, 502622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin DIGEST_MD5, 503622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin DIGEST_SHA1, 504622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin DIGEST_SHA224, 505622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin DIGEST_SHA256, 506622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin DIGEST_SHA384, 507622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin DIGEST_SHA512, 5084d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin }) 5094d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin public @interface DigestEnum {} 5104d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 5114d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin /** 512622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * No digest: sign/authenticate the raw message. 5134d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin */ 514622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String DIGEST_NONE = "NONE"; 5154d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 516622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 517622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * MD5 digest. 518622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 519622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String DIGEST_MD5 = "MD5"; 5204d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 521622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 522622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * SHA-1 digest. 523622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 524622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String DIGEST_SHA1 = "SHA-1"; 5254d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 526622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 527622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * SHA-2 224 (aka SHA-224) digest. 528622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 529622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String DIGEST_SHA224 = "SHA-224"; 5304d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 531622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 532622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * SHA-2 256 (aka SHA-256) digest. 533622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 534622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String DIGEST_SHA256 = "SHA-256"; 5354d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 536622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 537622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * SHA-2 384 (aka SHA-384) digest. 538622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 539622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String DIGEST_SHA384 = "SHA-384"; 5404d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 541622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 542622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * SHA-2 512 (aka SHA-512) digest. 543622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 544622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final String DIGEST_SHA512 = "SHA-512"; 5454d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 5463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 5473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @hide 5483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 5493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static abstract class Digest { 550622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin private Digest() {} 5514d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 5523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static int toKeymaster(@NonNull @DigestEnum String digest) { 5534d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin switch (digest.toUpperCase(Locale.US)) { 554622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin case DIGEST_SHA1: 5554d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_DIGEST_SHA1; 556622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin case DIGEST_SHA224: 5574d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_DIGEST_SHA_2_224; 558622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin case DIGEST_SHA256: 5594d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_DIGEST_SHA_2_256; 560622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin case DIGEST_SHA384: 5614d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_DIGEST_SHA_2_384; 562622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin case DIGEST_SHA512: 5634d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_DIGEST_SHA_2_512; 564622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin case DIGEST_NONE: 5654d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_DIGEST_NONE; 566622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin case DIGEST_MD5: 5674d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return KeymasterDefs.KM_DIGEST_MD5; 5684d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin default: 5694d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin throw new IllegalArgumentException("Unsupported digest algorithm: " + digest); 5704d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 5714d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 5724d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 57354bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 5743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static @DigestEnum String fromKeymaster(int digest) { 5754d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin switch (digest) { 5764d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_DIGEST_NONE: 577622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return DIGEST_NONE; 5784d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_DIGEST_MD5: 579622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return DIGEST_MD5; 5804d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_DIGEST_SHA1: 581622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return DIGEST_SHA1; 5824d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_DIGEST_SHA_2_224: 583622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return DIGEST_SHA224; 5844d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_DIGEST_SHA_2_256: 585622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return DIGEST_SHA256; 5864d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_DIGEST_SHA_2_384: 587622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return DIGEST_SHA384; 5884d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin case KeymasterDefs.KM_DIGEST_SHA_2_512: 589622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return DIGEST_SHA512; 5904d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin default: 5914d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin throw new IllegalArgumentException("Unsupported digest algorithm: " + digest); 5923ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin } 5933ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin } 5943ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin 5953ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin @NonNull 5963ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin public static @DigestEnum String fromKeymasterToSignatureAlgorithmDigest(int digest) { 5973ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin switch (digest) { 5983ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin case KeymasterDefs.KM_DIGEST_NONE: 5993ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return "NONE"; 6003ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin case KeymasterDefs.KM_DIGEST_MD5: 6013ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return "MD5"; 6023ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin case KeymasterDefs.KM_DIGEST_SHA1: 6033ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return "SHA1"; 6043ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin case KeymasterDefs.KM_DIGEST_SHA_2_224: 6053ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return "SHA224"; 6063ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin case KeymasterDefs.KM_DIGEST_SHA_2_256: 6073ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return "SHA256"; 6083ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin case KeymasterDefs.KM_DIGEST_SHA_2_384: 6093ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return "SHA384"; 6103ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin case KeymasterDefs.KM_DIGEST_SHA_2_512: 6113ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return "SHA512"; 6123ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin default: 6133ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin throw new IllegalArgumentException("Unsupported digest algorithm: " + digest); 6144d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 6154d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 6164d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 61754bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 6183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static @DigestEnum String[] allFromKeymaster(@NonNull Collection<Integer> digests) { 6194d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin if (digests.isEmpty()) { 6204d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return EmptyArray.STRING; 6214d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 6224d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin String[] result = new String[digests.size()]; 6234d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin int offset = 0; 6244d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin for (int digest : digests) { 6254d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin result[offset] = fromKeymaster(digest); 6264d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin offset++; 6274d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 6284d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return result; 6294d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 6304d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin 63154bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 6323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static int[] allToKeymaster(@Nullable @DigestEnum String[] digests) { 6334d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin if ((digests == null) || (digests.length == 0)) { 6344d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return EmptyArray.INT; 6354d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 6364d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin int[] result = new int[digests.length]; 6374d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin int offset = 0; 6384d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin for (@DigestEnum String digest : digests) { 6394d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin result[offset] = toKeymaster(digest); 6404d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin offset++; 6414d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 6424d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin return result; 6434d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin } 6445927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 6455927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 646dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin /** 647dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin * @hide 648dddd6f73a96a10a07edf486155e3b078380f9146Alex Klyubin */ 6495927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin @Retention(RetentionPolicy.SOURCE) 650622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin @IntDef({ 651622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin ORIGIN_GENERATED, 652622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin ORIGIN_IMPORTED, 653622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin ORIGIN_UNKNOWN, 654622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin }) 6555927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin public @interface OriginEnum {} 6565927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 657622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Key was generated inside AndroidKeyStore. */ 658622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final int ORIGIN_GENERATED = 1 << 0; 6595927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 660622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** Key was imported into AndroidKeyStore. */ 661622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final int ORIGIN_IMPORTED = 1 << 1; 6625927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 663622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin /** 664622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * Origin of the key is unknown. This can occur only for keys backed by an old TEE-backed 665622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * implementation which does not record origin information. 666622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin */ 667622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin public static final int ORIGIN_UNKNOWN = 1 << 2; 6685927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 6693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 6703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @hide 6713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 6723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static abstract class Origin { 673622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin private Origin() {} 67445d27836bde9e641a57b69a1502924a29b9b3bf1Alex Klyubin 6753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public static @OriginEnum int fromKeymaster(int origin) { 6765927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin switch (origin) { 67745d27836bde9e641a57b69a1502924a29b9b3bf1Alex Klyubin case KeymasterDefs.KM_ORIGIN_GENERATED: 678622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return ORIGIN_GENERATED; 6795927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin case KeymasterDefs.KM_ORIGIN_IMPORTED: 680622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return ORIGIN_IMPORTED; 68145d27836bde9e641a57b69a1502924a29b9b3bf1Alex Klyubin case KeymasterDefs.KM_ORIGIN_UNKNOWN: 682622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin return ORIGIN_UNKNOWN; 6835927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin default: 6845927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin throw new IllegalArgumentException("Unknown origin: " + origin); 6855927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 6865927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 6875927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 6885927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 6895927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin private static int[] getSetFlags(int flags) { 6905927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin if (flags == 0) { 6915927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin return EmptyArray.INT; 6925927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 6935927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin int result[] = new int[getSetBitCount(flags)]; 6945927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin int resultOffset = 0; 6955927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin int flag = 1; 6965927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin while (flags != 0) { 6975927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin if ((flags & 1) != 0) { 6985927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin result[resultOffset] = flag; 6995927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin resultOffset++; 7005927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 7015927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin flags >>>= 1; 7025927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin flag <<= 1; 7035927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 7045927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin return result; 7055927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 7065927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin 7075927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin private static int getSetBitCount(int value) { 7085927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin if (value == 0) { 7095927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin return 0; 7105927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 7115927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin int result = 0; 7125927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin while (value != 0) { 7135927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin if ((value & 1) != 0) { 7145927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin result++; 7155927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 7165927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin value >>>= 1; 7175927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 7185927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin return result; 7195927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin } 7205927c9f1b12f597839a664c1c6593114175cbcd8Alex Klyubin} 721