1. 程式人生 > 程式設計 >Android加密之全盤加密詳解

Android加密之全盤加密詳解

前言

Android 的安全性問題一直備受關注,Google 在 Android 系統的安全方面也是一直沒有停止過更新,努力做到更加安全的手機移動作業系統。

在 Android 的安全性方面,有很多模組:

1 核心安全性
2 應用安全性
3 應用簽名
4 身份驗證
5 Trusty TEE
6 SELinux
7 加密
等等

其中,加密又分全盤加密(Android 4.4 引入)和檔案級加密(Android 7.0 引入),本文將論述加密中的全盤加密的基本知識。全盤加密在 Android 4.4 中引入,在 Android 5.0 中做了比較大的更新。

Android加密之全盤加密詳解

本文部分片段摘自 Android 官網,融合筆者的個人理解和知識。

什麼是全盤加密

全盤加密是使用已加密的金鑰對 Android 裝置上的所有使用者資料進行編碼的過程。裝置經過加密後,所有由使用者建立的資料在寫入磁碟之前都會自動加密,並且所有讀取操作都會在將資料返回給呼叫程序之前自動解密資料。

Android 5.0 中又引入了以下新功能:

建立了快速加密方式,這種加密方式只會對資料分割槽中已使用的分塊進行加密,以免首次啟動用時過長。目前只有 EXT4 和 F2FS 檔案系統支援快速加密。

添加了 forceencrypt fstab 標記,以便在首次啟動時進行加密。

添加了對解鎖圖案和無密碼加密的支援。

添加了由硬體支援的加密金鑰儲存空間,該空間使用可信執行環境(TEE,例如 TrustZone)的簽名功能。

全盤加密運作方式

Android 全盤加密基於在塊裝置層執行的核心功能 dm-crypt。因此,這種加密方式適用於以塊裝置的形式呈現給核心的嵌入式多媒體卡 (eMMC) 和類似快閃記憶體裝置。YAFFS 會直接與原始 NAND 快閃記憶體晶片互動,無法進行全盤加密。

全盤加密採用的是 128 位高階加密標準 (AES) 演算法(搭配密碼塊連結 (CBC) 和 ESSIV:SHA256)。對主金鑰進行加密時使用的是 128 位 AES 演算法,並會呼叫 OpenSSL 庫。對於該金鑰,您必須使用 128 位或更多位(可以選擇 256 位)。

Android 5.0 版中有以下 4 種加密狀態:

預設

PIN 碼
密碼
解鎖圖案

Android加密之全盤加密詳解

首次啟動時,裝置會建立一個隨機生成的 128 位主金鑰,然後會使用預設密碼和儲存的鹽對其進行雜湊處理。預設密碼是“default_password”。不過,裝置還會通過 TEE(例如 TrustZone)為生成的雜湊簽名。TEE 會使用相應簽名的雜湊來加密主金鑰。

您可以在 Android 開放原始碼專案 cryptfs.c 檔案中找到定義的預設密碼。

當用戶在裝置上設定 PIN 碼/通行碼或密碼時,只有 128 位的金鑰會被重新加密並存儲起來(也就是說,更改使用者 PIN 碼/通行碼/解鎖圖案不會導致重新加密使用者資料)。請注意,受管理的裝置可能受 PIN 碼、解鎖圖案或密碼限制。

加密操作由 init 和 vold 管理。 init 負責呼叫 vold,然後 vold 會設定相關屬性以觸發 init 中的事件。系統的其他部分也會檢視這些屬性以執行各項任務,例如報告狀態、提示輸入密碼,或有嚴重錯誤發生時提示恢復出廠設定。為了呼叫 vold 中的加密功能,系統會使用命令列工具 vdc 的 cryptfs 命令:checkpw、restart、enablecrypto、changepw、cryptocomplete、verifypw、setfield、getfield、mountdefaultencrypted、getpwtype、getpw 以及 clearpw。

