Người gác cổng

Hệ thống con Gatekeeper thực hiện quy trình xác thực hình mở khoá/mật khẩu của thiết bị trong Môi trường thực thi đáng tin cậy (TEE). Gatekeeper đăng ký và xác minh mật khẩu bằng khoá bí mật dựa trên phần cứng. Ngoài ra, Gatekeeper điều tiết các lần cố gắng xác minh không thành công liên tiếp và phải từ chối các yêu cầu dịch vụ dựa trên thời gian chờ nhất định và số lần cố gắng xác minh không thành công liên tiếp nhất định.

Khi người dùng xác minh mật khẩu, Gatekeeper sẽ phát ra một mã xác thực được ký bằng khoá HMAC cho mỗi lần khởi động. Khoá này chỉ dành cho các thành phần bảo mật và mã này được gửi đến Kho khoá dựa trên phần cứng. Nghĩa là mã xác thực Gatekeeper thông báo cho Kho khoá rằng các ứng dụng có thể sử dụng khoá liên kết với việc xác thực (ví dụ: khoá mà ứng dụng đã tạo).

Kiến trúc

Gatekeeper bao gồm 3 thành phần chính:

  • gatekeeperd (Trình nền Gatekeeper) — Một dịch vụ Binder C++ trong Android chứa logic độc lập với nền tảng, triển khai giao diện AIDL IGateKeeperService, dựa trên một phương thức triển khai cơ bản dành riêng cho nhà cung cấp của IGatekeeper.
  • Dịch vụ lớp trừu tượng phần cứng (HAL) Gatekeeper – Một phương thức triển khai dành riêng cho nhà cung cấp của giao diện AIDL IGatekeeper. Dịch vụ HAL này chạy trong Android, nhưng chức năng cốt lõi của Gatekeeper cần chạy trong một môi trường bảo mật, vì vậy, dịch vụ này thường giao tiếp với Gatekeeper TA.
  • Ứng dụng đáng tin cậy (TA) của Gatekeeper — Một phương thức triển khai dành riêng cho nhà cung cấp chạy trong TEE và thực hiện quy trình xác minh mật khẩu hoặc hình mở khoá thực tế.

LockSettingsService đưa ra yêu cầu (thông qua Binder) đến trình nền gatekeeperd trong hệ điều hành Android. Sau đó, trình nền gatekeeperd sẽ gửi yêu cầu đến dịch vụ HAL IGatekeeper, và dịch vụ này sẽ tiếp cận Gatekeeper TA tương ứng trong TEE:

Quy trình dành cho người gác cổng

Hình 1. Luồng dữ liệu cấp cao để xác thực bằng GateKeeper.

Trình nền gatekeeperd cấp cho các API khung Android quyền truy cập vào HAL và tham gia báo cáo thông tin xác thực của thiết bị cho Kho khoá. Trình nền gatekeeperd chạy trong quy trình riêng và tách biệt với máy chủ hệ thống.

Triển khai HAL

Trình nền gatekeeperd sử dụng HAL IGatekeeper để tương tác với TA Gatekeeper cơ bản cho việc xác thực mật khẩu. Quá trình triển khai Gatekeeper TA phải có khả năng ký (đăng ký) và xác minh các blob. Tất cả các phương thức triển khai đều phải tuân thủ định dạng chuẩn cho mã xác thực (HardwareAuthToken) được tạo sau mỗi lần xác minh mật khẩu thành công. Để biết thông tin chi tiết về nội dung và ngữ nghĩa của HardwareAuthToken, hãy xem định nghĩa về HardwareAuthToken.aidl.

Các phương thức triển khai của nhà cung cấp cho HAL IGatekeeper phải triển khai các hàm enroll và verify:

  • Phương thức enroll lấy một blob mật khẩu, ký và trả về chữ ký dưới dạng một handle. Blob được trả về (từ lệnh gọi đến enroll) phải có cấu trúc như trong system/gatekeeper/include/gatekeeper/password_handle.h.
  • Hàm verify phải so sánh chữ ký do mật khẩu đã cung cấp tạo ra và đảm bảo chữ ký đó khớp với tên người dùng mật khẩu đã đăng ký.

Khoá dùng để đăng ký và xác minh không bao giờ được thay đổi và phải có thể lấy lại được mỗi khi thiết bị khởi động.

Trusty và các cách triển khai khác

Hệ điều hành Trusty là hệ điều hành đáng tin cậy nguồn mở của Google dành cho môi trường TEE và chứa một bản triển khai Gatekeeper đã được phê duyệt. Tuy nhiên, bất kỳ hệ điều hành TEE nào cũng có thể triển khai Gatekeeper, miễn là TEE có quyền truy cập vào khoá dựa trên phần cứng cố định và đồng hồ đơn điệu, bảo mật vẫn hoạt động khi tạm ngưng.

Trusty sử dụng hệ thống IPC nội bộ để truyền trực tiếp một khoá bí mật dùng chung giữa KeyMint (trước đây là Keymaster) và quá trình triển khai Gatekeeper của Trusty (Trusty Gatekeeper). Khoá bí mật dùng chung này được dùng để ký mã xác thực gửi đến Kho khoá nhằm cung cấp chứng thực xác minh mật khẩu. Trusty Gatekeeper yêu cầu khoá từ KeyMint cho mỗi lần sử dụng và không lưu trữ hoặc lưu giá trị vào bộ nhớ đệm. Các phương thức triển khai có thể chia sẻ khoá bí mật này theo bất kỳ cách nào không ảnh hưởng đến tính bảo mật.

