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 #pragma once 18 19 #include <ITransport.h> 20 21 #include "CborConverter.h" 22 23 #define APDU_CLS 0x80 24 #define APDU_P1 0x60 25 #define APDU_P2 0x00 26 #define APDU_RESP_STATUS_OK 0x9000 27 28 #define KEYMINT_CMD_APDU_START 0x20 29 30 namespace keymint::javacard { 31 using std::shared_ptr; 32 using std::vector; 33 34 enum class Instruction { 35 // Keymaster commands 36 INS_GENERATE_KEY_CMD = KEYMINT_CMD_APDU_START + 1, 37 INS_IMPORT_KEY_CMD = KEYMINT_CMD_APDU_START + 2, 38 INS_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 3, 39 INS_EXPORT_KEY_CMD = KEYMINT_CMD_APDU_START + 4, 40 INS_ATTEST_KEY_CMD = KEYMINT_CMD_APDU_START + 5, 41 INS_UPGRADE_KEY_CMD = KEYMINT_CMD_APDU_START + 6, 42 INS_DELETE_KEY_CMD = KEYMINT_CMD_APDU_START + 7, 43 INS_DELETE_ALL_KEYS_CMD = KEYMINT_CMD_APDU_START + 8, 44 INS_ADD_RNG_ENTROPY_CMD = KEYMINT_CMD_APDU_START + 9, 45 INS_COMPUTE_SHARED_SECRET_CMD = KEYMINT_CMD_APDU_START + 10, 46 INS_DESTROY_ATT_IDS_CMD = KEYMINT_CMD_APDU_START + 11, 47 INS_VERIFY_AUTHORIZATION_CMD = KEYMINT_CMD_APDU_START + 12, 48 INS_GET_SHARED_SECRET_PARAM_CMD = KEYMINT_CMD_APDU_START + 13, 49 INS_GET_KEY_CHARACTERISTICS_CMD = KEYMINT_CMD_APDU_START + 14, 50 INS_GET_HW_INFO_CMD = KEYMINT_CMD_APDU_START + 15, 51 INS_BEGIN_OPERATION_CMD = KEYMINT_CMD_APDU_START + 16, 52 INS_UPDATE_OPERATION_CMD = KEYMINT_CMD_APDU_START + 17, 53 INS_FINISH_OPERATION_CMD = KEYMINT_CMD_APDU_START + 18, 54 INS_ABORT_OPERATION_CMD = KEYMINT_CMD_APDU_START + 19, 55 INS_DEVICE_LOCKED_CMD = KEYMINT_CMD_APDU_START + 20, 56 INS_EARLY_BOOT_ENDED_CMD = KEYMINT_CMD_APDU_START + 21, 57 INS_GET_CERT_CHAIN_CMD = KEYMINT_CMD_APDU_START + 22, 58 INS_UPDATE_AAD_OPERATION_CMD = KEYMINT_CMD_APDU_START + 23, 59 INS_BEGIN_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 24, 60 INS_FINISH_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 25, 61 INS_INIT_STRONGBOX_CMD = KEYMINT_CMD_APDU_START + 26, 62 // RKP Commands 63 INS_GET_RKP_HARDWARE_INFO = KEYMINT_CMD_APDU_START + 27, 64 INS_GENERATE_RKP_KEY_CMD = KEYMINT_CMD_APDU_START + 28, 65 INS_BEGIN_SEND_DATA_CMD = KEYMINT_CMD_APDU_START + 29, 66 INS_UPDATE_KEY_CMD = KEYMINT_CMD_APDU_START + 30, 67 INS_UPDATE_EEK_CHAIN_CMD = KEYMINT_CMD_APDU_START + 31, 68 INS_UPDATE_CHALLENGE_CMD = KEYMINT_CMD_APDU_START + 32, 69 INS_FINISH_SEND_DATA_CMD = KEYMINT_CMD_APDU_START + 33, 70 INS_GET_RESPONSE_CMD = KEYMINT_CMD_APDU_START + 34, 71 INS_GET_UDS_CERTS_CMD = KEYMINT_CMD_APDU_START + 35, 72 INS_GET_DICE_CERT_CHAIN_CMD = KEYMINT_CMD_APDU_START + 36, 73 // SE ROT Commands 74 INS_GET_ROT_CHALLENGE_CMD = KEYMINT_CMD_APDU_START + 45, 75 INS_GET_ROT_DATA_CMD = KEYMINT_CMD_APDU_START + 46, 76 INS_SEND_ROT_DATA_CMD = KEYMINT_CMD_APDU_START + 47, 77 }; 78 79 class JavacardSecureElement { 80 public: JavacardSecureElement(shared_ptr<ITransport> transport)81 explicit JavacardSecureElement(shared_ptr<ITransport> transport) 82 : transport_(transport), isEarlyBootEndedPending(false), isDeleteAllKeysPending(false) { 83 transport_->openConnection(); 84 } ~JavacardSecureElement()85 virtual ~JavacardSecureElement() { transport_->closeConnection(); } 86 87 std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins, 88 Array& request); 89 std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins); 90 std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins, 91 std::vector<uint8_t>& command); 92 93 keymaster_error_t sendData(Instruction ins, std::vector<uint8_t>& inData, 94 std::vector<uint8_t>& response); 95 96 keymaster_error_t constructApduMessage(Instruction& ins, std::vector<uint8_t>& inputData, 97 std::vector<uint8_t>& apduOut); 98 keymaster_error_t initializeJavacard(); 99 void sendPendingEvents(); 100 void setEarlyBootEndedPending(); 101 void setDeleteAllKeysPending(); 102 getApduStatus(std::vector<uint8_t> & inputData)103 inline uint16_t getApduStatus(std::vector<uint8_t>& inputData) { 104 // Last two bytes are the status SW0SW1 105 uint8_t SW0 = inputData.at(inputData.size() - 2); 106 uint8_t SW1 = inputData.at(inputData.size() - 1); 107 return (SW0 << 8 | SW1); 108 } 109 110 private: 111 shared_ptr<ITransport> transport_; 112 bool isEarlyBootEndedPending; 113 bool isDeleteAllKeysPending; 114 CborConverter cbor_; 115 }; 116 } // namespace keymint::javacard 117