要加密、解密或清空 /data,/data 不得處於裝載狀態。但要顯示任何介面,框架都必須啟動,而框架需要 /data 才能執行。為了解決這一衝突,/data 上會裝載一個臨時檔案系統。通過該檔案系統,Android 可以提示輸入密碼、顯示進度或根據需要建議清除資料。不過,該檔案系統會帶來以下限制:要從臨時檔案系統切換到實際的 /data 檔案系統,系統必須停止臨時檔案系統中打開了檔案的所有程序,並在實際的 /data 檔案系統中重啟這些程序。為此,所有服務都必須位於以下其中一個組內:core、main 和 late_start。

core:啟動後一直不會關閉。

main:關閉,然後在使用者輸入磁碟密碼後會重啟。

late_start:在 /data 未解密並裝載之前,一直不會啟動。

為了觸發這些操作,vold.decrypt 屬性會被設為多種字串。要結束和重啟服務,請使用以下 init 命令:

class_reset:停止相應服務,但允許通過 class_start 重啟該服務。

class_start:重啟相應服務。

class_stop:停止相應服務並新增 SVC_DISABLED 標記。被停止的服務不會對。

class_start 做出響應。

加密流程和啟動流程

使用 forceencrypt 加密新裝置

這是 Android 5.0 裝置首次啟動時的常規流程。

檢測帶有 forceencrypt 標記的未加密檔案系統

/data 未加密,但需要加密,因為 forceencrypt 強制要求進行此項加密。解除安裝 /data。

開始加密 /data

vold.decrypt = “trigger_encryption” 會觸發 init.rc,從而使 vold 對 /data 進行無密碼加密。(因為這應該是新裝置,還沒有設定密碼。)

裝載 tmpfs

vold 會裝載一個 tmpfs /data(使用 ro.crypto.tmpfs_options 中的 tmpfs 選項),並會將 vold.encrypt_progress 屬性設為 0。 vold 會準備 tmpfs /data 以便啟動已加密的系統,並會將 vold.decrypt 屬性設為 trigger_restart_min_framework

啟動框架以顯示進度

由於裝置上幾乎沒有要加密的資料,加密過程很快就會完成,因此實際上通常並不會顯示進度條。如需關於進度介面的更多詳細資訊,請參閱加密現有裝置。

/data 加密後,關閉框架

vold 會將 vold.decrypt 設為 trigger_default_encryption,這會啟動 defaultcrypto 服務。(這會啟動以下流程來裝載預設的已加密使用者資料。)trigger_default_encryption 會檢查加密型別,以瞭解 /data 加密是否使用了密碼。由於 Android 5.0 裝置是在首次啟動時加密,應該沒有設定任何密碼,因此我們要解密並裝載 /data。

裝載 /data

接下來,init 會使用從 ro.crypto.tmpfs_options(在 init.rc 中設定)中選取的引數在 tmpfs RAMDisk 中裝載 /data。

啟動框架

將 vold 設為 trigger_restart_framework,這會繼續常規啟動過程。

啟動未進行預設加密的已加密裝置

當您啟動設有密碼的已加密裝置時,則會發生該流程。裝置的密碼可以是 PIN 碼、解鎖圖案或密碼。

檢測設有密碼的已加密裝置

會發現 Android 裝置已加密,因為設定了 ro.crypto.state = “encrypted” 標記

由於 /data 是使用密碼加密的,因此 vold 會將 vold.decrypt 設為 trigger_restart_min_framework。

裝載 tmpfs

init 會設定 5 個屬性,以儲存為 /data(包含從 init.rc 傳入的引數)提供的初始裝載選項。 vold 會使用這些屬性來設定加密對映:

ro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags (ASCII 碼 8 位十六進位制數字,以 0x 開頭)

啟動框架以提示輸入密碼

框架會啟動並看到 vold.decrypt 已設為 trigger_restart_min_framework。這讓框架知道自己是在 tmpfs /data 磁碟中啟動的,並且需要獲取使用者密碼。

