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 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 namespace keymint::javacard { 49 using ndk::ScopedAStatus; 50 using std::optional; 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_SET_BOOT_PARAMS_CMD = KEYMINT_CMD_APDU_START + 26, 82 INS_SET_BOOT_PARAMS_CMD = 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_ROT_CHALLENGE_CMD = KEYMINT_CMD_APDU_START + 45, 93 INS_GET_ROT_DATA_CMD = KEYMINT_CMD_APDU_START + 46, 94 INS_SEND_ROT_DATA_CMD = KEYMINT_CMD_APDU_START + 47, 95 }; 96 97 class JavacardSecureElement { 98 public: JavacardSecureElement(shared_ptr<ITransport> transport,uint32_t osVersion,uint32_t osPatchLevel,uint32_t vendorPatchLevel)99 explicit JavacardSecureElement(shared_ptr<ITransport> transport, uint32_t osVersion, 100 uint32_t osPatchLevel, uint32_t vendorPatchLevel) 101 : transport_(transport), osVersion_(osVersion), osPatchLevel_(osPatchLevel), 102 vendorPatchLevel_(vendorPatchLevel) { 103 transport_->openConnection(); 104 } ~JavacardSecureElement()105 virtual ~JavacardSecureElement() { transport_->closeConnection(); } 106 107 std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins, 108 Array& request); 109 std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins); 110 std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins, std::vector<uint8_t>& command); 111 112 keymaster_error_t sendData(Instruction ins, std::vector<uint8_t>& inData, 113 std::vector<uint8_t>& response); 114 115 keymaster_error_t constructApduMessage(Instruction& ins, std::vector<uint8_t>& inputData, 116 std::vector<uint8_t>& apduOut); 117 keymaster_error_t initializeJavacard(); getApduStatus(std::vector<uint8_t> & inputData)118 inline uint16_t getApduStatus(std::vector<uint8_t>& inputData) { 119 // Last two bytes are the status SW0SW1 120 uint8_t SW0 = inputData.at(inputData.size() - 2); 121 uint8_t SW1 = inputData.at(inputData.size() - 1); 122 return (SW0 << 8 | SW1); 123 } 124 125 shared_ptr<ITransport> transport_; 126 uint32_t osVersion_; 127 uint32_t osPatchLevel_; 128 uint32_t vendorPatchLevel_; 129 CborConverter cbor_; 130 }; 131 } // namespace keymint::javacard 132