Mã hóa toàn bộ đĩa là quá trình mã hóa tất cả dữ liệu người dùng trên thiết bị Android bằng khóa được mã hóa. Khi một thiết bị được mã hóa, tất cả dữ liệu do người dùng tạo sẽ tự động được mã hóa trước khi đưa nó vào đĩa và tất cả các lần đọc sẽ tự động giải mã dữ liệu trước khi đưa dữ liệu trở lại quy trình gọi.
Mã hóa toàn bộ đĩa đã được giới thiệu cho Android trong 4.4, nhưng Android 5.0 đã giới thiệu các tính năng mới sau:
- Đã tạo mã hóa nhanh, chỉ mã hóa các khối đã sử dụng trên phân vùng dữ liệu để tránh mất nhiều thời gian cho lần khởi động đầu tiên. Chỉ các hệ thống tệp ext4 và f2fs hiện hỗ trợ mã hóa nhanh.
- Đã thêm cờ fstab
forceencrypt
để mã hóa trong lần khởi động đầu tiên. - Đã thêm hỗ trợ cho các mẫu và mã hóa mà không cần mật khẩu.
- Đã thêm bộ nhớ được hỗ trợ bởi phần cứng của khóa mã hóa bằng cách sử dụng khả năng ký của Môi trường thực thi tin cậy (TEE) (chẳng hạn như trong TrustZone). Xem Lưu trữ khóa được mã hóa để biết thêm chi tiết.
Thận trọng: Các thiết bị được nâng cấp lên Android 5.0 và sau đó được mã hóa có thể trở về trạng thái không được mã hóa bằng cách đặt lại dữ liệu ban đầu. Các thiết bị Android 5.0 mới được mã hóa ở lần khởi động đầu tiên không thể quay trở lại trạng thái không được mã hóa.
Cách mã hóa toàn bộ đĩa của Android hoạt động
Mã hóa toàn bộ đĩa của Android dựa trên dm-crypt
, đây là một tính năng hạt nhân hoạt động ở lớp thiết bị khối. Do đó, mã hóa hoạt động với Thẻ đa phương tiện nhúng ( eMMC) và các thiết bị flash tương tự tự hiển thị cho nhân dưới dạng thiết bị khối. Không thể mã hóa với YAFFS, giao tiếp trực tiếp với chip flash NAND thô.
Thuật toán mã hóa là 128 Tiêu chuẩn mã hóa nâng cao (AES) với chuỗi khối mật mã (CBC) và ESSIV:SHA256. Khóa chính được mã hóa bằng AES 128-bit thông qua các cuộc gọi đến thư viện OpenSSL. Bạn phải sử dụng 128 bit trở lên cho khóa (với 256 là tùy chọn).
Lưu ý: OEM có thể sử dụng 128-bit trở lên để mã hóa khóa chính.
Trong bản phát hành Android 5.0, có bốn loại trạng thái mã hóa:
- mặc định
- GHIM
- mật khẩu
- mẫu
Khi khởi động lần đầu, thiết bị sẽ tạo khóa chính 128 bit được tạo ngẫu nhiên, sau đó băm nó bằng mật khẩu mặc định và muối được lưu trữ. Mật khẩu mặc định là: "default_password" Tuy nhiên, hàm băm kết quả cũng được ký thông qua TEE (chẳng hạn như TrustZone), sử dụng hàm băm của chữ ký để mã hóa khóa chính.
Bạn có thể tìm thấy mật khẩu mặc định được xác định trong tệp cryptfs.cpp của Dự án mã nguồn mở Android.
Khi người dùng đặt mã PIN/mật khẩu hoặc mật khẩu trên thiết bị, chỉ có khóa 128 bit được mã hóa lại và lưu trữ. (nghĩa là các thay đổi về mã PIN/mật khẩu/mẫu của người dùng KHÔNG gây ra quá trình mã hóa lại dữ liệu người dùng.) Lưu ý rằng thiết bị được quản lý có thể phải tuân theo các hạn chế về mã PIN, mẫu hoặc mật khẩu.
Mã hóa được quản lý bởi init
và vold
. init
gọi vold
và vold đặt thuộc tính để kích hoạt các sự kiện trong init. Các phần khác của hệ thống cũng xem xét các thuộc tính để tiến hành các tác vụ như báo cáo trạng thái, yêu cầu mật khẩu hoặc nhắc khôi phục cài đặt gốc trong trường hợp xảy ra lỗi nghiêm trọng. Để gọi các tính năng mã hóa trong vold
, hệ thống sử dụng các lệnh cryptfs
của công cụ dòng lệnh vdc
: checkpw
, restart
, enablecrypto
, changepw
, cryptocomplete
, verifypw
, setfield
, getfield
, mountdefaultencrypted
, getpwtype
, getpw
và clearpw
.
Để mã hóa, giải mã hoặc xóa /data
, /data
không được gắn kết. Tuy nhiên, để hiển thị bất kỳ giao diện người dùng (UI) nào, khung phải bắt đầu và khung yêu cầu /data
để chạy. Để giải quyết câu hỏi hóc búa này, một hệ thống tệp tạm thời được gắn trên /data
. Điều này cho phép Android nhắc nhập mật khẩu, hiển thị tiến trình hoặc đề xuất xóa dữ liệu nếu cần. Nó đặt ra giới hạn rằng để chuyển từ hệ thống tệp tạm thời sang hệ thống tệp /data
thực, hệ thống phải dừng mọi quy trình có tệp đang mở trên hệ thống tệp tạm thời và khởi động lại các quy trình đó trên hệ thống /data
thực. Để làm điều này, tất cả các dịch vụ phải thuộc một trong ba nhóm: core
, main
và late_start
.
-
core
: Không bao giờ tắt sau khi bắt đầu. -
main
: Tắt và sau đó khởi động lại sau khi nhập mật khẩu đĩa. -
late_start
: Không bắt đầu cho đến sau khi/data
đã được giải mã và gắn kết.
Để kích hoạt những hành động này, thuộc tính vold.decrypt
được đặt thành các chuỗi khác nhau . Để hủy và khởi động lại dịch vụ, các lệnh init
là:
-
class_reset
: Dừng dịch vụ nhưng cho phép khởi động lại dịch vụ đó với class_start. -
class_start
: Khởi động lại một dịch vụ. -
class_stop
: Dừng dịch vụ và thêm cờSVC_DISABLED
. Các dịch vụ đã dừng không phản hồiclass_start
.
Chảy
Có bốn luồng cho một thiết bị được mã hóa. Một thiết bị chỉ được mã hóa một lần và sau đó tuân theo quy trình khởi động bình thường.
- Mã hóa một thiết bị chưa được mã hóa trước đó:
- Mã hóa thiết bị mới bằng
forceencrypt
: Mã hóa bắt buộc khi khởi động lần đầu (bắt đầu từ Android L). - Mã hóa thiết bị hiện có: Mã hóa do người dùng thực hiện (Android K trở về trước).
- Mã hóa thiết bị mới bằng
- Khởi động một thiết bị được mã hóa:
- Khởi động thiết bị được mã hóa mà không cần mật khẩu: Khởi động thiết bị được mã hóa không có mật khẩu đã đặt (phù hợp với các thiết bị chạy Android 5.0 trở lên).
- Khởi động thiết bị được mã hóa bằng mật khẩu: Khởi động thiết bị được mã hóa có mật khẩu đã đặt.
Ngoài các luồng này, thiết bị cũng có thể không mã hóa /data
. Mỗi luồng được giải thích chi tiết bên dưới.
Mã hóa thiết bị mới bằng forceencrypt
Đây là lần khởi động đầu tiên thông thường đối với thiết bị Android 5.0.
- Phát hiện hệ thống tệp không được mã hóa bằng cờ
forceencrypt
/data
không được mã hóa nhưng cần phải như vậy vìforceencrypt
bắt buộc nó. Ngắt kết nối/data
. - Bắt đầu mã hóa
/data
vold.decrypt = "trigger_encryption"
kích hoạtinit.rc
, điều này sẽ khiếnvold
mã hóa/data
mà không cần mật khẩu. (Không được đặt vì đây phải là một thiết bị mới.) - Gắn kết tmpfs
vold
gắn tmpfs/data
(sử dụng tùy chọn tmpfs từro.crypto.tmpfs_options
) và đặt thuộc tínhvold.encrypt_progress
thành 0.vold
chuẩn bị tmpfs/data
để khởi động hệ thống được mã hóa và đặt thuộc tínhvold.decrypt
thành:trigger_restart_min_framework
- Đưa ra khuôn khổ để hiển thị tiến độ
Bởi vì thiết bị hầu như không có dữ liệu để mã hóa, nên thanh tiến trình thường sẽ không thực sự xuất hiện do quá trình mã hóa diễn ra quá nhanh. Xem Mã hóa thiết bị hiện có để biết thêm chi tiết về giao diện người dùng tiến trình.
- Khi
/data
được mã hóa, hãy gỡ bỏ khungvold
đặtvold.decrypt
thànhtrigger_default_encryption
khởi động dịch vụdefaultcrypto
. (Thao tác này bắt đầu quy trình bên dưới để gắn dữ liệu người dùng được mã hóa mặc định.)trigger_default_encryption
kiểm tra loại mã hóa để xem liệu/data
có được mã hóa bằng mật khẩu hay không. Vì các thiết bị Android 5.0 được mã hóa trong lần khởi động đầu tiên nên không cần đặt mật khẩu; do đó chúng tôi giải mã và gắn kết/data
. - Gắn kết
/data
init
sau đó gắn kết/data
trên tmpfs RAMDisk bằng cách sử dụng các tham số mà nó chọn từro.crypto.tmpfs_options
, được đặt tronginit.rc
- bắt đầu khung
vold
đặtvold.decrypt
thànhtrigger_restart_framework
để tiếp tục quá trình khởi động thông thường.
Mã hóa một thiết bị hiện có
Đây là điều xảy ra khi bạn mã hóa một thiết bị Android K hoặc cũ hơn chưa được mã hóa đã được di chuyển sang L.
Quá trình này do người dùng bắt đầu và được gọi là "mã hóa tại chỗ" trong mã. Khi người dùng chọn mã hóa thiết bị, giao diện người dùng sẽ đảm bảo rằng pin đã được sạc đầy và bộ chuyển đổi AC được cắm vào để có đủ năng lượng để hoàn tất quá trình mã hóa.
Cảnh báo: Nếu thiết bị hết điện và tắt trước khi mã hóa xong, dữ liệu tệp sẽ ở trạng thái được mã hóa một phần. Thiết bị phải được khôi phục cài đặt gốc và tất cả dữ liệu sẽ bị mất.
Để bật mã hóa tại chỗ, vold
bắt đầu một vòng lặp để đọc từng khu vực của thiết bị khối thực và sau đó ghi nó vào thiết bị khối tiền điện tử. vold
kiểm tra xem một sector có được sử dụng hay không trước khi đọc và ghi nó, điều này giúp mã hóa nhanh hơn nhiều trên một thiết bị mới có ít hoặc không có dữ liệu.
Trạng thái của thiết bị : Đặt ro.crypto.state = "unencrypted"
và thực thi trình kích hoạt init
on nonencrypted
để tiếp tục khởi động.
- kiểm tra mật khẩu
Giao diện người dùng gọi
vold
bằng lệnhcryptfs enablecrypto inplace
trong đópasswd
là mật khẩu màn hình khóa của người dùng. - Gỡ bỏ khuôn khổ
vold
kiểm tra lỗi, trả về -1 nếu không thể mã hóa và in lý do trong nhật ký. Nếu nó có thể mã hóa, nó sẽ đặt thuộc tínhvold.decrypt
thànhtrigger_shutdown_framework
. Điều này khiếninit.rc
ngừng dịch vụ trong các lớplate_start
vàmain
. - Tạo chân trang tiền điện tử
- Tạo một tệp breadcrumb
- khởi động lại
- Phát hiện tệp breadcrumb
- Bắt đầu mã hóa
/data
vold
sau đó thiết lập ánh xạ tiền điện tử, tạo ra một thiết bị khối tiền điện tử ảo ánh xạ lên thiết bị khối thực nhưng mã hóa từng khu vực khi nó được viết và giải mã từng khu vực khi nó được đọc.vold
sau đó tạo và ghi ra siêu dữ liệu tiền điện tử. - Trong khi mã hóa, hãy gắn tmpfs
vold
gắn tmpfs/data
(sử dụng tùy chọn tmpfs từro.crypto.tmpfs_options
) và đặt thuộc tínhvold.encrypt_progress
thành 0.vold
chuẩn bị tmpfs/data
để khởi động hệ thống được mã hóa và đặt thuộc tínhvold.decrypt
thành:trigger_restart_min_framework
- Đưa ra khuôn khổ để hiển thị tiến độ
trigger_restart_min_framework
khiếninit.rc
bắt đầu lớp dịch vụmain
. Khi khung thấy rằngvold.encrypt_progress
được đặt thành 0, nó sẽ hiển thị giao diện người dùng thanh tiến trình, truy vấn thuộc tính đó cứ sau 5 giây và cập nhật thanh tiến trình. Vòng lặp mã hóa cập nhậtvold.encrypt_progress
mỗi khi nó mã hóa một phần trăm khác của phân vùng. - Khi
/data
được mã hóa, hãy cập nhật chân trang tiền điện tửKhi
/data
được mã hóa thành công,vold
sẽ xóa cờENCRYPTION_IN_PROGRESS
trong siêu dữ liệu.Khi thiết bị được mở khóa thành công, mật khẩu sẽ được sử dụng để mã hóa khóa chính và chân trang tiền điện tử được cập nhật.
Nếu khởi động lại không thành công vì lý do nào đó,
vold
đặt thuộc tínhvold.encrypt_progress
thànherror_reboot_failed
và giao diện người dùng sẽ hiển thị thông báo yêu cầu người dùng nhấn nút để khởi động lại. Điều này dự kiến sẽ không bao giờ xảy ra.
Bắt đầu một thiết bị được mã hóa bằng mã hóa mặc định
Đây là điều xảy ra khi bạn khởi động một thiết bị được mã hóa mà không có mật khẩu. Vì các thiết bị Android 5.0 được mã hóa trong lần khởi động đầu tiên, nên không có mật khẩu được đặt và do đó, đây là trạng thái mã hóa mặc định .
- Phát hiện mã hóa
/data
không có mật khẩuPhát hiện rằng thiết bị Android được mã hóa vì
/data
không thể được gắn và một trong các cờencryptable
hoặcforceencrypt
được đặt.vold
đặtvold.decrypt
thànhtrigger_default_encryption
, khởi động dịch vụdefaultcrypto
.trigger_default_encryption
kiểm tra loại mã hóa để xem liệu/data
có được mã hóa bằng mật khẩu hay không. - Giải mã/dữ liệu
Tạo thiết bị
dm-crypt
trên thiết bị khối để thiết bị sẵn sàng sử dụng. - Gắn kết/dữ liệu
vold
sau đó gắn kết phân vùng thực/data
được giải mã và sau đó chuẩn bị phân vùng mới. Nó đặt thuộc tínhvold.post_fs_data_done
thành 0 và sau đó đặtvold.decrypt
thànhtrigger_post_fs_data
. Điều này khiếninit.rc
chạy các lệnhpost-fs-data
của nó. Họ sẽ tạo bất kỳ thư mục hoặc liên kết cần thiết nào, sau đó đặtvold.post_fs_data_done
thành 1.Khi
vold
nhìn thấy 1 trong thuộc tính đó, nó sẽ đặt thuộc tínhvold.decrypt
thành:trigger_restart_framework.
Điều này khiếninit.rc
bắt đầu lại các dịch vụ trong lớpmain
và cũng bắt đầu các dịch vụ trong lớplate_start
lần đầu tiên kể từ khi khởi động. - bắt đầu khung
Giờ đây, khung khởi động tất cả các dịch vụ của nó bằng cách sử dụng
/data
đã được giải mã và hệ thống đã sẵn sàng để sử dụng.
Bắt đầu một thiết bị được mã hóa mà không cần mã hóa mặc định
Đây là điều xảy ra khi bạn khởi động một thiết bị được mã hóa có mật khẩu đã đặt. Mật khẩu của thiết bị có thể là mã pin, hình mở khóa hoặc mật khẩu.
- Phát hiện thiết bị được mã hóa bằng mật khẩu
Phát hiện thiết bị Android được mã hóa vì cờ
ro.crypto.state = "encrypted"
vold
đặtvold.decrypt
thànhtrigger_restart_min_framework
vì/data
được mã hóa bằng mật khẩu. - Gắn kết tmpfs
init
đặt năm thuộc tính để lưu các tùy chọn gắn kết ban đầu được cung cấp cho/data
với các tham số được truyền từinit.rc
.vold
sử dụng các thuộc tính này để thiết lập ánh xạ tiền điện tử:-
ro.crypto.fs_type
-
ro.crypto.fs_real_blkdev
-
ro.crypto.fs_mnt_point
-
ro.crypto.fs_options
-
ro.crypto.fs_flags
(số hex 8 chữ số ASCII đứng trước 0x)
-
- Bắt đầu khung để nhắc nhập mật khẩu
Khung khởi động và thấy rằng
vold.decrypt
được đặt thànhtrigger_restart_min_framework
. Điều này cho khung công tác biết rằng nó đang khởi động trên đĩa/data
tmpfs và nó cần lấy mật khẩu người dùng.Tuy nhiên, trước tiên, nó cần đảm bảo rằng đĩa đã được mã hóa đúng cách. Nó gửi lệnh
cryptfs cryptocomplete
tớivold
.vold
trả về 0 nếu quá trình mã hóa được hoàn tất thành công, -1 nếu có lỗi nội bộ hoặc -2 nếu quá trình mã hóa không được hoàn tất thành công.vold
xác định điều này bằng cách xem trong siêu dữ liệu tiền điện tử để tìm cờCRYPTO_ENCRYPTION_IN_PROGRESS
. Nếu nó được đặt, thì quá trình mã hóa đã bị gián đoạn và không có dữ liệu nào có thể sử dụng được trên thiết bị. Nếuvold
trả về lỗi, giao diện người dùng sẽ hiển thị thông báo yêu cầu người dùng khởi động lại và khôi phục cài đặt gốc cho thiết bị, đồng thời cung cấp cho người dùng một nút để nhấn để làm như vậy. - Giải mã dữ liệu bằng mật khẩu
Khi
cryptfs cryptocomplete
thành công, khung sẽ hiển thị giao diện người dùng yêu cầu mật khẩu đĩa. Giao diện người dùng kiểm tra mật khẩu bằng cách gửi lệnhcryptfs checkpw
tớivold
. Nếu mật khẩu chính xác (được xác định bằng cách gắn thành công/data
đã giải mã vào một vị trí tạm thời, sau đó ngắt kết nối nó),vold
sẽ lưu tên của thiết bị khối đã giải mã trong thuộc tínhro.crypto.fs_crypto_blkdev
và trả về trạng thái 0 cho giao diện người dùng . Nếu mật khẩu không chính xác, nó sẽ trả về -1 cho giao diện người dùng. - dừng khuôn khổ
Giao diện người dùng đưa ra một đồ họa khởi động tiền điện tử và sau đó gọi
vold
bằng lệnhcryptfs restart
.vold
đặt thuộc tínhvold.decrypt
thànhtrigger_reset_main
, khiếninit.rc
thực hiệnclass_reset main
. Điều này dừng tất cả các dịch vụ trong lớp chính, cho phép tmpfs/data
không được đếm. - Gắn kết
/data
vold
sau đó gắn kết phân vùng thực/data
đã được giải mã và chuẩn bị phân vùng mới (phân vùng này có thể chưa bao giờ được chuẩn bị nếu nó được mã hóa bằng tùy chọn xóa, tùy chọn này không được hỗ trợ trong lần phát hành đầu tiên). Nó đặt thuộc tínhvold.post_fs_data_done
thành 0 và sau đó đặtvold.decrypt
thànhtrigger_post_fs_data
. Điều này khiếninit.rc
chạy các lệnhpost-fs-data
của nó. Họ sẽ tạo bất kỳ thư mục hoặc liên kết cần thiết nào, sau đó đặtvold.post_fs_data_done
thành 1. Khivold
nhìn thấy 1 trong thuộc tính đó, nó sẽ đặt thuộc tínhvold.decrypt
thànhtrigger_restart_framework
. Điều này khiếninit.rc
bắt đầu lại các dịch vụ trong lớpmain
và cũng bắt đầu các dịch vụ trong lớplate_start
lần đầu tiên kể từ khi khởi động. - Bắt đầu khung đầy đủ
Giờ đây, khung khởi động tất cả các dịch vụ của nó bằng cách sử dụng hệ thống tệp
/data
đã được giải mã và hệ thống đã sẵn sàng để sử dụng.
Sự thất bại
Một thiết bị không giải mã được có thể bị lỗi vì một vài lý do. Thiết bị bắt đầu với một loạt các bước khởi động thông thường:
- Phát hiện thiết bị được mã hóa bằng mật khẩu
- Gắn kết tmpfs
- Bắt đầu khung để nhắc nhập mật khẩu
Nhưng sau khi khung mở ra, thiết bị có thể gặp một số lỗi:
- Mật khẩu trùng khớp nhưng không thể giải mã dữ liệu
- Người dùng nhập sai mật khẩu 30 lần
Nếu những lỗi này không được giải quyết, hãy nhắc người dùng xóa sạch nhà máy :
Nếu vold
phát hiện lỗi trong quá trình mã hóa và nếu chưa có dữ liệu nào bị hủy và khung được kích hoạt, vold
sẽ đặt thuộc tính vold.encrypt_progress
thành error_not_encrypted
. Giao diện người dùng nhắc người dùng khởi động lại và cảnh báo họ rằng quá trình mã hóa chưa bao giờ bắt đầu. Nếu lỗi xảy ra sau khi khung đã bị phá bỏ, nhưng trước khi giao diện người dùng trên thanh tiến trình hoạt động, vold
sẽ khởi động lại hệ thống. Nếu khởi động lại không thành công, nó sẽ đặt vold.encrypt_progress
thành error_shutting_down
và trả về -1; nhưng sẽ không có bất cứ điều gì để bắt lỗi. Điều này không được mong đợi sẽ xảy ra.
Nếu vold
phát hiện lỗi trong quá trình mã hóa, nó sẽ đặt vold.encrypt_progress
thành error_partially_encrypted
và trả về -1. Sau đó, giao diện người dùng sẽ hiển thị thông báo cho biết mã hóa không thành công và cung cấp một nút để người dùng khôi phục cài đặt gốc cho thiết bị.
Lưu trữ khóa được mã hóa
Khóa được mã hóa được lưu trữ trong siêu dữ liệu tiền điện tử. Sao lưu phần cứng được triển khai bằng cách sử dụng khả năng ký của Môi trường thực thi tin cậy (TEE). Trước đây, chúng tôi đã mã hóa khóa chính bằng khóa được tạo bằng cách áp dụng scrypt cho mật khẩu của người dùng và muối được lưu trữ. Để làm cho khóa có khả năng phục hồi trước các cuộc tấn công ngoài hộp, chúng tôi mở rộng thuật toán này bằng cách ký vào khóa kết quả bằng khóa TEE được lưu trữ. Chữ ký kết quả sau đó được biến thành một khóa có độ dài thích hợp bằng một ứng dụng mã hóa khác. Khóa này sau đó được sử dụng để mã hóa và giải mã khóa chính. Để lưu khóa này:
- Tạo khóa mã hóa đĩa 16 byte ngẫu nhiên (DEK) và muối 16 byte.
- Áp dụng scrypt cho mật khẩu người dùng và muối để tạo khóa trung gian 32 byte 1 (IK1).
- Pad IK1 với 0 byte so với kích thước của khóa riêng liên kết với phần cứng (HBK). Cụ thể, chúng tôi đệm như: 00 || IK1 || 00..00; một byte không, 32 byte IK1, 223 byte không.
- Ký tên IK1 được đệm bằng HBK để tạo IK2 256 byte.
- Áp dụng scrypt cho IK2 và muối (cùng muối với bước 2) để tạo IK3 32 byte.
- Sử dụng 16 byte đầu tiên của IK3 làm KEK và 16 byte cuối cùng làm IV.
- Mã hóa DEK bằng AES_CBC, bằng khóa KEK và vectơ khởi tạo IV.
Thay đổi mật khẩu
Khi người dùng chọn thay đổi hoặc xóa mật khẩu của họ trong cài đặt, giao diện người dùng sẽ gửi lệnh cryptfs changepw
tới vold
và vold
mã hóa lại khóa chính của đĩa bằng mật khẩu mới.
Thuộc tính mã hóa
vold
và init
giao tiếp với nhau bằng cách đặt thuộc tính. Dưới đây là danh sách các thuộc tính có sẵn để mã hóa.
Thuộc tính Vold
Tài sản | Sự miêu tả |
---|---|
vold.decrypt trigger_encryption | Mã hóa ổ đĩa mà không cần mật khẩu. |
vold.decrypt trigger_default_encryption | Kiểm tra ổ đĩa để xem nó có được mã hóa mà không cần mật khẩu hay không. Nếu có, hãy giải mã và gắn nó, nếu không, hãy đặt vold.decrypt thành trigger_restart_min_framework. |
vold.decrypt trigger_reset_main | Đặt theo vold để tắt giao diện người dùng yêu cầu mật khẩu đĩa. |
vold.decrypt trigger_post_fs_data | Đặt theo vold để chuẩn bị /data với các thư mục cần thiết, et al. |
vold.decrypt trigger_restart_framework | Đặt theo vold để bắt đầu khung thực và tất cả các dịch vụ. |
vold.decrypt trigger_shutdown_framework | Đặt theo vold để tắt toàn bộ khung để bắt đầu mã hóa. |
vold.decrypt trigger_restart_min_framework | Đặt theo vold để bắt đầu giao diện người dùng trên thanh tiến trình để mã hóa hoặc nhắc nhập mật khẩu, tùy thuộc vào giá trị của ro.crypto.state . |
vold.encrypt_progress | Khi khung khởi động, nếu thuộc tính này được đặt, hãy vào chế độ giao diện người dùng của thanh tiến trình. |
vold.encrypt_progress 0 to 100 | Giao diện người dùng thanh tiến trình sẽ hiển thị giá trị phần trăm đã đặt. |
vold.encrypt_progress error_partially_encrypted | Giao diện người dùng trên thanh tiến trình sẽ hiển thị thông báo rằng mã hóa không thành công và cung cấp cho người dùng tùy chọn khôi phục cài đặt gốc cho thiết bị. |
vold.encrypt_progress error_reboot_failed | Giao diện người dùng trên thanh tiến trình sẽ hiển thị thông báo cho biết quá trình mã hóa đã hoàn tất và cung cấp cho người dùng một nút để khởi động lại thiết bị. Lỗi này dự kiến sẽ không xảy ra. |
vold.encrypt_progress error_not_encrypted | Giao diện người dùng trên thanh tiến trình sẽ hiển thị thông báo cho biết đã xảy ra lỗi, không có dữ liệu nào được mã hóa hoặc bị mất và cung cấp cho người dùng một nút để khởi động lại hệ thống. |
vold.encrypt_progress error_shutting_down | Giao diện người dùng thanh tiến trình không chạy, vì vậy không rõ ai sẽ phản hồi lỗi này. Và nó không bao giờ nên xảy ra anyway. |
vold.post_fs_data_done 0 | Đặt theo vold ngay trước khi đặt vold.decrypt thành trigger_post_fs_data . |
vold.post_fs_data_done 1 | Được đặt bởi init.rc hoặc init.rc ngay sau khi hoàn thành tác vụ post-fs-data . |
thuộc tính ban đầu
Tài sản | Sự miêu tả |
---|---|
ro.crypto.fs_crypto_blkdev | Đặt bằng lệnh vold checkpw để sử dụng sau này bằng lệnh vold restart . |
ro.crypto.state unencrypted | Được đặt bởi init để nói rằng hệ thống này đang chạy với /data ro.crypto.state encrypted . Được thiết lập bởi init để nói rằng hệ thống này đang chạy với mã hóa /data . |
| Năm thuộc tính này được thiết lập bởi init khi nó cố gắn /data với các tham số được truyền vào từ init.rc . vold sử dụng những thứ này để thiết lập ánh xạ tiền điện tử. |
ro.crypto.tmpfs_options | Được đặt bởi init.rc với các tùy chọn mà init nên sử dụng khi gắn hệ thống tệp tmpfs /data . |
bắt đầu hành động
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,
Mã hóa toàn bộ đĩa là quá trình mã hóa tất cả dữ liệu người dùng trên thiết bị Android bằng khóa được mã hóa. Khi một thiết bị được mã hóa, tất cả dữ liệu do người dùng tạo sẽ tự động được mã hóa trước khi đưa nó vào đĩa và tất cả các lần đọc sẽ tự động giải mã dữ liệu trước khi đưa dữ liệu trở lại quy trình gọi.
Mã hóa toàn bộ đĩa đã được giới thiệu cho Android trong 4.4, nhưng Android 5.0 đã giới thiệu các tính năng mới sau:
- Đã tạo mã hóa nhanh, chỉ mã hóa các khối đã sử dụng trên phân vùng dữ liệu để tránh mất nhiều thời gian cho lần khởi động đầu tiên. Hiện chỉ có các hệ thống tệp ext4 và f2fs hỗ trợ mã hóa nhanh.
- Đã thêm cờ fstab
forceencrypt
để mã hóa trong lần khởi động đầu tiên. - Đã thêm hỗ trợ cho các mẫu và mã hóa mà không cần mật khẩu.
- Đã thêm bộ nhớ được hỗ trợ bởi phần cứng của khóa mã hóa bằng cách sử dụng khả năng ký của Môi trường thực thi tin cậy (TEE) (chẳng hạn như trong TrustZone). Xem Lưu trữ khóa được mã hóa để biết thêm chi tiết.
Thận trọng: Các thiết bị được nâng cấp lên Android 5.0 và sau đó được mã hóa có thể trở về trạng thái không được mã hóa bằng cách đặt lại dữ liệu ban đầu. Các thiết bị Android 5.0 mới được mã hóa ở lần khởi động đầu tiên không thể quay trở lại trạng thái không được mã hóa.
Cách mã hóa toàn bộ đĩa của Android hoạt động
Mã hóa toàn bộ đĩa của Android dựa trên dm-crypt
, đây là một tính năng hạt nhân hoạt động ở lớp thiết bị khối. Do đó, mã hóa hoạt động với Thẻ đa phương tiện nhúng ( eMMC) và các thiết bị flash tương tự tự hiển thị cho nhân dưới dạng thiết bị khối. Không thể mã hóa với YAFFS, giao tiếp trực tiếp với chip flash NAND thô.
Thuật toán mã hóa là 128 Tiêu chuẩn mã hóa nâng cao (AES) với chuỗi khối mật mã (CBC) và ESSIV:SHA256. Khóa chính được mã hóa bằng AES 128-bit thông qua các cuộc gọi đến thư viện OpenSSL. Bạn phải sử dụng 128 bit trở lên cho khóa (với 256 là tùy chọn).
Lưu ý: OEM có thể sử dụng 128-bit trở lên để mã hóa khóa chính.
Trong bản phát hành Android 5.0, có bốn loại trạng thái mã hóa:
- mặc định
- GHIM
- mật khẩu
- mẫu
Khi khởi động lần đầu, thiết bị sẽ tạo khóa chính 128 bit được tạo ngẫu nhiên, sau đó băm nó bằng mật khẩu mặc định và muối được lưu trữ. Mật khẩu mặc định là: "default_password" Tuy nhiên, hàm băm kết quả cũng được ký thông qua TEE (chẳng hạn như TrustZone), sử dụng hàm băm của chữ ký để mã hóa khóa chính.
Bạn có thể tìm thấy mật khẩu mặc định được xác định trong tệp cryptfs.cpp của Dự án mã nguồn mở Android.
Khi người dùng đặt mã PIN/mật khẩu hoặc mật khẩu trên thiết bị, chỉ có khóa 128 bit được mã hóa lại và lưu trữ. (nghĩa là các thay đổi về mã PIN/mật khẩu/mẫu của người dùng KHÔNG gây ra quá trình mã hóa lại dữ liệu người dùng.) Lưu ý rằng thiết bị được quản lý có thể phải tuân theo các hạn chế về mã PIN, mẫu hoặc mật khẩu.
Mã hóa được quản lý bởi init
và vold
. init
gọi vold
và vold đặt thuộc tính để kích hoạt các sự kiện trong init. Các phần khác của hệ thống cũng xem xét các thuộc tính để tiến hành các tác vụ như báo cáo trạng thái, yêu cầu mật khẩu hoặc nhắc khôi phục cài đặt gốc trong trường hợp xảy ra lỗi nghiêm trọng. Để gọi các tính năng mã hóa trong vold
, hệ thống sử dụng các lệnh cryptfs
của công cụ dòng lệnh vdc
: checkpw
, restart
, enablecrypto
, changepw
, cryptocomplete
, verifypw
, setfield
, getfield
, mountdefaultencrypted
, getpwtype
, getpw
và clearpw
.
Để mã hóa, giải mã hoặc xóa /data
, /data
không được gắn kết. Tuy nhiên, để hiển thị bất kỳ giao diện người dùng (UI) nào, khung phải bắt đầu và khung yêu cầu /data
để chạy. Để giải quyết câu hỏi hóc búa này, một hệ thống tệp tạm thời được gắn trên /data
. Điều này cho phép Android nhắc nhập mật khẩu, hiển thị tiến trình hoặc đề xuất xóa dữ liệu nếu cần. Nó đặt ra giới hạn rằng để chuyển từ hệ thống tệp tạm thời sang hệ thống tệp /data
thực, hệ thống phải dừng mọi quy trình có tệp đang mở trên hệ thống tệp tạm thời và khởi động lại các quy trình đó trên hệ thống /data
thực. Để làm điều này, tất cả các dịch vụ phải thuộc một trong ba nhóm: core
, main
và late_start
.
-
core
: Không bao giờ tắt sau khi bắt đầu. -
main
: Tắt và sau đó khởi động lại sau khi nhập mật khẩu đĩa. -
late_start
: Không bắt đầu cho đến sau khi/data
đã được giải mã và gắn kết.
Để kích hoạt những hành động này, thuộc tính vold.decrypt
được đặt thành các chuỗi khác nhau . Để hủy và khởi động lại dịch vụ, các lệnh init
là:
-
class_reset
: Dừng dịch vụ nhưng cho phép khởi động lại dịch vụ đó với class_start. -
class_start
: Khởi động lại một dịch vụ. -
class_stop
: Dừng dịch vụ và thêm cờSVC_DISABLED
. Các dịch vụ đã dừng không phản hồiclass_start
.
Chảy
Có bốn luồng cho một thiết bị được mã hóa. Một thiết bị chỉ được mã hóa một lần và sau đó tuân theo quy trình khởi động bình thường.
- Mã hóa một thiết bị chưa được mã hóa trước đó:
- Mã hóa thiết bị mới bằng
forceencrypt
: Mã hóa bắt buộc khi khởi động lần đầu (bắt đầu từ Android L). - Mã hóa thiết bị hiện có: Mã hóa do người dùng thực hiện (Android K trở về trước).
- Mã hóa thiết bị mới bằng
- Khởi động một thiết bị được mã hóa:
- Khởi động thiết bị được mã hóa mà không cần mật khẩu: Khởi động thiết bị được mã hóa không có mật khẩu đã đặt (phù hợp với các thiết bị chạy Android 5.0 trở lên).
- Khởi động thiết bị được mã hóa bằng mật khẩu: Khởi động thiết bị được mã hóa có mật khẩu đã đặt.
Ngoài các luồng này, thiết bị cũng có thể không mã hóa /data
. Mỗi luồng được giải thích chi tiết bên dưới.
Mã hóa thiết bị mới bằng forceencrypt
Đây là lần khởi động đầu tiên thông thường đối với thiết bị Android 5.0.
- Phát hiện hệ thống tệp không được mã hóa bằng cờ
forceencrypt
/data
không được mã hóa nhưng cần phải như vậy vìforceencrypt
bắt buộc nó. Ngắt kết nối/data
. - Bắt đầu mã hóa
/data
vold.decrypt = "trigger_encryption"
kích hoạtinit.rc
, điều này sẽ khiếnvold
mã hóa/data
mà không cần mật khẩu. (Không được đặt vì đây phải là một thiết bị mới.) - Gắn kết tmpfs
vold
gắn tmpfs/data
(sử dụng tùy chọn tmpfs từro.crypto.tmpfs_options
) và đặt thuộc tínhvold.encrypt_progress
thành 0.vold
chuẩn bị tmpfs/data
để khởi động hệ thống được mã hóa và đặt thuộc tínhvold.decrypt
thành:trigger_restart_min_framework
- Đưa ra khuôn khổ để hiển thị tiến độ
Bởi vì thiết bị hầu như không có dữ liệu để mã hóa, nên thanh tiến trình thường sẽ không thực sự xuất hiện do quá trình mã hóa diễn ra quá nhanh. Xem Mã hóa thiết bị hiện có để biết thêm chi tiết về giao diện người dùng tiến trình.
- Khi
/data
được mã hóa, hãy gỡ bỏ khungvold
đặtvold.decrypt
thànhtrigger_default_encryption
khởi động dịch vụdefaultcrypto
. (Thao tác này bắt đầu quy trình bên dưới để gắn dữ liệu người dùng được mã hóa mặc định.)trigger_default_encryption
kiểm tra loại mã hóa để xem liệu/data
có được mã hóa bằng mật khẩu hay không. Vì các thiết bị Android 5.0 được mã hóa trong lần khởi động đầu tiên nên không cần đặt mật khẩu; do đó chúng tôi giải mã và gắn kết/data
. - Gắn kết
/data
init
sau đó gắn kết/data
trên tmpfs RAMDisk bằng cách sử dụng các tham số mà nó chọn từro.crypto.tmpfs_options
, được đặt tronginit.rc
- bắt đầu khung
vold
đặtvold.decrypt
thànhtrigger_restart_framework
để tiếp tục quá trình khởi động thông thường.
Mã hóa một thiết bị hiện có
Đây là điều xảy ra khi bạn mã hóa một thiết bị Android K hoặc cũ hơn chưa được mã hóa đã được di chuyển sang L.
Quá trình này do người dùng bắt đầu và được gọi là "mã hóa tại chỗ" trong mã. Khi người dùng chọn mã hóa thiết bị, giao diện người dùng sẽ đảm bảo rằng pin đã được sạc đầy và bộ chuyển đổi AC được cắm vào để có đủ năng lượng để hoàn tất quá trình mã hóa.
Cảnh báo: Nếu thiết bị hết điện và tắt trước khi mã hóa xong, dữ liệu tệp sẽ ở trạng thái được mã hóa một phần. Thiết bị phải được khôi phục cài đặt gốc và tất cả dữ liệu sẽ bị mất.
Để bật mã hóa tại chỗ, vold
bắt đầu một vòng lặp để đọc từng khu vực của thiết bị khối thực và sau đó ghi nó vào thiết bị khối tiền điện tử. vold
kiểm tra xem một sector có được sử dụng hay không trước khi đọc và ghi nó, điều này giúp mã hóa nhanh hơn nhiều trên một thiết bị mới có ít hoặc không có dữ liệu.
Trạng thái của thiết bị : Đặt ro.crypto.state = "unencrypted"
và thực thi trình kích hoạt init
on nonencrypted
để tiếp tục khởi động.
- kiểm tra mật khẩu
Giao diện người dùng gọi
vold
bằng lệnhcryptfs enablecrypto inplace
trong đópasswd
là mật khẩu màn hình khóa của người dùng. - Gỡ bỏ khuôn khổ
vold
kiểm tra lỗi, trả về -1 nếu không thể mã hóa và in lý do trong nhật ký. Nếu nó có thể mã hóa, nó sẽ đặt thuộc tínhvold.decrypt
thànhtrigger_shutdown_framework
. Điều này khiếninit.rc
ngừng dịch vụ trong các lớplate_start
vàmain
. - Tạo chân trang tiền điện tử
- Tạo một tệp breadcrumb
- khởi động lại
- Phát hiện tệp breadcrumb
- Bắt đầu mã hóa
/data
vold
sau đó thiết lập ánh xạ tiền điện tử, tạo ra một thiết bị khối tiền điện tử ảo ánh xạ lên thiết bị khối thực nhưng mã hóa từng khu vực khi nó được viết và giải mã từng khu vực khi nó được đọc.vold
sau đó tạo và ghi ra siêu dữ liệu tiền điện tử. - Trong khi mã hóa, hãy gắn tmpfs
vold
gắn tmpfs/data
(sử dụng các tùy chọn tmpfs từro.crypto.tmpfs_options
) và đặt thuộc tínhvold.encrypt_progress
thành 0.vold
chuẩn bị tmpfs/data
để khởi động hệ thống được mã hóa và đặt thuộc tínhvold.decrypt
thành:trigger_restart_min_framework
- Đưa ra khuôn khổ để hiển thị tiến độ
trigger_restart_min_framework
khiếninit.rc
bắt đầu lớp dịch vụmain
. Khi khung thấy rằngvold.encrypt_progress
được đặt thành 0, nó sẽ hiển thị giao diện người dùng thanh tiến trình, truy vấn thuộc tính đó cứ sau 5 giây và cập nhật thanh tiến trình. Vòng lặp mã hóa cập nhậtvold.encrypt_progress
mỗi khi nó mã hóa một phần trăm khác của phân vùng. - Khi
/data
được mã hóa, hãy cập nhật chân trang tiền điện tửKhi
/data
được mã hóa thành công,vold
sẽ xóa cờENCRYPTION_IN_PROGRESS
trong siêu dữ liệu.Khi thiết bị được mở khóa thành công, mật khẩu sẽ được sử dụng để mã hóa khóa chính và chân trang tiền điện tử được cập nhật.
Nếu khởi động lại không thành công vì lý do nào đó,
vold
đặt thuộc tínhvold.encrypt_progress
thànherror_reboot_failed
và giao diện người dùng sẽ hiển thị thông báo yêu cầu người dùng nhấn nút để khởi động lại. Điều này dự kiến sẽ không bao giờ xảy ra.
Bắt đầu một thiết bị được mã hóa bằng mã hóa mặc định
Đây là điều xảy ra khi bạn khởi động một thiết bị được mã hóa mà không có mật khẩu. Vì các thiết bị Android 5.0 được mã hóa trong lần khởi động đầu tiên, nên không có mật khẩu được đặt và do đó, đây là trạng thái mã hóa mặc định .
- Phát hiện mã hóa
/data
không có mật khẩuPhát hiện rằng thiết bị Android được mã hóa vì
/data
không thể được gắn và một trong các cờencryptable
hoặcforceencrypt
được đặt.vold
đặtvold.decrypt
thànhtrigger_default_encryption
, khởi động dịch vụdefaultcrypto
.trigger_default_encryption
kiểm tra loại mã hóa để xem liệu/data
có được mã hóa bằng mật khẩu hay không. - Giải mã/dữ liệu
Tạo thiết bị
dm-crypt
trên thiết bị khối để thiết bị sẵn sàng sử dụng. - Gắn kết/dữ liệu
vold
sau đó gắn kết phân vùng thực/data
được giải mã và sau đó chuẩn bị phân vùng mới. Nó đặt thuộc tínhvold.post_fs_data_done
thành 0 và sau đó đặtvold.decrypt
thànhtrigger_post_fs_data
. Điều này khiếninit.rc
chạy các lệnhpost-fs-data
của nó. Họ sẽ tạo bất kỳ thư mục hoặc liên kết cần thiết nào rồi đặtvold.post_fs_data_done
thành 1.Khi
vold
nhìn thấy 1 trong thuộc tính đó, nó sẽ đặt thuộc tínhvold.decrypt
thành:trigger_restart_framework.
Điều này khiếninit.rc
bắt đầu lại các dịch vụ trong lớpmain
và cũng bắt đầu các dịch vụ trong lớplate_start
lần đầu tiên kể từ khi khởi động. - bắt đầu khung
Giờ đây, khung khởi động tất cả các dịch vụ của nó bằng cách sử dụng
/data
đã được giải mã và hệ thống đã sẵn sàng để sử dụng.
Starting an encrypted device without default encryption
This is what happens when you boot up an encrypted device that has a set password. The device's password can be a pin, pattern, or password.
- Detect encrypted device with a password
Detect that the Android device is encrypted because the flag
ro.crypto.state = "encrypted"
vold
setsvold.decrypt
totrigger_restart_min_framework
because/data
is encrypted with a password. - Mount tmpfs
init
sets five properties to save the initial mount options given for/data
with parameters passed frominit.rc
.vold
uses these properties to set up the crypto mapping:-
ro.crypto.fs_type
-
ro.crypto.fs_real_blkdev
-
ro.crypto.fs_mnt_point
-
ro.crypto.fs_options
-
ro.crypto.fs_flags
(ASCII 8-digit hex number preceded by 0x)
-
- Start framework to prompt for password
The framework starts up and sees that
vold.decrypt
is set totrigger_restart_min_framework
. This tells the framework that it is booting on a tmpfs/data
disk and it needs to get the user password.First, however, it needs to make sure that the disk was properly encrypted. It sends the command
cryptfs cryptocomplete
tovold
.vold
returns 0 if encryption was completed successfully, -1 on internal error, or -2 if encryption was not completed successfully.vold
determines this by looking in the crypto metadata for theCRYPTO_ENCRYPTION_IN_PROGRESS
flag. If it's set, the encryption process was interrupted, and there is no usable data on the device. Ifvold
returns an error, the UI should display a message to the user to reboot and factory reset the device, and give the user a button to press to do so. - Decrypt data with password
Once
cryptfs cryptocomplete
is successful, the framework displays a UI asking for the disk password. The UI checks the password by sending the commandcryptfs checkpw
tovold
. If the password is correct (which is determined by successfully mounting the decrypted/data
at a temporary location, then unmounting it),vold
saves the name of the decrypted block device in the propertyro.crypto.fs_crypto_blkdev
and returns status 0 to the UI. If the password is incorrect, it returns -1 to the UI. - Stop framework
The UI puts up a crypto boot graphic and then calls
vold
with the commandcryptfs restart
.vold
sets the propertyvold.decrypt
totrigger_reset_main
, which causesinit.rc
to doclass_reset main
. This stops all services in the main class, which allows the tmpfs/data
to be unmounted. - Mount
/data
vold
then mounts the decrypted real/data
partition and prepares the new partition (which may never have been prepared if it was encrypted with the wipe option, which is not supported on first release). It sets the propertyvold.post_fs_data_done
to 0 and then setsvold.decrypt
totrigger_post_fs_data
. This causesinit.rc
to run itspost-fs-data
commands. They will create any necessary directories or links and then setvold.post_fs_data_done
to 1. Oncevold
sees the 1 in that property, it sets the propertyvold.decrypt
totrigger_restart_framework
. This causesinit.rc
to start services in classmain
again and also start services in classlate_start
for the first time since boot. - Start full framework
Now the framework boots all its services using the decrypted
/data
filesystem, and the system is ready for use.
Failure
A device that fails to decrypt might be awry for a few reasons. The device starts with the normal series of steps to boot:
- Detect encrypted device with a password
- Mount tmpfs
- Start framework to prompt for password
But after the framework opens, the device can encounter some errors:
- Password matches but cannot decrypt data
- User enters wrong password 30 times
If these errors are not resolved, prompt user to factory wipe :
If vold
detects an error during the encryption process, and if no data has been destroyed yet and the framework is up, vold
sets the property vold.encrypt_progress
to error_not_encrypted
. The UI prompts the user to reboot and alerts them the encryption process never started. If the error occurs after the framework has been torn down, but before the progress bar UI is up, vold
will reboot the system. If the reboot fails, it sets vold.encrypt_progress
to error_shutting_down
and returns -1; but there will not be anything to catch the error. This is not expected to happen.
If vold
detects an error during the encryption process, it sets vold.encrypt_progress
to error_partially_encrypted
and returns -1. The UI should then display a message saying the encryption failed and provide a button for the user to factory reset the device.
Storing the encrypted key
The encrypted key is stored in the crypto metadata. Hardware backing is implemented by using Trusted Execution Environment's (TEE) signing capability. Previously, we encrypted the master key with a key generated by applying scrypt to the user's password and the stored salt. In order to make the key resilient against off-box attacks, we extend this algorithm by signing the resultant key with a stored TEE key. The resultant signature is then turned into an appropriate length key by one more application of scrypt. This key is then used to encrypt and decrypt the master key. To store this key:
- Generate random 16-byte disk encryption key (DEK) and 16-byte salt.
- Apply scrypt to the user password and the salt to produce 32-byte intermediate key 1 (IK1).
- Pad IK1 with zero bytes to the size of the hardware-bound private key (HBK). Specifically, we pad as: 00 || IK1 || 00..00; one zero byte, 32 IK1 bytes, 223 zero bytes.
- Sign padded IK1 with HBK to produce 256-byte IK2.
- Apply scrypt to IK2 and salt (same salt as step 2) to produce 32-byte IK3.
- Use the first 16 bytes of IK3 as KEK and the last 16 bytes as IV.
- Encrypt DEK with AES_CBC, with key KEK, and initialization vector IV.
Changing the password
When a user elects to change or remove their password in settings, the UI sends the command cryptfs changepw
to vold
, and vold
re-encrypts the disk master key with the new password.
Encryption properties
vold
and init
communicate with each other by setting properties. Here is a list of available properties for encryption.
Vold properties
Property | Description |
---|---|
vold.decrypt trigger_encryption | Encrypt the drive with no password. |
vold.decrypt trigger_default_encryption | Check the drive to see if it is encrypted with no password. If it is, decrypt and mount it, else set vold.decrypt to trigger_restart_min_framework. |
vold.decrypt trigger_reset_main | Set by vold to shutdown the UI asking for the disk password. |
vold.decrypt trigger_post_fs_data | Set by vold to prep /data with necessary directories, et al. |
vold.decrypt trigger_restart_framework | Set by vold to start the real framework and all services. |
vold.decrypt trigger_shutdown_framework | Set by vold to shutdown the full framework to start encryption. |
vold.decrypt trigger_restart_min_framework | Set by vold to start the progress bar UI for encryption or prompt for password, depending on the value of ro.crypto.state . |
vold.encrypt_progress | When the framework starts up, if this property is set, enter the progress bar UI mode. |
vold.encrypt_progress 0 to 100 | The progress bar UI should display the percentage value set. |
vold.encrypt_progress error_partially_encrypted | The progress bar UI should display a message that the encryption failed, and give the user an option to factory reset the device. |
vold.encrypt_progress error_reboot_failed | The progress bar UI should display a message saying encryption completed, and give the user a button to reboot the device. This error is not expected to happen. |
vold.encrypt_progress error_not_encrypted | The progress bar UI should display a message saying an error occurred, no data was encrypted or lost, and give the user a button to reboot the system. |
vold.encrypt_progress error_shutting_down | The progress bar UI is not running, so it is unclear who will respond to this error. And it should never happen anyway. |
vold.post_fs_data_done 0 | Set by vold just before setting vold.decrypt to trigger_post_fs_data . |
vold.post_fs_data_done 1 | Set by init.rc or init.rc just after finishing the task post-fs-data . |
init properties
Property | Description |
---|---|
ro.crypto.fs_crypto_blkdev | Set by the vold command checkpw for later use by the vold command restart . |
ro.crypto.state unencrypted | Set by init to say this system is running with an unencrypted /data ro.crypto.state encrypted . Set by init to say this system is running with an encrypted /data . |
| These five properties are set by init when it tries to mount /data with parameters passed in from init.rc . vold uses these to setup the crypto mapping. |
ro.crypto.tmpfs_options | Set by init.rc with the options init should use when mounting the tmpfs /data filesystem. |
Init actions
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