blob: b1f330f355ef9db12cb96f7e0eb3fd7da42bc69f [file] [log] [blame]
Alex Klyubin5927c9f2015-04-10 13:28:03 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.security;
18
19import android.annotation.IntDef;
20import android.security.keymaster.KeymasterDefs;
21
22import libcore.util.EmptyArray;
23
24import java.lang.annotation.Retention;
25import java.lang.annotation.RetentionPolicy;
26import java.util.Collection;
27
28/**
29 * Properties of {@code AndroidKeyStore} keys.
Alex Klyubin5927c9f2015-04-10 13:28:03 -070030 */
31public abstract class KeyStoreKeyProperties {
32 private KeyStoreKeyProperties() {}
33
34 @Retention(RetentionPolicy.SOURCE)
35 @IntDef(flag = true,
36 value = {Purpose.ENCRYPT, Purpose.DECRYPT, Purpose.SIGN, Purpose.VERIFY})
37 public @interface PurposeEnum {}
38
39 /**
40 * Purpose of key.
41 */
42 public static abstract class Purpose {
43 private Purpose() {}
44
45 /**
46 * Purpose: encryption.
47 */
48 public static final int ENCRYPT = 1 << 0;
49
50 /**
51 * Purpose: decryption.
52 */
53 public static final int DECRYPT = 1 << 1;
54
55 /**
56 * Purpose: signing.
57 */
58 public static final int SIGN = 1 << 2;
59
60 /**
61 * Purpose: signature verification.
62 */
63 public static final int VERIFY = 1 << 3;
64
65 /**
66 * @hide
67 */
68 public static int toKeymaster(@PurposeEnum int purpose) {
69 switch (purpose) {
70 case ENCRYPT:
71 return KeymasterDefs.KM_PURPOSE_ENCRYPT;
72 case DECRYPT:
73 return KeymasterDefs.KM_PURPOSE_DECRYPT;
74 case SIGN:
75 return KeymasterDefs.KM_PURPOSE_SIGN;
76 case VERIFY:
77 return KeymasterDefs.KM_PURPOSE_VERIFY;
78 default:
79 throw new IllegalArgumentException("Unknown purpose: " + purpose);
80 }
81 }
82
83 /**
84 * @hide
85 */
86 public static @PurposeEnum int fromKeymaster(int purpose) {
87 switch (purpose) {
88 case KeymasterDefs.KM_PURPOSE_ENCRYPT:
89 return ENCRYPT;
90 case KeymasterDefs.KM_PURPOSE_DECRYPT:
91 return DECRYPT;
92 case KeymasterDefs.KM_PURPOSE_SIGN:
93 return SIGN;
94 case KeymasterDefs.KM_PURPOSE_VERIFY:
95 return VERIFY;
96 default:
97 throw new IllegalArgumentException("Unknown purpose: " + purpose);
98 }
99 }
100
101 /**
102 * @hide
103 */
104 public static int[] allToKeymaster(@PurposeEnum int purposes) {
105 int[] result = getSetFlags(purposes);
106 for (int i = 0; i < result.length; i++) {
107 result[i] = toKeymaster(result[i]);
108 }
109 return result;
110 }
111
112 /**
113 * @hide
114 */
115 public static @PurposeEnum int allFromKeymaster(Collection<Integer> purposes) {
116 @PurposeEnum int result = 0;
117 for (int keymasterPurpose : purposes) {
118 result |= fromKeymaster(keymasterPurpose);
119 }
120 return result;
121 }
122 }
123
124 @Retention(RetentionPolicy.SOURCE)
125 @IntDef(flag = true,
Alex Klyubinfbf14722015-04-13 10:54:53 -0700126 value = {UserAuthenticator.LOCK_SCREEN, UserAuthenticator.FINGERPRINT_READER})
Alex Klyubin5927c9f2015-04-10 13:28:03 -0700127 public @interface UserAuthenticatorEnum {}
128
129 /**
130 * User authenticators which can be used to restrict/protect access to keys.
131 */
132 public static abstract class UserAuthenticator {
133 private UserAuthenticator() {}
134
135 /** Lock screen. */
136 public static final int LOCK_SCREEN = 1 << 0;
137
Alex Klyubinfbf14722015-04-13 10:54:53 -0700138 /** Fingerprint reader/sensor. */
139 public static final int FINGERPRINT_READER = 1 << 1;
140
Alex Klyubin5927c9f2015-04-10 13:28:03 -0700141 /**
142 * @hide
143 */
144 public static int toKeymaster(@UserAuthenticatorEnum int userAuthenticator) {
145 switch (userAuthenticator) {
146 case LOCK_SCREEN:
147 return KeymasterDefs.HW_AUTH_PASSWORD;
Alex Klyubinfbf14722015-04-13 10:54:53 -0700148 case FINGERPRINT_READER:
149 return KeymasterDefs.HW_AUTH_FINGERPRINT;
Alex Klyubin5927c9f2015-04-10 13:28:03 -0700150 default:
151 throw new IllegalArgumentException(
152 "Unknown user authenticator: " + userAuthenticator);
153 }
154 }
155
156 /**
157 * @hide
158 */
159 public static @UserAuthenticatorEnum int fromKeymaster(int userAuthenticator) {
160 switch (userAuthenticator) {
161 case KeymasterDefs.HW_AUTH_PASSWORD:
162 return LOCK_SCREEN;
Alex Klyubinfbf14722015-04-13 10:54:53 -0700163 case KeymasterDefs.HW_AUTH_FINGERPRINT:
164 return FINGERPRINT_READER;
Alex Klyubin5927c9f2015-04-10 13:28:03 -0700165 default:
166 throw new IllegalArgumentException(
167 "Unknown user authenticator: " + userAuthenticator);
168 }
169 }
170
171 /**
172 * @hide
173 */
174 public static int allToKeymaster(@UserAuthenticatorEnum int userAuthenticators) {
175 int result = 0;
176 int userAuthenticator = 1;
177 while (userAuthenticators != 0) {
178 if ((userAuthenticators & 1) != 0) {
179 result |= toKeymaster(userAuthenticator);
180 }
181 userAuthenticators >>>= 1;
182 userAuthenticator <<= 1;
183 }
184 return result;
185 }
186
187 /**
188 * @hide
189 */
190 public static @UserAuthenticatorEnum int allFromKeymaster(int userAuthenticators) {
191 @UserAuthenticatorEnum int result = 0;
192 int userAuthenticator = 1;
193 while (userAuthenticators != 0) {
194 if ((userAuthenticators & 1) != 0) {
195 result |= fromKeymaster(userAuthenticator);
196 }
197 userAuthenticators >>>= 1;
198 userAuthenticator <<= 1;
199 }
200 return result;
201 }
202
203 /**
204 * @hide
205 */
206 public static String toString(@UserAuthenticatorEnum int userAuthenticator) {
207 switch (userAuthenticator) {
208 case LOCK_SCREEN:
209 return "LOCK_SCREEN";
Alex Klyubinfbf14722015-04-13 10:54:53 -0700210 case FINGERPRINT_READER:
211 return "FINGERPRINT_READER";
Alex Klyubin5927c9f2015-04-10 13:28:03 -0700212 default:
213 throw new IllegalArgumentException(
214 "Unknown user authenticator: " + userAuthenticator);
215 }
216 }
217 }
218
219 @Retention(RetentionPolicy.SOURCE)
220 @IntDef({Origin.GENERATED, Origin.IMPORTED})
221 public @interface OriginEnum {}
222
223 /**
224 * Origin of the key.
225 */
226 public static abstract class Origin {
227 private Origin() {}
228
229 /** Key was generated inside AndroidKeyStore. */
230 public static final int GENERATED = 1 << 0;
231
232 /** Key was imported into AndroidKeyStore. */
233 public static final int IMPORTED = 1 << 1;
234
235 /**
236 * @hide
237 */
238 public static @OriginEnum int fromKeymaster(int origin) {
239 switch (origin) {
240 case KeymasterDefs.KM_ORIGIN_HARDWARE:
241 return GENERATED;
242 case KeymasterDefs.KM_ORIGIN_IMPORTED:
243 return IMPORTED;
244 default:
245 throw new IllegalArgumentException("Unknown origin: " + origin);
246 }
247 }
248 }
249
250 private static int[] getSetFlags(int flags) {
251 if (flags == 0) {
252 return EmptyArray.INT;
253 }
254 int result[] = new int[getSetBitCount(flags)];
255 int resultOffset = 0;
256 int flag = 1;
257 while (flags != 0) {
258 if ((flags & 1) != 0) {
259 result[resultOffset] = flag;
260 resultOffset++;
261 }
262 flags >>>= 1;
263 flag <<= 1;
264 }
265 return result;
266 }
267
268 private static int getSetBitCount(int value) {
269 if (value == 0) {
270 return 0;
271 }
272 int result = 0;
273 while (value != 0) {
274 if ((value & 1) != 0) {
275 result++;
276 }
277 value >>>= 1;
278 }
279 return result;
280 }
281}