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> &,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 
59     UpdateOperationResponse response(impl_->message_version());
60     impl_->UpdateOperation(request, &response);
61 
62     return kmError2ScopedAStatus(response.error);
63 }
64 
update(const vector<uint8_t> & input,const optional<HardwareAuthToken> &,const optional<TimeStampToken> &,vector<uint8_t> * output)65 ScopedAStatus AndroidKeyMintOperation::update(const vector<uint8_t>& input,
66                                               const optional<HardwareAuthToken>& /* authToken */,
67                                               const optional<TimeStampToken>&
68                                               /* timestampToken */,
69                                               vector<uint8_t>* output) {
70     if (!output) return kmError2ScopedAStatus(KM_ERROR_OUTPUT_PARAMETER_NULL);
71 
72     UpdateOperationRequest request(impl_->message_version());
73     request.op_handle = opHandle_;
74     request.input.Reinitialize(input.data(), input.size());
75 
76     UpdateOperationResponse response(impl_->message_version());
77     impl_->UpdateOperation(request, &response);
78 
79     if (response.error != KM_ERROR_OK) return kmError2ScopedAStatus(response.error);
80     if (response.input_consumed != request.input.buffer_size()) {
81         return kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
82     }
83 
84     *output = kmBuffer2vector(response.output);
85     return ScopedAStatus::ok();
86 }
87 
88 ScopedAStatus
finish(const optional<vector<uint8_t>> & input,const optional<vector<uint8_t>> & signature,const optional<HardwareAuthToken> &,const optional<TimeStampToken> &,const optional<vector<uint8_t>> &,vector<uint8_t> * output)89 AndroidKeyMintOperation::finish(const optional<vector<uint8_t>>& input,      //
90                                 const optional<vector<uint8_t>>& signature,  //
91                                 const optional<HardwareAuthToken>& /* authToken */,
92                                 const optional<TimeStampToken>& /* timestampToken */,
93                                 const optional<vector<uint8_t>>& /* confirmationToken */,
94                                 vector<uint8_t>* output) {
95 
96     if (!output) {
97         return ScopedAStatus(AStatus_fromServiceSpecificError(
98             static_cast<int32_t>(ErrorCode::OUTPUT_PARAMETER_NULL)));
99     }
100 
101     FinishOperationRequest request(impl_->message_version());
102     request.op_handle = opHandle_;
103     if (input) request.input.Reinitialize(input->data(), input->size());
104     if (signature) request.signature.Reinitialize(signature->data(), signature->size());
105 
106     FinishOperationResponse response(impl_->message_version());
107     impl_->FinishOperation(request, &response);
108     opHandle_ = 0;
109 
110     if (response.error != KM_ERROR_OK) return kmError2ScopedAStatus(response.error);
111 
112     *output = kmBuffer2vector(response.output);
113     return ScopedAStatus::ok();
114 }
115 
abort()116 ScopedAStatus AndroidKeyMintOperation::abort() {
117     AbortOperationRequest request(impl_->message_version());
118     request.op_handle = opHandle_;
119 
120     AbortOperationResponse response(impl_->message_version());
121     impl_->AbortOperation(request, &response);
122     opHandle_ = 0;
123 
124     return kmError2ScopedAStatus(response.error);
125 }
126 
127 }  // namespace aidl::android::hardware::security::keymint
128