1 /*
2  * Copyright 2020, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "android.hardware.security.keymint-impl"
18 #include <log/log.h>
19 
20 #include "AndroidKeyMintOperation.h"
21 
22 #include <aidl/android/hardware/security/keymint/ErrorCode.h>
23 #include <aidl/android/hardware/security/secureclock/ISecureClock.h>
24 
25 #include <keymaster/android_keymaster.h>
26 
27 #include "KeyMintUtils.h"
28 
29 namespace aidl::android::hardware::security::keymint {
30 
31 using ::keymaster::AbortOperationRequest;
32 using ::keymaster::AbortOperationResponse;
33 using ::keymaster::FinishOperationRequest;
34 using ::keymaster::FinishOperationResponse;
35 using ::keymaster::TAG_ASSOCIATED_DATA;
36 using ::keymaster::UpdateOperationRequest;
37 using ::keymaster::UpdateOperationResponse;
38 using secureclock::TimeStampToken;
39 using namespace km_utils;  // NOLINT(google-build-using-namespace)
40 
AndroidKeyMintOperation(shared_ptr<::keymaster::AndroidKeymaster> implementation,keymaster_operation_handle_t opHandle)41 AndroidKeyMintOperation::AndroidKeyMintOperation(
42     shared_ptr<::keymaster::AndroidKeymaster> implementation, keymaster_operation_handle_t opHandle)
43     : impl_(std::move(implementation)), opHandle_(opHandle) {}
44 
~AndroidKeyMintOperation()45 AndroidKeyMintOperation::~AndroidKeyMintOperation() {
46     if (opHandle_ != 0) {
47         abort();
48     }
49 }
50 
51 ScopedAStatus
updateAad(const vector<uint8_t> & input,const optional<HardwareAuthToken> & authToken,const optional<TimeStampToken> &)52 AndroidKeyMintOperation::updateAad(const vector<uint8_t>& input,
53                                    const optional<HardwareAuthToken>& authToken,
54                                    const optional<TimeStampToken>& /* timestampToken */) {
55     UpdateOperationRequest request(impl_->message_version());
56     request.op_handle = opHandle_;
57     request.additional_params.push_back(TAG_ASSOCIATED_DATA, input.data(), input.size());
58     if (authToken) {
59         auto tokenAsVec(authToken2AidlVec(*authToken));
60         request.additional_params.push_back(keymaster::TAG_AUTH_TOKEN, tokenAsVec.data(),
61                                             tokenAsVec.size());
62     }
63 
64     UpdateOperationResponse response(impl_->message_version());
65     impl_->UpdateOperation(request, &response);
66 
67     return kmError2ScopedAStatus(response.error);
68 }
69 
update(const vector<uint8_t> & input,const optional<HardwareAuthToken> & authToken,const optional<TimeStampToken> &,vector<uint8_t> * output)70 ScopedAStatus AndroidKeyMintOperation::update(const vector<uint8_t>& input,
71                                               const optional<HardwareAuthToken>& authToken,
72                                               const optional<TimeStampToken>&
73                                               /* timestampToken */,
74                                               vector<uint8_t>* output) {
75     if (!output) return kmError2ScopedAStatus(KM_ERROR_OUTPUT_PARAMETER_NULL);
76 
77     UpdateOperationRequest request(impl_->message_version());
78     request.op_handle = opHandle_;
79     request.input.Reinitialize(input.data(), input.size());
80     if (authToken) {
81         auto tokenAsVec(authToken2AidlVec(*authToken));
82         request.additional_params.push_back(keymaster::TAG_AUTH_TOKEN, tokenAsVec.data(),
83                                             tokenAsVec.size());
84     }
85 
86     UpdateOperationResponse response(impl_->message_version());
87     impl_->UpdateOperation(request, &response);
88 
89     if (response.error != KM_ERROR_OK) return kmError2ScopedAStatus(response.error);
90     if (response.input_consumed != request.input.buffer_size()) {
91         return kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
92     }
93 
94     *output = kmBuffer2vector(response.output);
95     return ScopedAStatus::ok();
96 }
97 
98 ScopedAStatus
finish(const optional<vector<uint8_t>> & input,const optional<vector<uint8_t>> & signature,const optional<HardwareAuthToken> & authToken,const optional<TimeStampToken> &,const optional<vector<uint8_t>> &,vector<uint8_t> * output)99 AndroidKeyMintOperation::finish(const optional<vector<uint8_t>>& input,      //
100                                 const optional<vector<uint8_t>>& signature,  //
101                                 const optional<HardwareAuthToken>& authToken,
102                                 const optional<TimeStampToken>& /* timestampToken */,
103                                 const optional<vector<uint8_t>>& /* confirmationToken */,
104                                 vector<uint8_t>* output) {
105 
106     if (!output) {
107         return ScopedAStatus(AStatus_fromServiceSpecificError(
108             static_cast<int32_t>(ErrorCode::OUTPUT_PARAMETER_NULL)));
109     }
110 
111     FinishOperationRequest request(impl_->message_version());
112     request.op_handle = opHandle_;
113     if (input) request.input.Reinitialize(input->data(), input->size());
114     if (signature) request.signature.Reinitialize(signature->data(), signature->size());
115     if (authToken) {
116         auto tokenAsVec(authToken2AidlVec(*authToken));
117         request.additional_params.push_back(keymaster::TAG_AUTH_TOKEN, tokenAsVec.data(),
118                                             tokenAsVec.size());
119     }
120 
121     FinishOperationResponse response(impl_->message_version());
122     impl_->FinishOperation(request, &response);
123     opHandle_ = 0;
124 
125     if (response.error != KM_ERROR_OK) return kmError2ScopedAStatus(response.error);
126 
127     *output = kmBuffer2vector(response.output);
128     return ScopedAStatus::ok();
129 }
130 
abort()131 ScopedAStatus AndroidKeyMintOperation::abort() {
132     AbortOperationRequest request(impl_->message_version());
133     request.op_handle = opHandle_;
134 
135     AbortOperationResponse response(impl_->message_version());
136     impl_->AbortOperation(request, &response);
137     opHandle_ = 0;
138 
139     return kmError2ScopedAStatus(response.error);
140 }
141 
142 }  // namespace aidl::android::hardware::security::keymint
143