此頁面提供詳細信息以幫助 Keymaster 硬件抽象層 (HAL) 的實施者。它涵蓋了 API 中的每個函數以及該函數在哪個 Keymaster 版本中可用,並描述了默認實現。有關標籤,請參閱Keymaster 標籤頁面。
一般實施指南
以下指南適用於 API 中的所有函數。
輸入指針參數
版本:1、2
未用於給定調用的輸入指針參數可能為NULL
。調用者不需要提供佔位符。例如,某些鍵類型和模式可能不使用inParams
參數中的任何值作為begin ,因此調用者可以將inParams
設置為NULL
或提供空參數集。調用者還可以提供未使用的參數,並且 Keymaster 方法不應發出錯誤。
如果必需的輸入參數為 NULL,則 Keymaster 方法應返回ErrorCode::UNEXPECTED_NULL_POINTER
。
從 Keymaster 3 開始,沒有指針參數。所有參數都通過值或常量引用傳遞。
輸出指針參數
版本:1、2
與輸入指針參數類似,未使用的輸出指針參數可能為NULL
。如果方法需要返回發現為NULL
的輸出參數中的數據,它應該返回ErrorCode::OUTPUT_PARAMETER_NULL
。
從 Keymaster 3 開始,沒有指針參數。所有參數都通過值或常量引用傳遞。
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
。 - 如果硬件
supportsAttestation
生成 Keymaster 公鑰認證證書,supportAttestation 為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。此方法在設備打開後、使用前調用一次。它用於向 keymaster 提供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);
addRng熵
版本:1、2、3
此函數在 Keymaster 1 中作為add_rng_entropy
引入,並在 Keymaster 3 中重命名。
將調用者提供的熵添加到 Keymaster 1 實現用於生成隨機數、密鑰、IV 等的池中。
Keymaster 實現需要將提供的熵安全地混合到它們的池中,該池還必須包含來自硬件隨機數生成器的內部生成的熵。應該處理混合,以便完全控制addRngEntropy
的位或硬件生成的位(但不能同時控制兩者)的攻擊者在預測從熵池生成的位時沒有不可忽略的優勢。
嘗試估計其內部池中的熵的 Keymaster 實現假定addRngEntropy
提供的數據不包含熵。如果 Keymaster 實現在一次調用中獲得超過 2 KiB 的數據,則可能會返回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
UNSUPPORTED_DIGEST 。
主要特徵
如果特徵參數不為 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添加到關鍵特性中。
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 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 模塊實現。
destroyAttestationIds
版本: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 個,留給 vold 用於密碼加密。當 Keystore 有 15 個操作正在進行時(已經調用了begin
,但尚未調用finish
或abort
)並且它接收到開始第 16 個操作的請求,它對最近最少使用的操作調用abort
以減少活動操作的數量到 14 之前調用begin
開始新請求的操作。
如果在密鑰生成或導入期間指定了Tag::APPLICATION_ID或Tag::APPLICATION_DATA ,則對begin
的調用會在此方法的inParams
參數中包含具有最初指定值的那些標籤。
授權執行
在此方法期間,如果實現將它們置於“硬件強制”特徵中並且操作不是公鑰操作,則 Trustlet 會強制執行以下密鑰授權。公鑰操作,即KeyPurpose::ENCRYPT
和KeyPurpose::VERIFY
,使用 RSA 或 EC 密鑰,即使不滿足授權要求,也允許成功。
- Tag::PURPOSE :在
begin()
調用中指定的目的必須與密鑰授權中的目的之一相匹配,除非請求的操作是公鑰操作。如果指定的目的不匹配並且操作不是公鑰操作,begin
將返回ErrorCode::UNSUPPORTED_PURPOSE
。公鑰操作是非對稱加密或驗證操作。 - Tag::ACTIVE_DATETIME只有在可信的 UTC 時間源可用時才能強制執行。如果當前日期和時間早於標籤值,則該方法返回
ErrorCode::KEY_NOT_YET_VALID
。 - Tag::ORIGINATION_EXPIRE_DATETIME只有在可信的 UTC 時間源可用時才能強制執行。如果當前日期和時間晚於標記值並且用途是
KeyPurpose::ENCRYPT
或KeyPurpose::SIGN
,則該方法返回ErrorCode::KEY_EXPIRED
。 - Tag::USAGE_EXPIRE_DATETIME只有在可信的 UTC 時間源可用時才能強制執行。如果當前日期和時間晚於標記值並且用途是
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::
inParams
。要使身份驗證令牌有效,必須滿足以下所有條件:- 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 或 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
inParams
。指定的值必須是 8 的倍數,不大於摘要長度或小於密鑰授權中Tag::MIN_MAC_LENGTH
的值。對於大於摘要長度或非 8 倍數的 MAC 長度,返回ErrorCode::UNSUPPORTED_MAC_LENGTH
。對於小於鍵最小長度的值,返回ErrorCode::INVALID_MAC_LENGTH
。
更新
版本:1、2、3
提供數據以在以begin 開始的持續操作中進行處理。操作由operationHandle
參數指定。
為了為緩衝區處理提供更大的靈活性,此方法的實現可以選擇使用比提供的更少的數據。調用者負責循環以在後續調用中提供其餘數據。消耗的輸入量在inputConsumed
參數中返回。實現總是消耗至少一個字節,除非操作不能再接受;如果提供了多於零個字節並且消耗了零個字節,則調用者認為這是一個錯誤併中止操作。
作為更新的結果,實現還可以選擇返回多少數據。這僅與加密和解密操作相關,因為簽名和驗證在完成之前不會返回任何數據。儘早返回數據,而不是緩衝它。
錯誤處理
如果此方法返回ErrorCode::OK
以外的錯誤代碼,則操作將中止並且操作句柄無效。將來使用此方法、完成或中止對句柄的任何使用都會返回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
。
調用者為每次調用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
Finishes an ongoing operation started with begin , processing all of the as-yet-unprocessed data provided by update (s).
This method is the last one called in an operation, so all processed data is returned.
Whether it completes successfully or returns an error, this method finalizes the operation and therefore invalidates the provided operation handle. Any future use of the handle, with this method or update or abort , returns ErrorCode::INVALID_OPERATION_HANDLE
.
Signing operations return the signature as the output. Verification operations accept the signature in the signature
parameter, and return no output.
Authorization enforcement
Key authorization enforcement is performed primarily in begin . The one exception is the case where the key has:
- One or more Tag::USER_SECURE_IDs , and
- Does not have a Tag::AUTH_TIMEOUT
In this case, the key requires an authorization per operation, and the update method receives a Tag::AUTH_TOKEN in the inParams
argument. HMAC verifies that the token is valid and contains a matching secure user ID, matches the key's Tag::USER_AUTH_TYPE , and contains the operation handle of the current operation in the challenge field. If these conditions aren't met, return ErrorCode::KEY_USER_NOT_AUTHENTICATED
.
The caller provides the authentication token to every call to update and finish . The implementation need only validate the token once if it prefers.
RSA keys
Some additional requirements, depending on the padding mode:
-
PaddingMode::NONE
. For unpadded signing and encryption operations, if the provided data is shorter than the key, the data is be zero-padded on the left before signing/encryption. If the data is the same length as the key, but numerically larger, returnErrorCode::INVALID_ARGUMENT
. For verification and decryption operations, the data must be exactly as long as the key. Otherwise, returnErrorCode::INVALID_INPUT_LENGTH.
-
PaddingMode::RSA_PSS
. For PSS-padded signature operations, the PSS salt is at least 20 bytes in length and randomly generated. The salt may be longer; the reference implementation uses maximally sized salt. The digest specified with Tag::DIGEST ininputParams
on begin is used as the PSS digest algorithm, and SHA1 is used as the MGF1 digest algorithm. -
PaddingMode::RSA_OAEP
. The digest specified with Tag::DIGEST ininputParams
on begin is used as the OAEP digest algorithm, and SHA1 is used as the MGF1 digest algorithm.
ECDSA keys
If the data provided for unpadded signing or verification is too long, truncate it.
AES keys
Some additional conditions, depending on block mode:
-
BlockMode::ECB
orBlockMode::CBC
. If padding isPaddingMode::NONE
and the data length is not a multiple of the AES block size, returnErrorCode::INVALID_INPUT_LENGTH
. If padding isPaddingMode::PKCS7
, pad the data per the PKCS#7 specification. Note that PKCS#7 recommends adding an additional padding block if the data is a multiple of the block length. -
BlockMode::GCM
. During encryption, after processing all plaintext, compute the tag ( Tag::MAC_LENGTH bytes) and append it to the returned ciphertext. During decryption, process the last Tag::MAC_LENGTH bytes as the tag. If tag verification fails, returnErrorCode::VERIFICATION_FAILED
.
abort
Version : 1, 2, 3
Aborts the in-progress operation. After the call to abort, return ErrorCode::INVALID_OPERATION_HANDLE
for any subsequent use of the provided operation handle with update , finish , or abort .
get_supported_algorithms
Version : 1
Returns the list of algorithms supported by the Keymaster hardware implementation. A software implementation returns an empty list; a hybrid implementation returns a list containing only the algorithms that are supported by hardware.
Keymaster 1 implementations support RSA, EC, AES and HMAC.
get_supported_block_modes
Version : 1
Returns the list of AES block modes supported by the Keymaster hardware implementation for a specified algorithm and purpose.
For RSA, EC and HMAC, which are not block ciphers, the method returns an empty list for all valid purposes. Invalid purposes should cause the method to return ErrorCode::INVALID_PURPOSE
.
Keymaster 1 implementations support ECB, CBC, CTR and GCM for AES encryption and decryption.
get_supported_padding_modes
Version : 1
Returns the list of padding modes supported by the Keymaster hardware implementation for a specified algorithm and purpose.
HMAC and EC have no notion of padding so the method returns an empty list for all valid purposes. Invalid purposes should cause the method to return ErrorCode::INVALID_PURPOSE
.
For RSA, Keymaster 1 implementations support:
- Unpadded encryption, decryption, signing and verification. For unpadded encryption and signing, if the message is shorter than the public modulus, implementations must left-pad it with zeros. For unpadded decryption and verification, the input length must match the public modulus size.
- PKCS#1 v1.5 encryption and signing padding modes
- PSS with a minimum salt length of 20
- OAEP
For AES in ECB and CBC modes, Keymaster 1 implementations support no padding and PKCS#7-padding. CTR and GCM modes support only no padding.
get_supported_digests
Version : 1
Returns the list of digest modes supported by the Keymaster hardware implementation for a specified algorithm and purpose.
No AES modes support or require digesting, so the method returns an empty list for valid purposes.
Keymaster 1 implementations can implement a subset of the defined digests. Implementations provide SHA-256 and can provide MD5, SHA1, SHA-224, SHA-256, SHA384 and SHA512 (the full set of defined digests).
get_supported_import_formats
Version : 1
Returns the list of import formats supported by the Keymaster hardware implementation of a specified algorithm.
Keymaster 1 implementations support the PKCS#8 format (without password protection) for importing RSA and EC key pairs, and support RAW import of AES and HMAC key material.
get_supported_export_formats
Version : 1
Returns the list of export formats supported by the Keymaster hardware implementation of a specified algorithm.
Keymaster1 implementations support the X.509 format for exporting RSA and EC public keys. Export of private keys or asymmetric keys is not supported.
Historical functions
Keymaster 0
The following functions belong to the original Keymaster 0 definition. They were present in Keymaster 1 struct keymaster1_device_t. However, in Keymaster 1.0 they were not implemented, and their function pointers were set to NULL.
-
generate_keypair
-
import_keypair
-
get_keypair_public
-
delete_keypair
-
delete_all
-
sign_data
-
Verify_data
Keymaster 1
The following functions belong to the Keymaster 1 definition, but were removed in Keymaster 2, along with the Keymaster 0 functions listed above.
-
get_supported_algorithms
-
get_supported_block_modes
-
get_supported_padding_modes
-
get_supported_digests
-
get_supported_import_formats
-
get_supported_export_formats
Keymaster 2
The following functions belong to the Keymaster 2 definition, but were removed in Keymaster 3, along with the Keymaster 1 functions listed above.
-
configure