1 /* 2 * Copyright (C) 2017 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 com.android.server.locksettings; 18 19 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; 20 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN; 21 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN; 22 import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback; 23 import static com.android.internal.widget.LockPatternUtils.PIN_LENGTH_UNAVAILABLE; 24 import static com.android.internal.widget.LockPatternUtils.USER_FRP; 25 import static com.android.internal.widget.LockPatternUtils.USER_REPAIR_MODE; 26 import static com.android.internal.widget.LockPatternUtils.pinOrPasswordQualityToCredentialType; 27 28 import android.annotation.IntDef; 29 import android.annotation.NonNull; 30 import android.annotation.Nullable; 31 import android.annotation.UserIdInt; 32 import android.app.admin.PasswordMetrics; 33 import android.content.Context; 34 import android.content.pm.UserInfo; 35 import android.hardware.weaver.IWeaver; 36 import android.hardware.weaver.WeaverConfig; 37 import android.hardware.weaver.WeaverReadResponse; 38 import android.hardware.weaver.WeaverReadStatus; 39 import android.os.IBinder; 40 import android.os.RemoteCallbackList; 41 import android.os.RemoteException; 42 import android.os.ServiceManager; 43 import android.os.ServiceSpecificException; 44 import android.os.UserManager; 45 import android.provider.Settings; 46 import android.security.GateKeeper; 47 import android.security.Scrypt; 48 import android.service.gatekeeper.GateKeeperResponse; 49 import android.service.gatekeeper.IGateKeeperService; 50 import android.text.TextUtils; 51 import android.util.ArrayMap; 52 import android.util.ArraySet; 53 import android.util.Slog; 54 55 import com.android.internal.annotations.VisibleForTesting; 56 import com.android.internal.util.ArrayUtils; 57 import com.android.internal.util.Preconditions; 58 import com.android.internal.widget.ICheckCredentialProgressCallback; 59 import com.android.internal.widget.IWeakEscrowTokenRemovedListener; 60 import com.android.internal.widget.LockPatternUtils; 61 import com.android.internal.widget.LockscreenCredential; 62 import com.android.internal.widget.VerifyCredentialResponse; 63 import com.android.server.locksettings.LockSettingsStorage.PersistentData; 64 import com.android.server.utils.Slogf; 65 66 import libcore.util.HexEncoding; 67 68 import java.lang.annotation.Retention; 69 import java.lang.annotation.RetentionPolicy; 70 import java.nio.ByteBuffer; 71 import java.util.Arrays; 72 import java.util.Collections; 73 import java.util.HashSet; 74 import java.util.List; 75 import java.util.Map; 76 import java.util.NoSuchElementException; 77 import java.util.Objects; 78 import java.util.Set; 79 80 /** 81 * A class that manages a user's synthetic password (SP) ({@link #SyntheticPassword}), along with a 82 * set of SP protectors that are independent ways that the SP is protected. 83 * 84 * Invariants for SPs: 85 * 86 * - A user's SP never changes, but SP protectors can be added and removed. There is always a 87 * protector that protects the SP with the user's Lock Screen Knowledge Factor (LSKF), a.k.a. 88 * LockscreenCredential. The LSKF may be empty (none). There may be escrow token-based 89 * protectors as well, only for specific use cases such as enterprise-managed users. 90 * 91 * - The user's credential-encrypted storage is always protected by the SP. 92 * 93 * - The user's Keystore superencryption keys are always protected by the SP. These in turn 94 * protect the Keystore keys that require user authentication, an unlocked device, or both. 95 * 96 * - A secret derived from the synthetic password is enrolled in Gatekeeper for the user, but only 97 * while the user has a (nonempty) LSKF. This enrollment has an associated ID called the Secure 98 * user ID or SID. This use of Gatekeeper, which is separate from the use of GateKeeper that may 99 * be used in the LSKF-based protector, makes it so that unlocking the synthetic password 100 * generates a HardwareAuthToken (but only when the user has LSKF). That HardwareAuthToken can 101 * be provided to KeyMint to authorize the use of the user's authentication-bound Keystore keys. 102 * 103 * Files stored on disk for each user: 104 * For the SP itself, stored under NULL_PROTECTOR_ID: 105 * SP_HANDLE_NAME: GateKeeper password handle of a password derived from the SP. Only exists 106 * while the LSKF is nonempty. 107 * SP_E0_NAME, SP_P1_NAME: Information needed to create and use escrow token-based protectors. 108 * Deleted when escrow token support is disabled for the user. 109 * VENDOR_AUTH_SECRET_NAME: A copy of the secret passed using the IAuthSecret interface, 110 * encrypted using a secret derived from the SP using 111 * PERSONALIZATION_AUTHSECRET_ENCRYPTION_KEY. 112 * 113 * For each protector, stored under the corresponding protector ID: 114 * SP_BLOB_NAME: The encrypted SP secret (the SP itself or the P0 value). Always exists. 115 * PASSWORD_DATA_NAME: Data used for LSKF verification, such as the scrypt salt and 116 * parameters. Only exists for LSKF-based protectors. Doesn't exist when 117 * the LSKF is empty, except in old protectors. 118 * PASSWORD_METRICS_NAME: Metrics about the LSKF, encrypted by a key derived from the SP. 119 * Only exists for LSKF-based protectors. Doesn't exist when the LSKF 120 * is empty, except in old protectors. 121 * SECDISCARDABLE_NAME: A large number of random bytes that all need to be known in order to 122 * decrypt SP_BLOB_NAME. When the protector is deleted, this file is 123 * overwritten and deleted as a "best-effort" attempt to support secure 124 * deletion when hardware support for secure deletion is unavailable. 125 * Doesn't exist for LSKF-based protectors that use Weaver. 126 * WEAVER_SLOT: Contains the Weaver slot number used by this protector. Only exists if the 127 * protector uses Weaver. 128 */ 129 class SyntheticPasswordManager { 130 private static final String SP_BLOB_NAME = "spblob"; 131 private static final String SP_E0_NAME = "e0"; 132 private static final String SP_P1_NAME = "p1"; 133 private static final String SP_HANDLE_NAME = "handle"; 134 private static final String SECDISCARDABLE_NAME = "secdis"; 135 private static final int SECDISCARDABLE_LENGTH = 16 * 1024; 136 private static final String PASSWORD_DATA_NAME = "pwd"; 137 private static final String WEAVER_SLOT_NAME = "weaver"; 138 private static final String PASSWORD_METRICS_NAME = "metrics"; 139 private static final String VENDOR_AUTH_SECRET_NAME = "vendor_auth_secret"; 140 141 // used for files associated with the SP itself, not with a particular protector 142 public static final long NULL_PROTECTOR_ID = 0L; 143 144 private static final byte[] DEFAULT_PASSWORD = "default-password".getBytes(); 145 146 private static final byte WEAVER_VERSION = 1; 147 private static final int INVALID_WEAVER_SLOT = -1; 148 149 // Careful: the SYNTHETIC_PASSWORD_* version numbers are overloaded to identify both the version 150 // of the protector and the version of the synthetic password itself. All a user's protectors 151 // must use a version that treats the synthetic password itself in a compatible way. 152 private static final byte SYNTHETIC_PASSWORD_VERSION_V1 = 1; 153 private static final byte SYNTHETIC_PASSWORD_VERSION_V2 = 2; 154 private static final byte SYNTHETIC_PASSWORD_VERSION_V3 = 3; 155 156 private static final byte PROTECTOR_TYPE_LSKF_BASED = 0; 157 private static final byte PROTECTOR_TYPE_STRONG_TOKEN_BASED = 1; 158 private static final byte PROTECTOR_TYPE_WEAK_TOKEN_BASED = 2; 159 160 private static final String PROTECTOR_KEY_ALIAS_PREFIX = "synthetic_password_"; 161 162 // The security strength of the synthetic password, in bytes 163 private static final int SYNTHETIC_PASSWORD_SECURITY_STRENGTH = 256 / 8; 164 165 private static final int PASSWORD_SCRYPT_LOG_N = 11; 166 private static final int PASSWORD_SCRYPT_LOG_R = 3; 167 private static final int PASSWORD_SCRYPT_LOG_P = 1; 168 private static final int PASSWORD_SALT_LENGTH = 16; 169 private static final int STRETCHED_LSKF_LENGTH = 32; 170 private static final String TAG = "SyntheticPasswordManager"; 171 172 private static final byte[] PERSONALIZATION_SECDISCARDABLE = "secdiscardable-transform".getBytes(); 173 private static final byte[] PERSONALIZATION_KEY_STORE_PASSWORD = "keystore-password".getBytes(); 174 private static final byte[] PERSONALIZATION_USER_GK_AUTH = "user-gk-authentication".getBytes(); 175 private static final byte[] PERSONALIZATION_SP_GK_AUTH = "sp-gk-authentication".getBytes(); 176 private static final byte[] PERSONALIZATION_FBE_KEY = "fbe-key".getBytes(); 177 private static final byte[] PERSONALIZATION_AUTHSECRET_KEY = "authsecret-hal".getBytes(); 178 private static final byte[] PERSONALIZATION_AUTHSECRET_ENCRYPTION_KEY = 179 "vendor-authsecret-encryption-key".getBytes(); 180 private static final byte[] PERSONALIZATION_SP_SPLIT = "sp-split".getBytes(); 181 private static final byte[] PERSONALIZATION_PASSWORD_HASH = "pw-hash".getBytes(); 182 private static final byte[] PERSONALIZATION_E0 = "e0-encryption".getBytes(); 183 private static final byte[] PERSONALIZATION_WEAVER_PASSWORD = "weaver-pwd".getBytes(); 184 private static final byte[] PERSONALIZATION_WEAVER_KEY = "weaver-key".getBytes(); 185 private static final byte[] PERSONALIZATION_WEAVER_TOKEN = "weaver-token".getBytes(); 186 private static final byte[] PERSONALIZATION_PASSWORD_METRICS = "password-metrics".getBytes(); 187 private static final byte[] PERSONALIZATION_CONTEXT = 188 "android-synthetic-password-personalization-context".getBytes(); 189 190 static class AuthenticationResult { 191 // Non-null if password/token passes verification, null otherwise 192 @Nullable public SyntheticPassword syntheticPassword; 193 // OK: password / token passes verification, user has a lockscreen 194 // null: user does not have a lockscreen (but password / token passes verification) 195 // ERROR: password / token fails verification 196 // RETRY: password / token verification is throttled at the moment. 197 @Nullable public VerifyCredentialResponse gkResponse; 198 // For unlockLskfBasedProtector() this is set to true if the protector uses Weaver. 199 public boolean usedWeaver; 200 } 201 202 /** 203 * A synthetic password (SP) is the main cryptographic secret for a user. The SP is used only 204 * as input to a Key Derivation Function (KDF) to derive other keys. 205 * 206 * SPs are created by {@link SyntheticPassword#create()} as the hash of two random values P0 and 207 * P1. E0 (P0 encrypted by an SP-derived key) and P1 can then be stored on-disk. This approach 208 * is used instead of direct random generation of the SP so that escrow token-based protectors 209 * can protect P0 instead of the SP itself. This makes it possible to cryptographically disable 210 * the ability to create and use such protectors by deleting (or never storing) E0 and P1. 211 * 212 * When protecting the SP directly, use {@link SyntheticPassword#getSyntheticPassword()} to get 213 * the raw SP, and later {@link SyntheticPassword#recreateDirectly(byte[])} to re-create the SP. 214 * When protecting P0, use {@link SyntheticPassword#getEscrowSecret()} to get P0, and later 215 * {@link SyntheticPassword#setEscrowData(byte[], byte[])} followed by 216 * {@link SyntheticPassword#recreateFromEscrow()} to re-create the SP. 217 */ 218 static class SyntheticPassword { 219 private final byte mVersion; 220 /** 221 * Here is the relationship between these fields: 222 * Generate two random block P0 and P1. P1 is recorded in mEscrowSplit1 but P0 is not. 223 * mSyntheticPassword = hash(P0 || P1) 224 * E0 = P0 encrypted under syntheticPassword, recorded in mEncryptedEscrowSplit0. 225 */ 226 private @NonNull byte[] mSyntheticPassword; 227 private @Nullable byte[] mEncryptedEscrowSplit0; 228 private @Nullable byte[] mEscrowSplit1; 229 SyntheticPassword(byte version)230 SyntheticPassword(byte version) { 231 mVersion = version; 232 } 233 234 /** 235 * Derives a subkey from the synthetic password. For v3 and later synthetic passwords the 236 * subkeys are 256-bit; for v1 and v2 they are 512-bit. 237 */ deriveSubkey(byte[] personalization)238 private byte[] deriveSubkey(byte[] personalization) { 239 if (mVersion == SYNTHETIC_PASSWORD_VERSION_V3) { 240 return (new SP800Derive(mSyntheticPassword)) 241 .withContext(personalization, PERSONALIZATION_CONTEXT); 242 } else { 243 return SyntheticPasswordCrypto.personalizedHash(personalization, 244 mSyntheticPassword); 245 } 246 } 247 deriveKeyStorePassword()248 public byte[] deriveKeyStorePassword() { 249 return bytesToHex(deriveSubkey(PERSONALIZATION_KEY_STORE_PASSWORD)); 250 } 251 deriveGkPassword()252 public byte[] deriveGkPassword() { 253 return deriveSubkey(PERSONALIZATION_SP_GK_AUTH); 254 } 255 deriveFileBasedEncryptionKey()256 public byte[] deriveFileBasedEncryptionKey() { 257 return deriveSubkey(PERSONALIZATION_FBE_KEY); 258 } 259 deriveVendorAuthSecret()260 public byte[] deriveVendorAuthSecret() { 261 return deriveSubkey(PERSONALIZATION_AUTHSECRET_KEY); 262 } 263 derivePasswordHashFactor()264 public byte[] derivePasswordHashFactor() { 265 return deriveSubkey(PERSONALIZATION_PASSWORD_HASH); 266 } 267 268 /** Derives key used to encrypt password metrics */ deriveMetricsKey()269 public byte[] deriveMetricsKey() { 270 return deriveSubkey(PERSONALIZATION_PASSWORD_METRICS); 271 } 272 deriveVendorAuthSecretEncryptionKey()273 public byte[] deriveVendorAuthSecretEncryptionKey() { 274 return deriveSubkey(PERSONALIZATION_AUTHSECRET_ENCRYPTION_KEY); 275 } 276 277 /** 278 * Assigns escrow data to this synthetic password. This is a prerequisite to call 279 * {@link SyntheticPassword#recreateFromEscrow}. 280 */ setEscrowData(@ullable byte[] encryptedEscrowSplit0, @Nullable byte[] escrowSplit1)281 public void setEscrowData(@Nullable byte[] encryptedEscrowSplit0, 282 @Nullable byte[] escrowSplit1) { 283 mEncryptedEscrowSplit0 = encryptedEscrowSplit0; 284 mEscrowSplit1 = escrowSplit1; 285 } 286 287 /** 288 * Re-creates a synthetic password from the escrow secret (escrowSplit0, returned from 289 * {@link SyntheticPassword#getEscrowSecret}). Escrow data needs to be loaded 290 * by {@link #setEscrowData} before calling this. 291 */ recreateFromEscrow(byte[] escrowSplit0)292 public void recreateFromEscrow(byte[] escrowSplit0) { 293 Objects.requireNonNull(mEscrowSplit1); 294 Objects.requireNonNull(mEncryptedEscrowSplit0); 295 recreate(escrowSplit0, mEscrowSplit1); 296 } 297 298 /** 299 * Re-creates a synthetic password from its raw bytes. 300 */ recreateDirectly(byte[] syntheticPassword)301 public void recreateDirectly(byte[] syntheticPassword) { 302 this.mSyntheticPassword = Arrays.copyOf(syntheticPassword, syntheticPassword.length); 303 } 304 305 /** 306 * Generates a new random synthetic password with escrow data. 307 */ create()308 static SyntheticPassword create() { 309 SyntheticPassword result = new SyntheticPassword(SYNTHETIC_PASSWORD_VERSION_V3); 310 byte[] escrowSplit0 = 311 SecureRandomUtils.randomBytes(SYNTHETIC_PASSWORD_SECURITY_STRENGTH); 312 byte[] escrowSplit1 = 313 SecureRandomUtils.randomBytes(SYNTHETIC_PASSWORD_SECURITY_STRENGTH); 314 result.recreate(escrowSplit0, escrowSplit1); 315 byte[] encrypteEscrowSplit0 = SyntheticPasswordCrypto.encrypt(result.mSyntheticPassword, 316 PERSONALIZATION_E0, escrowSplit0); 317 result.setEscrowData(encrypteEscrowSplit0, escrowSplit1); 318 return result; 319 } 320 321 /** 322 * Re-creates synthetic password from both escrow splits. See javadoc for 323 * SyntheticPassword.mSyntheticPassword for details on what each block means. 324 */ recreate(byte[] escrowSplit0, byte[] escrowSplit1)325 private void recreate(byte[] escrowSplit0, byte[] escrowSplit1) { 326 mSyntheticPassword = bytesToHex(SyntheticPasswordCrypto.personalizedHash( 327 PERSONALIZATION_SP_SPLIT, escrowSplit0, escrowSplit1)); 328 } 329 330 /** 331 * Returns the escrow secret that can be used later to reconstruct this synthetic password 332 * from {@link #recreateFromEscrow(byte[])}. Only possible if escrow is not disabled 333 * (encryptedEscrowSplit0 known). 334 */ getEscrowSecret()335 public byte[] getEscrowSecret() { 336 if (mEncryptedEscrowSplit0 == null) { 337 return null; 338 } 339 return SyntheticPasswordCrypto.decrypt(mSyntheticPassword, PERSONALIZATION_E0, 340 mEncryptedEscrowSplit0); 341 } 342 343 /** 344 * Returns the raw synthetic password, for later use with {@link #recreateDirectly(byte[])}. 345 */ getSyntheticPassword()346 public byte[] getSyntheticPassword() { 347 return mSyntheticPassword; 348 } 349 350 /** 351 * Returns the version number of this synthetic password. This version number determines 352 * the algorithm used to derive subkeys. 353 */ getVersion()354 public byte getVersion() { 355 return mVersion; 356 } 357 } 358 359 static class PasswordData { 360 byte scryptLogN; 361 byte scryptLogR; 362 byte scryptLogP; 363 public int credentialType; 364 byte[] salt; 365 // When Weaver is unavailable, this is the Gatekeeper password handle that resulted from 366 // enrolling the stretched LSKF. 367 public byte[] passwordHandle; 368 /** 369 * Pin length field, only stored in version 2 of the password data and when auto confirm 370 * flag is enabled, otherwise this field contains PIN_LENGTH_UNAVAILABLE 371 */ 372 public int pinLength; 373 create(int credentialType, int pinLength)374 public static PasswordData create(int credentialType, int pinLength) { 375 PasswordData result = new PasswordData(); 376 result.scryptLogN = PASSWORD_SCRYPT_LOG_N; 377 result.scryptLogR = PASSWORD_SCRYPT_LOG_R; 378 result.scryptLogP = PASSWORD_SCRYPT_LOG_P; 379 result.credentialType = credentialType; 380 result.pinLength = pinLength; 381 result.salt = SecureRandomUtils.randomBytes(PASSWORD_SALT_LENGTH); 382 return result; 383 } 384 385 /** 386 * Returns true if the given serialized PasswordData begins with the value 2 as a short. 387 * This detects the "bad" (non-forwards-compatible) PasswordData format that was temporarily 388 * used during development of Android 14. For more details, see fromBytes() below. 389 */ isBadFormatFromAndroid14Beta(byte[] data)390 public static boolean isBadFormatFromAndroid14Beta(byte[] data) { 391 return data != null && data.length >= 2 && data[0] == 0 && data[1] == 2; 392 } 393 fromBytes(byte[] data)394 public static PasswordData fromBytes(byte[] data) { 395 PasswordData result = new PasswordData(); 396 ByteBuffer buffer = ByteBuffer.allocate(data.length); 397 buffer.put(data, 0, data.length); 398 buffer.flip(); 399 400 /* 401 * The serialized PasswordData is supposed to begin with credentialType as an int. 402 * However, all credentialType values fit in a short and the byte order is big endian, 403 * so the first two bytes don't convey any non-redundant information. For this reason, 404 * temporarily during development of Android 14, the first two bytes were "stolen" from 405 * credentialType to use for a data format version number. 406 * 407 * However, this change was reverted as it was a non-forwards-compatible change. (See 408 * toBytes() for why this data format needs to be forwards-compatible.) Therefore, 409 * recover from this misstep by ignoring the first two bytes. 410 */ 411 result.credentialType = (short) buffer.getInt(); 412 result.scryptLogN = buffer.get(); 413 result.scryptLogR = buffer.get(); 414 result.scryptLogP = buffer.get(); 415 int saltLen = buffer.getInt(); 416 result.salt = new byte[saltLen]; 417 buffer.get(result.salt); 418 int handleLen = buffer.getInt(); 419 if (handleLen > 0) { 420 result.passwordHandle = new byte[handleLen]; 421 buffer.get(result.passwordHandle); 422 } else { 423 result.passwordHandle = null; 424 } 425 if (buffer.remaining() >= Integer.BYTES) { 426 result.pinLength = buffer.getInt(); 427 } else { 428 result.pinLength = PIN_LENGTH_UNAVAILABLE; 429 } 430 return result; 431 } 432 433 /** 434 * Serializes this PasswordData into a byte array. 435 * <p> 436 * Careful: all changes to the format of the serialized PasswordData must be forwards 437 * compatible. I.e., older versions of Android must still accept the latest PasswordData. 438 * This is because a serialized PasswordData is stored in the Factory Reset Protection (FRP) 439 * persistent data block. It's possible that a device has FRP set up on a newer version of 440 * Android, is factory reset, and then is set up with an older version of Android. 441 */ toBytes()442 public byte[] toBytes() { 443 444 ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + 3 * Byte.BYTES 445 + Integer.BYTES + salt.length + Integer.BYTES + 446 (passwordHandle != null ? passwordHandle.length : 0) + Integer.BYTES); 447 // credentialType must fit in a short. For an explanation, see fromBytes(). 448 if (credentialType < Short.MIN_VALUE || credentialType > Short.MAX_VALUE) { 449 throw new IllegalArgumentException("Unknown credential type: " + credentialType); 450 } 451 buffer.putInt(credentialType); 452 buffer.put(scryptLogN); 453 buffer.put(scryptLogR); 454 buffer.put(scryptLogP); 455 buffer.putInt(salt.length); 456 buffer.put(salt); 457 if (passwordHandle != null && passwordHandle.length > 0) { 458 buffer.putInt(passwordHandle.length); 459 buffer.put(passwordHandle); 460 } else { 461 buffer.putInt(0); 462 } 463 buffer.putInt(pinLength); 464 return buffer.array(); 465 } 466 } 467 468 private static class SyntheticPasswordBlob { 469 byte mVersion; 470 byte mProtectorType; 471 byte[] mContent; 472 create(byte version, byte protectorType, byte[] content)473 public static SyntheticPasswordBlob create(byte version, byte protectorType, 474 byte[] content) { 475 SyntheticPasswordBlob result = new SyntheticPasswordBlob(); 476 result.mVersion = version; 477 result.mProtectorType = protectorType; 478 result.mContent = content; 479 return result; 480 } 481 fromBytes(byte[] data)482 public static SyntheticPasswordBlob fromBytes(byte[] data) { 483 SyntheticPasswordBlob result = new SyntheticPasswordBlob(); 484 result.mVersion = data[0]; 485 result.mProtectorType = data[1]; 486 result.mContent = Arrays.copyOfRange(data, 2, data.length); 487 return result; 488 } 489 toByte()490 public byte[] toByte() { 491 byte[] blob = new byte[mContent.length + 1 + 1]; 492 blob[0] = mVersion; 493 blob[1] = mProtectorType; 494 System.arraycopy(mContent, 0, blob, 2, mContent.length); 495 return blob; 496 } 497 } 498 499 @Retention(RetentionPolicy.SOURCE) 500 @IntDef({TOKEN_TYPE_STRONG, TOKEN_TYPE_WEAK}) 501 @interface TokenType {} 502 static final int TOKEN_TYPE_STRONG = 0; 503 static final int TOKEN_TYPE_WEAK = 1; 504 505 private static class TokenData { 506 byte[] secdiscardableOnDisk; 507 byte[] weaverSecret; 508 byte[] aggregatedSecret; 509 @TokenType int mType; 510 EscrowTokenStateChangeCallback mCallback; 511 } 512 513 private final Context mContext; 514 private LockSettingsStorage mStorage; 515 private volatile IWeaver mWeaver; 516 private WeaverConfig mWeaverConfig; 517 private PasswordSlotManager mPasswordSlotManager; 518 519 private final UserManager mUserManager; 520 521 private final RemoteCallbackList<IWeakEscrowTokenRemovedListener> mListeners = 522 new RemoteCallbackList<>(); 523 SyntheticPasswordManager(Context context, LockSettingsStorage storage, UserManager userManager, PasswordSlotManager passwordSlotManager)524 public SyntheticPasswordManager(Context context, LockSettingsStorage storage, 525 UserManager userManager, PasswordSlotManager passwordSlotManager) { 526 mContext = context; 527 mStorage = storage; 528 mUserManager = userManager; 529 mPasswordSlotManager = passwordSlotManager; 530 } 531 isDeviceProvisioned()532 private boolean isDeviceProvisioned() { 533 return Settings.Global.getInt(mContext.getContentResolver(), 534 Settings.Global.DEVICE_PROVISIONED, 0) != 0; 535 } 536 isWeaverDisabledOnUnsecuredUsers()537 private boolean isWeaverDisabledOnUnsecuredUsers() { 538 return mContext.getResources().getBoolean( 539 com.android.internal.R.bool.config_disableWeaverOnUnsecuredUsers); 540 } 541 542 @VisibleForTesting getWeaverHidlService()543 protected android.hardware.weaver.V1_0.IWeaver getWeaverHidlService() throws RemoteException { 544 try { 545 return android.hardware.weaver.V1_0.IWeaver.getService(/* retry */ true); 546 } catch (NoSuchElementException e) { 547 return null; 548 } 549 } 550 551 private class WeaverDiedRecipient implements IBinder.DeathRecipient { 552 // Not synchronized on the outer class, since setting the pointer to null is atomic, and we 553 // don't want to have to worry about any sort of deadlock here. 554 @Override binderDied()555 public void binderDied() { 556 // Weaver died. Try to recover by setting mWeaver to null, which makes 557 // getWeaverService() look up the service again. This is done only as a simple 558 // robustness measure; it should not be relied on. If this triggers, the root cause is 559 // almost certainly a bug in the device's Weaver implementation, which must be fixed. 560 Slog.wtf(TAG, "Weaver service has died"); 561 mWeaver.asBinder().unlinkToDeath(this, 0); 562 mWeaver = null; 563 } 564 } 565 getWeaverAidlService()566 private @Nullable IWeaver getWeaverAidlService() { 567 final IWeaver aidlWeaver; 568 try { 569 aidlWeaver = 570 IWeaver.Stub.asInterface( 571 ServiceManager.waitForDeclaredService(IWeaver.DESCRIPTOR + "/default")); 572 } catch (SecurityException e) { 573 Slog.w(TAG, "Does not have permissions to get AIDL weaver service"); 574 return null; 575 } 576 if (aidlWeaver == null) { 577 return null; 578 } 579 final int aidlVersion; 580 try { 581 aidlVersion = aidlWeaver.getInterfaceVersion(); 582 } catch (RemoteException e) { 583 Slog.e(TAG, "Cannot get AIDL weaver service version", e); 584 return null; 585 } 586 if (aidlVersion < 2) { 587 Slog.w(TAG, 588 "Ignoring AIDL weaver service v" 589 + aidlVersion 590 + " because only v2 and later are supported"); 591 return null; 592 } 593 Slog.i(TAG, "Found AIDL weaver service v" + aidlVersion); 594 return aidlWeaver; 595 } 596 getWeaverServiceInternal()597 private @Nullable IWeaver getWeaverServiceInternal() { 598 // Try to get the AIDL service first 599 IWeaver aidlWeaver = getWeaverAidlService(); 600 if (aidlWeaver != null) { 601 Slog.i(TAG, "Using AIDL weaver service"); 602 try { 603 aidlWeaver.asBinder().linkToDeath(new WeaverDiedRecipient(), 0); 604 } catch (RemoteException e) { 605 Slog.w(TAG, "Unable to register Weaver death recipient", e); 606 } 607 return aidlWeaver; 608 } 609 610 // If the AIDL service can't be found, look for the HIDL service 611 try { 612 android.hardware.weaver.V1_0.IWeaver hidlWeaver = getWeaverHidlService(); 613 if (hidlWeaver != null) { 614 Slog.i(TAG, "Using HIDL weaver service"); 615 return new WeaverHidlAdapter(hidlWeaver); 616 } 617 } catch (RemoteException e) { 618 Slog.w(TAG, "Failed to get HIDL weaver service.", e); 619 } 620 Slog.w(TAG, "Device does not support weaver"); 621 return null; 622 } 623 624 @VisibleForTesting isAutoPinConfirmationFeatureAvailable()625 public boolean isAutoPinConfirmationFeatureAvailable() { 626 return LockPatternUtils.isAutoPinConfirmFeatureAvailable(); 627 } 628 629 /** 630 * Returns a handle to the Weaver service, or null if Weaver is unavailable. Note that not all 631 * devices support Weaver. 632 */ getWeaverService()633 private synchronized @Nullable IWeaver getWeaverService() { 634 IWeaver weaver = mWeaver; 635 if (weaver != null) { 636 return weaver; 637 } 638 639 // Re-initialize weaver in case there was a transient error preventing access to it. 640 weaver = getWeaverServiceInternal(); 641 if (weaver == null) { 642 return null; 643 } 644 645 final WeaverConfig weaverConfig; 646 try { 647 weaverConfig = weaver.getConfig(); 648 } catch (RemoteException | ServiceSpecificException e) { 649 Slog.e(TAG, "Failed to get weaver config", e); 650 return null; 651 } 652 if (weaverConfig == null || weaverConfig.slots <= 0) { 653 Slog.e(TAG, "Invalid weaver config"); 654 return null; 655 } 656 657 mWeaver = weaver; 658 mWeaverConfig = weaverConfig; 659 mPasswordSlotManager.refreshActiveSlots(getUsedWeaverSlots()); 660 Slog.i(TAG, "Weaver service initialized"); 661 return weaver; 662 } 663 664 /** 665 * Enroll the given key value pair into the specified weaver slot. if the given key is null, 666 * a default all-zero key is used. If the value is not specified, a fresh random secret is 667 * generated as the value. 668 * 669 * @return the value stored in the weaver slot, or null if the operation fails 670 */ weaverEnroll(IWeaver weaver, int slot, byte[] key, @Nullable byte[] value)671 private byte[] weaverEnroll(IWeaver weaver, int slot, byte[] key, @Nullable byte[] value) { 672 if (slot == INVALID_WEAVER_SLOT || slot >= mWeaverConfig.slots) { 673 throw new IllegalArgumentException("Invalid slot for weaver"); 674 } 675 if (key == null) { 676 key = new byte[mWeaverConfig.keySize]; 677 } else if (key.length != mWeaverConfig.keySize) { 678 throw new IllegalArgumentException("Invalid key size for weaver"); 679 } 680 if (value == null) { 681 value = SecureRandomUtils.randomBytes(mWeaverConfig.valueSize); 682 } 683 try { 684 weaver.write(slot, key, value); 685 } catch (RemoteException e) { 686 Slog.e(TAG, "weaver write binder call failed, slot: " + slot, e); 687 return null; 688 } catch (ServiceSpecificException e) { 689 Slog.e(TAG, "weaver write failed, slot: " + slot, e); 690 return null; 691 } 692 return value; 693 } 694 695 /** 696 * Create a VerifyCredentialResponse from a timeout base on the WeaverReadResponse. 697 * This checks the received timeout(long) to make sure it sure it fits in an int before 698 * using it. If it doesn't fit, we use Integer.MAX_VALUE. 699 */ responseFromTimeout(WeaverReadResponse response)700 private static VerifyCredentialResponse responseFromTimeout(WeaverReadResponse response) { 701 int timeout = 702 response.timeout > Integer.MAX_VALUE || response.timeout < 0 703 ? Integer.MAX_VALUE 704 : (int) response.timeout; 705 return VerifyCredentialResponse.fromTimeout(timeout); 706 } 707 708 /** 709 * Verify the supplied key against a weaver slot, returning a response indicating whether 710 * the verification is successful, throttled or failed. If successful, the bound secret 711 * is also returned. 712 */ 713 private VerifyCredentialResponse weaverVerify(IWeaver weaver, int slot, byte[] key) { 714 if (slot == INVALID_WEAVER_SLOT || slot >= mWeaverConfig.slots) { 715 throw new IllegalArgumentException("Invalid slot for weaver"); 716 } 717 if (key == null) { 718 key = new byte[mWeaverConfig.keySize]; 719 } else if (key.length != mWeaverConfig.keySize) { 720 throw new IllegalArgumentException("Invalid key size for weaver"); 721 } 722 final WeaverReadResponse readResponse; 723 try { 724 readResponse = weaver.read(slot, key); 725 } catch (RemoteException e) { 726 Slog.e(TAG, "weaver read failed, slot: " + slot, e); 727 return VerifyCredentialResponse.ERROR; 728 } 729 730 switch (readResponse.status) { 731 case WeaverReadStatus.OK: 732 return new VerifyCredentialResponse.Builder() 733 .setGatekeeperHAT(readResponse.value) 734 .build(); 735 case WeaverReadStatus.THROTTLE: 736 Slog.e(TAG, "weaver read failed (THROTTLE), slot: " + slot); 737 return responseFromTimeout(readResponse); 738 case WeaverReadStatus.INCORRECT_KEY: 739 if (readResponse.timeout == 0) { 740 Slog.e(TAG, "weaver read failed (INCORRECT_KEY), slot: " + slot); 741 return VerifyCredentialResponse.ERROR; 742 } else { 743 Slog.e(TAG, "weaver read failed (INCORRECT_KEY/THROTTLE), slot: " + slot); 744 return responseFromTimeout(readResponse); 745 } 746 case WeaverReadStatus.FAILED: 747 Slog.e(TAG, "weaver read failed (FAILED), slot: " + slot); 748 return VerifyCredentialResponse.ERROR; 749 default: 750 Slog.e(TAG, 751 "weaver read unknown status " + readResponse.status 752 + ", slot: " + slot); 753 return VerifyCredentialResponse.ERROR; 754 } 755 } 756 removeUser(IGateKeeperService gatekeeper, int userId)757 public void removeUser(IGateKeeperService gatekeeper, int userId) { 758 for (long protectorId : mStorage.listSyntheticPasswordProtectorsForUser(SP_BLOB_NAME, 759 userId)) { 760 destroyWeaverSlot(protectorId, userId); 761 destroyProtectorKey(getProtectorKeyAlias(protectorId)); 762 } 763 // Remove potential persistent state (in RPMB), to prevent them from accumulating and 764 // causing problems. 765 try { 766 gatekeeper.clearSecureUserId(fakeUserId(userId)); 767 } catch (RemoteException ignore) { 768 Slog.w(TAG, "Failed to clear SID from gatekeeper"); 769 } 770 } 771 getPinLength(long protectorId, int userId)772 int getPinLength(long protectorId, int userId) { 773 byte[] passwordData = loadState(PASSWORD_DATA_NAME, protectorId, userId); 774 if (passwordData == null) { 775 return LockPatternUtils.PIN_LENGTH_UNAVAILABLE; 776 } 777 return PasswordData.fromBytes(passwordData).pinLength; 778 } 779 getCredentialType(long protectorId, int userId)780 int getCredentialType(long protectorId, int userId) { 781 byte[] passwordData = loadState(PASSWORD_DATA_NAME, protectorId, userId); 782 if (passwordData == null) { 783 return LockPatternUtils.CREDENTIAL_TYPE_NONE; 784 } 785 return PasswordData.fromBytes(passwordData).credentialType; 786 } 787 getSpecialUserCredentialType(int userId)788 int getSpecialUserCredentialType(int userId) { 789 final PersistentData data = getSpecialUserPersistentData(userId); 790 if (data.type != PersistentData.TYPE_SP_GATEKEEPER 791 && data.type != PersistentData.TYPE_SP_WEAVER) { 792 return CREDENTIAL_TYPE_NONE; 793 } 794 if (data.payload == null) { 795 return LockPatternUtils.CREDENTIAL_TYPE_NONE; 796 } 797 final int credentialType = PasswordData.fromBytes(data.payload).credentialType; 798 if (credentialType != CREDENTIAL_TYPE_PASSWORD_OR_PIN) { 799 return credentialType; 800 } 801 return pinOrPasswordQualityToCredentialType(data.qualityForUi); 802 } 803 getSpecialUserPersistentData(int userId)804 private PersistentData getSpecialUserPersistentData(int userId) { 805 if (userId == USER_FRP) { 806 return mStorage.readPersistentDataBlock(); 807 } 808 if (userId == USER_REPAIR_MODE) { 809 return mStorage.readRepairModePersistentData(); 810 } 811 throw new IllegalArgumentException("Unknown special user id " + userId); 812 } 813 814 /** 815 * Creates a new synthetic password (SP) for the given user. 816 * <p> 817 * Any existing SID for the user is cleared. 818 * <p> 819 * Also saves the escrow information necessary to re-generate the synthetic password under 820 * an escrow scheme. This information can be removed with {@link #destroyEscrowData} if 821 * password escrow should be disabled completely on the given user. 822 * <p> 823 * {@link syncState()} is not called yet; the caller should create a protector afterwards, which 824 * handles this. This makes it so that all the user's initial SP state files, including the 825 * initial LSKF-based protector, are efficiently created with only a single {@link syncState()}. 826 */ newSyntheticPassword(int userId)827 SyntheticPassword newSyntheticPassword(int userId) { 828 clearSidForUser(userId); 829 SyntheticPassword result = SyntheticPassword.create(); 830 saveEscrowData(result, userId); 831 return result; 832 } 833 834 /** 835 * Enroll a new password handle and SID for the given synthetic password and persist it on disk. 836 * Used when the LSKF is changed from empty to nonempty. 837 */ newSidForUser(IGateKeeperService gatekeeper, SyntheticPassword sp, int userId)838 public void newSidForUser(IGateKeeperService gatekeeper, SyntheticPassword sp, int userId) { 839 GateKeeperResponse response; 840 try { 841 response = gatekeeper.enroll(userId, null, null, sp.deriveGkPassword()); 842 } catch (RemoteException e) { 843 throw new IllegalStateException("Failed to create new SID for user", e); 844 } 845 if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) { 846 throw new IllegalStateException("Fail to create new SID for user " + userId 847 + " response: " + response.getResponseCode()); 848 } 849 saveSyntheticPasswordHandle(response.getPayload(), userId); 850 } 851 852 // Nuke the SP handle (and as a result, its SID) for the given user. clearSidForUser(int userId)853 public void clearSidForUser(int userId) { 854 destroyState(SP_HANDLE_NAME, NULL_PROTECTOR_ID, userId); 855 } 856 hasSidForUser(int userId)857 public boolean hasSidForUser(int userId) { 858 return hasState(SP_HANDLE_NAME, NULL_PROTECTOR_ID, userId); 859 } 860 861 // If this returns null, it means there is no SID associated with the user. This happens if the 862 // user has an empty LSKF, but does have an SP. loadSyntheticPasswordHandle(int userId)863 private byte[] loadSyntheticPasswordHandle(int userId) { 864 return loadState(SP_HANDLE_NAME, NULL_PROTECTOR_ID, userId); 865 } 866 saveSyntheticPasswordHandle(byte[] spHandle, int userId)867 private void saveSyntheticPasswordHandle(byte[] spHandle, int userId) { 868 saveState(SP_HANDLE_NAME, spHandle, NULL_PROTECTOR_ID, userId); 869 syncState(userId); 870 } 871 loadEscrowData(SyntheticPassword sp, int userId)872 private boolean loadEscrowData(SyntheticPassword sp, int userId) { 873 byte[] e0 = loadState(SP_E0_NAME, NULL_PROTECTOR_ID, userId); 874 byte[] p1 = loadState(SP_P1_NAME, NULL_PROTECTOR_ID, userId); 875 sp.setEscrowData(e0, p1); 876 return e0 != null && p1 != null; 877 } 878 879 /** 880 * Saves the escrow data for the synthetic password. The caller is responsible for calling 881 * {@link syncState()} afterwards, once the user's other initial synthetic password state files 882 * have been created. 883 */ saveEscrowData(SyntheticPassword sp, int userId)884 private void saveEscrowData(SyntheticPassword sp, int userId) { 885 saveState(SP_E0_NAME, sp.mEncryptedEscrowSplit0, NULL_PROTECTOR_ID, userId); 886 saveState(SP_P1_NAME, sp.mEscrowSplit1, NULL_PROTECTOR_ID, userId); 887 } 888 hasEscrowData(int userId)889 public boolean hasEscrowData(int userId) { 890 return hasState(SP_E0_NAME, NULL_PROTECTOR_ID, userId) 891 && hasState(SP_P1_NAME, NULL_PROTECTOR_ID, userId); 892 } 893 hasAnyEscrowData(int userId)894 public boolean hasAnyEscrowData(int userId) { 895 return hasState(SP_E0_NAME, NULL_PROTECTOR_ID, userId) 896 || hasState(SP_P1_NAME, NULL_PROTECTOR_ID, userId); 897 } 898 destroyEscrowData(int userId)899 public void destroyEscrowData(int userId) { 900 destroyState(SP_E0_NAME, NULL_PROTECTOR_ID, userId); 901 destroyState(SP_P1_NAME, NULL_PROTECTOR_ID, userId); 902 } 903 loadWeaverSlot(long protectorId, int userId)904 private int loadWeaverSlot(long protectorId, int userId) { 905 final int LENGTH = Byte.BYTES + Integer.BYTES; 906 byte[] data = loadState(WEAVER_SLOT_NAME, protectorId, userId); 907 if (data == null || data.length != LENGTH) { 908 return INVALID_WEAVER_SLOT; 909 } 910 ByteBuffer buffer = ByteBuffer.allocate(LENGTH); 911 buffer.put(data, 0, data.length); 912 buffer.flip(); 913 if (buffer.get() != WEAVER_VERSION) { 914 Slog.e(TAG, "Invalid weaver slot version for protector " + protectorId); 915 return INVALID_WEAVER_SLOT; 916 } 917 return buffer.getInt(); 918 } 919 920 /** 921 * Creates a file that stores the Weaver slot the protector is using. The caller is responsible 922 * for calling {@link syncState()} afterwards, once all the protector's files have been created. 923 */ saveWeaverSlot(int slot, long protectorId, int userId)924 private void saveWeaverSlot(int slot, long protectorId, int userId) { 925 ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES + Integer.BYTES); 926 buffer.put(WEAVER_VERSION); 927 buffer.putInt(slot); 928 saveState(WEAVER_SLOT_NAME, buffer.array(), protectorId, userId); 929 } 930 destroyWeaverSlot(long protectorId, int userId)931 private void destroyWeaverSlot(long protectorId, int userId) { 932 int slot = loadWeaverSlot(protectorId, userId); 933 destroyState(WEAVER_SLOT_NAME, protectorId, userId); 934 if (slot != INVALID_WEAVER_SLOT) { 935 final IWeaver weaver = getWeaverService(); 936 if (weaver == null) { 937 Slog.e(TAG, "Cannot erase Weaver slot because Weaver is unavailable"); 938 return; 939 } 940 Set<Integer> usedSlots = getUsedWeaverSlots(); 941 if (!usedSlots.contains(slot)) { 942 Slogf.i(TAG, "Erasing Weaver slot %d", slot); 943 weaverEnroll(weaver, slot, null, null); 944 mPasswordSlotManager.markSlotDeleted(slot); 945 } else { 946 Slogf.i(TAG, "Weaver slot %d was already reused; not erasing it", slot); 947 } 948 } 949 } 950 951 /** 952 * Return the set of weaver slots that are currently in use by all users on the device. 953 * <p> 954 * <em>Note:</em> Users who are in the process of being deleted are not tracked here 955 * (due to them being marked as partial in UserManager so not visible from 956 * {@link UserManager#getUsers}). As a result their weaver slots will not be considered 957 * taken and can be reused by new users. Care should be taken when cleaning up the 958 * deleted user in {@link #removeUser}, to prevent a reused slot from being erased 959 * unintentionally. 960 */ getUsedWeaverSlots()961 private Set<Integer> getUsedWeaverSlots() { 962 Map<Integer, List<Long>> protectorIds = 963 mStorage.listSyntheticPasswordProtectorsForAllUsers(WEAVER_SLOT_NAME); 964 HashSet<Integer> slots = new HashSet<>(); 965 for (Map.Entry<Integer, List<Long>> entry : protectorIds.entrySet()) { 966 for (Long protectorId : entry.getValue()) { 967 int slot = loadWeaverSlot(protectorId, entry.getKey()); 968 slots.add(slot); 969 } 970 } 971 return slots; 972 } 973 getNextAvailableWeaverSlot()974 private int getNextAvailableWeaverSlot() { 975 Set<Integer> usedSlots = getUsedWeaverSlots(); 976 usedSlots.addAll(mPasswordSlotManager.getUsedSlots()); 977 // If the device is not yet provisioned, then the Weaver slot used by the FRP credential may 978 // be still needed and must not be reused yet. (This *should* instead check "has FRP been 979 // resolved yet?", which would allow reusing the slot a bit earlier. However, the 980 // SECURE_FRP_MODE setting gets set to 1 too late for it to be used here.) 981 if (!isDeviceProvisioned()) { 982 PersistentData persistentData = mStorage.readPersistentDataBlock(); 983 if (persistentData != null && persistentData.type == PersistentData.TYPE_SP_WEAVER) { 984 int slot = persistentData.userId; // Note: field name is misleading 985 usedSlots.add(slot); 986 } 987 } 988 for (int i = 0; i < mWeaverConfig.slots; i++) { 989 if (!usedSlots.contains(i)) { 990 return i; 991 } 992 } 993 throw new IllegalStateException("Run out of weaver slots."); 994 } 995 996 /** 997 * Creates a protector that protects the user's SP with the given LSKF (which may be empty). 998 * 999 * This method only creates a new protector that isn't referenced by anything; it doesn't handle 1000 * any higher-level tasks involved in changing the LSKF. 1001 * 1002 * @return the ID of the new protector 1003 * @throws IllegalStateException on failure 1004 */ createLskfBasedProtector(IGateKeeperService gatekeeper, LockscreenCredential credential, SyntheticPassword sp, int userId)1005 public long createLskfBasedProtector(IGateKeeperService gatekeeper, 1006 LockscreenCredential credential, SyntheticPassword sp, int userId) { 1007 long protectorId = generateProtectorId(); 1008 int pinLength = PIN_LENGTH_UNAVAILABLE; 1009 if (isAutoPinConfirmationFeatureAvailable()) { 1010 pinLength = derivePinLength(credential.size(), credential.isPin(), userId); 1011 } 1012 // There's no need to store password data about an empty LSKF. 1013 PasswordData pwd = credential.isNone() ? null : 1014 PasswordData.create(credential.getType(), pinLength); 1015 byte[] stretchedLskf = stretchLskf(credential, pwd); 1016 long sid = GateKeeper.INVALID_SECURE_USER_ID; 1017 final byte[] protectorSecret; 1018 1019 Slogf.i(TAG, "Creating LSKF-based protector %016x for user %d", protectorId, userId); 1020 1021 final IWeaver weaver; 1022 if (credential.isNone() && isWeaverDisabledOnUnsecuredUsers()) { 1023 weaver = null; 1024 Slog.w(TAG, "Not using Weaver for unsecured user (disabled by config)"); 1025 } else { 1026 weaver = getWeaverService(); 1027 } 1028 if (weaver != null) { 1029 // Weaver is available, so make the protector use it to verify the LSKF. Do this even 1030 // if the LSKF is empty, as that gives us support for securely deleting the protector. 1031 int weaverSlot = getNextAvailableWeaverSlot(); 1032 Slogf.i(TAG, "Enrolling LSKF for user %d into Weaver slot %d", userId, weaverSlot); 1033 byte[] weaverSecret = weaverEnroll(weaver, weaverSlot, 1034 stretchedLskfToWeaverKey(stretchedLskf), null); 1035 if (weaverSecret == null) { 1036 throw new IllegalStateException( 1037 "Fail to enroll user password under weaver " + userId); 1038 } 1039 saveWeaverSlot(weaverSlot, protectorId, userId); 1040 mPasswordSlotManager.markSlotInUse(weaverSlot); 1041 // No need to pass in quality since the credential type already encodes sufficient info 1042 synchronizeWeaverFrpPassword(pwd, 0, userId, weaverSlot); 1043 1044 protectorSecret = transformUnderWeaverSecret(stretchedLskf, weaverSecret); 1045 } else { 1046 // Weaver is unavailable, so make the protector use Gatekeeper (GK) to verify the LSKF. 1047 // 1048 // However, skip GK when the LSKF is empty. There are two reasons for this, one 1049 // performance and one correctness. The performance reason is that GK wouldn't give any 1050 // benefit with an empty LSKF anyway, since GK isn't expected to provide secure 1051 // deletion. The correctness reason is that it is unsafe to enroll a password in the 1052 // 'fakeUserId' GK range on an FRP-protected device that is in the setup wizard with FRP 1053 // not passed yet, as that may overwrite the enrollment used by the FRP credential. 1054 if (!credential.isNone()) { 1055 // In case GK enrollment leaves persistent state around (in RPMB), this will nuke 1056 // them to prevent them from accumulating and causing problems. 1057 try { 1058 gatekeeper.clearSecureUserId(fakeUserId(userId)); 1059 } catch (RemoteException ignore) { 1060 Slog.w(TAG, "Failed to clear SID from gatekeeper"); 1061 } 1062 Slogf.i(TAG, "Enrolling LSKF for user %d into Gatekeeper", userId); 1063 GateKeeperResponse response; 1064 try { 1065 response = gatekeeper.enroll(fakeUserId(userId), null, null, 1066 stretchedLskfToGkPassword(stretchedLskf)); 1067 } catch (RemoteException e) { 1068 throw new IllegalStateException("Failed to enroll LSKF for new SP protector" 1069 + " for user " + userId, e); 1070 } 1071 if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) { 1072 throw new IllegalStateException("Failed to enroll LSKF for new SP protector" 1073 + " for user " + userId); 1074 } 1075 pwd.passwordHandle = response.getPayload(); 1076 sid = sidFromPasswordHandle(pwd.passwordHandle); 1077 } 1078 protectorSecret = transformUnderSecdiscardable(stretchedLskf, 1079 createSecdiscardable(protectorId, userId)); 1080 // No need to pass in quality since the credential type already encodes sufficient info 1081 synchronizeGatekeeperFrpPassword(pwd, 0, userId); 1082 } 1083 if (!credential.isNone()) { 1084 saveState(PASSWORD_DATA_NAME, pwd.toBytes(), protectorId, userId); 1085 savePasswordMetrics(credential, sp, protectorId, userId); 1086 } 1087 createSyntheticPasswordBlob(protectorId, PROTECTOR_TYPE_LSKF_BASED, sp, protectorSecret, 1088 sid, userId); 1089 syncState(userId); // ensure the new files are really saved to disk 1090 return protectorId; 1091 } 1092 derivePinLength(int sizeOfCredential, boolean isPinCredential, int userId)1093 private int derivePinLength(int sizeOfCredential, boolean isPinCredential, int userId) { 1094 if (!isPinCredential 1095 || !mStorage.isAutoPinConfirmSettingEnabled(userId) 1096 || sizeOfCredential < LockPatternUtils.MIN_AUTO_PIN_REQUIREMENT_LENGTH) { 1097 return PIN_LENGTH_UNAVAILABLE; 1098 } 1099 return sizeOfCredential; 1100 } 1101 verifySpecialUserCredential(int sourceUserId, IGateKeeperService gatekeeper, LockscreenCredential userCredential, ICheckCredentialProgressCallback progressCallback)1102 public VerifyCredentialResponse verifySpecialUserCredential(int sourceUserId, 1103 IGateKeeperService gatekeeper, LockscreenCredential userCredential, 1104 ICheckCredentialProgressCallback progressCallback) { 1105 final PersistentData persistentData = getSpecialUserPersistentData(sourceUserId); 1106 if (persistentData.type == PersistentData.TYPE_SP_GATEKEEPER) { 1107 PasswordData pwd = PasswordData.fromBytes(persistentData.payload); 1108 byte[] stretchedLskf = stretchLskf(userCredential, pwd); 1109 1110 GateKeeperResponse response; 1111 try { 1112 response = gatekeeper.verifyChallenge(fakeUserId(persistentData.userId), 1113 0 /* challenge */, pwd.passwordHandle, 1114 stretchedLskfToGkPassword(stretchedLskf)); 1115 } catch (RemoteException e) { 1116 Slog.e(TAG, "Persistent data credential verifyChallenge failed", e); 1117 return VerifyCredentialResponse.ERROR; 1118 } 1119 return VerifyCredentialResponse.fromGateKeeperResponse(response); 1120 } else if (persistentData.type == PersistentData.TYPE_SP_WEAVER) { 1121 final IWeaver weaver = getWeaverService(); 1122 if (weaver == null) { 1123 Slog.e(TAG, "No weaver service to verify SP-based persistent data credential"); 1124 return VerifyCredentialResponse.ERROR; 1125 } 1126 PasswordData pwd = PasswordData.fromBytes(persistentData.payload); 1127 byte[] stretchedLskf = stretchLskf(userCredential, pwd); 1128 int weaverSlot = persistentData.userId; 1129 1130 return weaverVerify(weaver, weaverSlot, 1131 stretchedLskfToWeaverKey(stretchedLskf)).stripPayload(); 1132 } else { 1133 Slog.e(TAG, "persistentData.type must be TYPE_SP_GATEKEEPER or TYPE_SP_WEAVER, but is " 1134 + persistentData.type); 1135 return VerifyCredentialResponse.ERROR; 1136 } 1137 } 1138 1139 migrateFrpPasswordLocked(long protectorId, UserInfo userInfo, int requestedQuality)1140 public void migrateFrpPasswordLocked(long protectorId, UserInfo userInfo, 1141 int requestedQuality) { 1142 if (mStorage.getPersistentDataBlockManager() != null 1143 && LockPatternUtils.userOwnsFrpCredential(mContext, userInfo) 1144 && getCredentialType(protectorId, userInfo.id) != 1145 LockPatternUtils.CREDENTIAL_TYPE_NONE) { 1146 Slog.i(TAG, "Migrating FRP credential to persistent data block"); 1147 PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, protectorId, 1148 userInfo.id)); 1149 int weaverSlot = loadWeaverSlot(protectorId, userInfo.id); 1150 if (weaverSlot != INVALID_WEAVER_SLOT) { 1151 synchronizeWeaverFrpPassword(pwd, requestedQuality, userInfo.id, weaverSlot); 1152 } else { 1153 synchronizeGatekeeperFrpPassword(pwd, requestedQuality, userInfo.id); 1154 } 1155 } 1156 } 1157 isNoneCredential(PasswordData pwd)1158 private static boolean isNoneCredential(PasswordData pwd) { 1159 return pwd == null || pwd.credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE; 1160 } 1161 shouldSynchronizeFrpCredential(@ullable PasswordData pwd, int userId)1162 private boolean shouldSynchronizeFrpCredential(@Nullable PasswordData pwd, int userId) { 1163 if (mStorage.getPersistentDataBlockManager() == null) { 1164 return false; 1165 } 1166 UserInfo userInfo = mUserManager.getUserInfo(userId); 1167 if (!LockPatternUtils.userOwnsFrpCredential(mContext, userInfo)) { 1168 return false; 1169 } 1170 // When initializing the synthetic password of the user that will own the FRP credential, 1171 // the FRP data block must not be cleared if the device isn't provisioned yet, since in this 1172 // case the old value of the block may still be needed for the FRP authentication step. The 1173 // FRP data block will instead be cleared later, by 1174 // LockSettingsService.DeviceProvisionedObserver.clearFrpCredentialIfOwnerNotSecure(). 1175 // 1176 // Don't check the SECURE_FRP_MODE setting here, as it gets set to 1 too late. 1177 // 1178 // Don't delay anything for a nonempty credential. A nonempty credential can be set before 1179 // the device has been provisioned, but it's guaranteed to be after FRP was resolved. 1180 if (isNoneCredential(pwd) && !isDeviceProvisioned()) { 1181 Slog.d(TAG, "Not clearing FRP credential yet because device is not yet provisioned"); 1182 return false; 1183 } 1184 return true; 1185 } 1186 synchronizeGatekeeperFrpPassword(@ullable PasswordData pwd, int requestedQuality, int userId)1187 private void synchronizeGatekeeperFrpPassword(@Nullable PasswordData pwd, int requestedQuality, 1188 int userId) { 1189 if (shouldSynchronizeFrpCredential(pwd, userId)) { 1190 Slogf.d(TAG, "Syncing Gatekeeper-based FRP credential tied to user %d", userId); 1191 if (!isNoneCredential(pwd)) { 1192 mStorage.writePersistentDataBlock(PersistentData.TYPE_SP_GATEKEEPER, userId, 1193 requestedQuality, pwd.toBytes()); 1194 } else { 1195 mStorage.writePersistentDataBlock(PersistentData.TYPE_NONE, userId, 0, null); 1196 } 1197 } 1198 } 1199 synchronizeWeaverFrpPassword(@ullable PasswordData pwd, int requestedQuality, int userId, int weaverSlot)1200 private void synchronizeWeaverFrpPassword(@Nullable PasswordData pwd, int requestedQuality, 1201 int userId, int weaverSlot) { 1202 if (shouldSynchronizeFrpCredential(pwd, userId)) { 1203 Slogf.d(TAG, "Syncing Weaver-based FRP credential tied to user %d", userId); 1204 if (!isNoneCredential(pwd)) { 1205 mStorage.writePersistentDataBlock(PersistentData.TYPE_SP_WEAVER, weaverSlot, 1206 requestedQuality, pwd.toBytes()); 1207 } else { 1208 mStorage.writePersistentDataBlock(PersistentData.TYPE_NONE, 0, 0, null); 1209 } 1210 } 1211 } 1212 1213 /** 1214 * Writes the user's synthetic password data to the repair mode file. 1215 * 1216 * @param protectorId current LSKF based protectorId 1217 * @param userId user id of the user 1218 */ writeRepairModeCredentialLocked(long protectorId, int userId)1219 public boolean writeRepairModeCredentialLocked(long protectorId, int userId) { 1220 if (!shouldWriteRepairModeCredential(userId)) { 1221 return false; 1222 } 1223 final byte[] data = loadState(PASSWORD_DATA_NAME, protectorId, userId); 1224 if (data == null) { 1225 Slogf.w(TAG, "Password data not found for user %d", userId); 1226 return false; 1227 } 1228 final PasswordData pwd = PasswordData.fromBytes(data); 1229 if (isNoneCredential(pwd)) { 1230 Slogf.w(TAG, "User %d has NONE credential", userId); 1231 return false; 1232 } 1233 Slogf.d(TAG, "Writing repair mode credential tied to user %d", userId); 1234 final int weaverSlot = loadWeaverSlot(protectorId, userId); 1235 if (weaverSlot != INVALID_WEAVER_SLOT) { 1236 // write weaver password 1237 mStorage.writeRepairModePersistentData( 1238 PersistentData.TYPE_SP_WEAVER, weaverSlot, pwd.toBytes()); 1239 } else { 1240 // write gatekeeper password 1241 mStorage.writeRepairModePersistentData( 1242 PersistentData.TYPE_SP_GATEKEEPER, userId, pwd.toBytes()); 1243 } 1244 return true; 1245 } 1246 shouldWriteRepairModeCredential(int userId)1247 private boolean shouldWriteRepairModeCredential(int userId) { 1248 final UserInfo userInfo = mUserManager.getUserInfo(userId); 1249 if (!LockPatternUtils.canUserEnterRepairMode(mContext, userInfo)) { 1250 Slogf.w(TAG, "User %d can't enter repair mode", userId); 1251 return false; 1252 } 1253 if (LockPatternUtils.isRepairModeActive(mContext)) { 1254 Slog.w(TAG, "Can't write repair mode credential while repair mode is already active"); 1255 return false; 1256 } 1257 if (LockPatternUtils.isGsiRunning()) { 1258 Slog.w(TAG, "Can't write repair mode credential while GSI is running"); 1259 return false; 1260 } 1261 return true; 1262 } 1263 1264 private ArrayMap<Integer, ArrayMap<Long, TokenData>> tokenMap = new ArrayMap<>(); 1265 1266 /** 1267 * Caches a pending escrow token in memory and pre-allocates an ID for a new SP protector. This 1268 * ID also serves as a handle for the pending token. 1269 * 1270 * This method doesn't persist any data, and it doesn't require access to the SP. 1271 * {@link #createTokenBasedProtector} can be called later to actually create the protector. 1272 * 1273 * @return the token handle 1274 */ addPendingToken(byte[] token, @TokenType int type, int userId, @Nullable EscrowTokenStateChangeCallback changeCallback)1275 public long addPendingToken(byte[] token, @TokenType int type, int userId, 1276 @Nullable EscrowTokenStateChangeCallback changeCallback) { 1277 long tokenHandle = generateProtectorId(); // tokenHandle is reused as protectorId later 1278 if (!tokenMap.containsKey(userId)) { 1279 tokenMap.put(userId, new ArrayMap<>()); 1280 } 1281 TokenData tokenData = new TokenData(); 1282 tokenData.mType = type; 1283 final byte[] secdiscardable = SecureRandomUtils.randomBytes(SECDISCARDABLE_LENGTH); 1284 if (getWeaverService() != null) { 1285 tokenData.weaverSecret = SecureRandomUtils.randomBytes(mWeaverConfig.valueSize); 1286 tokenData.secdiscardableOnDisk = SyntheticPasswordCrypto.encrypt(tokenData.weaverSecret, 1287 PERSONALIZATION_WEAVER_TOKEN, secdiscardable); 1288 } else { 1289 tokenData.secdiscardableOnDisk = secdiscardable; 1290 tokenData.weaverSecret = null; 1291 } 1292 tokenData.aggregatedSecret = transformUnderSecdiscardable(token, secdiscardable); 1293 tokenData.mCallback = changeCallback; 1294 1295 tokenMap.get(userId).put(tokenHandle, tokenData); 1296 return tokenHandle; 1297 } 1298 getPendingTokensForUser(int userId)1299 public Set<Long> getPendingTokensForUser(int userId) { 1300 if (!tokenMap.containsKey(userId)) { 1301 return Collections.emptySet(); 1302 } 1303 return new ArraySet<>(tokenMap.get(userId).keySet()); 1304 } 1305 1306 /** Remove the given pending token. */ removePendingToken(long tokenHandle, int userId)1307 public boolean removePendingToken(long tokenHandle, int userId) { 1308 if (!tokenMap.containsKey(userId)) { 1309 return false; 1310 } 1311 return tokenMap.get(userId).remove(tokenHandle) != null; 1312 } 1313 createTokenBasedProtector(long tokenHandle, SyntheticPassword sp, int userId)1314 public boolean createTokenBasedProtector(long tokenHandle, SyntheticPassword sp, int userId) { 1315 if (!tokenMap.containsKey(userId)) { 1316 return false; 1317 } 1318 TokenData tokenData = tokenMap.get(userId).get(tokenHandle); 1319 if (tokenData == null) { 1320 return false; 1321 } 1322 if (!loadEscrowData(sp, userId)) { 1323 Slog.w(TAG, "User is not escrowable"); 1324 return false; 1325 } 1326 Slogf.i(TAG, "Creating token-based protector %016x for user %d", tokenHandle, userId); 1327 final IWeaver weaver = getWeaverService(); 1328 if (weaver != null) { 1329 int slot = getNextAvailableWeaverSlot(); 1330 Slogf.i(TAG, "Using Weaver slot %d for new token-based protector", slot); 1331 if (weaverEnroll(weaver, slot, null, tokenData.weaverSecret) == null) { 1332 Slog.e(TAG, "Failed to enroll weaver secret when activating token"); 1333 return false; 1334 } 1335 saveWeaverSlot(slot, tokenHandle, userId); 1336 mPasswordSlotManager.markSlotInUse(slot); 1337 } 1338 saveSecdiscardable(tokenHandle, tokenData.secdiscardableOnDisk, userId); 1339 createSyntheticPasswordBlob(tokenHandle, getTokenBasedProtectorType(tokenData.mType), sp, 1340 tokenData.aggregatedSecret, 0L, userId); 1341 syncState(userId); // ensure the new files are really saved to disk 1342 tokenMap.get(userId).remove(tokenHandle); 1343 if (tokenData.mCallback != null) { 1344 tokenData.mCallback.onEscrowTokenActivated(tokenHandle, userId); 1345 } 1346 return true; 1347 } 1348 1349 /** 1350 * Creates a synthetic password blob, i.e. the file that stores the encrypted synthetic password 1351 * (or encrypted escrow secret) for a protector. The caller is responsible for calling 1352 * {@link syncState()} afterwards, once all the protector's files have been created. 1353 */ createSyntheticPasswordBlob(long protectorId, byte protectorType, SyntheticPassword sp, byte[] protectorSecret, long sid, int userId)1354 private void createSyntheticPasswordBlob(long protectorId, byte protectorType, 1355 SyntheticPassword sp, byte[] protectorSecret, long sid, int userId) { 1356 final byte[] spSecret; 1357 if (protectorType == PROTECTOR_TYPE_STRONG_TOKEN_BASED 1358 || protectorType == PROTECTOR_TYPE_WEAK_TOKEN_BASED) { 1359 spSecret = sp.getEscrowSecret(); 1360 } else { 1361 spSecret = sp.getSyntheticPassword(); 1362 } 1363 byte[] content = createSpBlob(getProtectorKeyAlias(protectorId), spSecret, protectorSecret, 1364 sid); 1365 /* 1366 * We can upgrade from v1 to v2 because that's just a change in the way that 1367 * the SP is stored. However, we can't upgrade to v3 because that is a change 1368 * in the way that passwords are derived from the SP. 1369 */ 1370 byte version = sp.mVersion == SYNTHETIC_PASSWORD_VERSION_V3 1371 ? SYNTHETIC_PASSWORD_VERSION_V3 : SYNTHETIC_PASSWORD_VERSION_V2; 1372 1373 SyntheticPasswordBlob blob = SyntheticPasswordBlob.create(version, protectorType, content); 1374 saveState(SP_BLOB_NAME, blob.toByte(), protectorId, userId); 1375 } 1376 1377 /** 1378 * Tries to unlock a user's LSKF-based SP protector, given its ID and the claimed LSKF (which 1379 * may be empty). On success, returns the user's synthetic password, and also does a Gatekeeper 1380 * verification to refresh the SID and HardwareAuthToken maintained by the system. 1381 */ unlockLskfBasedProtector(IGateKeeperService gatekeeper, long protectorId, @NonNull LockscreenCredential credential, int userId, ICheckCredentialProgressCallback progressCallback)1382 public AuthenticationResult unlockLskfBasedProtector(IGateKeeperService gatekeeper, 1383 long protectorId, @NonNull LockscreenCredential credential, int userId, 1384 ICheckCredentialProgressCallback progressCallback) { 1385 AuthenticationResult result = new AuthenticationResult(); 1386 1387 if (protectorId == SyntheticPasswordManager.NULL_PROTECTOR_ID) { 1388 // This should never happen, due to the migration done in LSS.onThirdPartyAppsStarted(). 1389 Slogf.wtf(TAG, "Synthetic password not found for user %d", userId); 1390 result.gkResponse = VerifyCredentialResponse.ERROR; 1391 return result; 1392 } 1393 1394 // Load the PasswordData file. If it doesn't exist, then the LSKF is empty (i.e., 1395 // CREDENTIAL_TYPE_NONE), and we'll skip the scrypt and Gatekeeper steps. If it exists, 1396 // then either the LSKF is nonempty, or it's an old protector that uses scrypt and 1397 // Gatekeeper even though the LSKF is empty. 1398 byte[] pwdDataBytes = loadState(PASSWORD_DATA_NAME, protectorId, userId); 1399 PasswordData pwd = null; 1400 int storedType = LockPatternUtils.CREDENTIAL_TYPE_NONE; 1401 if (pwdDataBytes != null) { 1402 pwd = PasswordData.fromBytes(pwdDataBytes); 1403 storedType = pwd.credentialType; 1404 } 1405 if (!credential.checkAgainstStoredType(storedType)) { 1406 Slogf.e(TAG, "Credential type mismatch: stored type is %s but provided type is %s", 1407 LockPatternUtils.credentialTypeToString(storedType), 1408 LockPatternUtils.credentialTypeToString(credential.getType())); 1409 result.gkResponse = VerifyCredentialResponse.ERROR; 1410 return result; 1411 } 1412 1413 byte[] stretchedLskf = stretchLskf(credential, pwd); 1414 1415 final byte[] protectorSecret; 1416 long sid = GateKeeper.INVALID_SECURE_USER_ID; 1417 int weaverSlot = loadWeaverSlot(protectorId, userId); 1418 if (weaverSlot != INVALID_WEAVER_SLOT) { 1419 // Protector uses Weaver to verify the LSKF 1420 result.usedWeaver = true; 1421 final IWeaver weaver = getWeaverService(); 1422 if (weaver == null) { 1423 Slog.e(TAG, "Protector uses Weaver, but Weaver is unavailable"); 1424 result.gkResponse = VerifyCredentialResponse.ERROR; 1425 return result; 1426 } 1427 result.gkResponse = weaverVerify(weaver, weaverSlot, 1428 stretchedLskfToWeaverKey(stretchedLskf)); 1429 if (result.gkResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) { 1430 return result; 1431 } 1432 protectorSecret = transformUnderWeaverSecret(stretchedLskf, 1433 result.gkResponse.getGatekeeperHAT()); 1434 } else { 1435 // Weaver is unavailable, so the protector uses Gatekeeper to verify the LSKF, unless 1436 // the LSKF is empty in which case Gatekeeper might not have been used at all. 1437 if (pwd == null || pwd.passwordHandle == null) { 1438 if (!credential.isNone()) { 1439 Slog.e(TAG, "Missing Gatekeeper password handle for nonempty LSKF"); 1440 result.gkResponse = VerifyCredentialResponse.ERROR; 1441 return result; 1442 } 1443 } else { 1444 byte[] gkPassword = stretchedLskfToGkPassword(stretchedLskf); 1445 GateKeeperResponse response; 1446 try { 1447 response = gatekeeper.verifyChallenge(fakeUserId(userId), 0L, 1448 pwd.passwordHandle, gkPassword); 1449 } catch (RemoteException e) { 1450 Slog.e(TAG, "gatekeeper verify failed", e); 1451 result.gkResponse = VerifyCredentialResponse.ERROR; 1452 return result; 1453 } 1454 int responseCode = response.getResponseCode(); 1455 if (responseCode == GateKeeperResponse.RESPONSE_OK) { 1456 result.gkResponse = VerifyCredentialResponse.OK; 1457 if (response.getShouldReEnroll()) { 1458 GateKeeperResponse reenrollResponse; 1459 try { 1460 reenrollResponse = gatekeeper.enroll(fakeUserId(userId), 1461 pwd.passwordHandle, gkPassword, gkPassword); 1462 } catch (RemoteException e) { 1463 Slog.w(TAG, "Fail to invoke gatekeeper.enroll", e); 1464 reenrollResponse = GateKeeperResponse.ERROR; 1465 // continue the flow anyway 1466 } 1467 if (reenrollResponse.getResponseCode() == GateKeeperResponse.RESPONSE_OK) { 1468 pwd.passwordHandle = reenrollResponse.getPayload(); 1469 // Use the reenrollment opportunity to update credential type 1470 // (getting rid of CREDENTIAL_TYPE_PASSWORD_OR_PIN) 1471 pwd.credentialType = credential.getType(); 1472 saveState(PASSWORD_DATA_NAME, pwd.toBytes(), protectorId, userId); 1473 syncState(userId); 1474 synchronizeGatekeeperFrpPassword(pwd, 0, userId); 1475 } else { 1476 Slog.w(TAG, "Fail to re-enroll user password for user " + userId); 1477 // continue the flow anyway 1478 } 1479 } 1480 } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) { 1481 result.gkResponse = VerifyCredentialResponse.fromTimeout(response.getTimeout()); 1482 return result; 1483 } else { 1484 result.gkResponse = VerifyCredentialResponse.ERROR; 1485 return result; 1486 } 1487 sid = sidFromPasswordHandle(pwd.passwordHandle); 1488 } 1489 byte[] secdiscardable = loadSecdiscardable(protectorId, userId); 1490 if (secdiscardable == null) { 1491 Slog.e(TAG, "secdiscardable file not found"); 1492 result.gkResponse = VerifyCredentialResponse.ERROR; 1493 return result; 1494 } 1495 protectorSecret = transformUnderSecdiscardable(stretchedLskf, secdiscardable); 1496 } 1497 // Supplied credential passes first stage weaver/gatekeeper check so it should be correct. 1498 // Notify the callback so the keyguard UI can proceed immediately. 1499 if (progressCallback != null) { 1500 try { 1501 progressCallback.onCredentialVerified(); 1502 } catch (RemoteException e) { 1503 Slog.w(TAG, "progressCallback throws exception", e); 1504 } 1505 } 1506 result.syntheticPassword = unwrapSyntheticPasswordBlob(protectorId, 1507 PROTECTOR_TYPE_LSKF_BASED, protectorSecret, sid, userId); 1508 1509 // Perform verifyChallenge to refresh auth tokens for GK if user password exists. 1510 result.gkResponse = verifyChallenge(gatekeeper, result.syntheticPassword, 0L, userId); 1511 1512 // Upgrade case: store the metrics if the device did not have stored metrics before, should 1513 // only happen once on old protectors. 1514 if (result.syntheticPassword != null && !credential.isNone() 1515 && !hasPasswordMetrics(protectorId, userId)) { 1516 savePasswordMetrics(credential, result.syntheticPassword, protectorId, userId); 1517 syncState(userId); // Not strictly needed as the upgrade can be re-done, but be safe. 1518 } 1519 return result; 1520 } 1521 1522 /** 1523 * {@link LockPatternUtils#refreshStoredPinLength(int)} 1524 * @param passwordMetrics passwordMetrics object containing the cached pin length 1525 * @param userId userId of the user whose pin length we want to store on disk 1526 * @param protectorId current LSKF based protectorId 1527 * @return true/false depending on whether PIN length has been saved on disk 1528 */ refreshPinLengthOnDisk(PasswordMetrics passwordMetrics, long protectorId, int userId)1529 public boolean refreshPinLengthOnDisk(PasswordMetrics passwordMetrics, 1530 long protectorId, int userId) { 1531 if (!isAutoPinConfirmationFeatureAvailable()) { 1532 return false; 1533 } 1534 1535 byte[] pwdDataBytes = loadState(PASSWORD_DATA_NAME, protectorId, userId); 1536 if (pwdDataBytes == null) { 1537 return false; 1538 } 1539 1540 PasswordData pwd = PasswordData.fromBytes(pwdDataBytes); 1541 int pinLength = derivePinLength(passwordMetrics.length, 1542 passwordMetrics.credType == CREDENTIAL_TYPE_PIN, userId); 1543 if (pwd.pinLength != pinLength) { 1544 pwd.pinLength = pinLength; 1545 saveState(PASSWORD_DATA_NAME, pwd.toBytes(), protectorId, userId); 1546 syncState(userId); 1547 } 1548 return true; 1549 } 1550 1551 /** 1552 * Tries to unlock a token-based SP protector (weak or strong), given its ID and the claimed 1553 * token. On success, returns the user's synthetic password, and also does a Gatekeeper 1554 * verification to refresh the SID and HardwareAuthToken maintained by the system. 1555 */ unlockTokenBasedProtector( IGateKeeperService gatekeeper, long protectorId, byte[] token, int userId)1556 public @NonNull AuthenticationResult unlockTokenBasedProtector( 1557 IGateKeeperService gatekeeper, long protectorId, byte[] token, int userId) { 1558 byte[] data = loadState(SP_BLOB_NAME, protectorId, userId); 1559 if (data == null) { 1560 AuthenticationResult result = new AuthenticationResult(); 1561 result.gkResponse = VerifyCredentialResponse.ERROR; 1562 Slogf.w(TAG, "spblob not found for protector %016x, user %d", protectorId, userId); 1563 return result; 1564 } 1565 SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(data); 1566 return unlockTokenBasedProtectorInternal(gatekeeper, protectorId, blob.mProtectorType, 1567 token, userId); 1568 } 1569 1570 /** 1571 * Like {@link #unlockTokenBasedProtector}, but throws an exception if the protector is not for 1572 * a strong token specifically. 1573 */ unlockStrongTokenBasedProtector( IGateKeeperService gatekeeper, long protectorId, byte[] token, int userId)1574 public @NonNull AuthenticationResult unlockStrongTokenBasedProtector( 1575 IGateKeeperService gatekeeper, long protectorId, byte[] token, int userId) { 1576 return unlockTokenBasedProtectorInternal(gatekeeper, protectorId, 1577 PROTECTOR_TYPE_STRONG_TOKEN_BASED, token, userId); 1578 } 1579 1580 /** 1581 * Like {@link #unlockTokenBasedProtector}, but throws an exception if the protector is not for 1582 * a weak token specifically. 1583 */ unlockWeakTokenBasedProtector( IGateKeeperService gatekeeper, long protectorId, byte[] token, int userId)1584 public @NonNull AuthenticationResult unlockWeakTokenBasedProtector( 1585 IGateKeeperService gatekeeper, long protectorId, byte[] token, int userId) { 1586 return unlockTokenBasedProtectorInternal(gatekeeper, protectorId, 1587 PROTECTOR_TYPE_WEAK_TOKEN_BASED, token, userId); 1588 } 1589 unlockTokenBasedProtectorInternal( IGateKeeperService gatekeeper, long protectorId, byte expectedProtectorType, byte[] token, int userId)1590 private @NonNull AuthenticationResult unlockTokenBasedProtectorInternal( 1591 IGateKeeperService gatekeeper, long protectorId, byte expectedProtectorType, 1592 byte[] token, int userId) { 1593 AuthenticationResult result = new AuthenticationResult(); 1594 byte[] secdiscardable = loadSecdiscardable(protectorId, userId); 1595 if (secdiscardable == null) { 1596 Slog.e(TAG, "secdiscardable file not found"); 1597 result.gkResponse = VerifyCredentialResponse.ERROR; 1598 return result; 1599 } 1600 int slotId = loadWeaverSlot(protectorId, userId); 1601 if (slotId != INVALID_WEAVER_SLOT) { 1602 final IWeaver weaver = getWeaverService(); 1603 if (weaver == null) { 1604 Slog.e(TAG, "Protector uses Weaver, but Weaver is unavailable"); 1605 result.gkResponse = VerifyCredentialResponse.ERROR; 1606 return result; 1607 } 1608 VerifyCredentialResponse response = weaverVerify(weaver, slotId, null); 1609 if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK || 1610 response.getGatekeeperHAT() == null) { 1611 Slog.e(TAG, 1612 "Failed to retrieve Weaver secret when unlocking token-based protector"); 1613 result.gkResponse = VerifyCredentialResponse.ERROR; 1614 return result; 1615 } 1616 secdiscardable = SyntheticPasswordCrypto.decrypt(response.getGatekeeperHAT(), 1617 PERSONALIZATION_WEAVER_TOKEN, secdiscardable); 1618 } 1619 byte[] protectorSecret = transformUnderSecdiscardable(token, secdiscardable); 1620 result.syntheticPassword = unwrapSyntheticPasswordBlob(protectorId, expectedProtectorType, 1621 protectorSecret, 0L, userId); 1622 if (result.syntheticPassword != null) { 1623 result.gkResponse = verifyChallenge(gatekeeper, result.syntheticPassword, 0L, userId); 1624 if (result.gkResponse == null) { 1625 // The user currently has no password. return OK with null payload so null 1626 // is propagated to unlockUser() 1627 result.gkResponse = VerifyCredentialResponse.OK; 1628 } 1629 } else { 1630 result.gkResponse = VerifyCredentialResponse.ERROR; 1631 } 1632 return result; 1633 } 1634 unwrapSyntheticPasswordBlob(long protectorId, byte expectedProtectorType, byte[] protectorSecret, long sid, int userId)1635 private SyntheticPassword unwrapSyntheticPasswordBlob(long protectorId, 1636 byte expectedProtectorType, byte[] protectorSecret, long sid, int userId) { 1637 byte[] data = loadState(SP_BLOB_NAME, protectorId, userId); 1638 if (data == null) { 1639 return null; 1640 } 1641 SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(data); 1642 if (blob.mVersion != SYNTHETIC_PASSWORD_VERSION_V3 1643 && blob.mVersion != SYNTHETIC_PASSWORD_VERSION_V2 1644 && blob.mVersion != SYNTHETIC_PASSWORD_VERSION_V1) { 1645 throw new IllegalArgumentException("Unknown blob version: " + blob.mVersion); 1646 } 1647 if (blob.mProtectorType != expectedProtectorType) { 1648 throw new IllegalArgumentException("Invalid protector type: " + blob.mProtectorType); 1649 } 1650 final byte[] spSecret; 1651 if (blob.mVersion == SYNTHETIC_PASSWORD_VERSION_V1) { 1652 spSecret = SyntheticPasswordCrypto.decryptBlobV1(getProtectorKeyAlias(protectorId), 1653 blob.mContent, protectorSecret); 1654 } else { 1655 spSecret = decryptSpBlob(getProtectorKeyAlias(protectorId), blob.mContent, 1656 protectorSecret); 1657 } 1658 if (spSecret == null) { 1659 Slog.e(TAG, "Fail to decrypt SP for user " + userId); 1660 return null; 1661 } 1662 SyntheticPassword result = new SyntheticPassword(blob.mVersion); 1663 if (blob.mProtectorType == PROTECTOR_TYPE_STRONG_TOKEN_BASED 1664 || blob.mProtectorType == PROTECTOR_TYPE_WEAK_TOKEN_BASED) { 1665 if (!loadEscrowData(result, userId)) { 1666 Slog.e(TAG, "User is not escrowable: " + userId); 1667 return null; 1668 } 1669 result.recreateFromEscrow(spSecret); 1670 } else { 1671 result.recreateDirectly(spSecret); 1672 } 1673 if (blob.mVersion == SYNTHETIC_PASSWORD_VERSION_V1) { 1674 Slog.i(TAG, "Upgrading v1 SP blob for user " + userId + ", protectorType = " 1675 + blob.mProtectorType); 1676 createSyntheticPasswordBlob(protectorId, blob.mProtectorType, result, protectorSecret, 1677 sid, userId); 1678 syncState(userId); // Not strictly needed as the upgrade can be re-done, but be safe. 1679 } 1680 return result; 1681 } 1682 1683 /** 1684 * performs GK verifyChallenge and returns auth token, re-enrolling SP password handle 1685 * if required. 1686 * 1687 * Normally performing verifyChallenge with an SP should always return RESPONSE_OK, since user 1688 * authentication failures are detected earlier when trying to decrypt the SP. 1689 */ verifyChallenge(IGateKeeperService gatekeeper, @NonNull SyntheticPassword sp, long challenge, int userId)1690 public @Nullable VerifyCredentialResponse verifyChallenge(IGateKeeperService gatekeeper, 1691 @NonNull SyntheticPassword sp, long challenge, int userId) { 1692 return verifyChallengeInternal(gatekeeper, sp.deriveGkPassword(), challenge, userId); 1693 } 1694 verifyChallengeInternal( IGateKeeperService gatekeeper, @NonNull byte[] gatekeeperPassword, long challenge, int userId)1695 protected @Nullable VerifyCredentialResponse verifyChallengeInternal( 1696 IGateKeeperService gatekeeper, @NonNull byte[] gatekeeperPassword, long challenge, 1697 int userId) { 1698 byte[] spHandle = loadSyntheticPasswordHandle(userId); 1699 if (spHandle == null) { 1700 // There is no password handle associated with the given user, i.e. the user is not 1701 // secured by lockscreen and has no SID, so just return here; 1702 return null; 1703 } 1704 GateKeeperResponse response; 1705 try { 1706 response = gatekeeper.verifyChallenge(userId, challenge, 1707 spHandle, gatekeeperPassword); 1708 } catch (RemoteException e) { 1709 Slog.e(TAG, "Fail to verify with gatekeeper " + userId, e); 1710 return VerifyCredentialResponse.ERROR; 1711 } 1712 int responseCode = response.getResponseCode(); 1713 if (responseCode == GateKeeperResponse.RESPONSE_OK) { 1714 VerifyCredentialResponse result = new VerifyCredentialResponse.Builder() 1715 .setGatekeeperHAT(response.getPayload()).build(); 1716 if (response.getShouldReEnroll()) { 1717 try { 1718 response = gatekeeper.enroll(userId, spHandle, gatekeeperPassword, 1719 gatekeeperPassword); 1720 } catch (RemoteException e) { 1721 Slog.e(TAG, "Failed to invoke gatekeeper.enroll", e); 1722 response = GateKeeperResponse.ERROR; 1723 } 1724 if (response.getResponseCode() == GateKeeperResponse.RESPONSE_OK) { 1725 spHandle = response.getPayload(); 1726 saveSyntheticPasswordHandle(spHandle, userId); 1727 // Call self again to re-verify with updated handle 1728 return verifyChallengeInternal(gatekeeper, gatekeeperPassword, challenge, 1729 userId); 1730 } else { 1731 // Fall through, return result from the previous verification attempt. 1732 Slog.w(TAG, "Fail to re-enroll SP handle for user " + userId); 1733 } 1734 } 1735 return result; 1736 } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) { 1737 Slog.e(TAG, "Gatekeeper verification of synthetic password failed with RESPONSE_RETRY"); 1738 return VerifyCredentialResponse.fromTimeout(response.getTimeout()); 1739 } else { 1740 Slog.e(TAG, "Gatekeeper verification of synthetic password failed with RESPONSE_ERROR"); 1741 return VerifyCredentialResponse.ERROR; 1742 } 1743 } 1744 protectorExists(long protectorId, int userId)1745 public boolean protectorExists(long protectorId, int userId) { 1746 return hasState(SP_BLOB_NAME, protectorId, userId); 1747 } 1748 1749 /** Destroy a token-based SP protector. */ destroyTokenBasedProtector(long protectorId, int userId)1750 public void destroyTokenBasedProtector(long protectorId, int userId) { 1751 Slogf.i(TAG, "Destroying token-based protector %016x for user %d", protectorId, userId); 1752 SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME, 1753 protectorId, userId)); 1754 destroyProtectorCommon(protectorId, userId); 1755 if (blob.mProtectorType == PROTECTOR_TYPE_WEAK_TOKEN_BASED) { 1756 notifyWeakEscrowTokenRemovedListeners(protectorId, userId); 1757 } 1758 } 1759 1760 /** Destroy all weak token-based SP protectors for the given user. */ destroyAllWeakTokenBasedProtectors(int userId)1761 public void destroyAllWeakTokenBasedProtectors(int userId) { 1762 List<Long> protectorIds = 1763 mStorage.listSyntheticPasswordProtectorsForUser(SP_BLOB_NAME, userId); 1764 for (long protectorId : protectorIds) { 1765 SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME, 1766 protectorId, userId)); 1767 if (blob.mProtectorType == PROTECTOR_TYPE_WEAK_TOKEN_BASED) { 1768 destroyTokenBasedProtector(protectorId, userId); 1769 } 1770 } 1771 } 1772 1773 /** 1774 * Destroy an LSKF-based SP protector. This is used when the user's LSKF is changed. 1775 */ destroyLskfBasedProtector(long protectorId, int userId)1776 public void destroyLskfBasedProtector(long protectorId, int userId) { 1777 Slogf.i(TAG, "Destroying LSKF-based protector %016x for user %d", protectorId, userId); 1778 destroyProtectorCommon(protectorId, userId); 1779 destroyState(PASSWORD_DATA_NAME, protectorId, userId); 1780 destroyState(PASSWORD_METRICS_NAME, protectorId, userId); 1781 } 1782 destroyProtectorCommon(long protectorId, int userId)1783 private void destroyProtectorCommon(long protectorId, int userId) { 1784 destroyState(SP_BLOB_NAME, protectorId, userId); 1785 destroyProtectorKey(getProtectorKeyAlias(protectorId)); 1786 destroyState(SECDISCARDABLE_NAME, protectorId, userId); 1787 if (hasState(WEAVER_SLOT_NAME, protectorId, userId)) { 1788 destroyWeaverSlot(protectorId, userId); 1789 } 1790 } 1791 transformUnderWeaverSecret(byte[] data, byte[] secret)1792 private byte[] transformUnderWeaverSecret(byte[] data, byte[] secret) { 1793 byte[] weaverSecret = SyntheticPasswordCrypto.personalizedHash( 1794 PERSONALIZATION_WEAVER_PASSWORD, secret); 1795 return ArrayUtils.concat(data, weaverSecret); 1796 } 1797 transformUnderSecdiscardable(byte[] data, byte[] rawSecdiscardable)1798 private byte[] transformUnderSecdiscardable(byte[] data, byte[] rawSecdiscardable) { 1799 byte[] secdiscardable = SyntheticPasswordCrypto.personalizedHash( 1800 PERSONALIZATION_SECDISCARDABLE, rawSecdiscardable); 1801 return ArrayUtils.concat(data, secdiscardable); 1802 } 1803 1804 /** 1805 * Generates and writes the secdiscardable file for the given protector. The caller is 1806 * responsible for calling {@link syncState()} afterwards, once all the protector's files have 1807 * been created. 1808 */ createSecdiscardable(long protectorId, int userId)1809 private byte[] createSecdiscardable(long protectorId, int userId) { 1810 byte[] data = SecureRandomUtils.randomBytes(SECDISCARDABLE_LENGTH); 1811 saveSecdiscardable(protectorId, data, userId); 1812 return data; 1813 } 1814 1815 /** 1816 * Writes the secdiscardable file for the given protector. The caller is responsible for 1817 * calling {@link syncState()} afterwards, once all the protector's files have been created. 1818 */ saveSecdiscardable(long protectorId, byte[] secdiscardable, int userId)1819 private void saveSecdiscardable(long protectorId, byte[] secdiscardable, int userId) { 1820 saveState(SECDISCARDABLE_NAME, secdiscardable, protectorId, userId); 1821 } 1822 loadSecdiscardable(long protectorId, int userId)1823 private byte[] loadSecdiscardable(long protectorId, int userId) { 1824 return loadState(SECDISCARDABLE_NAME, protectorId, userId); 1825 } 1826 getTokenBasedProtectorType(@okenType int type)1827 private byte getTokenBasedProtectorType(@TokenType int type) { 1828 switch (type) { 1829 case TOKEN_TYPE_WEAK: 1830 return PROTECTOR_TYPE_WEAK_TOKEN_BASED; 1831 case TOKEN_TYPE_STRONG: 1832 default: 1833 return PROTECTOR_TYPE_STRONG_TOKEN_BASED; 1834 } 1835 } 1836 1837 @VisibleForTesting hasPasswordData(long protectorId, int userId)1838 boolean hasPasswordData(long protectorId, int userId) { 1839 return hasState(PASSWORD_DATA_NAME, protectorId, userId); 1840 } 1841 1842 /** 1843 * Retrieves a user's saved password metrics from their LSKF-based SP protector. The 1844 * SyntheticPassword itself is needed to decrypt the file containing the password metrics. 1845 */ getPasswordMetrics(SyntheticPassword sp, long protectorId, int userId)1846 public @Nullable PasswordMetrics getPasswordMetrics(SyntheticPassword sp, long protectorId, 1847 int userId) { 1848 final byte[] encrypted = loadState(PASSWORD_METRICS_NAME, protectorId, userId); 1849 if (encrypted == null) { 1850 Slogf.e(TAG, "Failed to read password metrics file for user %d", userId); 1851 return null; 1852 } 1853 final byte[] decrypted = SyntheticPasswordCrypto.decrypt(sp.deriveMetricsKey(), 1854 /* personalization= */ new byte[0], encrypted); 1855 if (decrypted == null) { 1856 Slogf.e(TAG, "Failed to decrypt password metrics file for user %d", userId); 1857 return null; 1858 } 1859 return VersionedPasswordMetrics.deserialize(decrypted).getMetrics(); 1860 } 1861 1862 /** 1863 * Creates the password metrics file: the file associated with the LSKF-based protector that 1864 * contains the encrypted metrics about the LSKF. The caller is responsible for calling 1865 * {@link syncState()} afterwards if needed. 1866 */ savePasswordMetrics(LockscreenCredential credential, SyntheticPassword sp, long protectorId, int userId)1867 private void savePasswordMetrics(LockscreenCredential credential, SyntheticPassword sp, 1868 long protectorId, int userId) { 1869 final byte[] encrypted = SyntheticPasswordCrypto.encrypt(sp.deriveMetricsKey(), 1870 /* personalization= */ new byte[0], 1871 new VersionedPasswordMetrics(credential).serialize()); 1872 saveState(PASSWORD_METRICS_NAME, encrypted, protectorId, userId); 1873 } 1874 1875 @VisibleForTesting hasPasswordMetrics(long protectorId, int userId)1876 boolean hasPasswordMetrics(long protectorId, int userId) { 1877 return hasState(PASSWORD_METRICS_NAME, protectorId, userId); 1878 } 1879 hasState(String stateName, long protectorId, int userId)1880 private boolean hasState(String stateName, long protectorId, int userId) { 1881 return !ArrayUtils.isEmpty(loadState(stateName, protectorId, userId)); 1882 } 1883 loadState(String stateName, long protectorId, int userId)1884 private byte[] loadState(String stateName, long protectorId, int userId) { 1885 return mStorage.readSyntheticPasswordState(userId, protectorId, stateName); 1886 } 1887 1888 /** 1889 * Persists the given synthetic password state for the given user ID and protector ID. 1890 * <p> 1891 * For performance reasons, this doesn't sync the user's synthetic password state directory. As 1892 * a result, it doesn't guarantee that the file will really be present after a crash. If that 1893 * is needed, call {@link syncState()} afterwards, preferably after batching up related updates. 1894 */ saveState(String stateName, byte[] data, long protectorId, int userId)1895 private void saveState(String stateName, byte[] data, long protectorId, int userId) { 1896 mStorage.writeSyntheticPasswordState(userId, protectorId, stateName, data); 1897 } 1898 syncState(int userId)1899 private void syncState(int userId) { 1900 mStorage.syncSyntheticPasswordState(userId); 1901 } 1902 destroyState(String stateName, long protectorId, int userId)1903 private void destroyState(String stateName, long protectorId, int userId) { 1904 mStorage.deleteSyntheticPasswordState(userId, protectorId, stateName); 1905 } 1906 1907 @VisibleForTesting decryptSpBlob(String protectorKeyAlias, byte[] blob, byte[] protectorSecret)1908 protected byte[] decryptSpBlob(String protectorKeyAlias, byte[] blob, byte[] protectorSecret) { 1909 return SyntheticPasswordCrypto.decryptBlob(protectorKeyAlias, blob, protectorSecret); 1910 } 1911 1912 @VisibleForTesting createSpBlob(String protectorKeyAlias, byte[] data, byte[] protectorSecret, long sid)1913 protected byte[] createSpBlob(String protectorKeyAlias, byte[] data, byte[] protectorSecret, 1914 long sid) { 1915 return SyntheticPasswordCrypto.createBlob(protectorKeyAlias, data, protectorSecret, sid); 1916 } 1917 1918 @VisibleForTesting destroyProtectorKey(String keyAlias)1919 protected void destroyProtectorKey(String keyAlias) { 1920 SyntheticPasswordCrypto.destroyProtectorKey(keyAlias); 1921 } 1922 generateProtectorId()1923 private static long generateProtectorId() { 1924 while (true) { 1925 final long result = SecureRandomUtils.randomLong(); 1926 if (result != NULL_PROTECTOR_ID) { 1927 return result; 1928 } 1929 } 1930 } 1931 1932 @VisibleForTesting fakeUserId(int userId)1933 static int fakeUserId(int userId) { 1934 return 100000 + userId; 1935 } 1936 getProtectorKeyAlias(long protectorId)1937 private String getProtectorKeyAlias(long protectorId) { 1938 // Note, this arguably has a bug: %x should be %016x so that the protector ID is left-padded 1939 // with zeroes, like how the synthetic password state files are named. It's too late to fix 1940 // this, though, and it doesn't actually matter. 1941 return TextUtils.formatSimple("%s%x", PROTECTOR_KEY_ALIAS_PREFIX, protectorId); 1942 } 1943 1944 /** 1945 * Stretches <code>credential</code>, if needed, using the parameters from <code>data</code>. 1946 * <p> 1947 * When the credential is empty, stetching provides no security benefit. Thus, new protectors 1948 * for an empty credential use <code>null</code> {@link PasswordData} and skip the stretching. 1949 * <p> 1950 * However, old protectors always stored {@link PasswordData} and did the stretching, regardless 1951 * of whether the credential was empty or not. For this reason, this method also continues to 1952 * support stretching of empty credentials so that old protectors can still be unlocked. 1953 */ 1954 @VisibleForTesting stretchLskf(LockscreenCredential credential, @Nullable PasswordData data)1955 byte[] stretchLskf(LockscreenCredential credential, @Nullable PasswordData data) { 1956 final byte[] password = credential.isNone() ? DEFAULT_PASSWORD : credential.getCredential(); 1957 if (data == null) { 1958 Preconditions.checkArgument(credential.isNone()); 1959 return Arrays.copyOf(password, STRETCHED_LSKF_LENGTH); 1960 } 1961 return scrypt(password, data.salt, 1 << data.scryptLogN, 1 << data.scryptLogR, 1962 1 << data.scryptLogP, STRETCHED_LSKF_LENGTH); 1963 } 1964 stretchedLskfToGkPassword(byte[] stretchedLskf)1965 private byte[] stretchedLskfToGkPassword(byte[] stretchedLskf) { 1966 return SyntheticPasswordCrypto.personalizedHash(PERSONALIZATION_USER_GK_AUTH, 1967 stretchedLskf); 1968 } 1969 stretchedLskfToWeaverKey(byte[] stretchedLskf)1970 private byte[] stretchedLskfToWeaverKey(byte[] stretchedLskf) { 1971 byte[] key = SyntheticPasswordCrypto.personalizedHash(PERSONALIZATION_WEAVER_KEY, 1972 stretchedLskf); 1973 if (key.length < mWeaverConfig.keySize) { 1974 throw new IllegalArgumentException("weaver key length too small"); 1975 } 1976 return Arrays.copyOf(key, mWeaverConfig.keySize); 1977 } 1978 1979 @VisibleForTesting sidFromPasswordHandle(byte[] handle)1980 protected long sidFromPasswordHandle(byte[] handle) { 1981 return nativeSidFromPasswordHandle(handle); 1982 } 1983 1984 @VisibleForTesting scrypt(byte[] password, byte[] salt, int n, int r, int p, int outLen)1985 protected byte[] scrypt(byte[] password, byte[] salt, int n, int r, int p, int outLen) { 1986 return new Scrypt().scrypt(password, salt, n, r, p, outLen); 1987 } 1988 nativeSidFromPasswordHandle(byte[] handle)1989 private native long nativeSidFromPasswordHandle(byte[] handle); 1990 1991 @VisibleForTesting bytesToHex(byte[] bytes)1992 static byte[] bytesToHex(byte[] bytes) { 1993 return HexEncoding.encodeToString(bytes).getBytes(); 1994 } 1995 1996 /** 1997 * Migrates all existing SP protector keys from uid 1000 app domain to LSS selinux domain. 1998 */ migrateKeyNamespace()1999 public boolean migrateKeyNamespace() { 2000 boolean success = true; 2001 final Map<Integer, List<Long>> allProtectors = 2002 mStorage.listSyntheticPasswordProtectorsForAllUsers(SP_BLOB_NAME); 2003 for (List<Long> userProtectors : allProtectors.values()) { 2004 for (long protectorId : userProtectors) { 2005 success &= SyntheticPasswordCrypto.migrateLockSettingsKey( 2006 getProtectorKeyAlias(protectorId)); 2007 } 2008 } 2009 return success; 2010 } 2011 2012 /** Register the given IWeakEscrowTokenRemovedListener. */ registerWeakEscrowTokenRemovedListener( IWeakEscrowTokenRemovedListener listener)2013 public boolean registerWeakEscrowTokenRemovedListener( 2014 IWeakEscrowTokenRemovedListener listener) { 2015 return mListeners.register(listener); 2016 } 2017 2018 /** Unregister the given IWeakEscrowTokenRemovedListener. */ unregisterWeakEscrowTokenRemovedListener( IWeakEscrowTokenRemovedListener listener)2019 public boolean unregisterWeakEscrowTokenRemovedListener( 2020 IWeakEscrowTokenRemovedListener listener) { 2021 return mListeners.unregister(listener); 2022 } 2023 notifyWeakEscrowTokenRemovedListeners(long protectorId, int userId)2024 private void notifyWeakEscrowTokenRemovedListeners(long protectorId, int userId) { 2025 int i = mListeners.beginBroadcast(); 2026 try { 2027 while (i > 0) { 2028 i--; 2029 try { 2030 mListeners.getBroadcastItem(i).onWeakEscrowTokenRemoved(protectorId, userId); 2031 } catch (RemoteException e) { 2032 Slog.e(TAG, "Exception while notifying WeakEscrowTokenRemovedListener.", 2033 e); 2034 } 2035 } 2036 } finally { 2037 mListeners.finishBroadcast(); 2038 } 2039 } 2040 writeVendorAuthSecret( @onNull final byte[] vendorAuthSecret, @NonNull final SyntheticPassword sp, @UserIdInt final int userId)2041 public void writeVendorAuthSecret( 2042 @NonNull final byte[] vendorAuthSecret, 2043 @NonNull final SyntheticPassword sp, 2044 @UserIdInt final int userId) { 2045 final byte[] encrypted = 2046 SyntheticPasswordCrypto.encrypt( 2047 sp.deriveVendorAuthSecretEncryptionKey(), new byte[0], vendorAuthSecret); 2048 saveState(VENDOR_AUTH_SECRET_NAME, encrypted, NULL_PROTECTOR_ID, userId); 2049 syncState(userId); 2050 } 2051 readVendorAuthSecret( @onNull final SyntheticPassword sp, @UserIdInt final int userId)2052 public @Nullable byte[] readVendorAuthSecret( 2053 @NonNull final SyntheticPassword sp, @UserIdInt final int userId) { 2054 final byte[] encrypted = loadState(VENDOR_AUTH_SECRET_NAME, NULL_PROTECTOR_ID, userId); 2055 if (encrypted == null) { 2056 return null; 2057 } 2058 return SyntheticPasswordCrypto.decrypt( 2059 sp.deriveVendorAuthSecretEncryptionKey(), new byte[0], encrypted); 2060 } 2061 } 2062