/* * 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-2023 NXP * ******************************************************************************/ #pragma once #include #include "CborConverter.h" #define APDU_CLS 0x80 //#define APDU_P1 0x50 #define APDU_P1 0x60 #define APDU_P2 0x00 #define APDU_RESP_STATUS_OK 0x9000 #define KEYMINT_CMD_APDU_START 0x20 #define KEYMINT_VENDOR_CMD_APDU_START 0xD0 namespace keymint::javacard { 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_INIT_STRONGBOX_CMD = KEYMINT_CMD_APDU_START + 26, INS_INIT_STRONGBOX_CMD = KEYMINT_VENDOR_CMD_APDU_START + 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_UDS_CERTS_CMD = KEYMINT_CMD_APDU_START + 35, INS_GET_DICE_CERT_CHAIN_CMD = KEYMINT_CMD_APDU_START + 36, // SE ROT Commands 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 transport) : transport_(std::move(transport)), isEarlyBootEndedPending(false), isDeleteAllKeysPending(false) { transport_->openConnection(); } virtual ~JavacardSecureElement() { transport_->closeConnection(); } std::tuple, keymaster_error_t> sendRequest(Instruction ins, Array& request); std::tuple, keymaster_error_t> sendRequest(Instruction ins); std::tuple, keymaster_error_t> sendRequest(Instruction ins, std::vector& command); keymaster_error_t sendData(Instruction ins, std::vector& inData, std::vector& response); keymaster_error_t constructApduMessage(Instruction& ins, std::vector& inputData, std::vector& apduOut); keymaster_error_t initializeJavacard(); void sendPendingEvents(); void setEarlyBootEndedPending(); void setDeleteAllKeysPending(); inline uint16_t getApduStatus(std::vector& 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); } private: shared_ptr transport_; bool isEarlyBootEndedPending; bool isDeleteAllKeysPending; CborConverter cbor_; }; } // namespace keymint::javacard