不過,它首先需要確認磁碟是否已經過適當加密。它會向 vold 傳送 cryptfs cryptocomplete 命令。 如果加密已成功完成,vold 會返回 0;如果發生內部錯誤,則會返回 -1;如果加密未成功完成,則會返回 -2。vold 通過檢視 CRYPTO_ENCRYPTION_IN_PROGRESS 標記的加密元資料來確定應返回的值。如果設定了此標記,則表示加密過程中斷了,並且裝置上沒有可用的資料。如果 vold 返回錯誤,介面中應顯示一條訊息,提示使用者重新啟動裝置並將其恢復出廠設定,並且介面中應為使用者提供一個用於執行該操作的按鈕。

通過密碼解密資料

cryptfs cryptocomplete 成功後,框架會顯示一個介面,提示使用者輸入磁碟密碼。介面會向 vold 傳送 cryptfs checkpw 命令來檢查使用者輸入的密碼。如果密碼正確(通過以下方式判定:在臨時位置成功裝載已解密的 /data,然後將其解除安裝),vold 會將已解密塊裝置的名稱儲存在 ro.crypto.fs_crypto_blkdev 屬性中,並向介面返回狀態 0。如果密碼不正確,則向介面返回 -1。

停止框架

介面會顯示加密啟動圖形,然後使用 cryptfs restart 命令呼叫 vold。vold 會將 vold.decrypt 屬性設為 trigger_reset_main,這會使 init.rc 執行 class_reset main 命令。此命令會停止 main 類中的所有服務,以便解除安裝 tmpfs /data。

裝載 /data

然後,vold 會裝載已解密的實際 /data 分割槽,並準備新的分割槽(如果加密時採用了首次釋出不支援的資料清除選項,則可能永遠無法準備就緒)。它會將 vold.post_fs_data_done 屬性設為 0,接著將 vold.decrypt 設為 trigger_post_fs_data。這會使 init.rc 執行其 post-fs-data 命令。這些命令會建立所有必要的目錄或連結,然後將 vold.post_fs_data_done 設為 1。當 vold 看到該屬性中的 1 時,會將 vold.decrypt 屬性設為 trigger_restart_framework。這會使 init.rc 再次啟動 main 類中的服務,並啟動 late_start 類中的服務(這是裝置啟動後首次啟動這些服務)。

啟動整個框架

現在,框架會使用已解密的 /data 檔案系統啟動其所有服務,接下來系統就可以使用了。

程式碼解讀

結合上章節的流程,下面用程式碼來解析啟動未進行預設加密的已加密裝置這個流程。

# Android fstab file.
#<src>           <mnt_point> <type> 
...... 
/dev/block/platform/soc.0/f9824900.sdhci/by-name/userdata  /data   ext4 noatime,nosuid,nodev,barrier=1,data=ordered,nomblk_io_submit,noauto_da_alloc,errors=panic wait,check,fileencryption 
......
defaults

這個配置定義在 device/lge/bullhead/fstab_fbe.bullhead 檔案中。

如上面的程式碼,在 /data 的末尾加上 fileencryption,便會進行全盤加密。

步驟1:檢測設有密碼的已加密裝置

