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 * 18 * The original Work has been changed by NXP. 19 * 20 * Licensed under the Apache License, Version 2.0 (the "License"); 21 * you may not use this file except in compliance with the License. 22 * You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 * 32 * Copyright 2022-2023 NXP 33 * 34 ******************************************************************************/ 35 #pragma once 36 37 #include <ITransport.h> 38 #include "CborConverter.h" 39 40 #define APDU_CLS 0x80 41 //#define APDU_P1 0x50 42 #define APDU_P1 0x60 43 #define APDU_P2 0x00 44 #define APDU_RESP_STATUS_OK 0x9000 45 46 #define KEYMINT_CMD_APDU_START 0x20 47 48 #define KEYMINT_VENDOR_CMD_APDU_START 0xD0 49 50 namespace keymint::javacard { 51 using std::shared_ptr; 52 using std::vector; 53 54 enum class Instruction { 55 // Keymaster commands 56 INS_GENERATE_KEY_CMD = KEYMINT_CMD_APDU_START + 1, 57 INS_IMPORT_KEY_CMD = KEYMINT_CMD_APDU_START + 2, 58 INS_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 3, 59 INS_EXPORT_KEY_CMD = KEYMINT_CMD_APDU_START + 4, 60 INS_ATTEST_KEY_CMD = KEYMINT_CMD_APDU_START + 5, 61 INS_UPGRADE_KEY_CMD = KEYMINT_CMD_APDU_START + 6, 62 INS_DELETE_KEY_CMD = KEYMINT_CMD_APDU_START + 7, 63 INS_DELETE_ALL_KEYS_CMD = KEYMINT_CMD_APDU_START + 8, 64 INS_ADD_RNG_ENTROPY_CMD = KEYMINT_CMD_APDU_START + 9, 65 INS_COMPUTE_SHARED_SECRET_CMD = KEYMINT_CMD_APDU_START + 10, 66 INS_DESTROY_ATT_IDS_CMD = KEYMINT_CMD_APDU_START + 11, 67 INS_VERIFY_AUTHORIZATION_CMD = KEYMINT_CMD_APDU_START + 12, 68 INS_GET_SHARED_SECRET_PARAM_CMD = KEYMINT_CMD_APDU_START + 13, 69 INS_GET_KEY_CHARACTERISTICS_CMD = KEYMINT_CMD_APDU_START + 14, 70 INS_GET_HW_INFO_CMD = KEYMINT_CMD_APDU_START + 15, 71 INS_BEGIN_OPERATION_CMD = KEYMINT_CMD_APDU_START + 16, 72 INS_UPDATE_OPERATION_CMD = KEYMINT_CMD_APDU_START + 17, 73 INS_FINISH_OPERATION_CMD = KEYMINT_CMD_APDU_START + 18, 74 INS_ABORT_OPERATION_CMD = KEYMINT_CMD_APDU_START + 19, 75 INS_DEVICE_LOCKED_CMD = KEYMINT_CMD_APDU_START + 20, 76 INS_EARLY_BOOT_ENDED_CMD = KEYMINT_CMD_APDU_START + 21, 77 INS_GET_CERT_CHAIN_CMD = KEYMINT_CMD_APDU_START + 22, 78 INS_UPDATE_AAD_OPERATION_CMD = KEYMINT_CMD_APDU_START + 23, 79 INS_BEGIN_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 24, 80 INS_FINISH_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 25, 81 //INS_INIT_STRONGBOX_CMD = KEYMINT_CMD_APDU_START + 26, 82 INS_INIT_STRONGBOX_CMD = KEYMINT_VENDOR_CMD_APDU_START + 9, 83 // RKP Commands 84 INS_GET_RKP_HARDWARE_INFO = KEYMINT_CMD_APDU_START + 27, 85 INS_GENERATE_RKP_KEY_CMD = KEYMINT_CMD_APDU_START + 28, 86 INS_BEGIN_SEND_DATA_CMD = KEYMINT_CMD_APDU_START + 29, 87 INS_UPDATE_KEY_CMD = KEYMINT_CMD_APDU_START + 30, 88 INS_UPDATE_EEK_CHAIN_CMD = KEYMINT_CMD_APDU_START + 31, 89 INS_UPDATE_CHALLENGE_CMD = KEYMINT_CMD_APDU_START + 32, 90 INS_FINISH_SEND_DATA_CMD = KEYMINT_CMD_APDU_START + 33, 91 INS_GET_RESPONSE_CMD = KEYMINT_CMD_APDU_START + 34, 92 INS_GET_UDS_CERTS_CMD = KEYMINT_CMD_APDU_START + 35, 93 INS_GET_DICE_CERT_CHAIN_CMD = KEYMINT_CMD_APDU_START + 36, 94 // SE ROT Commands 95 INS_GET_ROT_CHALLENGE_CMD = KEYMINT_CMD_APDU_START + 45, 96 INS_GET_ROT_DATA_CMD = KEYMINT_CMD_APDU_START + 46, 97 INS_SEND_ROT_DATA_CMD = KEYMINT_CMD_APDU_START + 47, 98 }; 99 100 class JavacardSecureElement { 101 public: JavacardSecureElement(shared_ptr<ITransport> transport)102 explicit JavacardSecureElement(shared_ptr<ITransport> transport) 103 : transport_(std::move(transport)), isEarlyBootEndedPending(false), 104 isDeleteAllKeysPending(false) { 105 transport_->openConnection(); 106 } ~JavacardSecureElement()107 virtual ~JavacardSecureElement() { transport_->closeConnection(); } 108 109 std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins, 110 Array& request); 111 std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins); 112 std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins, 113 std::vector<uint8_t>& command); 114 115 keymaster_error_t sendData(Instruction ins, std::vector<uint8_t>& inData, 116 std::vector<uint8_t>& response); 117 118 keymaster_error_t constructApduMessage(Instruction& ins, std::vector<uint8_t>& inputData, 119 std::vector<uint8_t>& apduOut); 120 keymaster_error_t initializeJavacard(); 121 void sendPendingEvents(); 122 void setEarlyBootEndedPending(); 123 void setDeleteAllKeysPending(); 124 getApduStatus(std::vector<uint8_t> & inputData)125 inline uint16_t getApduStatus(std::vector<uint8_t>& inputData) { 126 // Last two bytes are the status SW0SW1 127 uint8_t SW0 = inputData.at(inputData.size() - 2); 128 uint8_t SW1 = inputData.at(inputData.size() - 1); 129 return (SW0 << 8 | SW1); 130 } 131 132 private: 133 shared_ptr<ITransport> transport_; 134 bool isEarlyBootEndedPending; 135 bool isDeleteAllKeysPending; 136 CborConverter cbor_; 137 }; 138 } // namespace keymint::javacard 139