本頁面提供詳細資訊,協助 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 金鑰
產生 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 的倍數的值。系統支援所有 8 的倍數,從 64 到 512 皆可。系統可能會支援更大的值。Tag::MIN_MAC_LENGTH
可指定可使用此金鑰產生或驗證的 MAC 長度下限。值為 8 的倍數,且至少為 64。Tag::DIGEST
指定金鑰的摘要演算法。請務必指定一個摘要,否則會傳回ErrorCode::UNSUPPORTED_DIGEST
。如果 Trustlet 不支援摘要,請傳回ErrorCode::UNSUPPORTED_DIGEST
。
主要特徵
如果特性引數不是 NULL
,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 無法確保在呼叫此方法後,永久停用 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
。公開金鑰作業是指非對稱式加密或驗證作業。- 只有在可取得可信任的世界標準時間來源時,才能強制執行
Tag::ACTIVE_DATETIME
。如果目前的日期和時間早於標記值,方法會傳回ErrorCode::KEY_NOT_YET_VALID
。 - 只有在可取得可信任的世界標準時間來源時,才能強制執行
Tag::ORIGINATION_EXPIRE_DATETIME
。如果目前的日期和時間晚於標記值,且用途為KeyPurpose::ENCRYPT
或KeyPurpose::SIGN
,則方法會傳回ErrorCode::KEY_EXPIRED
。 - 只有在可取得可信任的世界標準時間來源時,才能強制執行
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
參數會傳回所消耗的輸入量。除非作業無法接受更多位元組,否則實作一律會耗用至少一個位元組;如果提供的位元組數大於零,且耗用的位元組數為零,則呼叫端會將此視為錯誤,並中止作業。
實作項目也可以選擇要傳回多少資料,以便更新。這項設定僅適用於加密和解密作業,因為簽署和驗證作業在 finish
之前不會傳回任何資料。盡早傳回資料,而非緩衝資料。
處理錯誤
如果這個方法傳回的錯誤代碼不是 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
,以及 challenge
欄位中目前作業的作業句柄。如果不符合這些條件,請傳回 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
執行個體提供的所有未處理資料。
這個方法是作業中最後一個呼叫的方法,因此會傳回所有已處理的資料。
無論是否順利完成或傳回錯誤,這個方法都會完成作業,並因此使提供的作業句柄失效。日後使用句柄時,如果使用這個方法或 update
或 abort
,都會傳回 ErrorCode::INVALID_OPERATION_HANDLE
。
簽署作業會將簽名做為輸出結果傳回。驗證作業會接受 signature
參數中的簽名,且不會傳回任何輸出內容。
授權強制執行
主要在 begin
中執行金鑰授權強制執行作業。唯一的例外狀況是鍵同時具備下列兩種特性:
- 包含一或多個
Tag::USER_SECURE_IDs
- 沒有
Tag::AUTH_TIMEOUT
在這種情況下,每個作業都需要金鑰授權,更新方法會在 inParams
引數中接收 Tag::AUTH_TOKEN
。HMAC 會驗證權杖是否有效,並包含相符的安全使用者 ID、相符的金鑰 Tag::USER_AUTH_TYPE
,以及 challenge
欄位中目前作業的作業句柄。如果不符合這些條件,請傳回 ErrorCode::KEY_USER_NOT_AUTHENTICATED
。
呼叫端會在每次呼叫 update
和 finish
時提供驗證權杖。實作只需驗證權杖一次。
RSA 金鑰
視填充模式而定,可能需要遵守其他規定:
PaddingMode::NONE
. 如果是未填補的簽名和加密作業,如果提供的資料比金鑰短,則在簽名/加密前,資料會在左側填補零。如果資料的長度與鍵相同,但數值較大,則傳回ErrorCode::INVALID_ARGUMENT
。對於驗證和解密作業,資料長度必須與金鑰完全相同。否則,請傳回ErrorCode::INVALID_INPUT_LENGTH.
PaddingMode::RSA_PSS
. 針對 PSS 填充的簽名作業,PSS salt 是郵件摘要的大小,並隨機產生。在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
中止進行中的作業。在呼叫終止後,如果之後要使用提供的作業句柄,請使用 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