//設定ro.crypto.state標記,手機已被使用者加密
static int do_mount_all(const std::vector<std::string>& args) {
 ......
 if (ret == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
  ActionManager::GetInstance().QueueEventTrigger("encrypt");
 } else if (ret == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
  // 全盤加密,ro.crypto.state = encrypted, ro.crypto.type = block
  property_set("ro.crypto.state","encrypted");
  property_set("ro.crypto.type","block");
  //傳送vdc 命令 defaultcrypto
  ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
 ......
 } else if (ret == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
  if (e4crypt_install_keyring()) {
   return -1;
  }
  property_set("ro.crypto.state","file");
  ......

 return ret;
}

這個方法定義在檔案 system/core/init/builtins.cpp 中。

# One shot invocation to deal with encrypted volume.
# do_mount_all 中寫入命令 defaultcrypto,執行 vdc 傳送命令 mountdefaultencrypted
on defaultcrypto
 exec - root -- /system/bin/vdc --wait cryptfs mountdefaultencrypted
 # vold will set vold.decrypt to trigger_restart_framework (default
 # encryption) or trigger_restart_min_framework (other encryption)

# One shot invocation to encrypt unencrypted volumes
on encrypt
 start surfaceflinger
 exec - root -- /system/bin/vdc --wait cryptfs enablecrypto inplace default noui
 # vold will set vold.decrypt to trigger_restart_framework (default
 # encryption)

這個服務定義在檔案 system/vold/vdc.rc 中。

int CryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,int argc,char **argv) {
 ......
 } else if (subcommand == "mountdefaultencrypted") {
  ......
  //執行cryptfs_mount_default_encrypted
  std::thread(&cryptfs_mount_default_encrypted).detach();
 }
 ......
}

這個方法定義在檔案 vold/CryptCommandListener.cpp 中。

