summaryrefslogtreecommitdiff
path: root/KM300/JavacardKeyMintOperation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'KM300/JavacardKeyMintOperation.cpp')
-rw-r--r--KM300/JavacardKeyMintOperation.cpp323
1 files changed, 0 insertions, 323 deletions
diff --git a/KM300/JavacardKeyMintOperation.cpp b/KM300/JavacardKeyMintOperation.cpp
deleted file mode 100644
index 0d8c9da..0000000
--- a/KM300/JavacardKeyMintOperation.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright 2020, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/******************************************************************************
- **
- ** The original Work has been changed by NXP.
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- **
- ** Copyright 2022 NXP
- **
- *********************************************************************************/
-#define LOG_TAG "javacard.strongbox.keymint.operation-impl"
-
-#include "JavacardKeyMintOperation.h"
-
-#include <KeyMintUtils.h>
-#include <aidl/android/hardware/security/keymint/ErrorCode.h>
-#include <aidl/android/hardware/security/secureclock/ISecureClock.h>
-#include <android-base/logging.h>
-
-#include "CborConverter.h"
-
-namespace aidl::android::hardware::security::keymint {
-using cppbor::Bstr;
-using cppbor::Uint;
-using secureclock::TimeStampToken;
-
-JavacardKeyMintOperation::~JavacardKeyMintOperation() {
- if (opHandle_ != 0) {
- JavacardKeyMintOperation::abort();
- }
-}
-
-ScopedAStatus JavacardKeyMintOperation::updateAad(const vector<uint8_t>& input,
- const optional<HardwareAuthToken>& authToken,
- const optional<TimeStampToken>& timestampToken) {
- cppbor::Array request;
- request.add(Uint(opHandle_));
- request.add(Bstr(input));
- cbor_.addHardwareAuthToken(request, authToken.value_or(HardwareAuthToken()));
- cbor_.addTimeStampToken(request, timestampToken.value_or(TimeStampToken()));
- auto [item, err] = card_->sendRequest(Instruction::INS_UPDATE_AAD_OPERATION_CMD, request);
- if (err != KM_ERROR_OK) {
- return km_utils::kmError2ScopedAStatus(err);
- }
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus JavacardKeyMintOperation::update(const vector<uint8_t>& input,
- const optional<HardwareAuthToken>& authToken,
- const optional<TimeStampToken>& timestampToken,
- vector<uint8_t>* output) {
- HardwareAuthToken aToken = authToken.value_or(HardwareAuthToken());
- TimeStampToken tToken = timestampToken.value_or(TimeStampToken());
- DataView view = {.buffer = {}, .data = input, .start = 0, .length = input.size()};
- keymaster_error_t err = bufferData(view);
- if (err != KM_ERROR_OK) {
- return km_utils::kmError2ScopedAStatus(err);
- }
- if (!(bufferingMode_ == BufferingMode::EC_NO_DIGEST ||
- bufferingMode_ == BufferingMode::RSA_DECRYPT_OR_NO_DIGEST)) {
- if (view.length > MAX_CHUNK_SIZE) {
- err = updateInChunks(view, aToken, tToken, output);
- if (err != KM_ERROR_OK) {
- return km_utils::kmError2ScopedAStatus(err);
- }
- }
- vector<uint8_t> remaining = popNextChunk(view, view.length);
- err = sendUpdate(remaining, aToken, tToken, *output);
- }
- return km_utils::kmError2ScopedAStatus(err);
-}
-
-ScopedAStatus JavacardKeyMintOperation::finish(const optional<vector<uint8_t>>& input,
- const optional<vector<uint8_t>>& signature,
- const optional<HardwareAuthToken>& authToken,
- const optional<TimeStampToken>& timestampToken,
- const optional<vector<uint8_t>>& confirmationToken,
- vector<uint8_t>* output) {
- HardwareAuthToken aToken = authToken.value_or(HardwareAuthToken());
- TimeStampToken tToken = timestampToken.value_or(TimeStampToken());
- const vector<uint8_t> confToken = confirmationToken.value_or(vector<uint8_t>());
- const vector<uint8_t> inData = input.value_or(vector<uint8_t>());
- DataView view = {.buffer = {}, .data = inData, .start = 0, .length = inData.size()};
- const vector<uint8_t> sign = signature.value_or(vector<uint8_t>());
- if (!(bufferingMode_ == BufferingMode::EC_NO_DIGEST ||
- bufferingMode_ == BufferingMode::RSA_DECRYPT_OR_NO_DIGEST)) {
- appendBufferedData(view);
- if (view.length > MAX_CHUNK_SIZE) {
- auto err = updateInChunks(view, aToken, tToken, output);
- if (err != KM_ERROR_OK) {
- return km_utils::kmError2ScopedAStatus(err);
- }
- }
- } else {
- keymaster_error_t err = bufferData(view);
- if (err != KM_ERROR_OK) {
- return km_utils::kmError2ScopedAStatus(err);
- }
- appendBufferedData(view);
- }
- vector<uint8_t> remaining = popNextChunk(view, view.length);
- return km_utils::kmError2ScopedAStatus(
- sendFinish(remaining, sign, aToken, tToken, confToken, *output));
-}
-
-ScopedAStatus JavacardKeyMintOperation::abort() {
- Array request;
- request.add(Uint(opHandle_));
- auto [item, err] = card_->sendRequest(Instruction::INS_ABORT_OPERATION_CMD, request);
- opHandle_ = 0;
- buffer_.clear();
- return km_utils::kmError2ScopedAStatus(err);
-}
-
-void JavacardKeyMintOperation::blockAlign(DataView& view, uint16_t blockSize) {
- appendBufferedData(view);
- uint16_t offset = getDataViewOffset(view, blockSize);
- if (view.buffer.empty() && view.data.empty()) {
- offset = 0;
- } else if (view.buffer.empty()) {
- buffer_.insert(buffer_.end(), view.data.begin() + offset, view.data.end());
- } else if (view.data.empty()) {
- buffer_.insert(buffer_.end(), view.buffer.begin() + offset, view.buffer.end());
- } else {
- if (offset < view.buffer.size()) {
- buffer_.insert(buffer_.end(), view.buffer.begin() + offset, view.buffer.end());
- buffer_.insert(buffer_.end(), view.data.begin(), view.data.end());
- } else {
- offset = offset - view.buffer.size();
- buffer_.insert(buffer_.end(), view.data.begin() + offset, view.data.end());
- }
- }
- // adjust the view length by removing the buffered data size from it.
- view.length = view.length - buffer_.size();
-}
-
-uint16_t JavacardKeyMintOperation::getDataViewOffset(DataView& view, uint16_t blockSize) {
- uint16_t offset = 0;
- uint16_t remaining = 0;
- switch (bufferingMode_) {
- case BufferingMode::BUF_DES_DECRYPT_PKCS7_BLOCK_ALIGNED:
- case BufferingMode::BUF_AES_DECRYPT_PKCS7_BLOCK_ALIGNED:
- offset = ((view.length / blockSize)) * blockSize;
- remaining = (view.length % blockSize);
- if (offset >= blockSize && remaining == 0) {
- offset -= blockSize;
- }
- break;
- case BufferingMode::BUF_DES_ENCRYPT_PKCS7_BLOCK_ALIGNED:
- case BufferingMode::BUF_AES_ENCRYPT_PKCS7_BLOCK_ALIGNED:
- offset = ((view.length / blockSize)) * blockSize;
- break;
- case BufferingMode::BUF_AES_GCM_DECRYPT_BLOCK_ALIGNED:
- if (view.length > macLength_) {
- offset = (view.length - macLength_);
- }
- break;
- default:
- break;
- }
- return offset;
-}
-
-keymaster_error_t JavacardKeyMintOperation::bufferData(DataView& view) {
- if (view.data.empty()) return KM_ERROR_OK; // nothing to buffer
- switch (bufferingMode_) {
- case BufferingMode::RSA_DECRYPT_OR_NO_DIGEST:
- buffer_.insert(buffer_.end(), view.data.begin(), view.data.end());
- if (buffer_.size() > RSA_BUFFER_SIZE) {
- abort();
- return KM_ERROR_INVALID_INPUT_LENGTH;
- }
- view.start = 0;
- view.length = 0;
- break;
- case BufferingMode::EC_NO_DIGEST:
- if (buffer_.size() < EC_BUFFER_SIZE) {
- buffer_.insert(buffer_.end(), view.data.begin(), view.data.end());
- // Truncate the buffered data if greater than allowed EC buffer size.
- if (buffer_.size() > EC_BUFFER_SIZE) {
- buffer_.erase(buffer_.begin() + EC_BUFFER_SIZE, buffer_.end());
- }
- }
- view.start = 0;
- view.length = 0;
- break;
- case BufferingMode::BUF_AES_ENCRYPT_PKCS7_BLOCK_ALIGNED:
- case BufferingMode::BUF_AES_DECRYPT_PKCS7_BLOCK_ALIGNED:
- blockAlign(view, AES_BLOCK_SIZE);
- break;
- case BufferingMode::BUF_AES_GCM_DECRYPT_BLOCK_ALIGNED:
- blockAlign(view, macLength_);
- break;
- case BufferingMode::BUF_DES_ENCRYPT_PKCS7_BLOCK_ALIGNED:
- case BufferingMode::BUF_DES_DECRYPT_PKCS7_BLOCK_ALIGNED:
- blockAlign(view, DES_BLOCK_SIZE);
- break;
- case BufferingMode::NONE:
- break;
- }
- return KM_ERROR_OK;
-}
-
-// Incrementally send the request using multiple updates.
-keymaster_error_t JavacardKeyMintOperation::updateInChunks(DataView& view,
- HardwareAuthToken& authToken,
- TimeStampToken& timestampToken,
- vector<uint8_t>* output) {
- keymaster_error_t sendError = KM_ERROR_UNKNOWN_ERROR;
- while (view.length > MAX_CHUNK_SIZE) {
- vector<uint8_t> chunk = popNextChunk(view, MAX_CHUNK_SIZE);
- sendError = sendUpdate(chunk, authToken, timestampToken, *output);
- if (sendError != KM_ERROR_OK) {
- return sendError;
- }
- // Clear tokens
- if (!authToken.mac.empty()) authToken = HardwareAuthToken();
- if (!timestampToken.mac.empty()) timestampToken = TimeStampToken();
- }
- return KM_ERROR_OK;
-}
-
-vector<uint8_t> JavacardKeyMintOperation::popNextChunk(DataView& view, uint32_t chunkSize) {
- uint32_t start = view.start;
- uint32_t end = start + ((view.length < chunkSize) ? view.length : chunkSize);
- vector<uint8_t> chunk;
- if (start < view.buffer.size()) {
- if (end < view.buffer.size()) {
- chunk = {view.buffer.begin() + start, view.buffer.begin() + end};
- } else {
- end = end - view.buffer.size();
- chunk = {view.buffer.begin() + start, view.buffer.end()};
- chunk.insert(chunk.end(), view.data.begin(), view.data.begin() + end);
- }
- } else {
- start = start - view.buffer.size();
- end = end - view.buffer.size();
- chunk = {view.data.begin() + start, view.data.begin() + end};
- }
- view.start = view.start + chunk.size();
- view.length = view.length - chunk.size();
- return chunk;
-}
-
-keymaster_error_t JavacardKeyMintOperation::sendUpdate(const vector<uint8_t>& input,
- const HardwareAuthToken& authToken,
- const TimeStampToken& timestampToken,
- vector<uint8_t>& output) {
- if (input.empty()) {
- return KM_ERROR_OK;
- }
- cppbor::Array request;
- request.add(Uint(opHandle_));
- request.add(Bstr(input));
- cbor_.addHardwareAuthToken(request, authToken);
- cbor_.addTimeStampToken(request, timestampToken);
- auto [item, error] = card_->sendRequest(Instruction::INS_UPDATE_OPERATION_CMD, request);
- if (error != KM_ERROR_OK) {
- return error;
- }
- auto optTemp = cbor_.getByteArrayVec(item, 1);
- if (!optTemp) {
- return KM_ERROR_UNKNOWN_ERROR;
- }
- output.insert(output.end(), optTemp.value().begin(), optTemp.value().end());
- return KM_ERROR_OK;
-}
-
-keymaster_error_t JavacardKeyMintOperation::sendFinish(const vector<uint8_t>& data,
- const vector<uint8_t>& sign,
- const HardwareAuthToken& authToken,
- const TimeStampToken& timestampToken,
- const vector<uint8_t>& confToken,
- vector<uint8_t>& output) {
- cppbor::Array request;
- request.add(Uint(opHandle_));
- request.add(Bstr(data));
- request.add(Bstr(sign));
- cbor_.addHardwareAuthToken(request, authToken);
- cbor_.addTimeStampToken(request, timestampToken);
- request.add(Bstr(confToken));
-
- auto [item, err] = card_->sendRequest(Instruction::INS_FINISH_OPERATION_CMD, request);
- if (err != KM_ERROR_OK) {
- return err;
- }
- auto optTemp = cbor_.getByteArrayVec(item, 1);
- if (!optTemp) {
- return KM_ERROR_UNKNOWN_ERROR;
- }
- opHandle_ = 0;
- output.insert(output.end(), optTemp.value().begin(), optTemp.value().end());
-#ifdef NXP_EXTNS
- LOG(INFO) << "(finish) completed Successfully";
-#endif
- return KM_ERROR_OK;
-}
-
-} // namespace aidl::android::hardware::security::keymint