Người gác cổng

Hệ thống con Gatekeeper thực hiện quy trình xác thực mật khẩu/mẫu 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 sẽ điều tiết các lần thử xác minh liên tiếp không thành công và phải từ chối các yêu cầu dịch vụ dựa trên một khoảng thời gian chờ nhất định và một số lần thử liên tiếp không thành công 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, chỉ có các thành phần bảo mật mới có thể sử dụng khoá này và mã này được gửi đến Kho khoádựa trên phần cứng. Tức là mã xác thực Gatekeeper sẽ thông báo cho Kho khoá rằng các khoá liên kết với quy trình xác thực (ví dụ: các khoá mà ứng dụng đã tạo) có thể được ứng dụng sử dụng.

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 IGatekeeper cơ bản dành riêng cho nhà cung cấp.
  • Dịch vụ lớp trừu tượng phần cứng (HAL) Gatekeeper – Một phương thức triển khai giao diện AIDL IGatekeeper dành riêng cho nhà cung cấp. Dịch vụ HAL này chạy trong Android, nhưng chức năng Gatekeeper cốt lõi cần chạy trong một môi trường an toàn, vì vậy, dịch vụ này thường giao tiếp với TA Gatekeeper.
  • Ứng dụng đáng tin cậy (TA) 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 mẫu 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ẽ đưa ra yêu cầu về dịch vụ HAL IGatekeeper và yêu cầu này sẽ đến TA Gatekeeper đối tác trong TEE:

Quy trình dành cho người trực điện thoại

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

Trình nền gatekeeperd cho phép các API khung Android truy cập vào HAL và tham gia báo cáo quy trình xác thực 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 nhằm xác thực mật khẩu. Phương thức triển khai TA Gatekeeper phải có khả năng ký (đăng ký) và xác minh blob. Tất cả các phương thức triển khai đều phải tuân thủ định dạng tiêu chuẩn cho mã xác thực (HardwareAuthToken) được tạo trên 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 HardwareAuthToken.aidl định nghĩa.

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

  • Phương thức enroll lấy một blob mật khẩu, ký blob đó và trả về chữ ký dưới dạng một trình xử lý. 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 được cung cấp tạo ra và đảm bảo chữ ký đó khớp với trình xử lý 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ể được lấy lại ở mỗi lần khởi động thiết bị.

Trusty và các phương thức 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 phương thức triển khai đã được phê duyệt của Gatekeeper. 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 một khoá dựa trên phần cứng liên tục và một đồng hồ đơn điệu, an toàn tích tắc ở trạng thái tạm ngưng.

Trusty sử dụng một hệ thống IPC nội bộ để giao tiếp trực tiếp một khoá bí mật dùng chung giữa KeyMint (trước đây là Keymaster) và phương thức triển khai Gatekeeper của Trusty (Trusty Gatekeeper). Bí mật được chia sẻ này được dùng để ký AuthToken đượ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 duy trì hoặc lưu vào bộ nhớ đệm giá trị. Các phương thức triển khai có thể chia sẻ 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 chỉ được lấy và 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 Gatekeeper TEE 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. Các 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ủ HAL IGatekeeper.
  • Mã xác thực được trả về phải được định dạng theo quy cách HardwareAuthToken (được mô tả trong Xác thực).
  • Gatekeeper TEE phải có khả năng chia sẻ khoá HMAC với KeyMint, bằng cách yêu cầu khoá thông qua TEE IPC theo yêu cầu hoặc duy trì bộ nhớ đệm hợp lệ của giá trị này mọi lúc.

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

SID người dùng là đại diện TEE của người dùng (không có mối liên hệ chặt chẽ 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 mật khẩu mới mà không cung cấp mật khẩu trước đó. Đây được gọi là quy trình đăng ký lại không đáng tin cậy và thường chỉ xảy ra khi người dùng lần đầu tiên đặt mật khẩu hoặc mẫu.

Quy trình đă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 người dùng sẽ được di chuyển sang trình xử lý mật khẩu mới, giữ lại các khoá đã liên kết với SID đó.

SID 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 người dùng được đưa vào HardwareAuthToken do hàm verify() trả về và liên kết với tất cả các khoá Kho khoá liên kết với quy trình xác thực (để biết thông tin chi tiết về định dạng HardwareAuthToken và Kho khoá, hãy xem 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 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 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 lần thử tấn công bằng cách dò mật khẩu đối với thông tin xác thực của người dùng. Như trong GatekeeperVerifyResponse.aidl, HAL cung cấp tính năng trả về 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 nên xử lý các yêu cầu nếu có thời gian chờ đang chờ xử lý.

Gatekeeper phải ghi bộ đếm lỗi trước khi xác minh mật khẩu của người dùng. Nếu xác minh mật khẩu thành công, bộ đếm lỗi sẽ bị xoá. Điều này 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 (eMMC) nhúng sau khi đưa ra lệnh gọi verify. Hàm enroll cũng xác minh mật khẩu của người dùng (nếu được cung cấp) và phải được điều tiết theo cách tương tự.

Nếu thiết bị hỗ trợ, bạn nên ghi bộ đếm lỗi vào bộ nhớ an toàn. Nếu thiết bị không hỗ trợ tính năng mã hoá dựa trên tệp hoặc nếu bộ nhớ an toàn 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ệ khỏi phát lại (RPMB).