int cryptfs_mount_default_encrypted(void)
{
 int crypt_type = cryptfs_get_password_type();
 ......
 } else if (crypt_type != CRYPT_TYPE_DEFAULT) {
  SLOGD("Password is not default - "
    "starting min framework to prompt");
  //不是預設加密, 設定 vold.decrypt = trigger_restart_min_framework
  property_set("vold.decrypt","trigger_restart_min_framework");
  return 0;
 } else if (cryptfs_check_passwd(DEFAULT_PASSWORD) == 0) {
 ......

這個方法定義在檔案 system/vold/cryptfs.c 中。

#屬性vold.decrypt==trigger_restart_min_framework 時執行
on property:vold.decrypt=trigger_restart_min_framework
 # A/B update verifier that marks a successful boot.
 exec - root -- /system/bin/update_verifier trigger_restart_min_framework
 class_start main

這個服務定義在服務 system/core/rootdir/init.rc 中。

class_start main 可知重啟 main 類別的服務。main 類別的服務包括:

Android加密之全盤加密詳解

會重啟 zygote。

步驟2:裝載 tmpfs

Zygote 啟動後,會 fork() system_process 程序,就是執行 SystemServer 程式碼了。但是 system_process 的執行需要正常的使用者空間(/data),所以,需要臨時掛載 tmpfs 分割槽,這個分割槽是在記憶體裡分配的臨時空間。

int CommandListener::StorageCmd::runCommand(SocketClient *cli,char **argv) {
 ......
 if (!strcmp(argv[1],"mountall")) {
  if (argc != 2) {
   cli->sendMsg(ResponseCode::CommandSyntaxError,"Usage: mountall",false);
   return 0;
  }
  // 掛載所有裝置
  fs_mgr_mount_all(fstab);
  cli->sendMsg(ResponseCode::CommandOkay,"Mountall ran successfully",false);
  return 0;
 }

這個方法定義在檔案 system/vold/CommandListener.cpp 中。

int fs_mgr_mount_all(struct fstab *fstab)
{
 ......
 /* mount(2) returned an error,handle the encryptable/formattable case */
 bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
 //掛載 tmpfs 臨時分割槽
 if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
  ++error_count;
  continue;
 }
 //全盤加密
 encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
 ......
}

這個方法定義在檔案 system/core/fs_mgr/fs_mgr.c 中。

步驟3:啟動框架以提示輸入密碼

private void startBootstrapServices() {
 // Only run "core" apps if we're encrypting the device.
 //啟動min-framework 顯示密碼輸入介面,僅啟動 coreApp, 在AndroidManifest.xml中宣告。
 //此時啟動的 APP 在 tmpfs 臨時分割槽,所以,所有app都是原始安裝狀態,不包含任何使用者使用產生的資料。
 String cryptState = SystemProperties.get("vold.decrypt");
 if (ENCRYPTING_STATE.equals(cryptState)) {
  Slog.w(TAG,"Detected encryption in progress - only parsing core apps");
  mOnlyCore = true;
 } else if (ENCRYPTED_STATE.equals(cryptState)) {
  Slog.w(TAG,"Device encrypted - only parsing core apps");
  mOnlyCore = true;
 }
 ......
 mPackageManagerService = PackageManagerService.main(mSystemContext,installer,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF,mOnlyCore);
 ......

}

這個方法定義在檔案frameworks/base/services/java/com/android/server/SystemServer.java 中。

private PackageParser.Package scanPackageLI(File scanFile,int parseFlags,int scanFlags,long currentTime,UserHandle user) throws PackageManagerException {
  if (DEBUG_INSTALL) Slog.d(TAG,"Parsing: " + scanFile);
  PackageParser pp = new PackageParser();
  pp.setSeparateProcesses(mSeparateProcesses);
  // 設定僅解析 core app only,pp.setOnlyCoreApps(mOnlyCore);
  .....
}

這個方法定義在檔案 frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java 中

private Package parseClusterPackage(File packageDir,int flags) throws PackageParserException {
  final PackageLite lite = parseClusterPackageLite(packageDir,0);

  // 如果不是 !lite.coreApp, 跳過該 app,即啟動時,不會安裝該app
  if (mOnlyCoreApps && !lite.coreApp) {
   throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,"Not a coreApp: " + packageDir);
  }

這個方法定義在檔案 frameworks/base/core/java/android/content/pm/PackageParser.java 中。

安卓中定義為 coreApp 的應用有:

Android加密之全盤加密詳解

Framework-res.apk 的 manifest 配置檔案如下:

Android加密之全盤加密詳解

步驟4:通過密碼解密資料

這個過程不再闡述。

步驟5:停止框架

#重啟 main 類別服務
on property:vold.decrypt=trigger_reset_main
 class_reset main

這個 setion 定義在檔案 system/core/rootdir/init.rc 中。

步驟6:裝載 /data

static int do_mount_all(const std::vector<std::string>& args) {
 pid_t pid;
 .....
 //
 if (ret == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
  // 傳送 encrypt 事件到 vdc
  ActionManager::GetInstance().QueueEventTrigger("encrypt");
 } else if
 .....
}

這個方法定義在檔案 system/core/init/builtins.cpp 中。

on encrypt
 start surfaceflinger
 exec - root -- /system/bin/vdc --wait cryptfs enablecrypto inplace default noui
 # vold will set vold.decrypt to trigger_restart_framework (default
 # encryption)

這個 setion 定義在檔案 system/vold/vdc.rc 中。

on encrypt
 start surfaceflinger
 #傳送命令 enablecrypto 到 vold
 exec - root -- /system/bin/vdc --wait cryptfs enablecrypto inplace default noui
 # vold will set vold.decrypt to trigger_restart_framework (default
 # encryption)

這個 setion 定義在檔案 system/vold/vdc.rc 中。

int CryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,char **argv) {
 } else if (subcommand == "cryptocomplete") {
  if (!check_argc(cli,subcommand,argc,2,"")) return 0;
  dumpArgs(argc,argv,-1);
  rc = cryptfs_crypto_complete();
 // 命令是 enablecrypto
 } else if (subcommand == "enablecrypto") {
  .....

  // Spawn as thread so init can issue commands back to vold without
  // causing deadlock,usually as a result of prep_data_fs.
  char* arg2 = argc > 2 ? strdup(argv[2]) : NULL;
  char* arg4 = argc > 4 ? strdup(argv[4]) : NULL;
  // 執行 do_enablecrypto 方法
  std::thread(&do_enablecrypto,arg2,arg4,type,no_ui).detach();
}

這個方法定義在檔案 system/vold/CryptCommandListener.cpp 中。

