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