diff options
| author | android-build-team Robot <android-build-team-robot@google.com> | 2019-04-04 03:09:22 +0000 |
|---|---|---|
| committer | android-build-team Robot <android-build-team-robot@google.com> | 2019-04-04 03:09:22 +0000 |
| commit | cd1a0026cb360446a50b0f49373f19a154e02973 (patch) | |
| tree | 2c46798da1aacfbb399ca04376daa5389ec7e6a4 | |
| parent | 555ac9931cc5885b0e27ef38b42b10adae0a6430 (diff) | |
| parent | a8dca9ec4437a09360612f11d65aa4f53cb0098f (diff) | |
| download | android_system_keymaster-cd1a0026cb360446a50b0f49373f19a154e02973.tar.gz android_system_keymaster-cd1a0026cb360446a50b0f49373f19a154e02973.tar.bz2 android_system_keymaster-cd1a0026cb360446a50b0f49373f19a154e02973.zip | |
Snap for 5434517 from a8dca9ec4437a09360612f11d65aa4f53cb0098f to qt-release
Change-Id: Ia8d8699b585cd41dbeba081018954913e03612d8
| -rw-r--r-- | android_keymaster/keymaster_enforcement.cpp | 19 | ||||
| -rw-r--r-- | android_keymaster/keymaster_tags.cpp | 3 | ||||
| -rw-r--r-- | include/keymaster/attestation_record.h | 1 | ||||
| -rw-r--r-- | include/keymaster/keymaster_tags.h | 1 | ||||
| -rw-r--r-- | include/keymaster/km_openssl/ecdsa_operation.h | 8 | ||||
| -rw-r--r-- | include/keymaster/km_openssl/rsa_operation.h | 17 | ||||
| -rw-r--r-- | include/keymaster/operation.h | 2 | ||||
| -rw-r--r-- | km_openssl/attestation_record.cpp | 10 | ||||
| -rw-r--r-- | km_openssl/block_cipher_operation.cpp | 2 | ||||
| -rw-r--r-- | km_openssl/block_cipher_operation.h | 2 | ||||
| -rw-r--r-- | km_openssl/ecdsa_operation.cpp | 2 | ||||
| -rw-r--r-- | km_openssl/hmac_operation.cpp | 2 | ||||
| -rw-r--r-- | km_openssl/hmac_operation.h | 2 | ||||
| -rw-r--r-- | km_openssl/rsa_operation.cpp | 4 | ||||
| -rw-r--r-- | legacy_support/ecdsa_keymaster1_operation.cpp | 2 | ||||
| -rw-r--r-- | legacy_support/ecdsa_keymaster1_operation.h | 2 | ||||
| -rw-r--r-- | legacy_support/keymaster_passthrough_operation.h | 2 | ||||
| -rw-r--r-- | legacy_support/rsa_keymaster1_operation.cpp | 2 | ||||
| -rw-r--r-- | legacy_support/rsa_keymaster1_operation.h | 2 |
19 files changed, 55 insertions, 30 deletions
diff --git a/android_keymaster/keymaster_enforcement.cpp b/android_keymaster/keymaster_enforcement.cpp index e8bc2b2..bc42511 100644 --- a/android_keymaster/keymaster_enforcement.cpp +++ b/android_keymaster/keymaster_enforcement.cpp @@ -147,22 +147,30 @@ KeymasterEnforcement::AuthorizeUpdateOrFinish(const AuthProxy& auth_set, const AuthorizationSet& operation_params, keymaster_operation_handle_t op_handle) { int auth_type_index = -1; + int trusted_confirmation_index = -1; for (size_t pos = 0; pos < auth_set.size(); ++pos) { switch (auth_set[pos].tag) { - case KM_TAG_NO_AUTH_REQUIRED: - case KM_TAG_AUTH_TIMEOUT: - // If no auth is required or if auth is timeout-based, we have nothing to check. - return KM_ERROR_OK; - case KM_TAG_USER_AUTH_TYPE: auth_type_index = pos; break; + case KM_TAG_TRUSTED_CONFIRMATION_REQUIRED: + trusted_confirmation_index = pos; + break; + case KM_TAG_NO_AUTH_REQUIRED: + case KM_TAG_AUTH_TIMEOUT: + // If no auth is required or if auth is timeout-based, we have nothing to check. default: break; } } + // TODO verify trusted confirmation mac once we have a shared secret established + // For now, since we do not have such a service, any token offered here must be invalid. + if (trusted_confirmation_index != -1) { + return KM_ERROR_NO_USER_CONFIRMATION; + } + // Note that at this point we should be able to assume that authentication is required, because // authentication is required if KM_TAG_NO_AUTH_REQUIRED is absent. However, there are legacy // keys which have no authentication-related tags, so we assume that absence is equivalent to @@ -345,6 +353,7 @@ keymaster_error_t KeymasterEnforcement::AuthorizeBegin(const keymaster_purpose_t case KM_TAG_UNIQUE_ID: case KM_TAG_RESET_SINCE_ID_ROTATION: case KM_TAG_ALLOW_WHILE_ON_BODY: + case KM_TAG_TRUSTED_CONFIRMATION_REQUIRED: break; /* TODO(bcyoung): This is currently handled in keystore, but may move to keymaster in the diff --git a/android_keymaster/keymaster_tags.cpp b/android_keymaster/keymaster_tags.cpp index 7ee3728..b26d0ee 100644 --- a/android_keymaster/keymaster_tags.cpp +++ b/android_keymaster/keymaster_tags.cpp @@ -109,6 +109,8 @@ const char* StringifyTag(keymaster_tag_t tag) { return "KM_TAG_RESET_SINCE_ID_ROTATION"; case KM_TAG_ALLOW_WHILE_ON_BODY: return "KM_TAG_ALLOW_WHILE_ON_BODY"; + case KM_TAG_TRUSTED_CONFIRMATION_REQUIRED: + return "KM_TAG_TRUSTED_CONFIRMATION_REQUIRED"; case KM_TAG_UNLOCKED_DEVICE_REQUIRED: return "KM_TAG_UNLOCKED_DEVICE_REQUIRED"; case KM_TAG_ATTESTATION_CHALLENGE: @@ -181,6 +183,7 @@ DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_MEID); DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_MANUFACTURER); DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_MODEL); DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_UNLOCKED_DEVICE_REQUIRED); +DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_TRUSTED_CONFIRMATION_REQUIRED); // DEFINE_KEYMASTER_ENUM_TAG is used to create TypedEnumTag instances for each enum keymaster tag. diff --git a/include/keymaster/attestation_record.h b/include/keymaster/attestation_record.h index 6c97c4b..905252d 100644 --- a/include/keymaster/attestation_record.h +++ b/include/keymaster/attestation_record.h @@ -71,6 +71,7 @@ typedef struct km_auth_list { ASN1_INTEGER* user_auth_type; ASN1_INTEGER* auth_timeout; ASN1_NULL* allow_while_on_body; + ASN1_NULL* trusted_confirmation_required; ASN1_NULL* unlocked_device_required; ASN1_NULL* all_applications; ASN1_OCTET_STRING* application_id; diff --git a/include/keymaster/keymaster_tags.h b/include/keymaster/keymaster_tags.h index ac614fe..daa7b19 100644 --- a/include/keymaster/keymaster_tags.h +++ b/include/keymaster/keymaster_tags.h @@ -154,6 +154,7 @@ DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_NO_AUTH_REQUIRED); DECLARE_KEYMASTER_TAG(KM_UINT, TAG_AUTH_TIMEOUT); DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ALLOW_WHILE_ON_BODY); DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_UNLOCKED_DEVICE_REQUIRED); +DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_TRUSTED_CONFIRMATION_REQUIRED); DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ALL_APPLICATIONS); DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_APPLICATION_ID); DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_APPLICATION_DATA); diff --git a/include/keymaster/km_openssl/ecdsa_operation.h b/include/keymaster/km_openssl/ecdsa_operation.h index 6050784..4be0d2e 100644 --- a/include/keymaster/km_openssl/ecdsa_operation.h +++ b/include/keymaster/km_openssl/ecdsa_operation.h @@ -84,20 +84,20 @@ class EcdsaOperationFactory : public OperationFactory { private: KeyType registry_key() const override { return KeyType(KM_ALGORITHM_EC, purpose()); } OperationPtr CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) override; + keymaster_error_t* error) const override; const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override; virtual keymaster_purpose_t purpose() const = 0; virtual Operation* InstantiateOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, - keymaster_digest_t digest, EVP_PKEY* key) = 0; + keymaster_digest_t digest, EVP_PKEY* key) const = 0; }; class EcdsaSignOperationFactory : public EcdsaOperationFactory { private: keymaster_purpose_t purpose() const override { return KM_PURPOSE_SIGN; } Operation* InstantiateOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, - keymaster_digest_t digest, EVP_PKEY* key) override { + keymaster_digest_t digest, EVP_PKEY* key) const override { return new (std::nothrow) EcdsaSignOperation(move(hw_enforced), move(sw_enforced), digest, key); } @@ -107,7 +107,7 @@ class EcdsaVerifyOperationFactory : public EcdsaOperationFactory { public: keymaster_purpose_t purpose() const override { return KM_PURPOSE_VERIFY; } Operation* InstantiateOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, - keymaster_digest_t digest, EVP_PKEY* key) override { + keymaster_digest_t digest, EVP_PKEY* key) const override { return new (std::nothrow) EcdsaVerifyOperation(move(hw_enforced), move(sw_enforced), digest, key); } diff --git a/include/keymaster/km_openssl/rsa_operation.h b/include/keymaster/km_openssl/rsa_operation.h index 578a3d2..dd14b57 100644 --- a/include/keymaster/km_openssl/rsa_operation.h +++ b/include/keymaster/km_openssl/rsa_operation.h @@ -188,7 +188,7 @@ class RsaOperationFactory : public OperationFactory { virtual keymaster_purpose_t purpose() const = 0; OperationPtr CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) override { + keymaster_error_t* error) const override { return OperationPtr(CreateRsaOperation(move(key), begin_params, error)); } const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override; @@ -196,13 +196,14 @@ class RsaOperationFactory : public OperationFactory { protected: static EVP_PKEY* GetRsaKey(Key&& key, keymaster_error_t* error); virtual RsaOperation* CreateRsaOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error); + keymaster_error_t* error) const; private: virtual RsaOperation* InstantiateOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, keymaster_digest_t digest, - keymaster_padding_t padding, EVP_PKEY* key) = 0; + keymaster_padding_t padding, + EVP_PKEY* key) const = 0; }; /** @@ -220,7 +221,7 @@ class RsaDigestingOperationFactory : public RsaOperationFactory { class RsaCryptingOperationFactory : public RsaOperationFactory { public: RsaOperation* CreateRsaOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) override; + keymaster_error_t* error) const override; const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const override; }; @@ -232,7 +233,7 @@ class RsaSigningOperationFactory : public RsaDigestingOperationFactory { keymaster_purpose_t purpose() const override { return KM_PURPOSE_SIGN; } RsaOperation* InstantiateOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, keymaster_digest_t digest, - keymaster_padding_t padding, EVP_PKEY* key) override { + keymaster_padding_t padding, EVP_PKEY* key) const override { return new (std::nothrow) RsaSignOperation(move(hw_enforced), move(sw_enforced), digest, padding, key); } @@ -245,7 +246,7 @@ class RsaVerificationOperationFactory : public RsaDigestingOperationFactory { keymaster_purpose_t purpose() const override { return KM_PURPOSE_VERIFY; } RsaOperation* InstantiateOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, keymaster_digest_t digest, - keymaster_padding_t padding, EVP_PKEY* key) override { + keymaster_padding_t padding, EVP_PKEY* key) const override { return new (std::nothrow) RsaVerifyOperation(move(hw_enforced), move(sw_enforced), digest, padding, key); } @@ -258,7 +259,7 @@ class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory { keymaster_purpose_t purpose() const override { return KM_PURPOSE_ENCRYPT; } RsaOperation* InstantiateOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, keymaster_digest_t digest, - keymaster_padding_t padding, EVP_PKEY* key) override { + keymaster_padding_t padding, EVP_PKEY* key) const override { return new (std::nothrow) RsaEncryptOperation(move(hw_enforced), move(sw_enforced), digest, padding, key); } @@ -271,7 +272,7 @@ class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory { keymaster_purpose_t purpose() const override { return KM_PURPOSE_DECRYPT; } RsaOperation* InstantiateOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, keymaster_digest_t digest, - keymaster_padding_t padding, EVP_PKEY* key) override { + keymaster_padding_t padding, EVP_PKEY* key) const override { return new (std::nothrow) RsaDecryptOperation(move(hw_enforced), move(sw_enforced), digest, padding, key); } diff --git a/include/keymaster/operation.h b/include/keymaster/operation.h index 682aadf..f643e6b 100644 --- a/include/keymaster/operation.h +++ b/include/keymaster/operation.h @@ -53,7 +53,7 @@ class OperationFactory { // Factory methods virtual OperationPtr CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) = 0; + keymaster_error_t* error) const = 0; // Informational methods. The returned arrays reference static memory and must not be // deallocated or modified. diff --git a/km_openssl/attestation_record.cpp b/km_openssl/attestation_record.cpp index 2c94bbf..279088d 100644 --- a/km_openssl/attestation_record.cpp +++ b/km_openssl/attestation_record.cpp @@ -229,6 +229,9 @@ keymaster_error_t build_auth_list(const AuthorizationSet& auth_list, KM_AUTH_LIS case KM_TAG_CALLER_NONCE: bool_ptr = &record->caller_nonce; break; + case KM_TAG_TRUSTED_CONFIRMATION_REQUIRED: + bool_ptr = &record->trusted_confirmation_required; + break; /* Byte arrays*/ case KM_TAG_APPLICATION_ID: @@ -707,6 +710,13 @@ keymaster_error_t extract_auth_list(const KM_AUTH_LIST* record, AuthorizationSet record->attestation_id_model->length)) return KM_ERROR_MEMORY_ALLOCATION_FAILED; + // Trusted confirmation required + if (record->trusted_confirmation_required) { + if (!auth_list->push_back(TAG_NO_AUTH_REQUIRED)) { + return KM_ERROR_MEMORY_ALLOCATION_FAILED; + } + } + return KM_ERROR_OK; } diff --git a/km_openssl/block_cipher_operation.cpp b/km_openssl/block_cipher_operation.cpp index 20bd2a6..91440ea 100644 --- a/km_openssl/block_cipher_operation.cpp +++ b/km_openssl/block_cipher_operation.cpp @@ -78,7 +78,7 @@ static keymaster_error_t GetAndValidateGcmTagLength(const AuthorizationSet& begi OperationPtr BlockCipherOperationFactory::CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) { + keymaster_error_t* error) const { *error = KM_ERROR_OK; keymaster_block_mode_t block_mode; if (!begin_params.GetTagValue(TAG_BLOCK_MODE, &block_mode)) { diff --git a/km_openssl/block_cipher_operation.h b/km_openssl/block_cipher_operation.h index 1da94eb..92f510e 100644 --- a/km_openssl/block_cipher_operation.h +++ b/km_openssl/block_cipher_operation.h @@ -52,7 +52,7 @@ class BlockCipherOperationFactory : public OperationFactory { } OperationPtr CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) override; + keymaster_error_t* error) const override; const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const override { return GetCipherDescription().SupportedBlockModes(block_mode_count); diff --git a/km_openssl/ecdsa_operation.cpp b/km_openssl/ecdsa_operation.cpp index 59ce624..cd9f1ce 100644 --- a/km_openssl/ecdsa_operation.cpp +++ b/km_openssl/ecdsa_operation.cpp @@ -29,7 +29,7 @@ static const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE, KM_D KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512}; OperationPtr EcdsaOperationFactory::CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) { + keymaster_error_t* error) const { const EcKey& ecdsa_key = static_cast<EcKey&>(key); UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new()); diff --git a/km_openssl/hmac_operation.cpp b/km_openssl/hmac_operation.cpp index 30edf36..46941dc 100644 --- a/km_openssl/hmac_operation.cpp +++ b/km_openssl/hmac_operation.cpp @@ -35,7 +35,7 @@ typedef int openssl_size_t; namespace keymaster { OperationPtr HmacOperationFactory::CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) { + keymaster_error_t* error) const { uint32_t min_mac_length_bits; if (!key.authorizations().GetTagValue(TAG_MIN_MAC_LENGTH, &min_mac_length_bits)) { LOG_E("HMAC key must have KM_TAG_MIN_MAC_LENGTH", 0); diff --git a/km_openssl/hmac_operation.h b/km_openssl/hmac_operation.h index e67af93..3485f70 100644 --- a/km_openssl/hmac_operation.h +++ b/km_openssl/hmac_operation.h @@ -56,7 +56,7 @@ class HmacOperationFactory : public OperationFactory { virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_HMAC, purpose()); } virtual OperationPtr CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error); + keymaster_error_t* error) const; virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const; diff --git a/km_openssl/rsa_operation.cpp b/km_openssl/rsa_operation.cpp index b8d1443..d2ceeb5 100644 --- a/km_openssl/rsa_operation.cpp +++ b/km_openssl/rsa_operation.cpp @@ -61,7 +61,7 @@ const keymaster_digest_t* RsaOperationFactory::SupportedDigests(size_t* digest_c RsaOperation* RsaOperationFactory::CreateRsaOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) { + keymaster_error_t* error) const { keymaster_padding_t padding; if (!GetAndValidatePadding(begin_params, key, &padding, error)) return nullptr; @@ -90,7 +90,7 @@ RsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) RsaOperation* RsaCryptingOperationFactory::CreateRsaOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) { + keymaster_error_t* error) const { UniquePtr<RsaOperation> op( RsaOperationFactory::CreateRsaOperation(move(key), begin_params, error)); if (op.get()) { diff --git a/legacy_support/ecdsa_keymaster1_operation.cpp b/legacy_support/ecdsa_keymaster1_operation.cpp index e3d2ace..f3cc4a2 100644 --- a/legacy_support/ecdsa_keymaster1_operation.cpp +++ b/legacy_support/ecdsa_keymaster1_operation.cpp @@ -97,7 +97,7 @@ static EVP_PKEY* GetEvpKey(const EcdsaKeymaster1Key& key, keymaster_error_t* err OperationPtr EcdsaKeymaster1OperationFactory::CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) { + keymaster_error_t* error) const { keymaster_digest_t digest; if (!GetAndValidateDigest(begin_params, key, &digest, error)) return nullptr; diff --git a/legacy_support/ecdsa_keymaster1_operation.h b/legacy_support/ecdsa_keymaster1_operation.h index a24cc2b..5867a55 100644 --- a/legacy_support/ecdsa_keymaster1_operation.h +++ b/legacy_support/ecdsa_keymaster1_operation.h @@ -108,7 +108,7 @@ class EcdsaKeymaster1OperationFactory : public OperationFactory { KeyType registry_key() const override { return KeyType(KM_ALGORITHM_EC, purpose_); } OperationPtr CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) override; + keymaster_error_t* error) const override; const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override; const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const override; diff --git a/legacy_support/keymaster_passthrough_operation.h b/legacy_support/keymaster_passthrough_operation.h index 29c0372..aadcc73 100644 --- a/legacy_support/keymaster_passthrough_operation.h +++ b/legacy_support/keymaster_passthrough_operation.h @@ -102,7 +102,7 @@ class KeymasterPassthroughOperationFactory : public OperationFactory { // Factory methods OperationPtr CreateOperation(Key&& key, const AuthorizationSet& /*begin_params*/, - keymaster_error_t* error) override { + keymaster_error_t* error) const override { if (!error) return nullptr; *error = KM_ERROR_OK; OperationPtr op(new (std::nothrow) KeymasterPassthroughOperation<KeymasterDeviceType>( diff --git a/legacy_support/rsa_keymaster1_operation.cpp b/legacy_support/rsa_keymaster1_operation.cpp index dd2c094..c313206 100644 --- a/legacy_support/rsa_keymaster1_operation.cpp +++ b/legacy_support/rsa_keymaster1_operation.cpp @@ -118,7 +118,7 @@ static EVP_PKEY* GetEvpKey(const RsaKeymaster1Key& key, keymaster_error_t* error OperationPtr RsaKeymaster1OperationFactory::CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) { + keymaster_error_t* error) const { keymaster_digest_t digest; if (!GetAndValidateDigest(begin_params, key, &digest, error)) return nullptr; diff --git a/legacy_support/rsa_keymaster1_operation.h b/legacy_support/rsa_keymaster1_operation.h index c0219ea..04d82c9 100644 --- a/legacy_support/rsa_keymaster1_operation.h +++ b/legacy_support/rsa_keymaster1_operation.h @@ -108,7 +108,7 @@ class RsaKeymaster1OperationFactory : public OperationFactory { KeyType registry_key() const override { return KeyType(KM_ALGORITHM_RSA, purpose_); } OperationPtr CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) override; + keymaster_error_t* error) const override; const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override; const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const override; |