static int do_enablecrypto(char* arg2,char* arg4,int type,bool no_ui) {
 int rc;
 int tries;
 for (tries = 0; tries < 2; ++tries) {
  // 不是預設加密,執行方法 cryptfs_enable()
  if (type == CRYPT_TYPE_DEFAULT) {
   rc = cryptfs_enable_default(arg2,no_ui);
  } else {
   rc = cryptfs_enable(arg2,no_ui);
  }
  .....
 return -1;
}

這個方法定義在檔案 system/vold/CryptCommandListener.cpp 中。

int cryptfs_enable(char *howarg,char *passwd,int no_ui)
{
 return cryptfs_enable_internal(howarg,passwd,no_ui);
}

這個方法定義在檔案 system/vold/cryptfs.c 中。

int cryptfs_enable_internal(char *howarg,int crypt_type,int no_ui)
{
 /* restart the framework. */
 /* Create necessary paths on /data */
 if (prep_data_fs()) {
  goto error_shutting_down;
 }
}

這個方法定義在檔案 system/vold/cryptfs.c 中。

static int prep_data_fs(void)
{
 property_set("vold.post_fs_data_done","0");
 // 設定 vold.decrypt = trigger_post_fs_data,觸發 init.rc
 property_set("vold.decrypt","trigger_post_fs_data");
 SLOGD("Just triggered post_fs_data\n");

 /* Wait a max of 50 seconds,hopefully it takes much less */
 for (i=0; i<DATA_PREP_TIMEOUT; i++) {
  char p[PROPERTY_VALUE_MAX];
  // 等待 init 設定 vold.post_fs_data_done = 1
  property_get("vold.post_fs_data_done",p,"0");
  if (*p == '1') {
   break;
  } else {
   usleep(50000);
  }
 }
}

這個方法定義在檔案 system/vold/cryptfs.c 中。

on property:vold.decrypt=trigger_post_fs_data
trigger post-fs-data

這個 setion 定義在檔案 system/core/rootdir/init.rc 中。

#建立/data 子目錄和連結,啟動服務
on post-fs-data
 # We chown/chmod /data again so because mount is run as root + defaults
 chown system system /data
 chmod 0771 /data
 # We restorecon /data in case the userdata partition has been reset.
 restorecon /data

 # start debuggerd to make debugging early-boot crashes easier.
 start debuggerd
 start debuggerd64

 #task4597305 added by xiwu.peng to output logcat to uart
 start logcat2uart

 # Make sure we have the device encryption key.
 start vold
 installkey /data

 # Start bootcharting as soon as possible after the data partition is
 # mounted to collect more data.
 mkdir /data/bootchart 0755 shell shell
 bootchart_init

 .....

 mkdir /data/system_de 0770 system system
 mkdir /data/system_ce 0770 system system

 mkdir /data/misc_de 01771 system misc
 mkdir /data/misc_ce 01771 system misc

 mkdir /data/user 0711 system system
 mkdir /data/user_de 0711 system system
 symlink /data/data /data/user/0

 mkdir /data/media 0770 media_rw media_rw
 mkdir /data/media/obb 0770 media_rw media_rw

 init_user0
 # If there is no fs-post-data action in the init.<device>.rc file,you
 # must uncomment this line,otherwise encrypted filesystems
 # won't work.
 # Set indication (checked by vold) that we have finished this action
 #setprop vold.post_fs_data_done 1

這個 setion 定義在檔案 system/core/rootdir/init.rc 中。

static int cryptfs_restart_internal(int restart_main)
{
 // init 做完 post-fs-data,繼續往下執行程式碼
 if (prep_data_fs()) {
   return -1;
 }
 //init 做完 post-fs-data, vold 將 vold.decrypt 設為 trigger_restart_framework, 觸發init
 /* startup service classes main and late_start */
 property_set("vold.decrypt","trigger_restart_framework");
}

這個方法定義在檔案 system/vold/cryptfs.c 中。

#重啟所有服務
on property:vold.decrypt=trigger_restart_framework
 # A/B update verifier that marks a successful boot.
 exec - root -- /system/bin/update_verifier trigger_restart_framework
 class_start main
 class_start late_start

步驟7:啟動整個框架

vold.decrypt = trigger_restart_framework, framework 就可以正常啟動了。

加密屬性

vold 和 init 之間通過設定屬性進行通訊。下面列出了可用的加密屬性。

vold 屬性

屬性 說明

vold.decrypt trigger_encryption 以無密碼方式加密儲存卷。

vold.decrypt trigger_default_encryption 檢查儲存卷是否採用了無密碼加密。如果是,則解密並裝載儲存卷;如果不是,則將 vold.decrypt 設為 trigger_restart_min_framework。

vold.decrypt trigger_reset_main 由 vold 設定,用於關閉提示輸入磁碟密碼的介面。

vold.decrypt trigger_post_fs_data 由 vold 設定,用於準備具有必要目錄等內容的 /data。

vold.decrypt trigger_restart_framework 由 vold 設定,用於啟動實際框架和所有服務。

vold.decrypt trigger_shutdown_framework 由 vold 設定,用於關閉整個框架以開始加密。

vold.decrypt trigger_restart_min_framework 由 vold 設定,用於啟動加密進度條介面或提示輸入密碼,具體取決於 ro.crypto.state 的值。

vold.encrypt_progress 框架啟動時,如果設定了此屬性,則會進入進度條介面模式。

vold.encrypt_progress 0 to 100 進度條介面中應按照設定顯示百分比值。

vold.encrypt_progress error_partially_encrypted 進度條介面中應顯示一條訊息,告訴使用者加密失敗,並且介面中應為使用者提供一個用於將裝置恢復出廠設定的按鈕。

vold.encrypt_progress error_reboot_failed 進度條介面中應顯示一條訊息,告訴使用者加密已完成,並且介面中應為使用者提供一個用於重新啟動裝置的按鈕。此錯誤不應發生。

vold.encrypt_progress error_not_encrypted 進度條介面中應顯示一條訊息,告訴使用者發生錯誤,沒有已加密的資料或資料已丟失,並且介面中應為使用者提供一個用於重新啟動系統的按鈕。

vold.encrypt_progress error_shutting_down 進度條介面未執行,因此不清楚誰將響應此錯誤。在任何情況下,都不應發生此錯誤。

vold.post_fs_data_done 0 由 vold 在將 vold.decrypt 設為 trigger_post_fs_data 的前一刻設定。

vold.post_fs_data_done 1 由 init.rc 或 init.rc 在完成 post-fs-data 任務之後立即設定。

init 屬性

屬性 說明

ro.crypto.fs_crypto_blkdev 由 vold 命令 checkpw 設定,供 vold 命令 restart 以後使用。

ro.crypto.state unencrypted 由 init 設定,用於說明相應系統正在未加密的 /data ro.crypto.state encrypted 中執行。由 init 設定,用於說明相應系統正在已加密的 /data 中執行。

ro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags

這 5 個屬性由 init 在嘗試裝載 /data(包含從 init.rc 傳入的引數)時設定。vold 會使用這些屬性來設定加密對映。

ro.crypto.tmpfs_options 由 init.rc 設定,包含 init 在裝載 tmpfs /data 檔案系統時應使用的選項。

init 操作

on post-fs-data
on nonencrypted
on property:vold.decrypt=trigger_reset_main
on property:vold.decrypt=trigger_post_fs_data
on property:vold.decrypt=trigger_restart_min_framework
on property:vold.decrypt=trigger_restart_framework
on property:vold.decrypt=trigger_shutdown_framework
on property:vold.decrypt=trigger_encryption
on property:vold.decrypt=trigger_default_encryption.

Android 全盤加密分析到此為止。

以上這篇Android加密之全盤加密詳解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。