1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.service.persistentdata;
18 
19 import android.annotation.FlaggedApi;
20 import android.annotation.IntDef;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.RequiresPermission;
24 import android.annotation.SuppressLint;
25 import android.annotation.SystemApi;
26 import android.annotation.SystemService;
27 import android.content.Context;
28 import android.os.RemoteException;
29 import android.security.Flags;
30 import android.service.oemlock.OemLockManager;
31 
32 import java.lang.annotation.Retention;
33 import java.lang.annotation.RetentionPolicy;
34 
35 /**
36  * Interface to the persistent data partition.  Provides access to information about the state
37  * of factory reset protection.
38  */
39 @FlaggedApi(Flags.FLAG_FRP_ENFORCEMENT)
40 @SystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE)
41 public class PersistentDataBlockManager {
42     private static final String TAG = PersistentDataBlockManager.class.getSimpleName();
43     private IPersistentDataBlockService sService;
44 
45     /**
46      * Indicates that the device's bootloader lock state is UNKNOWN.
47      *
48      * @hide
49      */
50     @SystemApi
51     public static final int FLASH_LOCK_UNKNOWN = -1;
52     /**
53      * Indicates that the device's bootloader is UNLOCKED.
54      *
55      * @hide
56      */
57     @SystemApi
58     public static final int FLASH_LOCK_UNLOCKED = 0;
59     /**
60      * Indicates that the device's bootloader is LOCKED.
61      *
62      * @hide
63      */
64     @SystemApi
65     public static final int FLASH_LOCK_LOCKED = 1;
66 
67     /**
68      * @removed mistakenly exposed previously
69      *
70      * @hide
71      */
72     @SystemApi
73     @IntDef(prefix = { "FLASH_LOCK_" }, value = {
74             FLASH_LOCK_UNKNOWN,
75             FLASH_LOCK_LOCKED,
76             FLASH_LOCK_UNLOCKED,
77     })
78     @Retention(RetentionPolicy.SOURCE)
79     public @interface FlashLockState {}
80 
81     /**
82      * @hide
83      */
PersistentDataBlockManager(IPersistentDataBlockService service)84     public PersistentDataBlockManager(IPersistentDataBlockService service) {
85         sService = service;
86     }
87 
88     /**
89      * Writes {@code data} to the persistent partition. Previously written data
90      * will be overwritten. This data will persist across factory resets.
91      *
92      * Returns the number of bytes written or -1 on error. If the block is too big
93      * to fit on the partition, returns -MAX_BLOCK_SIZE.
94      *
95      * {@link #wipe} will block any further {@link #write} operation until reboot,
96      * in which case -1 will be returned.
97      *
98      * @param data the data to write
99      *
100      * @hide
101      */
102     @SystemApi
103     @SuppressLint("RequiresPermission")
write(@ullable byte[] data)104     public int write(@Nullable byte[] data) {
105         try {
106             return sService.write(data);
107         } catch (RemoteException e) {
108             throw e.rethrowFromSystemServer();
109         }
110     }
111 
112     /**
113      * Returns the data block stored on the persistent partition.
114      *
115      * @hide
116      */
117     @SystemApi
118     @SuppressLint("RequiresPermission")
read()119     public @Nullable byte[] read() {
120         try {
121             return sService.read();
122         } catch (RemoteException e) {
123             throw e.rethrowFromSystemServer();
124         }
125     }
126 
127     /**
128      * Retrieves the size of the block currently written to the persistent partition.
129      *
130      * Return -1 on error.
131      *
132      * @hide
133      */
134     @SystemApi
135     @RequiresPermission(android.Manifest.permission.ACCESS_PDB_STATE)
getDataBlockSize()136     public int getDataBlockSize() {
137         try {
138             return sService.getDataBlockSize();
139         } catch (RemoteException e) {
140             throw e.rethrowFromSystemServer();
141         }
142     }
143 
144     /**
145      * Retrieves the maximum size allowed for a data block.
146      *
147      * Returns -1 on error.
148      *
149      * @hide
150      */
151     @SystemApi
152     @SuppressLint("RequiresPermission")
getMaximumDataBlockSize()153     public long getMaximumDataBlockSize() {
154         try {
155             return sService.getMaximumDataBlockSize();
156         } catch (RemoteException e) {
157             throw e.rethrowFromSystemServer();
158         }
159     }
160 
161     /**
162      * Zeroes the previously written block in its entirety. Calling this method
163      * will erase all data written to the persistent data partition.
164      * It will also prevent any further {@link #write} operation until reboot,
165      * in order to prevent a potential race condition. See b/30352311.
166      *
167      * @hide
168      */
169     @SystemApi
170     @RequiresPermission(android.Manifest.permission.OEM_UNLOCK_STATE)
wipe()171     public void wipe() {
172         try {
173             sService.wipe();
174         } catch (RemoteException e) {
175             throw e.rethrowFromSystemServer();
176         }
177     }
178 
179     /**
180      * Writes a byte enabling or disabling the ability to "OEM unlock" the device.
181      *
182      * @deprecated use {@link OemLockManager#setOemUnlockAllowedByUser(boolean)} instead.
183      *
184      * @hide
185      */
186     @SystemApi
187     @Deprecated
188     @RequiresPermission(android.Manifest.permission.OEM_UNLOCK_STATE)
setOemUnlockEnabled(boolean enabled)189     public void setOemUnlockEnabled(boolean enabled) {
190         try {
191             sService.setOemUnlockEnabled(enabled);
192         } catch (RemoteException e) {
193             throw e.rethrowFromSystemServer();
194         }
195     }
196 
197     /**
198      * Returns whether or not "OEM unlock" is enabled or disabled on this device.
199      *
200      * @deprecated use {@link OemLockManager#isOemUnlockAllowedByUser()} instead.
201      *
202      * @hide
203      */
204     @SystemApi
205     @Deprecated
206     @RequiresPermission(anyOf = {
207             android.Manifest.permission.READ_OEM_UNLOCK_STATE,
208             android.Manifest.permission.OEM_UNLOCK_STATE
209     })
getOemUnlockEnabled()210     public boolean getOemUnlockEnabled() {
211         try {
212             return sService.getOemUnlockEnabled();
213         } catch (RemoteException e) {
214             throw e.rethrowFromSystemServer();
215         }
216     }
217 
218     /**
219      * Retrieves available information about this device's flash lock state.
220      *
221      * @return {@link #FLASH_LOCK_LOCKED} if device bootloader is locked,
222      * {@link #FLASH_LOCK_UNLOCKED} if device bootloader is unlocked, or {@link #FLASH_LOCK_UNKNOWN}
223      * if this information cannot be ascertained on this device.
224      *
225      * @hide
226      */
227     @SystemApi
228     @RequiresPermission(anyOf = {
229             android.Manifest.permission.READ_OEM_UNLOCK_STATE,
230             android.Manifest.permission.OEM_UNLOCK_STATE
231     })
232     @FlashLockState
getFlashLockState()233     public int getFlashLockState() {
234         try {
235             return sService.getFlashLockState();
236         } catch (RemoteException e) {
237             throw e.rethrowFromSystemServer();
238         }
239     }
240 
241     /**
242      * Returns the package name which can access the persistent data partition.
243      *
244      * @hide
245      */
246     @SystemApi
247     @NonNull
248     @RequiresPermission(android.Manifest.permission.ACCESS_PDB_STATE)
getPersistentDataPackageName()249     public String getPersistentDataPackageName() {
250         try {
251             return sService.getPersistentDataPackageName();
252         } catch (RemoteException e) {
253             throw e.rethrowFromSystemServer();
254         }
255     }
256 
257     /**
258      * Returns true if FactoryResetProtection (FRP) is active, meaning the device rebooted and has
259      * not been able to deactivate FRP because the deactivation secrets were wiped by an untrusted
260      * factory reset.
261      */
262     @FlaggedApi(Flags.FLAG_FRP_ENFORCEMENT)
isFactoryResetProtectionActive()263     public boolean isFactoryResetProtectionActive() {
264         try {
265             return sService.isFactoryResetProtectionActive();
266         } catch (RemoteException e) {
267             throw e.rethrowFromSystemServer();
268         }
269     }
270 
271     /**
272      * Attempt to deactivate FRP with the provided secret.  If the provided secret matches the
273      * stored FRP secret, FRP is deactivated and the method returns true.  Otherwise, FRP state
274      * remains unchanged and the method returns false.
275      *
276      * @hide
277      */
278     @FlaggedApi(Flags.FLAG_FRP_ENFORCEMENT)
279     @SystemApi
280     @RequiresPermission(android.Manifest.permission.CONFIGURE_FACTORY_RESET_PROTECTION)
deactivateFactoryResetProtection(@onNull byte[] secret)281     public boolean deactivateFactoryResetProtection(@NonNull byte[] secret) {
282         try {
283             return sService.deactivateFactoryResetProtection(secret);
284         } catch (RemoteException e) {
285             throw e.rethrowFromSystemServer();
286         }
287     }
288 
289     /**
290      * Store the provided FRP secret as the secret to be used for future FRP deactivation.  The
291      * secret must be 32 bytes in length.  Setting the all-zeros "default" value disables the FRP
292      * feature entirely.
293      *
294      * To ensure that the device doesn't end up in a bad state if a crash occurs, this method
295      * should be used in a three-step process:
296      *
297      * 1.  Generate a new secret and securely store any necessary copies (e.g. by encrypting them
298      *     and calling #write with a new data block that contains both the old encrypted secret
299      *     copies and the new ones).
300      * 2.  Call this method to set the new FRP secret.  This will also write the copy used during
301      *     normal boot.
302      * 3.  Delete any old FRP secret copies (e.g. by calling #write with a new data block that
303      *     contains only the new encrypted secret copies).
304      *
305      * Note that this method does nothing if FRP is currently active.
306      *
307      * This method does not require any permission, but can be called only by the
308      * PersistentDataBlockService's authorized caller UID.
309      *
310      * Returns true if the new secret was successfully written.  Returns false if FRP is currently
311      * active.
312      *
313      * @hide
314      */
315     @FlaggedApi(Flags.FLAG_FRP_ENFORCEMENT)
316     @SystemApi
317     @SuppressLint("RequiresPermission")
setFactoryResetProtectionSecret(@onNull byte[] secret)318     public boolean setFactoryResetProtectionSecret(@NonNull byte[] secret) {
319         try {
320             return sService.setFactoryResetProtectionSecret(secret);
321         } catch (RemoteException e) {
322             throw e.rethrowFromSystemServer();
323         }
324     }
325 }
326