1 /* 2 * Copyright 2020 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.internal.telephony.uicc; 18 19 import static android.security.keystore.KeyProperties.AUTH_DEVICE_CREDENTIAL; 20 import static android.security.keystore.KeyProperties.BLOCK_MODE_GCM; 21 import static android.security.keystore.KeyProperties.ENCRYPTION_PADDING_NONE; 22 import static android.security.keystore.KeyProperties.KEY_ALGORITHM_AES; 23 import static android.security.keystore.KeyProperties.PURPOSE_DECRYPT; 24 import static android.security.keystore.KeyProperties.PURPOSE_ENCRYPT; 25 26 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT; 27 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__CACHED_PIN_DISCARDED; 28 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_COUNT_NOT_MATCHING_AFTER_REBOOT; 29 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_DECRYPTION_ERROR; 30 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_ENCRYPTION_ERROR; 31 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_REQUIRED_AFTER_REBOOT; 32 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_STORED_FOR_VERIFICATION; 33 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_FAILURE; 34 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_SKIPPED_SIM_CARD_MISMATCH; 35 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_SUCCESS; 36 import static com.android.internal.telephony.uicc.IccCardStatus.PinState.PINSTATE_ENABLED_NOT_VERIFIED; 37 import static com.android.internal.telephony.uicc.IccCardStatus.PinState.PINSTATE_ENABLED_VERIFIED; 38 39 import android.annotation.Nullable; 40 import android.app.KeyguardManager; 41 import android.content.BroadcastReceiver; 42 import android.content.Context; 43 import android.content.Intent; 44 import android.content.IntentFilter; 45 import android.content.SharedPreferences; 46 import android.os.AsyncResult; 47 import android.os.Handler; 48 import android.os.Message; 49 import android.os.PersistableBundle; 50 import android.os.WorkSource; 51 import android.provider.Settings; 52 import android.security.keystore.KeyGenParameterSpec; 53 import android.telephony.CarrierConfigManager; 54 import android.telephony.TelephonyManager; 55 import android.telephony.TelephonyManager.SimState; 56 import android.util.Base64; 57 import android.util.SparseArray; 58 59 import com.android.internal.R; 60 import com.android.internal.annotations.VisibleForTesting; 61 import com.android.internal.telephony.Phone; 62 import com.android.internal.telephony.PhoneConstants; 63 import com.android.internal.telephony.PhoneFactory; 64 import com.android.internal.telephony.SubscriptionInfoUpdater; 65 import com.android.internal.telephony.TelephonyStatsLog; 66 import com.android.internal.telephony.nano.StoredPinProto.EncryptedPin; 67 import com.android.internal.telephony.nano.StoredPinProto.StoredPin; 68 import com.android.internal.telephony.nano.StoredPinProto.StoredPin.PinStatus; 69 import com.android.internal.telephony.uicc.IccCardStatus.PinState; 70 import com.android.internal.util.ArrayUtils; 71 import com.android.telephony.Rlog; 72 73 import java.io.FileDescriptor; 74 import java.io.PrintWriter; 75 import java.security.KeyStore; 76 import java.util.Arrays; 77 import java.util.Calendar; 78 import java.util.Date; 79 80 import javax.crypto.Cipher; 81 import javax.crypto.KeyGenerator; 82 import javax.crypto.SecretKey; 83 import javax.crypto.spec.GCMParameterSpec; 84 85 /** 86 * This class stores the SIM PIN for automatic verification after an unattended reboot. 87 */ 88 public class PinStorage extends Handler { 89 private static final String TAG = "PinStorage"; 90 private static final boolean VDBG = false; // STOPSHIP if true 91 92 /** 93 * Time duration in milliseconds to allow automatic PIN verification after reboot. All unused 94 * PINs are discarded when the timer expires. 95 */ 96 private static final int TIMER_VALUE_AFTER_OTA_MILLIS = 20_000; 97 98 /** 99 * Time duration in milliseconds to reboot the device after {@code prepareUnattendedReboot} 100 * is invoked. After the time expires, a new invocation of {@code prepareUnattendedReboot} is 101 * required to perform the automatic PIN verification after reboot. 102 */ 103 private static final int TIMER_VALUE_BEFORE_OTA_MILLIS = 20_000; 104 105 /** Minimum valid length of the ICCID. */ 106 private static final int MIN_ICCID_LENGTH = 12; 107 /** Minimum length of the SIM PIN, as per 3GPP TS 31.101. */ 108 private static final int MIN_PIN_LENGTH = 4; 109 /** Maximum length of the SIM PIN, as per 3GPP TS 31.101. */ 110 private static final int MAX_PIN_LENGTH = 8; 111 112 // Variables related to the encryption of the SIM PIN. 113 private static final String ANDROID_KEY_STORE_PROVIDER = "AndroidKeyStore"; 114 private static final String CIPHER_TRANSFORMATION = "AES/GCM/NoPadding"; 115 private static final int GCM_PARAMETER_TAG_BIT_LEN = 128; 116 private static final int SHORT_TERM_KEY_DURATION_MINUTES = 15; 117 118 /** Alias of the long-term key that does not require user authentication. */ 119 private static final String KEYSTORE_ALIAS_LONG_TERM_ALWAYS = "PinStorage_longTerm_always_key"; 120 /** Alias of the user authentication blound long-term key. */ 121 private static final String KEYSTORE_ALIAS_LONG_TERM_USER_AUTH = "PinStorage_longTerm_ua_key"; 122 /** Alias of the short-term key (30 minutes) used before and after an unattended reboot. */ 123 private static final String KEYSTORE_ALIAS_SHORT_TERM = "PinStorage_shortTerm_key"; 124 125 // Constants related to the storage of the encrypted SIM PIN to non-volatile memory. 126 // Data is stored in two separate files: 127 // - "available" is for the PIN(s) in AVAILABLE state and uses a key that does not expire 128 // - "reboot" is for the PIN(s) in other states and uses a short-term key (30 minutes) 129 private static final String SHARED_PREFS_NAME = "pinstorage_prefs"; 130 private static final String SHARED_PREFS_AVAILABLE_PIN_BASE_KEY = "encrypted_pin_available_"; 131 private static final String SHARED_PREFS_REBOOT_PIN_BASE_KEY = "encrypted_pin_reboot_"; 132 private static final String SHARED_PREFS_STORED_PINS = "stored_pins"; 133 134 // Events 135 private static final int ICC_CHANGED_EVENT = 1; 136 private static final int CARRIER_CONFIG_CHANGED_EVENT = 2; 137 private static final int TIMER_EXPIRATION_EVENT = 3; 138 private static final int USER_UNLOCKED_EVENT = 4; 139 private static final int SUPPLY_PIN_COMPLETE = 5; 140 141 private final Context mContext; 142 private final int mBootCount; 143 private final KeyStore mKeyStore; 144 145 private SecretKey mLongTermSecretKey; 146 private SecretKey mShortTermSecretKey; 147 148 private boolean mIsDeviceSecure; 149 private boolean mIsDeviceLocked; 150 private boolean mLastCommitResult = true; 151 152 /** Duration of the short-term key, in minutes. */ 153 @VisibleForTesting 154 public int mShortTermSecretKeyDurationMinutes; 155 156 /** RAM storage is used on secure devices before the device is unlocked. */ 157 private final SparseArray<byte[]> mRamStorage; 158 159 /** Receiver for the required intents. */ 160 private final BroadcastReceiver mCarrierConfigChangedReceiver = new BroadcastReceiver() { 161 @Override 162 public void onReceive(Context context, Intent intent) { 163 String action = intent.getAction(); 164 if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)) { 165 int slotId = intent.getIntExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, -1); 166 sendMessage(obtainMessage(CARRIER_CONFIG_CHANGED_EVENT, slotId, 0)); 167 } else if (TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED.equals(action) 168 || TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED.equals(action)) { 169 int slotId = intent.getIntExtra(PhoneConstants.PHONE_KEY, -1); 170 int state = intent.getIntExtra( 171 TelephonyManager.EXTRA_SIM_STATE, TelephonyManager.SIM_STATE_UNKNOWN); 172 if (validateSlotId(slotId)) { 173 sendMessage(obtainMessage(ICC_CHANGED_EVENT, slotId, state)); 174 } 175 } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) { 176 sendMessage(obtainMessage(USER_UNLOCKED_EVENT)); 177 } 178 } 179 }; 180 PinStorage(Context context)181 public PinStorage(Context context) { 182 mContext = context; 183 mBootCount = getBootCount(); 184 mKeyStore = initializeKeyStore(); 185 mShortTermSecretKeyDurationMinutes = SHORT_TERM_KEY_DURATION_MINUTES; 186 187 mIsDeviceSecure = isDeviceSecure(); 188 mIsDeviceLocked = mIsDeviceSecure ? isDeviceLocked() : false; 189 190 // Register for necessary intents. 191 IntentFilter intentFilter = new IntentFilter(); 192 intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); 193 intentFilter.addAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED); 194 intentFilter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED); 195 intentFilter.addAction(Intent.ACTION_USER_UNLOCKED); 196 mContext.registerReceiver(mCarrierConfigChangedReceiver, intentFilter); 197 198 // Initialize the long term secret key. This needs to be present in all cases: 199 // - if the device is not secure or is locked: key does not require user authentication 200 // - if the device is secure and unlocked: key requires user authentication. 201 // The short term key is retrieved later when needed. 202 String alias = (!mIsDeviceSecure || mIsDeviceLocked) 203 ? KEYSTORE_ALIAS_LONG_TERM_ALWAYS : KEYSTORE_ALIAS_LONG_TERM_USER_AUTH; 204 mLongTermSecretKey = initializeSecretKey(alias, /*createIfAbsent=*/ true); 205 206 // If the device is not securee or is unlocked, we can start logic. Otherwise we need to 207 // wait for the device to be unlocked and store any temporary PIN in RAM. 208 if (!mIsDeviceSecure || !mIsDeviceLocked) { 209 mRamStorage = null; 210 onDeviceReady(); 211 } else { 212 logd("Device is locked - Postponing initialization"); 213 mRamStorage = new SparseArray<>(); 214 } 215 } 216 217 /** Store the {@code pin} for the {@code slotId}. */ storePin(String pin, int slotId)218 public synchronized void storePin(String pin, int slotId) { 219 String iccid = getIccid(slotId); 220 221 if (!validatePin(pin) || !validateIccid(iccid) || !validateSlotId(slotId)) { 222 // We are unable to store the PIN. At least clear the old one, if present. 223 loge("storePin[%d] - Invalid PIN, slotId or ICCID", slotId); 224 clearPin(slotId); 225 return; 226 } 227 if (!isCacheAllowed(slotId)) { 228 logd("storePin[%d]: caching it not allowed", slotId); 229 return; 230 } 231 232 logd("storePin[%d]", slotId); 233 234 StoredPin storedPin = new StoredPin(); 235 storedPin.iccid = iccid; 236 storedPin.pin = pin; 237 storedPin.slotId = slotId; 238 storedPin.status = PinStatus.AVAILABLE; 239 240 savePinInformation(slotId, storedPin); 241 } 242 243 /** Clear the cached pin for the {@code slotId}. */ clearPin(int slotId)244 public synchronized void clearPin(int slotId) { 245 logd("clearPin[%d]", slotId); 246 247 if (!validateSlotId(slotId)) { 248 return; 249 } 250 savePinInformation(slotId, null); 251 } 252 253 /** 254 * Return the cached pin for the SIM card identified by {@code slotId} and {@code iccid}, or 255 * an empty string if it is not available. 256 * 257 * The method returns the PIN only if the state is VERIFICATION_READY. If the PIN is found, 258 * its state changes to AVAILABLE, so that it cannot be retrieved a second time during the 259 * same boot cycle. If the PIN verification fails, it will be removed after the failed attempt. 260 */ getPin(int slotId, String iccid)261 public synchronized String getPin(int slotId, String iccid) { 262 if (!validateSlotId(slotId) || !validateIccid(iccid)) { 263 return ""; 264 } 265 266 StoredPin storedPin = loadPinInformation(slotId); 267 if (storedPin != null) { 268 if (!storedPin.iccid.equals(iccid)) { 269 // The ICCID does not match: it's possible that the SIM card was changed. 270 // Delete the cached PIN. 271 savePinInformation(slotId, null); 272 TelephonyStatsLog.write(PIN_STORAGE_EVENT, 273 PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_SKIPPED_SIM_CARD_MISMATCH, 274 /* number_of_pins= */ 1, /* package_name= */ ""); 275 } else if (storedPin.status == PinStatus.VERIFICATION_READY) { 276 logd("getPin[%d] - Found PIN ready for verification", slotId); 277 // Move the state to AVAILABLE, so that it cannot be retrieved again. 278 storedPin.status = PinStatus.AVAILABLE; 279 savePinInformation(slotId, storedPin); 280 return storedPin.pin; 281 } 282 } 283 return ""; 284 } 285 286 /** 287 * Prepare for an unattended reboot. 288 * 289 * All PINs in AVAILABLE and VERIFICATION_READY state are moved to REBOOT_READY state. A 290 * timer is started to make sure that reboot occurs shortly after invoking this method. 291 * 292 * @return The result of the reboot preparation. 293 */ 294 @TelephonyManager.PrepareUnattendedRebootResult prepareUnattendedReboot(WorkSource workSource)295 public synchronized int prepareUnattendedReboot(WorkSource workSource) { 296 // Unattended reboot should never occur before the device is unlocked. 297 if (mIsDeviceLocked) { 298 loge("prepareUnattendedReboot - Device is locked"); 299 return TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR; 300 } 301 302 // Start timer to make sure that device is rebooted shortly after this is executed. 303 if (!startTimer(TIMER_VALUE_BEFORE_OTA_MILLIS)) { 304 return TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR; 305 } 306 307 int numSlots = getSlotCount(); 308 SparseArray<StoredPin> storedPins = loadPinInformation(); 309 310 // Delete any previous short-term key, if present: a new one is created (if needed). 311 deleteSecretKey(KEYSTORE_ALIAS_SHORT_TERM); 312 mShortTermSecretKey = null; 313 314 // If any PIN is present, generate a new short-term key to save PIN(s) to 315 // non-volatile memory. 316 if (storedPins.size() > 0) { 317 mShortTermSecretKey = 318 initializeSecretKey(KEYSTORE_ALIAS_SHORT_TERM, /*createIfAbsent=*/ true); 319 } 320 321 @TelephonyManager.PrepareUnattendedRebootResult 322 int result = TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS; 323 int storedCount = 0; 324 int notAvailableCount = 0; 325 326 for (int slotId = 0; slotId < numSlots; slotId++) { 327 StoredPin storedPin = storedPins.get(slotId); 328 if (storedPin != null) { 329 storedPin.status = PinStatus.REBOOT_READY; 330 if (!savePinInformation(slotId, storedPin)) { 331 result = TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR; 332 break; 333 } 334 storedCount++; 335 } else if (isPinState(slotId, PINSTATE_ENABLED_VERIFIED)) { 336 // If PIN is not available, check if PIN will be required after reboot (current PIN 337 // status is enabled and verified). 338 loge("Slot %d requires PIN and is not cached", slotId); 339 result = TelephonyManager.PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED; 340 notAvailableCount++; 341 } 342 } 343 344 // Generate metrics 345 String callingPackage = workSource == null || workSource.size() == 0 346 ? "" : workSource.getPackageName(0); 347 if (result == TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS) { 348 logd("prepareUnattendedReboot - Stored %d PINs", storedCount); 349 TelephonyStatsLog.write(PIN_STORAGE_EVENT, 350 PIN_STORAGE_EVENT__EVENT__PIN_STORED_FOR_VERIFICATION, storedCount, 351 callingPackage); 352 } else if (result == TelephonyManager.PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED) { 353 logd("prepareUnattendedReboot - Required %d PINs after reboot", notAvailableCount); 354 TelephonyStatsLog.write(PIN_STORAGE_EVENT, 355 PIN_STORAGE_EVENT__EVENT__PIN_REQUIRED_AFTER_REBOOT, notAvailableCount, 356 callingPackage); 357 } 358 359 // Save number of PINs to generate metrics after reboot 360 saveNumberOfCachedPins(storedCount); 361 362 return result; 363 } 364 365 /** 366 * Execute logic when a secure device is unlocked. 367 * 368 * The temporary long-term key that does not require user verification is replaced by the long 369 * term key that requires user verification. The cached PIN temporarily stored in RAM are 370 * merged with those on disk from the previous boot. 371 */ onUserUnlocked()372 private synchronized void onUserUnlocked() { 373 if (!mIsDeviceLocked) { 374 // This should never happen. 375 // Nothing to do because the device was already unlocked before 376 return; 377 } 378 379 logd("onUserUnlocked - Device is unlocked"); 380 381 // It's possible that SIM PIN was already verified and stored temporarily in RAM. Load the 382 // data and erase the memory. 383 SparseArray<StoredPin> storedPinInRam = loadPinInformation(); 384 cleanRamStorage(); 385 386 // Mark the device as unlocked 387 mIsDeviceLocked = false; 388 389 // Replace the temporary long-term key without user authentication with a new long-term 390 // key that requires user authentication to save all PINs previously in RAM (all in 391 // AVAILABLE state) to disk. 392 mLongTermSecretKey = 393 initializeSecretKey(KEYSTORE_ALIAS_LONG_TERM_USER_AUTH, /*createIfAbsent=*/ true); 394 395 // Save the PINs previously in RAM to disk, overwriting any PIN that might already exists. 396 for (int i = 0; i < storedPinInRam.size(); i++) { 397 savePinInformation(storedPinInRam.keyAt(i), storedPinInRam.valueAt(i)); 398 } 399 400 // At this point the module is fully initialized. Execute the start logic. 401 onDeviceReady(); 402 403 // Verify any pending PIN for SIM cards that need it. 404 verifyPendingPins(); 405 } 406 407 /** 408 * Executes logic when module is fully ready. This occurs immediately if the device is not 409 * secure or after the user unlocks the device. 410 * 411 * At this point, the short-term key is initialized (if present), the configuration is read 412 * and the status of each PIN is updated as needed. 413 */ onDeviceReady()414 private void onDeviceReady() { 415 logd("onDeviceReady"); 416 417 // Try to initialize the short term key, if present, as this would be required to read 418 // stored PIN for verification. 419 mShortTermSecretKey = 420 initializeSecretKey(KEYSTORE_ALIAS_SHORT_TERM, /*createIfAbsent=*/ false); 421 422 int verificationReadyCount = 0; 423 int slotCount = getSlotCount(); 424 for (int slotId = 0; slotId < slotCount; slotId++) { 425 // Read PIN information from storage 426 StoredPin storedPin = loadPinInformation(slotId); 427 if (storedPin == null) { 428 continue; 429 } 430 431 // For each PIN in AVAILABLE state, check the boot count. 432 // If the boot count matches, it means that module crashed and it's ok to preserve 433 // the PIN code. If the boot count does not match, then delete those PINs. 434 if (storedPin.status == PinStatus.AVAILABLE) { 435 if (storedPin.bootCount != mBootCount) { 436 logd("Boot count [%d] does not match - remove PIN", slotId); 437 savePinInformation(slotId, null); 438 continue; 439 } 440 logd("Boot count [%d] matches - keep stored PIN", slotId); 441 } 442 443 // If there is any PIN in REBOOT_READY state, move it to VERIFICATION_READY and start 444 // the timer. Don't change PINs that might be already in VERIFICATION_READY state 445 // (e.g. due to crash). 446 if (storedPin.status == PinStatus.REBOOT_READY) { 447 storedPin.status = PinStatus.VERIFICATION_READY; 448 savePinInformation(slotId, storedPin); 449 verificationReadyCount++; 450 } 451 } 452 if (verificationReadyCount > 0) { 453 startTimer(TIMER_VALUE_AFTER_OTA_MILLIS); 454 } 455 456 // Generate metrics for PINs that had been stored before reboot, but are not available 457 // after. This can happen if there is an excessive delay in unlocking the device (short 458 // term key expires), but also if a new SIM card without PIN is present. 459 int prevCachedPinCount = saveNumberOfCachedPins(0); 460 if (prevCachedPinCount > verificationReadyCount) { 461 TelephonyStatsLog.write(PIN_STORAGE_EVENT, 462 PIN_STORAGE_EVENT__EVENT__PIN_COUNT_NOT_MATCHING_AFTER_REBOOT, 463 prevCachedPinCount - verificationReadyCount, /* package_name= */ ""); 464 } 465 } 466 467 /** 468 * Executes logic at the expiration of the timer. This method is common for two cases: 469 * - timer started after unattended reeboot to verify the SIM PIN automatically 470 * - timer started after prepareUnattendedReboot() is invoked. 471 */ onTimerExpiration()472 private synchronized void onTimerExpiration() { 473 logd("onTimerExpiration"); 474 475 int discardedPin = 0; 476 int slotCount = getSlotCount(); 477 for (int slotId = 0; slotId < slotCount; slotId++) { 478 // Read PIN information from storage 479 StoredPin storedPin = loadPinInformation(slotId); 480 if (storedPin == null) { 481 continue; 482 } 483 484 // Delete all PINs in VERIFICATION_READY state. This happens when reboot occurred after 485 // OTA, but the SIM card is not detected on the device. 486 if (storedPin.status == PinStatus.VERIFICATION_READY) { 487 logd("onTimerExpiration - Discarding PIN in slot %d", slotId); 488 savePinInformation(slotId, null); 489 discardedPin++; 490 continue; 491 } 492 493 // Move all PINs in REBOOT_READY to AVAILABLE. This happens when 494 // prepareUnattendedReboot() is invoked, but the reboot does not occur. 495 if (storedPin.status == PinStatus.REBOOT_READY) { 496 logd("onTimerExpiration - Moving PIN in slot %d back to AVAILABLE", slotId); 497 storedPin.status = PinStatus.AVAILABLE; 498 savePinInformation(slotId, storedPin); 499 continue; 500 } 501 } 502 503 // Delete short term key no matter the reason of the timer expiration. 504 // This is done after loading the PIN information, so that it's possible to change 505 // the status of the PIN as needed. 506 deleteSecretKey(KEYSTORE_ALIAS_SHORT_TERM); 507 mShortTermSecretKey = null; 508 509 // Reset number of stored PINs (applicable if timer expired before unattended reboot). 510 saveNumberOfCachedPins(0); 511 512 // Write metrics about number of discarded PINs 513 if (discardedPin > 0) { 514 TelephonyStatsLog.write(PIN_STORAGE_EVENT, 515 PIN_STORAGE_EVENT__EVENT__CACHED_PIN_DISCARDED, discardedPin, 516 /* package_name= */ ""); 517 } 518 } 519 520 /** Handle the update of the {@code state} of the SIM card in {@code slotId}. */ onSimStatusChange(int slotId, @SimState int state)521 private synchronized void onSimStatusChange(int slotId, @SimState int state) { 522 logd("SIM card/application changed[%d]: %s", 523 slotId, SubscriptionInfoUpdater.simStateString(state)); 524 switch (state) { 525 case TelephonyManager.SIM_STATE_ABSENT: 526 case TelephonyManager.SIM_STATE_PIN_REQUIRED: { 527 // These states are likely to occur after a reboot, so we don't clear cached PINs 528 // in VERIFICATION_READY state, as they might be verified later, when the SIM is 529 // detected. On the other hand, we remove PINs in AVAILABLE state. 530 StoredPin storedPin = loadPinInformation(slotId); 531 if (storedPin != null && storedPin.status != PinStatus.VERIFICATION_READY) { 532 savePinInformation(slotId, null); 533 } 534 break; 535 } 536 case TelephonyManager.SIM_STATE_PUK_REQUIRED: 537 case TelephonyManager.SIM_STATE_PERM_DISABLED: 538 case TelephonyManager.SIM_STATE_CARD_IO_ERROR: 539 // These states indicate that the SIM card will need a manual PIN verification. 540 // Delete the cached PIN regardless of its state. 541 clearPin(slotId); 542 break; 543 case TelephonyManager.SIM_STATE_NETWORK_LOCKED: 544 case TelephonyManager.SIM_STATE_CARD_RESTRICTED: 545 case TelephonyManager.SIM_STATE_LOADED: 546 case TelephonyManager.SIM_STATE_READY: { 547 // These states can occur after successful PIN caching, so we don't clear cached 548 // PINs in AVAILABLE state, as they need to be retained. We clear any PIN in 549 // other states, as they are no longer needed for automatic verification. 550 StoredPin storedPin = loadPinInformation(slotId); 551 if (storedPin != null && storedPin.status != PinStatus.AVAILABLE) { 552 savePinInformation(slotId, null); 553 } 554 break; 555 } 556 557 case TelephonyManager.SIM_STATE_NOT_READY: 558 case TelephonyManager.SIM_STATE_PRESENT: 559 default: 560 break; 561 } 562 } 563 onCarrierConfigChanged(int slotId)564 private void onCarrierConfigChanged(int slotId) { 565 logv("onCarrierConfigChanged[%d]", slotId); 566 if (!isCacheAllowed(slotId)) { 567 logd("onCarrierConfigChanged[%d] - PIN caching not allowed", slotId); 568 clearPin(slotId); 569 } 570 } 571 onSupplyPinComplete(int slotId, boolean success)572 private void onSupplyPinComplete(int slotId, boolean success) { 573 logd("onSupplyPinComplete[%d] - success: %s", slotId, success); 574 if (!success) { 575 // In case of failure to verify the PIN, delete the stored value. 576 // Otherwise nothing to do. 577 clearPin(slotId); 578 } 579 // Update metrics: 580 TelephonyStatsLog.write( 581 PIN_STORAGE_EVENT, 582 success 583 ? PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_SUCCESS 584 : PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_FAILURE, 585 /* number_of_pins= */ 1, /* package_name= */ ""); 586 } 587 588 @Override handleMessage(Message msg)589 public void handleMessage(Message msg) { 590 switch (msg.what) { 591 case ICC_CHANGED_EVENT: 592 onSimStatusChange(/* slotId= */ msg.arg1, /* state= */ msg.arg2); 593 break; 594 case CARRIER_CONFIG_CHANGED_EVENT: 595 onCarrierConfigChanged(/* slotId= */ msg.arg1); 596 break; 597 case TIMER_EXPIRATION_EVENT: 598 onTimerExpiration(); 599 break; 600 case USER_UNLOCKED_EVENT: 601 onUserUnlocked(); 602 break; 603 case SUPPLY_PIN_COMPLETE: 604 AsyncResult ar = (AsyncResult) msg.obj; 605 boolean success = ar != null && ar.exception == null; 606 onSupplyPinComplete(/* slotId= */ msg.arg2, success); 607 break; 608 default: 609 // Nothing to do 610 break; 611 } 612 } 613 614 /** Return if the device is secure (device PIN is enabled). */ isDeviceSecure()615 private boolean isDeviceSecure() { 616 KeyguardManager keyguardManager = mContext.getSystemService(KeyguardManager.class); 617 return keyguardManager != null ? keyguardManager.isDeviceSecure() : false; 618 } 619 620 /** Return if the device is locked (device PIN is enabled and not verified). */ isDeviceLocked()621 private boolean isDeviceLocked() { 622 KeyguardManager keyguardManager = mContext.getSystemService(KeyguardManager.class); 623 return keyguardManager != null 624 ? keyguardManager.isDeviceSecure() && keyguardManager.isDeviceLocked() 625 : false; 626 } 627 628 /** Loads the stored PIN informations for all SIM slots. */ loadPinInformation()629 private SparseArray<StoredPin> loadPinInformation() { 630 SparseArray<StoredPin> result = new SparseArray<>(); 631 int slotCount = getSlotCount(); 632 for (int slotId = 0; slotId < slotCount; slotId++) { 633 StoredPin storedPin = loadPinInformation(slotId); 634 if (storedPin != null) { 635 result.put(slotId, storedPin); 636 } 637 } 638 return result; 639 } 640 641 /** 642 * Loads the stored PIN information for the {@code slotId}. 643 * 644 * The RAM storage is used if the device is locked, the disk storage is used otherwise. 645 * This method tries to use both the long-term key and the short-term key (if available) 646 * to retrieve the PIN information, regardless of its status. 647 * 648 * @return the stored {@code StoredPin}, or null if not present. 649 */ 650 @Nullable loadPinInformation(int slotId)651 private StoredPin loadPinInformation(int slotId) { 652 if (!mLastCommitResult) { 653 // If the last commit failed, do not read from file, as we might retrieve stale data. 654 loge("Last commit failed - returning empty values"); 655 return null; 656 } 657 658 StoredPin result = null; 659 660 if (mIsDeviceLocked) { 661 // If the device is still locked, retrieve data from RAM storage. 662 if (mRamStorage != null && mRamStorage.get(slotId) != null) { 663 result = decryptStoredPin(mRamStorage.get(slotId), mLongTermSecretKey); 664 } 665 } else { 666 // Load both the stored PIN in available state (with long-term key) and in other states 667 // (with short-term key). At most one of them should be present at any given time and 668 // we treat the case wheere both are present as an error. 669 StoredPin availableStoredPin = loadPinInformationFromDisk( 670 slotId, SHARED_PREFS_AVAILABLE_PIN_BASE_KEY, mLongTermSecretKey); 671 StoredPin rebootStoredPin = loadPinInformationFromDisk( 672 slotId, SHARED_PREFS_REBOOT_PIN_BASE_KEY, mShortTermSecretKey); 673 if (availableStoredPin != null && rebootStoredPin == null) { 674 result = availableStoredPin; 675 } else if (availableStoredPin == null && rebootStoredPin != null) { 676 result = rebootStoredPin; 677 } 678 } 679 680 // Validate the slot ID of the retrieved PIN information 681 if (result != null && result.slotId != slotId) { 682 loge("Load PIN: slot ID does not match (%d != %d)", result.slotId, slotId); 683 result = null; 684 } 685 686 if (result != null) { 687 logv("Load PIN: %s", result.toString()); 688 } else { 689 logv("Load PIN for slot %d: null", slotId); 690 } 691 return result; 692 } 693 694 /** 695 * Load the PIN information from a specific file in non-volatile memory. 696 * 697 * @param key the key in the {@code SharedPreferences} to read 698 * @param secretKey the key used for encryption/decryption 699 * @return the {@code StoredPin} from non-volatile memory. It returns a default instance in 700 * case of error. 701 */ 702 @Nullable loadPinInformationFromDisk( int slotId, String key, @Nullable SecretKey secretKey)703 private StoredPin loadPinInformationFromDisk( 704 int slotId, String key, @Nullable SecretKey secretKey) { 705 String base64encryptedPin = 706 mContext.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE) 707 .getString(key + slotId, ""); 708 if (!base64encryptedPin.isEmpty()) { 709 try { 710 byte[] blob = Base64.decode(base64encryptedPin, Base64.DEFAULT); 711 return decryptStoredPin(blob, secretKey); 712 } catch (Exception e) { 713 // Nothing to do 714 } 715 } 716 return null; 717 } 718 719 /** Load the PIN information from an encrypted binary blob. 720 * 721 * @param blob the encrypted binary blob 722 * @param secretKey the key used for encryption/decryption 723 * @return the decrypted {@code StoredPin}, or null in case of error. 724 */ 725 @Nullable decryptStoredPin(byte[] blob, @Nullable SecretKey secretKey)726 private StoredPin decryptStoredPin(byte[] blob, @Nullable SecretKey secretKey) { 727 if (secretKey != null) { 728 try { 729 byte[] decryptedPin = decrypt(secretKey, blob); 730 if (decryptedPin.length > 0) { 731 return StoredPin.parseFrom(decryptedPin); 732 } 733 } catch (Exception e) { 734 loge("cannot decrypt/parse PIN information", e); 735 } 736 } 737 return null; 738 } 739 740 /** 741 * Stores the PIN information. 742 * 743 * If the device is locked, the PIN information is stored to RAM, othewrwise to disk. 744 * The PIN information is divided based on the PIN status and stored in two separate 745 * files in non-volatile memory, each encrypted with a different key. 746 * 747 * @param slotId the slot ID 748 * @param storedPin the PIN information to be stored 749 * @return true if the operation was successfully done, false otherwise. 750 */ savePinInformation(int slotId, @Nullable StoredPin storedPin)751 private boolean savePinInformation(int slotId, @Nullable StoredPin storedPin) { 752 // Populate the boot count 753 if (storedPin != null) { 754 storedPin.bootCount = mBootCount; 755 } 756 757 // If the device is still locked, we can only save PINs in AVAILABLE state in RAM. 758 // NOTE: at this point, there should not be any PIN in any other state. 759 if (mIsDeviceLocked) { 760 return savePinInformationToRam(slotId, storedPin); 761 } 762 763 // Remove any prvious key related to this slot. 764 SharedPreferences.Editor editor = 765 mContext.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE) 766 .edit() 767 .remove(SHARED_PREFS_AVAILABLE_PIN_BASE_KEY + slotId) 768 .remove(SHARED_PREFS_REBOOT_PIN_BASE_KEY + slotId); 769 770 boolean result = true; 771 if (storedPin != null) { 772 // Available PINs are stored with a long-term key, while the PINs in other states 773 // are stored with a short-term key. 774 logd("Saving PIN for slot %d", slotId); 775 if (storedPin.status == PinStatus.AVAILABLE) { 776 result = savePinInformation(editor, slotId, storedPin, 777 SHARED_PREFS_AVAILABLE_PIN_BASE_KEY, mLongTermSecretKey); 778 } else { 779 result = savePinInformation(editor, slotId, storedPin, 780 SHARED_PREFS_REBOOT_PIN_BASE_KEY, mShortTermSecretKey); 781 } 782 } else { 783 logv("Deleting PIN for slot %d (if existed)", slotId); 784 } 785 786 mLastCommitResult = editor.commit() && result; 787 return mLastCommitResult; 788 } 789 790 /** 791 * Store the PIN information to a specific file in non-volatile memory. 792 * 793 * @param editor the {@code SharedPreferences.Editor} to use for storage 794 * @param slotId the slot ID 795 * @param storedPin the PIN information to store 796 * @param baseKey the base name of the key in the {@code SharedPreferences}. The full name is 797 * derived appending the value of {@code slotId}. 798 * @param secretKey the key used for encryption/decryption 799 * @return true if the operation was successful, false otherwise 800 */ savePinInformation(SharedPreferences.Editor editor, int slotId, StoredPin storedPin, String baseKey, SecretKey secretKey)801 private boolean savePinInformation(SharedPreferences.Editor editor, int slotId, 802 StoredPin storedPin, String baseKey, SecretKey secretKey) { 803 if (secretKey == null) { 804 // Secret key for encryption is missing 805 return false; 806 } 807 if (slotId != storedPin.slotId) { 808 loge("Save PIN: the slotId does not match (%d != %d)", slotId, storedPin.slotId); 809 return false; 810 } 811 812 logv("Save PIN: %s", storedPin.toString()); 813 814 byte[] encryptedPin = encrypt(secretKey, StoredPin.toByteArray(storedPin)); 815 if (encryptedPin.length > 0) { 816 editor.putString( 817 baseKey + slotId, Base64.encodeToString(encryptedPin, Base64.DEFAULT)); 818 return true; 819 } else { 820 return false; 821 } 822 } 823 824 /** Stored PIN information for slot {@code slotId} in RAM. */ savePinInformationToRam(int slotId, @Nullable StoredPin storedPin)825 private boolean savePinInformationToRam(int slotId, @Nullable StoredPin storedPin) { 826 // Clear the RAM in all cases, to avoid leaking any previous PIN. 827 cleanRamStorage(slotId); 828 829 if (storedPin == null) { 830 return true; 831 } 832 833 if (storedPin.status == PinStatus.AVAILABLE) { 834 byte[] encryptedPin = encrypt(mLongTermSecretKey, StoredPin.toByteArray(storedPin)); 835 if (encryptedPin != null && encryptedPin.length > 0) { 836 logd("Saving PIN for slot %d in RAM", slotId); 837 mRamStorage.put(slotId, encryptedPin); 838 return true; 839 } 840 } 841 return false; 842 } 843 844 845 /** Erases all the PINs stored in RAM before a secure device is unlocked. */ cleanRamStorage()846 private void cleanRamStorage() { 847 int slotCount = getSlotCount(); 848 for (int slotId = 0; slotId < slotCount; slotId++) { 849 cleanRamStorage(slotId); 850 } 851 } 852 853 /** Erases the PIN of slot {@code slotId} stored in RAM before a secure device is unlocked. */ cleanRamStorage(int slotId)854 private void cleanRamStorage(int slotId) { 855 if (mRamStorage != null) { 856 byte[] data = mRamStorage.get(slotId); 857 if (data != null) { 858 Arrays.fill(data, (byte) 0); 859 } 860 mRamStorage.delete(slotId); 861 } 862 } 863 864 /** 865 * Verifies all pending PIN codes that are ready for verification. 866 * 867 * The PIN verificartion is done if the PIN state is VERIFICATION_READY and the SIM 868 * card has the PIN enabled and not verified. 869 */ verifyPendingPins()870 private void verifyPendingPins() { 871 int slotCount = getSlotCount(); 872 for (int slotId = 0; slotId < slotCount; slotId++) { 873 if (isPinState(slotId, PINSTATE_ENABLED_NOT_VERIFIED)) { 874 verifyPendingPin(slotId); 875 } 876 } 877 } 878 879 /** Verifies the PIN code for a given SIM card in slot {@code slotId}. */ verifyPendingPin(int slotId)880 private void verifyPendingPin(int slotId) { 881 // We intentionally invoke getPin() here, as it updates the status and makes sure that 882 // same PIN is not used more than once 883 String pin = getPin(slotId, getIccid(slotId)); 884 if (pin.isEmpty()) { 885 // PIN is not available for verification: return. 886 return; 887 } 888 889 logd("Perform automatic verification of PIN in slot %d", slotId); 890 891 UiccProfile profile = UiccController.getInstance().getUiccProfileForPhone(slotId); 892 if (profile != null) { 893 Message onComplete = obtainMessage(SUPPLY_PIN_COMPLETE); 894 onComplete.arg2 = slotId; // arg1 is the number of remaining attempts in the response 895 profile.supplyPin(pin, onComplete); 896 } else { 897 logd("Perform automatic verification of PIN in slot %d not possible", slotId); 898 } 899 } 900 901 /** Returns the boot count. */ getBootCount()902 private int getBootCount() { 903 return Settings.Global.getInt( 904 mContext.getContentResolver(), 905 Settings.Global.BOOT_COUNT, 906 -1); 907 } 908 909 /** Returns the number of available SIM slots. */ getSlotCount()910 private int getSlotCount() { 911 // Count the number of slots as the number of Phones. 912 // At power up, it is possible that number of phones is still unknown, so we query 913 // TelephonyManager for it. 914 try { 915 return PhoneFactory.getPhones().length; 916 } catch (Exception ex) { 917 return TelephonyManager.getDefault().getActiveModemCount(); 918 } 919 } 920 921 /** 922 * Saves the number of cached PINs ready for verification after reboot and returns the 923 * previous value. 924 */ saveNumberOfCachedPins(int storedCount)925 private int saveNumberOfCachedPins(int storedCount) { 926 SharedPreferences sharedPrefs = 927 mContext.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE); 928 929 int previousValue = sharedPrefs.getInt(SHARED_PREFS_STORED_PINS, 0); 930 sharedPrefs.edit().putInt(SHARED_PREFS_STORED_PINS, storedCount).commit(); 931 return previousValue; 932 } 933 startTimer(int duration)934 private boolean startTimer(int duration) { 935 removeMessages(TIMER_EXPIRATION_EVENT); 936 return duration > 0 ? sendEmptyMessageDelayed(TIMER_EXPIRATION_EVENT, duration) : true; 937 } 938 939 /** Returns the ICCID of the SIM card for the given {@code slotId}. */ getIccid(int slotId)940 private String getIccid(int slotId) { 941 Phone phone = PhoneFactory.getPhone(slotId); 942 return phone != null ? phone.getFullIccSerialNumber() : ""; 943 } 944 validatePin(String pin)945 private boolean validatePin(String pin) { 946 return pin != null && pin.length() >= MIN_PIN_LENGTH && pin.length() <= MAX_PIN_LENGTH; 947 } 948 validateIccid(String iccid)949 private boolean validateIccid(String iccid) { 950 return iccid != null && iccid.length() >= MIN_ICCID_LENGTH; 951 } 952 validateSlotId(int slotId)953 private boolean validateSlotId(int slotId) { 954 return slotId >= 0 && slotId < getSlotCount(); 955 } 956 957 /** Checks if the PIN status of the SIM in slot {@code slotId} is a given {@code PinState}. */ isPinState(int slotId, PinState pinState)958 private boolean isPinState(int slotId, PinState pinState) { 959 UiccProfile profile = UiccController.getInstance().getUiccProfileForPhone(slotId); 960 if (profile != null) { 961 // Loop thru all possible app families to identify at least one that is available in 962 // order to check the PIN state. 963 int[] families = { 964 UiccController.APP_FAM_3GPP, 965 UiccController.APP_FAM_3GPP2, 966 UiccController.APP_FAM_IMS }; 967 for (int i = 0; i < families.length; i++) { 968 UiccCardApplication app = profile.getApplication(i); 969 if (app != null) { 970 return app.getPin1State() == pinState; 971 } 972 } 973 } 974 return false; 975 } 976 977 /** Returns if the PIN cache is allowed for a given slot. */ isCacheAllowed(int slotId)978 private boolean isCacheAllowed(int slotId) { 979 return isCacheAllowedByDevice() && isCacheAllowedByCarrier(slotId); 980 } 981 982 /** Returns if the PIN cache is allowed by the device. */ isCacheAllowedByDevice()983 private boolean isCacheAllowedByDevice() { 984 if (!mContext.getResources().getBoolean( 985 R.bool.config_allow_pin_storage_for_unattended_reboot)) { 986 logv("Pin caching disabled in resources"); 987 return false; 988 } 989 return true; 990 } 991 992 /** Returns if the PIN cache is allowed by carrier for a given slot. */ isCacheAllowedByCarrier(int slotId)993 private boolean isCacheAllowedByCarrier(int slotId) { 994 PersistableBundle config = null; 995 CarrierConfigManager configManager = 996 mContext.getSystemService(CarrierConfigManager.class); 997 if (configManager != null) { 998 Phone phone = PhoneFactory.getPhone(slotId); 999 if (phone != null) { 1000 // If an invalid subId is used, this bundle will contain default values. 1001 config = configManager.getConfigForSubId(phone.getSubId()); 1002 } 1003 } 1004 if (config == null) { 1005 config = CarrierConfigManager.getDefaultConfig(); 1006 } 1007 1008 return config.getBoolean( 1009 CarrierConfigManager.KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL, true); 1010 } 1011 1012 /** Initializes KeyStore and returns the instance. */ 1013 @Nullable initializeKeyStore()1014 private static KeyStore initializeKeyStore() { 1015 KeyStore keyStore = null; 1016 try { 1017 keyStore = KeyStore.getInstance(ANDROID_KEY_STORE_PROVIDER); 1018 keyStore.load(/*param=*/ null); 1019 } catch (Exception e) { 1020 // Should never happen. 1021 loge("Error loading KeyStore", e); 1022 return null; 1023 } 1024 logv("KeyStore ready"); 1025 return keyStore; 1026 } 1027 1028 /** 1029 * Initializes a secret key and returns it. 1030 * 1031 * @param alias alias of the key in {@link KeyStore}. 1032 * @param createIfAbsent indicates weather the key must be created if not already present. 1033 * @return the {@link SecretKey}, or null if the key does not exist. 1034 */ 1035 @Nullable initializeSecretKey(String alias, boolean createIfAbsent)1036 private SecretKey initializeSecretKey(String alias, boolean createIfAbsent) { 1037 if (mKeyStore == null) { 1038 return null; 1039 } 1040 1041 SecretKey secretKey = getSecretKey(alias); 1042 if (secretKey != null) { 1043 logd("KeyStore: alias %s exists", alias); 1044 return secretKey; 1045 } else if (createIfAbsent) { 1046 Date expiration = 1047 KEYSTORE_ALIAS_SHORT_TERM.equals(alias) ? getShortLivedKeyValidityEnd() : null; 1048 boolean isUserAuthRequired = 1049 !KEYSTORE_ALIAS_LONG_TERM_ALWAYS.equals(alias) && isDeviceSecure(); 1050 logd("KeyStore: alias %s does not exist - Creating (exp=%s, auth=%s)", 1051 alias, expiration != null ? expiration.toString() : "", isUserAuthRequired); 1052 return createSecretKey(alias, expiration, isUserAuthRequired); 1053 } else { 1054 // Nothing to do 1055 logd("KeyStore: alias %s does not exist - Nothing to do", alias); 1056 return null; 1057 } 1058 } 1059 1060 /** 1061 * Retrieves the secret key previously stored in {@link KeyStore}. 1062 * 1063 * @param alias alias of the key in {@link KeyStore}. 1064 * @return the {@link SecretKey}, or null in case of error or if the key does not exist. 1065 */ 1066 @Nullable getSecretKey(String alias)1067 private SecretKey getSecretKey(String alias) { 1068 try { 1069 final KeyStore.SecretKeyEntry secretKeyEntry = 1070 (KeyStore.SecretKeyEntry) mKeyStore.getEntry(alias, null); 1071 if (secretKeyEntry != null) { 1072 return secretKeyEntry.getSecretKey(); 1073 } 1074 } catch (Exception e) { 1075 // In case of exception, it means that key exists, but cannot be retrieved 1076 // We delete the old key, so that a new key can be created. 1077 loge("Exception with getting the key " + alias, e); 1078 deleteSecretKey(alias); 1079 } 1080 return null; 1081 } 1082 1083 /** 1084 * Generates a new secret key in {@link KeyStore}. 1085 * 1086 * @param alias alias of the key in {@link KeyStore}. 1087 * @param expiration expiration of the key, or null if the key does not expire. 1088 * @param isUserAuthRequired indicates if user authentication is required to use the key 1089 * @return the created {@link SecretKey}, or null in case of error 1090 */ 1091 @Nullable createSecretKey(String alias, Date expiration, boolean isUserAuthRequired)1092 private SecretKey createSecretKey(String alias, Date expiration, boolean isUserAuthRequired) { 1093 try { 1094 final KeyGenerator keyGenerator = 1095 KeyGenerator.getInstance(KEY_ALGORITHM_AES, ANDROID_KEY_STORE_PROVIDER); 1096 KeyGenParameterSpec.Builder keyGenParameterSpec = 1097 new KeyGenParameterSpec.Builder(alias, PURPOSE_ENCRYPT | PURPOSE_DECRYPT) 1098 .setBlockModes(BLOCK_MODE_GCM) 1099 .setEncryptionPaddings(ENCRYPTION_PADDING_NONE); 1100 if (expiration != null) { 1101 keyGenParameterSpec = keyGenParameterSpec 1102 .setKeyValidityEnd(expiration); 1103 } 1104 if (isUserAuthRequired) { 1105 keyGenParameterSpec = keyGenParameterSpec 1106 .setUserAuthenticationRequired(true) 1107 .setUserAuthenticationParameters(Integer.MAX_VALUE, AUTH_DEVICE_CREDENTIAL); 1108 } 1109 keyGenerator.init(keyGenParameterSpec.build()); 1110 return keyGenerator.generateKey(); 1111 } catch (Exception e) { 1112 loge("Create key exception", e); 1113 return null; 1114 } 1115 } 1116 1117 /** Returns the validity end of a new short-lived key, or null if key does not expire. */ 1118 @Nullable getShortLivedKeyValidityEnd()1119 private Date getShortLivedKeyValidityEnd() { 1120 if (mShortTermSecretKeyDurationMinutes > 0) { 1121 Calendar calendar = Calendar.getInstance(); 1122 calendar.setTime(new Date()); 1123 calendar.add(Calendar.MINUTE, mShortTermSecretKeyDurationMinutes); 1124 return calendar.getTime(); 1125 } else { 1126 return null; 1127 } 1128 } 1129 1130 /** Deletes the short term key from KeyStore, if it exists. */ deleteSecretKey(String alias)1131 private void deleteSecretKey(String alias) { 1132 if (mKeyStore != null) { 1133 logd("Delete key: %s", alias); 1134 try { 1135 mKeyStore.deleteEntry(alias); 1136 } catch (Exception e) { 1137 // Nothing to do. Even if the key removal fails, it becomes unusable. 1138 loge("Delete key exception"); 1139 } 1140 } 1141 } 1142 1143 /** Returns the encrypted version of {@code input}, or an empty array in case of error. */ encrypt(SecretKey secretKey, byte[] input)1144 private byte[] encrypt(SecretKey secretKey, byte[] input) { 1145 if (secretKey == null) { 1146 loge("Encrypt: Secret key is null"); 1147 return new byte[0]; 1148 } 1149 1150 try { 1151 final Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION); 1152 cipher.init(Cipher.ENCRYPT_MODE, secretKey); 1153 1154 EncryptedPin encryptedPin = new EncryptedPin(); 1155 encryptedPin.iv = cipher.getIV(); 1156 encryptedPin.encryptedStoredPin = cipher.doFinal(input); 1157 return EncryptedPin.toByteArray(encryptedPin); 1158 } catch (Exception e) { 1159 loge("Encrypt exception", e); 1160 TelephonyStatsLog.write(PIN_STORAGE_EVENT, 1161 PIN_STORAGE_EVENT__EVENT__PIN_ENCRYPTION_ERROR, 1, /* package_name= */ ""); 1162 } 1163 return new byte[0]; 1164 } 1165 1166 /** Returns the decrypted version of {@code input}, or an empty array in case of error. */ decrypt(SecretKey secretKey, byte[] input)1167 private byte[] decrypt(SecretKey secretKey, byte[] input) { 1168 if (secretKey == null) { 1169 loge("Decrypt: Secret key is null"); 1170 return new byte[0]; 1171 } 1172 1173 try { 1174 EncryptedPin encryptedPin = EncryptedPin.parseFrom(input); 1175 if (!ArrayUtils.isEmpty(encryptedPin.encryptedStoredPin) 1176 && !ArrayUtils.isEmpty(encryptedPin.iv)) { 1177 final Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION); 1178 final GCMParameterSpec spec = 1179 new GCMParameterSpec(GCM_PARAMETER_TAG_BIT_LEN, encryptedPin.iv); 1180 cipher.init(Cipher.DECRYPT_MODE, secretKey, spec); 1181 return cipher.doFinal(encryptedPin.encryptedStoredPin); 1182 } 1183 } catch (Exception e) { 1184 loge("Decrypt exception", e); 1185 TelephonyStatsLog.write(PIN_STORAGE_EVENT, 1186 PIN_STORAGE_EVENT__EVENT__PIN_DECRYPTION_ERROR, 1, /* package_name= */ ""); 1187 } 1188 return new byte[0]; 1189 } 1190 logv(String format, Object... args)1191 private static void logv(String format, Object... args) { 1192 if (VDBG) { 1193 Rlog.d(TAG, String.format(format, args)); 1194 } 1195 } 1196 logd(String format, Object... args)1197 private static void logd(String format, Object... args) { 1198 Rlog.d(TAG, String.format(format, args)); 1199 } 1200 loge(String format, Object... args)1201 private static void loge(String format, Object... args) { 1202 Rlog.e(TAG, String.format(format, args)); 1203 } 1204 loge(String msg, Throwable tr)1205 private static void loge(String msg, Throwable tr) { 1206 Rlog.e(TAG, msg, tr); 1207 } 1208 dump(FileDescriptor fd, PrintWriter pw, String[] args)1209 void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1210 pw.println("PinStorage:"); 1211 pw.println(" mIsDeviceSecure=" + mIsDeviceSecure); 1212 pw.println(" mIsDeviceLocked=" + mIsDeviceLocked); 1213 pw.println(" isLongTermSecretKey=" + (boolean) (mLongTermSecretKey != null)); 1214 pw.println(" isShortTermSecretKey=" + (boolean) (mShortTermSecretKey != null)); 1215 pw.println(" isCacheAllowedByDevice=" + isCacheAllowedByDevice()); 1216 int slotCount = getSlotCount(); 1217 for (int i = 0; i < slotCount; i++) { 1218 pw.println(" isCacheAllowedByCarrier[" + i + "]=" + isCacheAllowedByCarrier(i)); 1219 } 1220 if (VDBG) { 1221 SparseArray<StoredPin> storedPins = loadPinInformation(); 1222 for (int i = 0; i < storedPins.size(); i++) { 1223 pw.println(" pin=" + storedPins.valueAt(i).toString()); 1224 } 1225 } 1226 } 1227 } 1228