Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3d1023e5 authored by Matthew Maurer's avatar Matthew Maurer
Browse files

Inject auth token into tags

The reference keymaster at system/keymaster still expects to receive its
auth tokens in the tags, rather than as a separate parameter. This
change injects the separate parameter passed to the KM4 HAL as a legacy
tag in the request.

Longer term, system/keymaster should support a separate authToken
parameter, and it should be serialized and sent to Trusty separately.

Test: Keymaster VTS + Keystore CTS (sans attestation)
Change-Id: Ie69cbd358504bb7612f7d55158509043cdad4e4e
parent fc920dcb
Loading
Loading
Loading
Loading
+49 −6
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@

#define LOG_TAG "android.hardware.keymaster@4.0-impl.trusty"

#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
#include <authorization_set.h>
#include <cutils/log.h>
#include <keymaster/android_keymaster_messages.h>
@@ -46,6 +47,9 @@ using ::keymaster::UpdateOperationRequest;
using ::keymaster::UpdateOperationResponse;
using ::keymaster::ng::Tag;

typedef ::android::hardware::keymaster::V3_0::Tag Tag3;
using ::android::hardware::keymaster::V4_0::Constants;

namespace keymaster {
namespace V4_0 {
namespace {
@@ -79,6 +83,45 @@ inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) {
    return keymaster_tag_get_type(tag);
}

/*
 * injectAuthToken translates a KM4 authToken into a legacy AUTH_TOKEN tag
 *
 * Currently, system/keymaster's reference implementation only accepts this
 * method for passing an auth token, so until that changes we need to
 * translate to the old format.
 */
inline hidl_vec<KeyParameter> injectAuthToken(const hidl_vec<KeyParameter>& keyParamsBase,
                                              const HardwareAuthToken& authToken) {
    std::vector<KeyParameter> keyParams(keyParamsBase);
    const size_t mac_len = static_cast<size_t>(Constants::AUTH_TOKEN_MAC_LENGTH);
    /*
     * mac.size() == 0 indicates no token provided, so we should not copy.
     * mac.size() != mac_len means it is incompatible with the old
     *   hw_auth_token_t structure. This is forbidden by spec, but to be safe
     *   we only copy if mac.size() == mac_len, e.g. there is an authToken
     *   with a hw_auth_token_t compatible MAC.
     */
    if (authToken.mac.size() == mac_len) {
        KeyParameter p;
        p.tag = static_cast<Tag>(Tag3::AUTH_TOKEN);
        p.blob.resize(sizeof(hw_auth_token_t));

        hw_auth_token_t* auth_token = reinterpret_cast<hw_auth_token_t*>(p.blob.data());
        auth_token->version = 0;
        auth_token->challenge = authToken.challenge;
        auth_token->user_id = authToken.userId;
        auth_token->authenticator_id = authToken.authenticatorId;
        auth_token->authenticator_type =
                htobe32(static_cast<uint32_t>(authToken.authenticatorType));
        auth_token->timestamp = htobe64(authToken.timestamp);
        static_assert(mac_len == sizeof(auth_token->hmac));
        memcpy(auth_token->hmac, authToken.mac.data(), mac_len);
        keyParams.push_back(p);
    }

    return hidl_vec<KeyParameter>(std::move(keyParams));
}

class KmParamSet : public keymaster_key_param_set_t {
  public:
    KmParamSet(const hidl_vec<KeyParameter>& keyParams) {
@@ -472,11 +515,11 @@ Return<ErrorCode> TrustyKeymaster4Device::destroyAttestationIds() {
Return<void> TrustyKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
                                           const hidl_vec<KeyParameter>& inParams,
                                           const HardwareAuthToken& authToken, begin_cb _hidl_cb) {
    (void)authToken;
    hidl_vec<KeyParameter> extendedParams = injectAuthToken(inParams, authToken);
    BeginOperationRequest request;
    request.purpose = legacy_enum_conversion(purpose);
    request.SetKeyMaterial(key.data(), key.size());
    request.additional_params.Reinitialize(KmParamSet(inParams));
    request.additional_params.Reinitialize(KmParamSet(extendedParams));

    BeginOperationResponse response;
    impl_->BeginOperation(request, &response);
@@ -496,16 +539,16 @@ Return<void> TrustyKeymaster4Device::update(uint64_t operationHandle,
                                            const HardwareAuthToken& authToken,
                                            const VerificationToken& verificationToken,
                                            update_cb _hidl_cb) {
    (void)authToken;
    (void)verificationToken;
    UpdateOperationRequest request;
    UpdateOperationResponse response;
    hidl_vec<KeyParameter> resultParams;
    hidl_vec<uint8_t> resultBlob;
    hidl_vec<KeyParameter> extendedParams = injectAuthToken(inParams, authToken);
    uint32_t resultConsumed = 0;

    request.op_handle = operationHandle;
    request.additional_params.Reinitialize(KmParamSet(inParams));
    request.additional_params.Reinitialize(KmParamSet(extendedParams));

    size_t inp_size = input.size();
    size_t ser_size = request.SerializedSize();
@@ -537,13 +580,13 @@ Return<void> TrustyKeymaster4Device::finish(uint64_t operationHandle,
                                            const HardwareAuthToken& authToken,
                                            const VerificationToken& verificationToken,
                                            finish_cb _hidl_cb) {
    (void)authToken;
    (void)verificationToken;
    FinishOperationRequest request;
    hidl_vec<KeyParameter> extendedParams = injectAuthToken(inParams, authToken);
    request.op_handle = operationHandle;
    request.input.Reinitialize(input.data(), input.size());
    request.signature.Reinitialize(signature.data(), signature.size());
    request.additional_params.Reinitialize(KmParamSet(inParams));
    request.additional_params.Reinitialize(KmParamSet(extendedParams));

    FinishOperationResponse response;
    impl_->FinishOperation(request, &response);