1 /* 2 * Copyright (C) 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.server.locksettings; 18 19 import android.security.keystore.KeyGenParameterSpec; 20 import android.security.keystore.KeyProperties; 21 import android.security.keystore2.AndroidKeyStoreLoadStoreParameter; 22 import android.security.keystore2.AndroidKeyStoreSpi; 23 import android.util.Slog; 24 25 import com.android.internal.annotations.GuardedBy; 26 27 import java.io.IOException; 28 import java.security.GeneralSecurityException; 29 import java.security.KeyStore; 30 31 import javax.crypto.KeyGenerator; 32 import javax.crypto.SecretKey; 33 34 /** 35 * This class loads and generates the key used for resume on reboot from android keystore. 36 */ 37 public class RebootEscrowKeyStoreManager { 38 private static final String TAG = "RebootEscrowKeyStoreManager"; 39 40 /** 41 * The key alias in keystore. This key is used to wrap both escrow key and escrow data. 42 */ 43 public static final String REBOOT_ESCROW_KEY_STORE_ENCRYPTION_KEY_NAME = 44 "reboot_escrow_key_store_encryption_key"; 45 46 public static final int KEY_LENGTH = 256; 47 48 /** 49 * Use keystore2 once it's installed. 50 */ 51 private static final String ANDROID_KEY_STORE_PROVIDER = "AndroidKeystore"; 52 53 /** 54 * The selinux namespace for resume_on_reboot_key 55 */ 56 private static final int KEY_STORE_NAMESPACE = 120; 57 58 /** 59 * Hold this lock when getting or generating the encryption key in keystore. 60 */ 61 private final Object mKeyStoreLock = new Object(); 62 63 @GuardedBy("mKeyStoreLock") getKeyStoreEncryptionKeyLocked()64 private SecretKey getKeyStoreEncryptionKeyLocked() { 65 try { 66 KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE_PROVIDER); 67 KeyStore.LoadStoreParameter loadStoreParameter = null; 68 // Load from the specific namespace if keystore2 is enabled. 69 loadStoreParameter = new AndroidKeyStoreLoadStoreParameter(KEY_STORE_NAMESPACE); 70 keyStore.load(loadStoreParameter); 71 return (SecretKey) keyStore.getKey(REBOOT_ESCROW_KEY_STORE_ENCRYPTION_KEY_NAME, 72 null); 73 } catch (IOException | GeneralSecurityException e) { 74 Slog.e(TAG, "Unable to get encryption key from keystore.", e); 75 } 76 return null; 77 } 78 getKeyStoreEncryptionKey()79 protected SecretKey getKeyStoreEncryptionKey() { 80 synchronized (mKeyStoreLock) { 81 return getKeyStoreEncryptionKeyLocked(); 82 } 83 } 84 clearKeyStoreEncryptionKey()85 protected void clearKeyStoreEncryptionKey() { 86 synchronized (mKeyStoreLock) { 87 try { 88 KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE_PROVIDER); 89 KeyStore.LoadStoreParameter loadStoreParameter = null; 90 // Load from the specific namespace if keystore2 is enabled. 91 loadStoreParameter = new AndroidKeyStoreLoadStoreParameter(KEY_STORE_NAMESPACE); 92 keyStore.load(loadStoreParameter); 93 keyStore.deleteEntry(REBOOT_ESCROW_KEY_STORE_ENCRYPTION_KEY_NAME); 94 } catch (IOException | GeneralSecurityException e) { 95 Slog.e(TAG, "Unable to delete encryption key in keystore.", e); 96 } 97 } 98 } 99 generateKeyStoreEncryptionKeyIfNeeded()100 protected SecretKey generateKeyStoreEncryptionKeyIfNeeded() { 101 synchronized (mKeyStoreLock) { 102 SecretKey kk = getKeyStoreEncryptionKeyLocked(); 103 if (kk != null) { 104 return kk; 105 } 106 107 try { 108 KeyGenerator generator = KeyGenerator.getInstance( 109 KeyProperties.KEY_ALGORITHM_AES, AndroidKeyStoreSpi.NAME); 110 KeyGenParameterSpec.Builder parameterSpecBuilder = new KeyGenParameterSpec.Builder( 111 REBOOT_ESCROW_KEY_STORE_ENCRYPTION_KEY_NAME, 112 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) 113 .setKeySize(KEY_LENGTH) 114 .setBlockModes(KeyProperties.BLOCK_MODE_GCM) 115 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE); 116 // Generate the key with the correct namespace if keystore2 is enabled. 117 parameterSpecBuilder.setNamespace(KEY_STORE_NAMESPACE); 118 generator.init(parameterSpecBuilder.build()); 119 return generator.generateKey(); 120 } catch (GeneralSecurityException e) { 121 // Should never happen. 122 Slog.e(TAG, "Unable to generate key from keystore.", e); 123 } 124 return null; 125 } 126 } 127 } 128