Khoá HMAC dùng để đăng ký và xác minh mật khẩu được lấy và chỉ lưu giữ trong Gatekeeper.

Android cung cấp một phương thức triển khai Gatekeeper C++ chung, chỉ yêu cầu thêm các quy trình dành riêng cho thiết bị để hoàn tất; phương thức triển khai Trusty dựa trên phương thức này. Để triển khai TEE Gatekeeper bằng mã dành riêng cho thiết bị cho TEE, hãy tham khảo các hàm và nhận xét trong system/gatekeeper/include/gatekeeper/gatekeeper.h. Trách nhiệm chính của một phương thức triển khai tuân thủ bao gồm:

  • Tuân thủ IGatekeeper HAL.
  • Mã xác thực được trả về phải được định dạng theo quy cách HardwareAuthToken (được mô tả trong HardwareAuthToken.aidl).
  • Gatekeeper TEE phải có thể chia sẻ khoá HMAC với KeyMint bằng một trong những cách sau:
    • Thoả thuận bí mật chung: Gatekeeper có thể tham gia vào quá trình thương lượng theo từng lần khởi động của khoá HMAC bằng cách triển khai HAL ISharedSecret. Điều này yêu cầu cả Gatekeeper và KeyMint đều có quyền truy cập vào một khoá bí mật dùng chung.
    • Truy cập trực tiếp: Gatekeeper có thể truy xuất khoá HMAC từ KeyMint bằng cơ chế giao tiếp liên quy trình nội bộ TEE, theo yêu cầu hoặc trong lần sử dụng đầu tiên (sau đó được lưu vào bộ nhớ đệm).

Mã nhận dạng bảo mật (SID) của người dùng

SID người dùng là bản trình bày TEE của người dùng (không có kết nối mạnh mẽ với mã nhận dạng người dùng Android). SID được tạo bằng trình tạo số giả ngẫu nhiên (PRNG) mật mã bất cứ khi nào người dùng đăng ký mật khẩu mới mà không cung cấp mật khẩu trước đó. Đây được gọi là đăng ký lại không đáng tin cậy và thường chỉ xảy ra khi người dùng đặt mật khẩu hoặc hình mở khoá lần đầu tiên.

Việc đăng ký lại đáng tin cậy xảy ra khi người dùng cung cấp mật khẩu hợp lệ trước đó, chẳng hạn như khi thay đổi mật khẩu. Trong trường hợp này, SID của người dùng sẽ được di chuyển sang tên người dùng mật khẩu mới, giữ nguyên các khoá được liên kết với SID đó.

SID của người dùng được đưa vào quy trình xác thực HMAC cùng với mật khẩu trong trình xử lý mật khẩu khi mật khẩu được đăng ký.

SID của người dùng được đưa vào HardwareAuthToken do hàm verify() trả về và được liên kết với tất cả khoá Keystore liên kết với việc xác thực (để biết thông tin chi tiết về định dạng HardwareAuthToken và Keystore, hãy xem phần Xác thực).

Xin lưu ý rằng vì lệnh gọi không đáng tin cậy đến hàm enroll() sẽ thay đổi SID của người dùng, nên lệnh gọi này sẽ khiến các khoá liên kết với mật khẩu đó trở nên vô dụng. Kẻ tấn công có thể thay đổi mật khẩu cho thiết bị nếu chúng kiểm soát hệ điều hành Android, nhưng chúng sẽ phá huỷ các khoá nhạy cảm được bảo vệ bằng quyền truy cập gốc trong quá trình này.

Điều tiết yêu cầu

Gatekeeper phải có khả năng điều tiết một cách an toàn các nỗ lực tấn công brute-force vào thông tin xác thực của người dùng. Như minh hoạ trong GatekeeperVerifyResponse.aidl, HAL cung cấp thời gian chờ tính bằng mili giây. Thời gian chờ thông báo cho ứng dụng không gọi lại Gatekeeper cho đến khi hết thời gian chờ. Gatekeeper không được xử lý yêu cầu dịch vụ nếu có thời gian chờ đang chờ xử lý.

Gatekeeper phải ghi lại bộ đếm lỗi trước khi xác minh mật khẩu người dùng. Nếu xác minh mật khẩu thành công, thì bộ đếm lỗi sẽ bị xoá. Điều này giúp ngăn chặn các cuộc tấn công ngăn chặn việc điều tiết bằng cách tắt MMC nhúng (eMMC) sau khi thực hiện lệnh gọi verify. Hàm enroll cũng xác minh mật khẩu người dùng (nếu được cung cấp) và phải được điều tiết theo cùng một cách.

Nếu thiết bị hỗ trợ, bạn nên ghi bộ đếm lỗi vào bộ nhớ bảo mật. Nếu thiết bị không hỗ trợ mã hoá dựa trên tệp hoặc nếu bộ nhớ bảo mật quá chậm, thì các phương thức triển khai có thể sử dụng trực tiếp Khối bộ nhớ được bảo vệ chống phát lại (RPMB).