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-2024 NXP 33 * 34 ******************************************************************************/ 35 #pragma once 36 37 #include "CborConverter.h" 38 #include <ITransport.h> 39 40 #define APDU_CLS 0x80 41 // #define APDU_P1 0x50 42 #define APDU_P1 0x40 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 ndk::ScopedAStatus; 52 using std::optional; 53 using std::shared_ptr; 54 using std::vector; 55 56 enum class Instruction { 57 // Keymaster commands 58 INS_GENERATE_KEY_CMD = KEYMINT_CMD_APDU_START + 1, 59 INS_IMPORT_KEY_CMD = KEYMINT_CMD_APDU_START + 2, 60 INS_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 3, 61 INS_EXPORT_KEY_CMD = KEYMINT_CMD_APDU_START + 4, 62 INS_ATTEST_KEY_CMD = KEYMINT_CMD_APDU_START + 5, 63 INS_UPGRADE_KEY_CMD = KEYMINT_CMD_APDU_START + 6, 64 INS_DELETE_KEY_CMD = KEYMINT_CMD_APDU_START + 7, 65 INS_DELETE_ALL_KEYS_CMD = KEYMINT_CMD_APDU_START + 8, 66 INS_ADD_RNG_ENTROPY_CMD = KEYMINT_CMD_APDU_START + 9, 67 INS_COMPUTE_SHARED_SECRET_CMD = KEYMINT_CMD_APDU_START + 10, 68 INS_DESTROY_ATT_IDS_CMD = KEYMINT_CMD_APDU_START + 11, 69 INS_VERIFY_AUTHORIZATION_CMD = KEYMINT_CMD_APDU_START + 12, 70 INS_GET_SHARED_SECRET_PARAM_CMD = KEYMINT_CMD_APDU_START + 13, 71 INS_GET_KEY_CHARACTERISTICS_CMD = KEYMINT_CMD_APDU_START + 14, 72 INS_GET_HW_INFO_CMD = KEYMINT_CMD_APDU_START + 15, 73 INS_BEGIN_OPERATION_CMD = KEYMINT_CMD_APDU_START + 16, 74 INS_UPDATE_OPERATION_CMD = KEYMINT_CMD_APDU_START + 17, 75 INS_FINISH_OPERATION_CMD = KEYMINT_CMD_APDU_START + 18, 76 INS_ABORT_OPERATION_CMD = KEYMINT_CMD_APDU_START + 19, 77 INS_DEVICE_LOCKED_CMD = KEYMINT_CMD_APDU_START + 20, 78 INS_EARLY_BOOT_ENDED_CMD = KEYMINT_CMD_APDU_START + 21, 79 INS_GET_CERT_CHAIN_CMD = KEYMINT_CMD_APDU_START + 22, 80 INS_UPDATE_AAD_OPERATION_CMD = KEYMINT_CMD_APDU_START + 23, 81 INS_BEGIN_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 24, 82 INS_FINISH_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 25, 83 //INS_SET_BOOT_PARAMS_CMD = KEYMINT_CMD_APDU_START + 26, 84 INS_SET_BOOT_PARAMS_CMD = KEYMINT_VENDOR_CMD_APDU_START + 9, 85 // RKP Commands 86 INS_GET_RKP_HARDWARE_INFO = KEYMINT_CMD_APDU_START + 27, 87 INS_GENERATE_RKP_KEY_CMD = KEYMINT_CMD_APDU_START + 28, 88 INS_BEGIN_SEND_DATA_CMD = KEYMINT_CMD_APDU_START + 29, 89 INS_UPDATE_KEY_CMD = KEYMINT_CMD_APDU_START + 30, 90 INS_UPDATE_EEK_CHAIN_CMD = KEYMINT_CMD_APDU_START + 31, 91 INS_UPDATE_CHALLENGE_CMD = KEYMINT_CMD_APDU_START + 32, 92 INS_FINISH_SEND_DATA_CMD = KEYMINT_CMD_APDU_START + 33, 93 INS_GET_RESPONSE_CMD = KEYMINT_CMD_APDU_START + 34, 94 INS_GET_ROT_CHALLENGE_CMD = KEYMINT_CMD_APDU_START + 45, 95 INS_GET_ROT_DATA_CMD = KEYMINT_CMD_APDU_START + 46, 96 INS_SEND_ROT_DATA_CMD = KEYMINT_CMD_APDU_START + 47, 97 }; 98 99 #ifdef NXP_EXTNS 100 enum CryptoOperationState { STARTED = 0, FINISHED }; 101 #endif 102 103 class JavacardSecureElement { 104 public: JavacardSecureElement(shared_ptr<ITransport> transport,uint32_t osVersion,uint32_t osPatchLevel,uint32_t vendorPatchLevel)105 explicit JavacardSecureElement(shared_ptr<ITransport> transport, 106 uint32_t osVersion, uint32_t osPatchLevel, 107 uint32_t vendorPatchLevel) 108 : transport_(std::move(transport)), osVersion_(osVersion), 109 osPatchLevel_(osPatchLevel), vendorPatchLevel_(vendorPatchLevel), 110 isCardInitialized_(false) { 111 transport_->openConnection(); 112 } ~JavacardSecureElement()113 virtual ~JavacardSecureElement() { transport_->closeConnection(); } 114 115 std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins, 116 Array& request); 117 std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins); 118 std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins, std::vector<uint8_t>& command); 119 120 keymaster_error_t sendData(Instruction ins, std::vector<uint8_t>& inData, 121 std::vector<uint8_t>& response); 122 123 keymaster_error_t constructApduMessage(Instruction& ins, std::vector<uint8_t>& inputData, 124 std::vector<uint8_t>& apduOut); 125 keymaster_error_t initializeJavacard(); getApduStatus(std::vector<uint8_t> & inputData)126 inline uint16_t getApduStatus(std::vector<uint8_t>& inputData) { 127 // Last two bytes are the status SW0SW1 128 uint8_t SW0 = inputData.at(inputData.size() - 2); 129 uint8_t SW1 = inputData.at(inputData.size() - 1); 130 return (SW0 << 8 | SW1); 131 } 132 133 #ifdef NXP_EXTNS 134 void setOperationState(CryptoOperationState state); 135 #endif 136 shared_ptr<ITransport> transport_; 137 uint32_t osVersion_; 138 uint32_t osPatchLevel_; 139 uint32_t vendorPatchLevel_; 140 bool isCardInitialized_; 141 CborConverter cbor_; 142 }; 143 } // namespace keymint::javacard 144