本頁面提供詳細資訊,協助 Keymaster 硬體抽象層 (HAL) 的實作者。這份文件涵蓋 API 中的每個函式,以及該函式可在哪個 Keymaster 版本中使用,並說明預設實作方式。如需標記資訊,請參閱「Keymaster 標記」頁面。
一般導入指南
下列指南適用於 API 的所有函式。
輸入指標參數
版本:1、2
未用於特定呼叫的輸入指標參數可能為 NULL
。呼叫端不必提供預留位置。舉例來說,某些鍵類型和模式可能不會使用 inParams
引數到 begin 的任何值,因此呼叫端可能會將 inParams
設為 NULL
,或提供空參數集。呼叫者也可以提供未使用的參數,而 Keymaster 方法不應發生錯誤。
如果必要的輸入參數為 NULL,Keymaster 方法應傳回 ErrorCode::UNEXPECTED_NULL_POINTER
。
從 Keymaster 3 開始,就沒有指標參數。所有參數都會透過值或 const 參照傳遞。
輸出指標參數
版本:1、2
與輸入指標參數類似,未使用的輸出指標參數可能為 NULL
。如果方法需要在找到為 NULL
的輸出參數中傳回資料,則應傳回 ErrorCode::OUTPUT_PARAMETER_NULL
。
從 Keymaster 3 開始,就沒有指標參數。所有參數都會透過值或 const 參照傳遞。
API 濫用
版本:1、2、3
呼叫端有許多方式不合理,或者有詐騙內容,但不在技術上出錯。在這種情況下,Keymaster 實作不必失敗或發出診斷資訊。使用過小的金鑰、指定不相關的輸入參數、重複使用 IV 或 Nonce、產生無用途的金鑰 (因此無用) 等,實作項目不應對這些問題進行診斷。必須診斷缺少必要參數、指定無效的必要參數,以及類似的錯誤。
應用程式、架構和 Android KeyStore 必須負責確保對 Keymaster 模組的呼叫是合理且實用的。
函式
getHardwareFeatures
版本:3
新的 getHardwareFeatures
方法會向用戶端公開基礎安全硬體的一些重要特徵。這個方法不接受任何引數,並傳回四個值,全部都是布林值:
- 如果金鑰儲存在安全硬體 (TEE 等) 中,且絕不會離開,則
isSecure
為true
。 - 如果硬體支援橢圓曲線加密編譯,並使用 NIST 曲線 (P-224、P-256、P-384 和 P-521),
supportsEllipticCurve
就是true
。 - 如果硬體支援對稱式密碼學,包括 AES 和 HMAC,
supportsSymmetricCryptography
就是true
。 - 如果硬體支援產生 Keymaster 公開金鑰認證憑證,且憑證是使用在安全環境中插入的金鑰簽署,則
supportsAttestation
為true
。
這個方法只能傳回 ErrorCode:OK
、ErrorCode::KEYMASTER_NOT_CONFIGURED
或表示無法與安全硬體通訊的其中一個錯誤代碼。
getHardwareFeatures() generates(bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography, bool supportsAttestation, bool supportsAllDigests, string keymasterName, string keymasterAuthorName);
設定
版本:2
這個函式是在 Keymaster 2 中推出,並在 Keymaster 3 中淘汰,因為此資訊可在系統屬性檔案中找到,而製造商實作項目會在啟動期間讀取這些檔案。
設定 Keymaster。系統會在裝置開啟後,且在使用前呼叫此方法一次。這個值會用來將 KM_TAG_OS_VERSION 和 KM_TAG_OS_PATCHLEVEL 提供給 Keymaster。呼叫此方法前,所有其他方法都會傳回 KM_ERROR_KEYMASTER_NOT_CONFIGURED
。這個方法提供的值,每次開機時只會由 Keymaster 接受一次。後續呼叫會傳回 KM_ERROR_OK
,但不會執行任何動作。
如果 Keymaster 實作項目位於安全硬體中,且提供的 OS 版本和修補程式級別值與系統啟動載入程式提供給安全硬體的值不符 (或系統啟動載入程式未提供值),則此方法會傳回 KM_ERROR_INVALID_ARGUMENT
,而所有其他方法則會繼續傳回 KM_ERROR_KEYMASTER_NOT_CONFIGURED
。
keymaster_error_t (*configure)(const struct keymaster2_device* dev, const keymaster_key_param_set_t* params);
addRngEntropy
版本:1、2、3
這個函式在 Keymaster 1 中以 add_rng_entropy
的名稱推出,並在 Keymaster 3 中重新命名。
將呼叫端提供的資訊熵新增至 Keymaster 1 實作項目用來產生隨機號碼、金鑰和 IV 等的集區。
Keymaster 實作項目需要將提供的資訊熵安全地混入其集區,該集區也必須包含硬體隨機號碼產生器內部產生的資訊熵。應處理混合情況,讓攻擊者即使完全掌控 addRngEntropy
提供的位元或硬體產生的位元 (但不同時掌控兩者),也無法輕易預測從熵值集合產生的位元。
嘗試在內部集區中估算熵值的 Keymaster 實作會假設 addRngEntropy
提供的資料不含熵值。如果在單一呼叫中提供超過 2 KiB 的資料,Keymaster 實作項目可以傳回 ErrorCode::INVALID_INPUT_LENGTH
。
generateKey
版本:1、2、3
這個函式在 Keymaster 1 中以 generate_key
的名稱推出,並在 Keymaster 3 中重新命名。
產生新的加密編譯金鑰,指定相關授權,並永久綁定至金鑰。透過 Keymaster 實作,您無法以任何方式使用與產生時指定的授權不符的金鑰。對於安全硬體無法強制執行的授權,安全硬體的義務僅限於確保與金鑰相關的不可強制執行授權無法修改,因此每次呼叫 getKeyCharacteristics 都會傳回原始值。此外,generateKey
傳回的特性會在硬體強制執行的清單和軟體強制執行的清單之間正確分配授權。詳情請參閱 getKeyCharacteristics。
提供給 generateKey
的參數取決於產生的金鑰類型。本節概述各種金鑰的必要和選用標記。您必須指定類型,因此一律都需要使用 Tag::ALGORITHM。
RSA 金鑰
如要產生 RSA 金鑰,必須使用下列參數。
- Tag::KEY_SIZE 會以位元為單位指定公開模數的大小。如果省略,方法會傳回
ErrorCode::UNSUPPORTED_KEY_SIZE
。支援的值為 1024、2048、3072 和 4096。建議值是所有 8 的倍數的鍵大小。 - Tag::RSA_PUBLIC_EXPONENT 可指定 RSA 公開指數值。如果省略,方法會傳回
ErrorCode::INVALID_ARGUMENT
。支援的值為 3 和 65537。建議的值為所有質數值,上限為 2^64。
產生 RSA 金鑰時,並不需要下列參數,但如果沒有這些參數,產生的金鑰將無法使用。不過,如果省略這些參數,generateKey
函式不會傳回錯誤。
- Tag::PURPOSE 可指定允許的用途。RSA 金鑰必須支援任何用途 (不限組合)。
- Tag::DIGEST 會指定可與新金鑰搭配使用的摘要演算法。不支援所有摘要演算法的實作項目,需要接受包含不支援摘要的金鑰產生要求。不支援的摘要應放入傳回的鍵特性中「軟體強制執行」清單中。這是因為金鑰可與其他摘要一起使用,但摘要是在軟體中執行。接著,系統會呼叫硬體,以
Digest::NONE
執行作業。 - Tag::PADDING 會指定可與新鍵搭配使用的填充模式。如果未指定任何不支援的摘要演算法,則不支援所有摘要演算法的實作項目,需要將
PaddingMode::RSA_PSS
和PaddingMode::RSA_OAEP
放入軟體強制執行的關鍵特徵清單中。
ECDSA 金鑰
產生 ECDSA 金鑰時,只需要 Tag::KEY_SIZE。用於選取 EC 群組。支援的值為 224、256、384 和 521,分別代表 NIST p-224、p-256、p-384 和 p521 曲線。
Tag::DIGEST 也適用於實用的 ECDSA 金鑰,但產生密鑰並非必要。
AES 金鑰
只有 Tag::KEY_SIZE 才能產生 AES 金鑰。如果省略,方法會傳回 ErrorCode::UNSUPPORTED_KEY_SIZE
。支援的值為 128 和 256,可選支援 192 位元 AES 金鑰。
下列參數與 AES 金鑰特別相關,但不一定得產生一個參數:
Tag::BLOCK_MODE
會指定可搭配新金鑰使用的區塊模式。Tag::PADDING
會指定可使用的邊框模式。這項設定僅適用於 ECB 和 CBC 模式。
如果指定 GCM 封鎖模式,請提供 Tag::MIN_MAC_LENGTH。如果省略,方法會傳回 ErrorCode::MISSING_MIN_MAC_LENGTH
。標記的值為 8 的倍數,介於 96 和 128 之間。
HMAC 金鑰
產生 HMAC 金鑰時,必須提供下列參數:
- Tag::KEY_SIZE 會以位元為單位指定金鑰大小。系統不支援小於 64 的值,也不支援非 8 的倍數的值。系統支援所有 8 的倍數,從 64 到 512 皆可。系統可能會支援更大的值。
- Tag::MIN_MAC_LENGTH 可指定可使用此金鑰產生或驗證的 MAC 長度下限。值為 8 的倍數,且至少為 64。
- Tag::DIGEST 指定金鑰的摘要演算法。請務必指定一個摘要,否則會傳回
ErrorCode::UNSUPPORTED_DIGEST
。如果 Trustlet 不支援摘要,請傳回ErrorCode::UNSUPPORTED_DIGEST
。
主要特徵
如果特徵引數非空值,generateKey
會傳回新產生的鍵特徵,並適當地劃分為硬體強制執行和軟體強制執行清單。如需其中有哪些特性的說明,請參閱 getKeyCharacteristics。傳回的特性包含為金鑰產生作業指定的所有參數,但 Tag::APPLICATION_ID 和 Tag::APPLICATION_DATA 除外。如果這些標記包含在鍵參數中,系統會將這些標記從傳回的特性中移除,因此無法透過檢查傳回的鍵 blob 找出這些標記的值。不過,這些值會以加密編譯方式繫結至金鑰 blob,因此如果在使用金鑰時未提供正確的值,使用作業就會失敗。同樣地,Tag::ROOT_OF_TRUST 會以加密編譯方式繫結至金鑰,但無法在建立或匯入金鑰時指定,也不會傳回。
除了提供的代碼外,信任層也會加入 Tag::ORIGIN,並將值設為 KeyOrigin::GENERATED
。如果該鍵不支援回溯,
無法復原
復原保護功能可確保使用者無法透過 deleteKey 或 deleteAllKeys 刪除金鑰後,再將金鑰復原。不具備回溯防護功能的實作項目通常會將產生的或匯入的金鑰內容,以金鑰 blob 的形式傳回給呼叫端,這是經過加密和驗證的格式。當 KeyStore 刪除金鑰 blob 時,金鑰就會消失,但先前已成功擷取金鑰內容的攻擊者,可能會將金鑰還原至裝置。
如果安全硬體保證刪除的金鑰無法日後復原,則金鑰就具有防回溯功能。這通常是透過將其他重要中繼資料儲存在無法遭攻擊者操控的可信位置來達成。在行動裝置上,通常會使用重播保護記憶體區塊 (RPMB) 機制。由於可建立的金鑰數量基本上沒有上限,且用於回溯防護的受信任儲存空間可能有大小限制,因此即使無法為新金鑰提供回溯防護,這個方法也必須成功。在這種情況下,請勿將 Tag::ROLLBACK_RESISTANT 新增至主要特徵。
getKeyCharacteristics
版本:1、2、3
這個函式在 Keymaster 1 中以 get_key_characteristics
的名稱推出,並在 Keymaster 3 中重新命名。
傳回與提供的鍵相關聯的參數和授權,分為兩組:硬體強制執行和軟體強制執行。此處的說明同樣適用於 generateKey 和 importKey 傳回的主要特性清單。
如果在金鑰產生或匯入期間提供 Tag::APPLICATION_ID
,相同的值會在 clientId
引數中提供給這個方法。否則,方法會傳回 ErrorCode::INVALID_KEY_BLOB
。同樣地,如果在產生或匯入期間提供 Tag::APPLICATION_DATA
,則會在 appData
引數中為此方法提供相同的值。
這個方法傳回的特徵會完整說明指定鍵的類型和用途。
決定特定標記是否列於硬體強制執行清單或軟體強制執行清單的一般規則是,如果安全硬體可完全確保標記的含義,就會由硬體強制執行。否則,則是透過軟體強制執行。以下列出特定標記的清單,這些標記的正確分配方式可能不清楚:
- Tag::ALGORITHM、Tag::KEY_SIZE 和 Tag::RSA_PUBLIC_EXPONENT 是金鑰的內建屬性。硬體保護的所有金鑰都會列在硬體強制執行清單中。
- 安全硬體支援的 Tag::DIGEST 值會列入硬體支援的清單。不支援的摘要會列入軟體支援清單。
- Tag::PADDING 值通常會列在硬體支援清單中,除非軟體可能必須執行特定的邊框間距模式。在這種情況下,這些應用程式會列入軟體強制執行清單。對於允許使用 PSS 或 OAEP 填充的 RSA 金鑰,如果安全硬體不支援摘要演算法,就有可能發生這種情況。
- 只有在硬體強制執行使用者驗證時,Tag::USER_SECURE_ID 和 Tag::USER_AUTH_TYPE 才會強制執行硬體。為達成此目標,Keymaster 信任元件和相關的驗證信任元件都必須安全,並共用用於簽署及驗證驗證權杖的密鑰 HMAC 金鑰。詳情請參閱「驗證」頁面。
- Tag::ACTIVE_DATETIME、Tag::ORIGINATION_EXPIRE_DATETIME 和 Tag::USAGE_EXPIRE_DATETIME 標記需要存取可驗證的正確時鐘。大部分的安全硬體只能存取非安全 OS 提供的時間資訊,也就是說,代碼是由軟體強制執行。
- 硬體鍵的硬體清單中,一律會包含 Tag::ORIGIN。該清單中是否有該金鑰,是較高層級判斷金鑰是否為硬體支援的依據。
importKey
版本:1、2、3
這個函式在 Keymaster 1 中以 import_key
的名稱推出,並在 Keymaster 3 中重新命名。
將金鑰內容匯入 Keymaster 硬體。關鍵定義參數和輸出特性的處理方式與 generateKey
相同,但有以下例外狀況:
- 輸入參數不需要有 Tag::KEY_SIZE 和 Tag::RSA_PUBLIC_EXPONENT (僅適用於 RSA 金鑰)。如果未提供,信任層級會從提供的關鍵資料中推斷值,並將適當的標記和值新增至關鍵特徵。如果提供參數,信任程式會根據金鑰內容進行驗證。萬一發生不相符的情形,這個方法會傳回
ErrorCode::IMPORT_PARAMETER_MISMATCH
。 - 傳回的 Tag::ORIGIN 與
KeyOrigin::IMPORTED
具有相同的值。
exportKey
版本:1、2、3
這個函式在 Keymaster 1 中以 export_key
的名稱推出,並在 Keymaster 3 中重新命名。
從 Keymaster RSA 或 EC 金鑰組合匯出公開金鑰。
如果在金鑰產生或匯入期間提供 Tag::APPLICATION_ID
,相同的值會在 clientId
引數中提供給這個方法。否則,方法會傳回 ErrorCode::INVALID_KEY_BLOB
。同樣地,如果在產生或匯入期間提供 Tag::APPLICATION_DATA
,也會在 appData
引數中提供相同的值給這個方法。
deleteKey
版本:1、2、3
這個函式在 Keymaster 1 中導入為 delete_key
,並在 Keymaster 3 中重新命名。
刪除所提供的鍵。這個方法屬於選用,且僅由提供回溯防護功能的 Keymaster 模組實作。
刪除所有金鑰
版本:1、2、3
這個函式在 Keymaster 1 中以 delete_all_keys
的名稱推出,並在 Keymaster 3 中重新命名。
刪除所有鍵。這個方法屬於選用,且只有提供回溯防護功能的 Keymaster 模組才會實作。
destroyAttestationIds
版本:3
destroyAttestationIds()
方法可用於永久停用新的 (選用但強烈建議) ID 認證功能。如果 TEE 無法確保在呼叫此方法後會永久停用 ID 認證,則不得實作 ID 認證,在這種情況下,此方法不會執行任何操作並傳回 ErrorCode::UNIMPLEMENTED
。如果支援身分認證,就必須實作這個方法,並且必須永久停用日後所有身分認證嘗試。此方法的呼叫次數沒有限制。如果 ID 認證已永久停用,則此方法不會執行任何操作,並傳回 ErrorCode::OK
。
這個方法只能傳回 ErrorCode::UNIMPLEMENTED
(如果不支援 ID 認證)、ErrorCode:OK
、ErrorCode::KEYMASTER_NOT_CONFIGURED
或其中一個錯誤代碼 (表示無法與安全硬體通訊)。
開始
版本:1、2、3
根據指定目的,使用指定金鑰啟動加密編譯作業,並搭配指定參數 (視情況而定),然後傳回與 update 和 finish 搭配使用的作業控制代碼以完成作業。作業控制代碼也會在驗證作業中做為「挑戰」權杖使用,且這類作業會包含在驗證權杖的 challenge
欄位中。
Keymaster 實作支援至少 16 個並行作業。Keystore 最多使用 15 個,剩餘一個則供 vold 用於密碼加密。當 Keystore 有 15 個進行中的作業 (已呼叫 begin
,但未呼叫 finish
或 abort
),且收到開始第 16 個作業的要求時,它會針對最近最少使用的作業呼叫 abort
,將有效作業數量減少至 14,然後再呼叫 begin
來開始新要求的作業。
如果在產生或匯入金鑰時指定 Tag::APPLICATION_ID 或 Tag::APPLICATION_DATA,對 begin
的呼叫會在此方法的 inParams
引數中納入具有原始指定值的標記。
強制執行授權
在這個方法中,如果實作將金鑰授權置於「硬體強制執行」特性,且作業不是公開金鑰作業,信任元件就會強制執行下列金鑰授權。即使不符合授權要求,公開金鑰作業 (即 KeyPurpose::ENCRYPT
和 KeyPurpose::VERIFY
) 搭配 RSA 或 EC 金鑰,也能成功執行。
- Tag::PURPOSE:除非要求的作業為公開金鑰作業,否則在
begin()
呼叫中指定的用途必須與金鑰授權的其中一個用途相符。如果指定的用途不符,且作業並非公開金鑰作業,begin
就會傳回ErrorCode::UNSUPPORTED_PURPOSE
。公開金鑰作業是指非對稱式加密或驗證作業。 - 只有在可使用信任的 UTC 時間來源時,才能強制執行 Tag::ACTIVE_DATETIME。如果目前的日期和時間在標記值之前,這個方法會傳回
ErrorCode::KEY_NOT_YET_VALID
。 - 只有在可使用信任的 UTC 時間來源時,才能強制執行 Tag::ORIGINATION_EXPIRE_DATETIME。如果目前的日期和時間晚於標記值,且用途為
KeyPurpose::ENCRYPT
或KeyPurpose::SIGN
,此方法會傳回ErrorCode::KEY_EXPIRED
。 - 只有在可使用信任的 UTC 時間來源時,才能強制執行 Tag::USAGE_EXPIRE_DATETIME。如果目前的日期和時間晚於標記值,且用途為
KeyPurpose::DECRYPT
或KeyPurpose::VERIFY
,則方法會傳回ErrorCode::KEY_EXPIRED
。 - Tag::MIN_SECONDS_BETWEEN_OPS 會與可信任的相對計時器進行比較,後者會指出上次使用金鑰的時間。如果上次使用時間加上標記值小於目前時間,這個方法會傳回
ErrorCode::KEY_RATE_LIMIT_EXCEEDED
。如需瞭解導入的相關重要細節,請參閱代碼說明。 - Tag::MAX_USES_PER_BOOT 會與安全計數器進行比對,該計數器會追蹤自啟動時間起的金鑰用途。如果先前使用的計數超過標記值,這個方法會傳回
ErrorCode::KEY_MAX_OPS_EXCEEDED
。 - 只有在金鑰同時具有 Tag::AUTH_TIMEOUT 時,才會透過此方法強制執行 Tag::USER_SECURE_ID。如果鍵同時包含這兩者,則這個方法必須在
inParams
中收到有效的 Tag::AUTH_TOKEN。如要讓驗證權杖有效,下列所有條件都必須成立:- HMAC 欄位驗證成功。
- 金鑰中至少有一個 Tag::USER_SECURE_ID 值與權杖中的至少一個安全 ID 值相符。
- 此鍵包含 Tag::USER_AUTH_TYPE,與權杖中的驗證類型相符。
如果上述任一條件不符合,這個方法會傳回
ErrorCode::KEY_USER_NOT_AUTHENTICATED
。 - Tag::CALLER_NONCE 可讓呼叫端指定 Nonce 或初始化向量 (IV)。如果索引鍵沒有這個標記,但呼叫端為這個方法提供 Tag::NONCE,則會傳回
ErrorCode::CALLER_NONCE_PROHIBITED
。 - Tag::BOOTLOADER_ONLY 指定只有引導程式可以使用金鑰。如果在系統啟動載入程式執行完畢後,使用僅限系統啟動載入程式的鍵呼叫這個方法,則會傳回
ErrorCode::INVALID_KEY_BLOB
。
RSA 金鑰
所有 RSA 金鑰作業都會在 inParams
中指定單一填充模式。如果未指定或多次指定,這個方法會傳回 ErrorCode::UNSUPPORTED_PADDING_MODE
。
RSA 簽署和驗證作業需要摘要,與採用 OAEP 填充模式的 RSA 加密和解密作業相同。在這種情況下,呼叫端只會在 inParams
中指定一項摘要。如果未指定或多次指定,這個方法會傳回 ErrorCode::UNSUPPORTED_DIGEST
。
私密金鑰作業 (KeyPurpose::DECYPT
和 KeyPurpose::SIGN
) 需要摘要和填充值授權,也就是說,金鑰授權必須包含指定的值。如果沒有,此方法會視情況傳回 ErrorCode::INCOMPATIBLE_DIGEST
或 ErrorCode::INCOMPATIBLE_PADDING
。允許使用未經授權的摘要或填充資料,執行公開金鑰作業 (KeyPurpose::ENCRYPT
和 KeyPurpose::VERIFY
)。
除了 PaddingMode::NONE
之外,所有 RSA 填充模式都僅適用於特定用途。具體來說,PaddingMode::RSA_PKCS1_1_5_SIGN
和 PaddingMode::RSA_PSS
只支援簽署和驗證,而 PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT
和 PaddingMode::RSA_OAEP
只支援加密和解密。如果指定的模式不支援指定用途,這個方法會傳回 ErrorCode::UNSUPPORTED_PADDING_MODE
。
填充模式和摘要之間有一些重要的互動:
PaddingMode::NONE
表示系統執行「原始」RSA 作業。如果是簽署或驗證,則會為摘要指定Digest::NONE
。對於未填充的加密或解密作業,則不需要摘要。PaddingMode::RSA_PKCS1_1_5_SIGN
填充需要摘要。摘要可以是Digest::NONE
,在這種情況下,Keymaster 實作無法建立適當的 PKCS#1 v1.5 簽章結構體,因為它無法新增 DigestInfo 結構體。而是實作建構0x00 || 0x01 || PS || 0x00 || M
,其中 M 是提供的訊息,PS 是填充字串。RSA 金鑰的大小必須比訊息大至少 11 個位元組,否則方法會傳回ErrorCode::INVALID_INPUT_LENGTH
。PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT
填充值不需要摘要。PaddingMode::RSA_PSS
填充資料需要摘要,但摘要不能是Digest::NONE
。如果指定Digest::NONE
,方法會傳回ErrorCode::INCOMPATIBLE_DIGEST
。此外,RSA 金鑰的大小必須至少比摘要的輸出大小大 2 + D 個位元組,其中 D 是摘要的大小 (以位元為單位)。否則,方法會傳回ErrorCode::INCOMPATIBLE_DIGEST
。鹽大小為 D。PaddingMode::RSA_OAEP
填充資料需要摘要,但摘要不能是Digest::NONE
。如果指定Digest::NONE
,方法會傳回ErrorCode::INCOMPATIBLE_DIGEST
。
EC 金鑰
EC 金鑰作業會在 inParams
中指定單一邊框間距模式。如果未指定或多次指定,這個方法會傳回 ErrorCode::UNSUPPORTED_PADDING_MODE
。
私密金鑰作業 (KeyPurpose::SIGN
) 需要摘要和填充授權,也就是說金鑰授權必須包含指定的值。如果不是,請傳回 ErrorCode::INCOMPATIBLE_DIGEST
。公開金鑰作業 (KeyPurpose::VERIFY
) 可使用未經授權的摘要或填充資料。
AES 金鑰
AES 金鑰作業在 inParams
中只會指定一個區塊模式和一個填充模式。如果任一值未指定或指定多次,則傳回 ErrorCode::UNSUPPORTED_BLOCK_MODE
或 ErrorCode::UNSUPPORTED_PADDING_MODE
。指定的模式必須具有金鑰授權,否則此方法會傳回 ErrorCode::INCOMPATIBLE_BLOCK_MODE
或 ErrorCode::INCOMPATIBLE_PADDING_MODE
。
如果區塊模式為 BlockMode::GCM
,inParams
會指定 Tag::MAC_LENGTH
,且指定的值為 8 的倍數,且不會大於 128 或小於金鑰授權中的 Tag::MIN_MAC_LENGTH
值。如果 MAC 長度大於 128 或不是 8 的倍數,則會傳回 ErrorCode::UNSUPPORTED_MAC_LENGTH
。如果值小於該鍵的長度下限,則會傳回 ErrorCode::INVALID_MAC_LENGTH
。
如果區塊模式為 BlockMode::GCM
或 BlockMode::CTR
,則指定的邊框模式必須為 PaddingMode::NONE
。對於 BlockMode::ECB
或 BlockMode::CBC
,模式可以是 PaddingMode::NONE
或 PaddingMode::PKCS7
。如果填充模式不符合這些條件,請傳回 ErrorCode::INCOMPATIBLE_PADDING_MODE
。
如果區塊模式為 BlockMode::CBC
、BlockMode::CTR
或 BlockMode::GCM
,就需要初始化向量或 Nonce。在大多數情況下,呼叫端不應提供 IV 或 nonce。在這種情況下,Keymaster 實作會產生隨機 IV 或 Nonce,並透過 outParams
中的 Tag::NONCE 傳回。CBC 和 CTR IV 為 16 個位元組。GCM 隨機碼為 12 個位元組。如果金鑰授權包含 Tag::CALLER_NONCE,則呼叫端可以透過 inParams
中的 Tag::NONCE 提供 IV 或 nonce。如果在 Tag::CALLER_NONCE 未經授權時提供 Nonce,請傳回 ErrorCode::CALLER_NONCE_PROHIBITED
。如果在授權 Tag::CALLER_NONCE 時未提供 Nonce,會產生隨機 IV/nonce。
HMAC 金鑰
HMAC 金鑰運算會在 inParams
中指定 Tag::MAC_LENGTH
。指定的值必須是 8 的倍數,且不得大於摘要長度,或小於金鑰授權中 Tag::MIN_MAC_LENGTH
的值。如果 MAC 長度大於摘要長度或非 8 的倍數,則會傳回 ErrorCode::UNSUPPORTED_MAC_LENGTH
。如果值小於索引鍵長度下限,則傳回 ErrorCode::INVALID_MAC_LENGTH
。
更新
版本:1、2、3
提供在以 begin 啟動的持續性作業中處理的資料。作業會由 operationHandle
參數指定。
為提供更靈活的緩衝區處理方式,實作此方法時,可以選擇使用比提供的資料更少的資料。呼叫端負責迴圈,在後續呼叫中提供其餘資料。inputConsumed
參數會傳回所消耗的輸入量。實作項目一律會消耗至少一個位元組,除非作業無法接受更多位元組;如果提供超過零的位元組,且使用了零位元組,呼叫端會將此錯誤視為錯誤並取消該作業。
實作項目也可以選擇要傳回多少資料,以便更新。這僅適用於加密和解密作業,因為簽署和驗證作業在完成之前不會傳回任何資料。請盡早傳回資料,不要進行緩衝處理。
處理錯誤
如果此方法傳回的錯誤代碼不是 ErrorCode::OK
,作業就會中止,且作業句柄會失效。日後使用此方法時,如果使用此方法完成或取消,都會傳回 ErrorCode::INVALID_OPERATION_HANDLE
。
授權強制執行
- 一個或多個 Tag::USER_SECURE_IDs,以及
- 沒有 Tag::AUTH_TIMEOUT
在這種情況下,每個作業都需要金鑰授權,更新方法會在 inParams
引數中接收 Tag::AUTH_TOKEN。HMAC 會驗證權杖是否有效,並包含相符的安全使用者 ID、相符的金鑰 Tag::USER_AUTH_TYPE,以及挑戰字段中目前作業的作業句柄。如果不符合這些條件,就會傳回 ErrorCode::KEY_USER_NOT_AUTHENTICATED
。
呼叫端會在每次呼叫 update 和 finish 時提供驗證權杖。實作方式只需驗證一次權杖 (如果偏好這樣做)。
RSA 金鑰
針對使用 Digest::NONE
的簽署和驗證作業,這個方法會在單一更新中接受整個區塊進行簽署或驗證。無法只使用區塊的一部分。不過,如果呼叫端選擇在多個更新中提供資料,這個方法會接受該資料。如果呼叫端提供的簽署資料比可用的資料還多 (資料長度超過 RSA 金鑰大小),請傳回 ErrorCode::INVALID_INPUT_LENGTH
。
ECDSA 金鑰
針對使用 Digest::NONE
的簽署和驗證作業,此方法會接受在單次更新中簽署或驗證的整個區塊。此方法無法只使用區塊的一部分。
不過,如果呼叫端選擇在多個更新中提供資料,這個方法會接受該資料。如果呼叫端提供的簽署資料超過可使用的數量,則會在不發出通知的情況下截斷資料。(這與處理類似 RSA 作業中提供的多餘資料不同。這是因為與舊版用戶端的相容性。)
AES 金鑰
AES GCM 模式支援「關聯的驗證資料」,可透過 inParams
引數中的 Tag::ASSOCIATED_DATA 標記提供。相關資料可在重複呼叫中提供 (如果資料太大而無法在單一區塊中傳送,這點就很重要),但必須先於要加密或解密的資料提供。更新呼叫可接收相關資料和資料來加密/解密,但後續的更新不能包含相關資料。如果呼叫端在包含要加密/解密資料的呼叫之後,向更新呼叫提供相關資料,請傳回 ErrorCode::INVALID_TAG
。
針對 GCM 加密,標記會由 finish 附加至密文。在解密期間,提供給上次更新呼叫的資料的最後 Tag::MAC_LENGTH
個位元組就是標記。由於指定的叫用 update 無法得知是否為上次叫用,因此除了標記長度以外,系統會在「完成」期間處理所有標記長度以外的可能標記資料,並緩衝處理可能的標記資料。
完成
版本:1、2、3
完成以 begin 啟動的持續性作業,處理 update 提供的所有尚未處理的資料。
此方法是在作業中呼叫的最後一個項目,因此會傳回所有已處理的資料。
無論是否順利完成或傳回錯誤,這個方法都會完成作業,並因此使提供的作業句柄失效。日後使用此方法或更新或中斷時,都會傳回 ErrorCode::INVALID_OPERATION_HANDLE
。
簽署作業會將簽名做為輸出內容。驗證作業會接受 signature
參數中的簽名,且不會傳回任何輸出內容。
授權強制執行
主要在 begin 中執行金鑰授權強制執行作業。唯一的例外情況是鍵有:
- 一或多個 Tag::USER_SECURE_IDs,以及
- 沒有 Tag::AUTH_TIMEOUT
在此情況下,金鑰需要每項作業的授權,而更新方法會在 inParams
引數中接收 Tag::AUTH_TOKEN。HMAC 會驗證憑證是否有效,並且包含相符的安全使用者 ID、與金鑰的 Tag::USER_AUTH_TYPE 相符,並在驗證欄位中包含目前作業的作業控制代碼。如果不符合這些條件,就會傳回 ErrorCode::KEY_USER_NOT_AUTHENTICATED
。
呼叫端會為每個 update 和 完成 呼叫提供驗證權杖。實作方式只需驗證一次權杖 (如果偏好這樣做)。
RSA 金鑰
視填充模式而定,可能需要遵守其他規定:
PaddingMode::NONE
. 對於未填補的簽名和加密作業,如果提供的資料比金鑰短,則在簽名/加密前,資料會在左側填補零。如果資料的長度與鍵相同,但數值較大,則傳回ErrorCode::INVALID_ARGUMENT
。在驗證和解密作業中,資料長度必須與金鑰完全相同。否則,則傳回ErrorCode::INVALID_INPUT_LENGTH.
PaddingMode::RSA_PSS
:針對 PSS 填充的簽名作業,PSS 鹽是訊息摘要及隨機產生的大小。在 begin 的inputParams
中,使用 Tag::DIGEST 指定的摘要,做為 PSS 摘要演算法和 MGF1 摘要演算法。PaddingMode::RSA_OAEP
。在 begin 的inputParams
中,使用 Tag::DIGEST 指定的摘要做為 OAEP 摘要演算法,並使用 SHA1 做為 MGF1 摘要演算法。
ECDSA 金鑰
如果為未填補簽名或驗證而提供的資料過長,請截斷資料。
AES 金鑰
其他條件 (視封鎖模式而定):
BlockMode::ECB
或BlockMode::CBC
。如果填充值為PaddingMode::NONE
,且資料長度不是 AES 區塊大小的倍數,則會傳回ErrorCode::INVALID_INPUT_LENGTH
。如果填充值為PaddingMode::PKCS7
,請根據 PKCS#7 規格填充資料。請注意,如果資料是區塊長度的倍數,PKCS#7 建議您新增額外的填充區塊。BlockMode::GCM
。在加密期間,處理所有明文後,請計算標記 (Tag::MAC_LENGTH 位元組),並附加至傳回的密文。在解密期間,請將最後 Tag::MAC_LENGTH 位元組做為標記處理。如果標記驗證失敗,請傳回ErrorCode::VERIFICATION_FAILED
。
取消
版本:1、2、3
取消進行中的作業。在呼叫取消後,每次使用提供的作業控制代碼時,請傳回 ErrorCode::INVALID_OPERATION_HANDLE
,也就是包含「update」、「完成」或「取消」。
get_supported_algorithms
版本:1
傳回 Keymaster 硬體實作支援的演算法清單。軟體實作會傳回空白清單;混合式實作會傳回清單,其中只包含硬體支援的演算法。
Keymaster 1 實作支援 RSA、EC、AES 和 HMAC。
get_supported_block_modes
版本:1
傳回 Keymaster 硬體實作針對指定演算法和用途支援的 AES 區塊模式清單。
對於不是區塊加密法的 RSA、EC 和 HMAC,此方法會針對所有有效用途傳回空白清單。無效的用途應導致方法傳回 ErrorCode::INVALID_PURPOSE
。
Keymaster 1 實作支援 AES 加密與解密的 ECB、CBC、CTR 和 GCM。
get_supported_padding_modes
版本:1
針對指定演算法和用途,傳回 Keymaster 硬體實作項目支援的填充模式清單。
HMAC 和 EC 沒有填充概念,因此方法會針對所有有效用途傳回空白清單。無效的用途應導致方法傳回 ErrorCode::INVALID_PURPOSE
。
對於 RSA,Keymaster 1 實作支援:
- 不填充的加密、解密、簽署和驗證。對於未填補的加密和簽署作業,如果訊息比公開模數短,實作項目必須在左側填補零。對於未填充的解密和驗證作業,輸入長度必須與公開模數大小相符。
- PKCS#1 v1.5 加密和簽署填充模式
- PSS,鹽值長度不得少於 20
- 睡眠
針對 ECB 和 CBC 模式的 AES,Keymaster 1 實作項目支援無填充和 PKCS#7 填充。點閱率和 GCM 模式不支援邊框間距。
get_supported_digests
版本:1
傳回 Keymaster 硬體實作針對指定演算法和用途支援的摘要模式清單。
沒有任何 AES 模式支援或需要摘要,因此這個方法會傳回空白清單以達到有效目的。
Keymaster 1 實作項目可實作部分定義的摘要。實作會提供 SHA-256,並可提供 MD5、SHA1、SHA-224、SHA-256、SHA384 和 SHA512 (完整的定義摘要)。
get_supported_import_formats
版本:1
傳回指定演算法的 Keymaster 硬體實作項目支援的匯入格式清單。
Keymaster 1 實作項目支援 PKCS#8 格式 (不含密碼保護),可用於匯入 RSA 和 EC 金鑰組,並支援匯入 AES 和 HMAC 金鑰內容的原始資料。
get_supported_export_formats
版本:1
傳回 Keymaster 硬體實作指定演算法時支援的匯出格式清單。
Keymaster1 實作支援用於匯出 RSA 和 EC 公開金鑰的 X.509 格式。系統不支援匯出私密金鑰或非對稱式金鑰。
歷史函式
Keymaster 0
下列函式屬於原始 Keymaster 0 定義。這些值曾出現在 Keymaster 1 結構體 keymaster1_device_t 中。不過,在 Keymaster 1.0 中,系統並未實作這些函式,而是將函式指標設為 NULL。
generate_keypair
import_keypair
get_keypair_public
delete_keypair
delete_all
sign_data
Verify_data
Keymaster 1
下列函式屬於 Keymaster 1 定義,但已在 Keymaster 2 中移除,與上述 Keymaster 0 函式相同。
get_supported_algorithms
get_supported_block_modes
get_supported_padding_modes
get_supported_digests
get_supported_import_formats
get_supported_export_formats
Keymaster 2
下列函式屬於 Keymaster 2 定義,但已在 Keymaster 3 中移除,與上述 Keymaster 1 函式相同。
configure