blob: 60347b77818c51a02b6325bb45cce81b40d4004e [file] [log] [blame]
/*
* 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
*
******************************************************************************/
#pragma once
#include "CborConverter.h"
#include <ITransport.h>
#define APDU_CLS 0x80
//#define APDU_P1 0x50
#define APDU_P1 0x40
#define APDU_P2 0x00
#define APDU_RESP_STATUS_OK 0x9000
#define KEYMINT_CMD_APDU_START 0x20
namespace keymint::javacard {
using ndk::ScopedAStatus;
using std::optional;
using std::shared_ptr;
using std::vector;
enum class Instruction {
// Keymaster commands
INS_GENERATE_KEY_CMD = KEYMINT_CMD_APDU_START + 1,
INS_IMPORT_KEY_CMD = KEYMINT_CMD_APDU_START + 2,
INS_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 3,
INS_EXPORT_KEY_CMD = KEYMINT_CMD_APDU_START + 4,
INS_ATTEST_KEY_CMD = KEYMINT_CMD_APDU_START + 5,
INS_UPGRADE_KEY_CMD = KEYMINT_CMD_APDU_START + 6,
INS_DELETE_KEY_CMD = KEYMINT_CMD_APDU_START + 7,
INS_DELETE_ALL_KEYS_CMD = KEYMINT_CMD_APDU_START + 8,
INS_ADD_RNG_ENTROPY_CMD = KEYMINT_CMD_APDU_START + 9,
INS_COMPUTE_SHARED_SECRET_CMD = KEYMINT_CMD_APDU_START + 10,
INS_DESTROY_ATT_IDS_CMD = KEYMINT_CMD_APDU_START + 11,
INS_VERIFY_AUTHORIZATION_CMD = KEYMINT_CMD_APDU_START + 12,
INS_GET_SHARED_SECRET_PARAM_CMD = KEYMINT_CMD_APDU_START + 13,
INS_GET_KEY_CHARACTERISTICS_CMD = KEYMINT_CMD_APDU_START + 14,
INS_GET_HW_INFO_CMD = KEYMINT_CMD_APDU_START + 15,
INS_BEGIN_OPERATION_CMD = KEYMINT_CMD_APDU_START + 16,
INS_UPDATE_OPERATION_CMD = KEYMINT_CMD_APDU_START + 17,
INS_FINISH_OPERATION_CMD = KEYMINT_CMD_APDU_START + 18,
INS_ABORT_OPERATION_CMD = KEYMINT_CMD_APDU_START + 19,
INS_DEVICE_LOCKED_CMD = KEYMINT_CMD_APDU_START + 20,
INS_EARLY_BOOT_ENDED_CMD = KEYMINT_CMD_APDU_START + 21,
INS_GET_CERT_CHAIN_CMD = KEYMINT_CMD_APDU_START + 22,
INS_UPDATE_AAD_OPERATION_CMD = KEYMINT_CMD_APDU_START + 23,
INS_BEGIN_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 24,
INS_FINISH_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 25,
//INS_SET_BOOT_PARAMS_CMD = KEYMINT_CMD_APDU_START + 26,
INS_SET_BOOT_PARAMS_CMD = 9,
// RKP Commands
INS_GET_RKP_HARDWARE_INFO = KEYMINT_CMD_APDU_START + 27,
INS_GENERATE_RKP_KEY_CMD = KEYMINT_CMD_APDU_START + 28,
INS_BEGIN_SEND_DATA_CMD = KEYMINT_CMD_APDU_START + 29,
INS_UPDATE_KEY_CMD = KEYMINT_CMD_APDU_START + 30,
INS_UPDATE_EEK_CHAIN_CMD = KEYMINT_CMD_APDU_START + 31,
INS_UPDATE_CHALLENGE_CMD = KEYMINT_CMD_APDU_START + 32,
INS_FINISH_SEND_DATA_CMD = KEYMINT_CMD_APDU_START + 33,
INS_GET_RESPONSE_CMD = KEYMINT_CMD_APDU_START + 34,
INS_GET_ROT_CHALLENGE_CMD = KEYMINT_CMD_APDU_START + 45,
INS_GET_ROT_DATA_CMD = KEYMINT_CMD_APDU_START + 46,
INS_SEND_ROT_DATA_CMD = KEYMINT_CMD_APDU_START + 47,
};
class JavacardSecureElement {
public:
explicit JavacardSecureElement(shared_ptr<ITransport> transport, uint32_t osVersion,
uint32_t osPatchLevel, uint32_t vendorPatchLevel)
: transport_(transport), osVersion_(osVersion), osPatchLevel_(osPatchLevel),
vendorPatchLevel_(vendorPatchLevel) {
transport_->openConnection();
}
virtual ~JavacardSecureElement() { transport_->closeConnection(); }
std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins,
Array& request);
std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins);
std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins, std::vector<uint8_t>& command);
keymaster_error_t sendData(Instruction ins, std::vector<uint8_t>& inData,
std::vector<uint8_t>& response);
keymaster_error_t constructApduMessage(Instruction& ins, std::vector<uint8_t>& inputData,
std::vector<uint8_t>& apduOut);
keymaster_error_t initializeJavacard();
inline uint16_t getApduStatus(std::vector<uint8_t>& inputData) {
// Last two bytes are the status SW0SW1
uint8_t SW0 = inputData.at(inputData.size() - 2);
uint8_t SW1 = inputData.at(inputData.size() - 1);
return (SW0 << 8 | SW1);
}
shared_ptr<ITransport> transport_;
uint32_t osVersion_;
uint32_t osPatchLevel_;
uint32_t vendorPatchLevel_;
CborConverter cbor_;
};
} // namespace keymint::javacard