本頁面提供詳細資訊,協助 Keymaster 硬體抽象層 (HAL) 的實作者。這份文件涵蓋 API 中的每個函式,以及該函式可在哪個 Keymaster 版本中使用,並說明預設實作方式。如需瞭解標記,請參閱「Keymaster 標記」頁面。
一般導入指南
下列規範適用於 API 中的所有函式。
輸入指標參數
版本:1、2
未用於特定呼叫的輸入指標參數可能為 NULL
。呼叫端不必提供預留位置。舉例來說,某些鍵類型和模式可能不會使用 inParams
引數到 begin 的任何值,因此呼叫端可能會將 inParams
設為 NULL
,或提供空白參數集。呼叫端也可以提供未使用的參數,而 Keymaster 方法則不應發出錯誤。
如果必要的輸入參數為空值,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 金鑰的必要條件,但如果在建立 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 金鑰
產生 AES 金鑰時,只需要 Tag::KEY_SIZE。如果省略,則方法會傳回 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 的倍數的值。系統支援 64 到 512 之間的所有 8 的倍數。系統可能會支援更大的值。
- 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
,如果該鍵可回溯,則會加入 Tag::ROLLBACK_RESISTANT。
無法復原
回溯防護功能是指使用 deleteKey 或 deleteAllKeys 刪除金鑰後,安全硬體會保證該金鑰永遠無法再使用。未提供回溯防護功能的實作項目通常會將產生的或匯入的金鑰內容以金鑰 blob 的形式傳回給呼叫端,這是經過加密和驗證的格式。當金鑰庫刪除金鑰 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 模組才會實作。
deleteAllKeys
版本:1、2、3
這個函式在 Keymaster 1 中以 delete_all_keys
的名稱推出,並在 Keymaster 3 中重新命名。
刪除所有鍵。這個方法屬於選用,且只有提供回溯防護功能的 Keymaster 模組才會實作。
destroyAttestationIds
版本:3
destroyAttestationIds()
方法用於永久停用新的 (選用但強烈建議使用) ID 認證功能。如果 TEE 無法確保在呼叫此方法後,永久停用身分認證,則絕對不應實作身分認證,在這種情況下,此方法不會執行任何操作,並傳回 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
。公開金鑰作業是指非對稱式加密或驗證作業。 - 只有在可使用可信任的世界標準時間來源時,才能強制執行 Tag::ACTIVE_DATETIME。如果目前的日期和時間早於標記值,方法會傳回
ErrorCode::KEY_NOT_YET_VALID
。 - 只有在可使用信任的世界標準時間來源時,才能強制執行 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 指定只有 Bootloader 可以使用金鑰。如果在引導程式執行完畢後,使用僅限引導程式鍵呼叫這個方法,則會傳回
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
中提供 IV 或 Nonce Tag::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
,系統就會中止作業,並將作業句柄設為無效。日後使用此方法、finish 或 abort 的任何控制項,都會傳回 ErrorCode::INVALID_OPERATION_HANDLE
。
授權強制執行
主要在 begin 中執行金鑰授權強制執行作業。唯一的例外狀況是鍵有以下情況:
- 一或多個 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 叫用無法得知是否為最後一次叫用,因此會處理所有標記長度以外的所有內容,並在 finish 期間緩衝可能的標記資料。
完成
版本:1、2、3
完成以 begin 啟動的持續性作業,處理 update 提供的所有尚未處理的資料。
這個方法是作業中最後一個呼叫的方法,因此會傳回所有已處理的資料。
無論是否順利完成或傳回錯誤,這個方法都會完成作業,並因此使提供的作業句柄失效。日後使用此方法或更新或中止時,都會透過句柄傳回 ErrorCode::INVALID_OPERATION_HANDLE
。
簽署作業會將簽名做為輸出內容傳回。驗證作業會接受 signature
參數中的簽名,且不會傳回任何輸出內容。
授權強制執行
主要在 begin 中執行金鑰授權強制執行作業。唯一的例外狀況是鍵有以下情況:
- 一或多個 Tag::USER_SECURE_ID,以及
- 沒有 Tag::AUTH_TIMEOUT
在這種情況下,金鑰需要每個作業的授權,更新方法會在 inParams
引數中接收 Tag::AUTH_TOKEN。HMAC 會驗證權杖是否有效,並包含相符的安全使用者 ID、與金鑰的 Tag::USER_AUTH_TYPE 相符,以及挑戰字段中目前作業的作業句柄。如果不符合這些條件,請傳回 ErrorCode::KEY_USER_NOT_AUTHENTICATED
。
呼叫端會在每次呼叫更新和完成時,提供驗證權杖。實作方式只需驗證一次權杖 (如果需要的話)。
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 上使用 Tag::DIGEST 指定的摘要,會用於 OAEP 摘要演算法,而 SHA1 會用於 MGF1 摘要演算法。inputParams
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
中止進行中的作業。呼叫終止後,如果後續使用提供的作業句柄,請使用 update、finish 或 abort 傳回 ErrorCode::INVALID_OPERATION_HANDLE
。
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 實作項目支援 ECB、CBC、CTR 和 GCM,可用於 AES 加密和解密。
get_supported_padding_modes
版本:1
傳回 Keymaster 硬體實作項目支援的填充模式清單,適用於指定的演算法和用途。
HMAC 和 EC 沒有填充概念,因此方法會針對所有有效用途傳回空白清單。無效的用途應會導致方法傳回 ErrorCode::INVALID_PURPOSE
。
針對 RSA,Keymaster 1 實作項目支援:
- 不填充的加密、解密、簽署和驗證。對於未填補的加密和簽署作業,如果訊息比公開模數短,實作項目必須在左側填補零。對於未填充的解密和驗證作業,輸入長度必須與公開模數大小相符。
- PKCS#1 v1.5 加密和簽署填充模式
- PSS,鹽長度下限為 20
- OAEP
針對 ECB 和 CBC 模式的 AES,Keymaster 1 實作項目支援無填充和 PKCS#7 填充。CTR 和 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 實作項目支援 X.509 格式,可用於匯出 RSA 和 EC 公開金鑰。系統不支援匯出私密金鑰或非對稱式金鑰。
歷來函式
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