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