本頁提供了幫助 Keymaster 硬體抽象層 (HAL) 實施者的詳細資訊。它涵蓋了 API 中的每個函數以及該函數可用的 Keymaster 版本,並描述了預設實作。有關標籤,請參閱Keymaster 標籤頁面。
一般實施指南
以下準則適用於 API 中的所有函數。
輸入指針參數
版本:1、2
未用於給定呼叫的輸入指標參數可能為NULL
。呼叫者不需要提供佔位符。例如,某些鍵類型和模式可能不會使用inParams
參數中的任何值來開始,因此呼叫者可以將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 或隨機數、產生沒有目的的金鑰(因此無用)等等,不應透過實作來診斷。必須診斷遺漏所需參數、指定無效所需參數、類似錯誤。
應用程式、框架和 Android 金鑰庫有責任確保對 Keymaster 模組的呼叫合理且有用。
功能
取得硬體特性
版本: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 中棄用,因為此資訊在系統屬性檔案中可用,且製造商實作在啟動期間讀取這些檔案。
配置密鑰管理器。此方法在設備開啟後、使用前調用一次。它用於向金鑰管理員提供KM_TAG_OS_VERSION和KM_TAG_OS_PATCHLEVEL 。在呼叫此方法之前,所有其他方法都會傳回KM_ERROR_KEYMASTER_NOT_CONFIGURED
。此方法提供的值每次啟動時僅被 keymaster 接受一次。後續呼叫返回KM_ERROR_OK
,但不執行任何操作。
如果 keymaster 實作位於安全硬體中,且提供的作業系統版本和修補程式等級值與引導程式提供給安全硬體的值不符(或開機載入程式未提供值),則此方法傳回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);
附加熵
版本:1、2、3
函數在 Keymaster 1 中以add_rng_entropy
引入,並在 Keymaster 3 中重新命名。
將呼叫者提供的熵加入 Keymaster 1 實作所使用的池中,用於產生隨機數、金鑰、IV 等。
Keymaster 實作需要將提供的熵安全地混合到其池中,該池還必須包含由硬體隨機數產生器內部產生的熵。應處理混合,以便完全控制addRngEntropy
提供的位元或硬體產生的位元(但不能同時控制兩者)的攻擊者在預測從熵池產生的位元時沒有不可忽視的優勢。
嘗試估計其內部池中的熵的 Keymaster 實作假設addRngEntropy
提供的資料不包含熵。如果在單次呼叫中提供超過 2 KiB 的數據,Keymaster 實作可能會傳回ErrorCode::INVALID_INPUT_LENGTH
。
產生金鑰
版本: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 金鑰
只需Tag::KEY_SIZE即可產生 ECDSA 金鑰。它用於選擇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 的倍數的值。支援從 64 到 512 的所有 8 的倍數。可以支援更大的值。
- Tag::MIN_MAC_LENGTH指定可以使用此金鑰產生或驗證的 MAC 的最小長度。該值是 8 的倍數且至少為 64。
- Tag::DIGEST指定密鑰的摘要演算法。僅指定一個摘要,否則傳回
ErrorCode::UNSUPPORTED_DIGEST
。如果 trustlet 不支援摘要,則傳回ErrorCode::UNSUPPORTED_DIGEST
。
主要特點
如果 features 參數非 NULL, generateKey
傳回新產生的金鑰的特徵,並適當地分為硬體強制清單和軟體強制清單。有關哪些特性屬於哪個清單的描述,請參閱getKeyCharacteristics 。傳回的特徵包括指定給密鑰產生的所有參數,但Tag::APPLICATION_ID和Tag::APPLICATION_DATA除外。如果這些標籤包含在關鍵參數中,則會從傳回的特徵中刪除它們,以便無法透過檢查傳回的關鍵 blob 找到它們的值。但是,它們以加密方式綁定到金鑰 blob,因此如果在使用金鑰時未提供正確的值,則使用會失敗。同樣, Tag::ROOT_OF_TRUST以加密方式綁定到密鑰,但在密鑰建立或導入期間可能不會指定,並且永遠不會返回。
除了提供的標籤之外,trustlet 還添加了Tag::ORIGIN ,其值為KeyOrigin::GENERATED
,如果密鑰具有防回滾功能,
抗復原性
抗回滾意味著一旦使用deleteKey或deleteAllKeys刪除金鑰,安全硬體將保證該金鑰永遠不再可用。沒有回滾阻力的實作通常會將產生或匯入的金鑰材料作為金鑰 blob(加密且經過驗證的形式)傳回給呼叫者。當金鑰庫刪除金鑰 blob 時,金鑰就消失了,但先前成功檢索金鑰材質的攻擊者有可能將其恢復到裝置上。
如果安全硬體保證刪除的金鑰以後無法恢復,則金鑰是防回滾的。這通常是透過將附加密鑰元資料儲存在攻擊者無法操縱的受信任位置來完成的。在行動裝置上,用於此目的的機制通常是重播保護記憶體區塊(RPMB)。因為可以創建的密鑰的數量本質上是無限的,並且用於防回滾的可信存儲的大小可能有限,所以即使不能為新密鑰提供防回滾,該方法也需要成功。在這種情況下, Tag::ROLLBACK_RESISTANT不應加入關鍵特性。
取得關鍵特徵
版本: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 trustlet 和相關的身份驗證 trustlet 都必須是安全的,並共用用於簽署和驗證身份驗證令牌的秘密 HMAC 金鑰。有關詳細信息,請參閱身份驗證頁面。
- Tag::ACTIVE_DATETIME 、 Tag::ORIGINATION_EXPIRE_DATETIME和Tag::USAGE_EXPIRE_DATETIME標籤需要存取可驗證正確的掛鐘。大多數安全硬體只能存取非安全作業系統提供的時間信息,這意味著標籤是軟體強制執行的。
- Tag::ORIGIN始終位於硬體綁定密鑰的硬體清單中。它在該清單中的存在是高層決定密鑰是否受硬體支援的方式。
導入金鑰
版本:1、2、3
此函數在 Keymaster 1 中以import_key
引入,並在 Keymaster 3 中重新命名。
將密鑰材料導入 Keymaster 硬體。金鑰定義參數與輸出特性的處理方式與generateKey
相同,但有以下例外:
- 輸入參數中不需要Tag::KEY_SIZE和Tag::RSA_PUBLIC_EXPONENT (僅適用於 RSA 金鑰)。如果未提供,trustlet 會從提供的密鑰材料中推導出值,並為密鑰特徵添加適當的標籤和值。如果提供了參數,trustlet 將根據密鑰材料驗證它們。如果不匹配,則該方法將傳回
ErrorCode::IMPORT_PARAMETER_MISMATCH
。 - 傳回的Tag::ORIGIN與
KeyOrigin::IMPORTED
具有相同的值。
匯出金鑰
版本:1、2、3
此函數在 Keymaster 1 中以export_key
引入,並在 Keymaster 3 中重新命名。
從 Keymaster RSA 或 EC 金鑰對匯出公鑰。
如果在金鑰產生或匯入期間提供了Tag::APPLICATION_ID
,則在clientId
參數中為此方法提供相同的值。否則,該方法傳回ErrorCode::INVALID_KEY_BLOB
。同樣,如果在生成或導入期間提供了Tag::APPLICATION_DATA
,則在appData
參數中為此方法提供相同的值。
刪除鍵
版本:1、2、3
函數在 Keymaster 1 中以delete_key
引入,並在 Keymaster 3 中重新命名。
刪除提供的密鑰。此方法是可選的,並且僅由提供回滾阻力的 Keymaster 模組實作。
刪除所有鍵
版本:1、2、3
此函數在 Keymaster 1 中以delete_all_keys
引入,並在 Keymaster 3 中重新命名。
刪除所有鍵。此方法是可選的,並且僅由提供回滾阻力的 Keymaster 模組實作。
銷毀證明ID
版本:3
destroyAttestationIds()
方法用於永久停用新的(可選,但強烈建議) ID 證明功能。如果呼叫此方法後 TEE 無法確保永久停用 ID 證明,則根本無法實作 ID 證明,在這種情況下,此方法不執行任何操作並傳回ErrorCode::UNIMPLEMENTED
。如果支援 ID 證明,則需要實施此方法,並且必須永久停用所有未來的 ID 證明嘗試。此方法可以被呼叫任意多次。如果 ID 證明已永久停用,則該方法不執行任何操作並傳回ErrorCode::OK
。
此方法可能傳回的唯一錯誤代碼是ErrorCode::UNIMPLEMENTED
(如果不支援 ID 證明)、 ErrorCode:OK
、 ErrorCode::KEYMASTER_NOT_CONFIGURED
或指示與安全硬體通訊失敗的錯誤代碼之一。
開始
版本:1、2、3
使用指定的金鑰、出於指定的目的、使用指定的參數(根據需要)開始加密操作,並傳回與update和finish一起使用的操作句柄以完成操作。操作句柄也用作經過驗證的操作中的「質詢」令牌,且對於此類操作,操作句柄包含在身分驗證令牌的challenge
欄位中。
Keymaster 實作支援至少 16 個並發操作。 Keystore 最多使用 15 個,留下 1 個供 vold 用於密碼加密。當 Keystore 有 15 個操作正在進行時(已呼叫begin
,但尚未呼叫finish
或abort
)並且它收到開始第 16 個操作的請求,它會對最近最少使用的操作調用abort
,以減少活動操作的數量在呼叫begin 之前到14 begin
新請求的操作。
如果在金鑰產生或匯入期間指定了Tag::APPLICATION_ID或Tag::APPLICATION_DATA ,則對begin
的呼叫將包含那些具有此方法的inParams
參數中最初指定值的標籤。
授權執行
在此方法期間,如果實作將它們置於「硬體強制」特性中且操作不是公鑰操作,則 Trustlet 會強制執行下列金鑰授權。即使未滿足授權要求,公鑰作業(即使用 RSA 或 EC 金鑰的KeyPurpose::ENCRYPT
和KeyPurpose::VERIFY
也可以成功。
- 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允許呼叫者指定隨機數或初始化向量 (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
的值。對於大於 128 或非 8 的倍數的 MAC 長度,傳回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
,則需要初始化向量或隨機數。在大多數情況下,呼叫者不應提供 IV 或隨機數。在這種情況下,Keymaster 實作會產生隨機 IV 或隨機數,並透過outParams
中的Tag::NONCE傳回它。 CBC 和 CTR IV 均為 16 位元組。 GCM 隨機數為 12 位元組。如果金鑰授權包含Tag::CALLER_NONCE ,則呼叫者可以在inParams
中提供帶有Tag::NONCE 的IV/nonce 。如果在Tag::CALLER_NONCE未授權時提供了隨機數,則傳回ErrorCode::CALLER_NONCE_PROHIBITED
。如果授權Tag::CALLER_NONCE時未提供 nonce,則產生隨機 IV/nonce。
HMAC 金鑰
HMAC 金鑰操作在inParams
中指定Tag::MAC_LENGTH
。指定的值必須是8的倍數,且不大於摘要長度,也不小於金鑰授權中Tag::MIN_MAC_LENGTH
的值。對於大於摘要長度或非 8 的倍數的 MAC 長度,傳回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 ,以及
- 沒有標籤::AUTH_TIMEOUT
在這種情況下,金鑰需要對每個操作進行授權,並且更新方法在inParams
參數中接收Tag::AUTH_TOKEN 。 HMAC 驗證令牌是否有效並包含匹配的安全使用者 ID、與金鑰的Tag::USER_AUTH_TYPE匹配,並在質詢欄位中包含目前操作的操作句柄。如果不符合這些條件,則傳回ErrorCode::KEY_USER_NOT_AUTHENTICATED
。
呼叫者為每個呼叫提供身份驗證令牌以更新和完成。如果願意,實作只需驗證令牌一次。
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
參數中的簽名,然後傳回不輸出。
授權執行
主要授權執行主要是在開始時執行的。鑰匙具有的例外是:
- 一個或多個標籤:: user_secure_ids ,並且
- 沒有標籤:: auth_timeout
在這種情況下,金鑰需要每個操作的授權,並且更新方法在inParams
參數中接收標籤:: auth_token 。 HMAC驗證令牌是否有效並包含匹配的安全性使用者ID,匹配鍵的標籤:: User_auth_type ,並包含挑戰欄位中目前操作的操作句柄。如果無法滿足這些條件,請回傳ErrorCode::KEY_USER_NOT_AUTHENTICATED
。
呼叫者為每個呼叫以更新和完成的呼叫提供身份驗證令牌。如果實作更喜歡,則只需驗證令牌一次即可。
RSA鍵
根據填充模式,一些其他要求:
-
PaddingMode::NONE
。對於未完成的簽章和加密操作,如果提供的資料比金鑰短,則在簽章/加密之前將資料填入左側零。如果資料的長度與金鑰相同,但在數值上大,則傳回ErrorCode::INVALID_ARGUMENT
。為了進行驗證和解密操作,資料必須與金鑰一樣長。否則,返回ErrorCode::INVALID_INPUT_LENGTH.
-
PaddingMode::RSA_PSS
。對於PSS填充的簽名操作,PSS鹽是訊息消化的大小和隨機產生的大小。用TAG :: Digest指定的摘要在開始時在inputParams
中用作PSS Digest演算法,並用作MGF1 Digest演算法。 -
PaddingMode::RSA_OAEP
。用TAG :: Digest指定的inputParams
中的摘要用作OAEP Digest演算法,SHA1用作MGF1 Digest演算法。
ECDSA鍵
如果提供的未完成簽名或驗證的資料太長,請截斷。
AES鍵
一些其他條件,取決於區塊模式:
-
BlockMode::ECB
或BlockMode::CBC
。如果填充是PaddingMode::NONE
,且資料長度不是AES區塊大小的倍數,則傳回ErrorCode::INVALID_INPUT_LENGTH
。如果填充是PaddingMode::PKCS7
,請在PKCS#7規格中新增資料。請注意,如果資料是區塊長度的倍數,則PKCS#7建議增加一個額外的填充區塊。 -
BlockMode::GCM
。在加密過程中,處理所有明文後,計算標籤(標籤:: mac_length Bytes),然後將其附加到傳回的Ciphertext。在解密期間,處理最後一個標籤:: mac_length位元組作為標籤。如果標籤驗證失敗,請回傳ErrorCode::VERIFICATION_FAILED
。
中止
版本:1、2、3
中止過程中的操作。通話後,返回ErrorCode::INVALID_OPERATION_HANDLE
用於隨後使用更新,完成或流產的提供的操作句柄。
get_supported_algorithm
版本: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加密與簽章填充模式
- 最小鹽長度20的PSS
- OAEP
對於歐洲央行和CBC模式中的AES,Keymaster 1實作不支援填充和PKCS#7-padding。 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 struct keymaster1_device_t中。但是,在Keymaster 1.0中,它們沒有實施,其功能指標被設定為無效。
-
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