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 <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 #ifdef NXP_EXTNS
100 enum CryptoOperationState { STARTED = 0, FINISHED };
101 #endif
102 
103 class JavacardSecureElement {
104   public:
JavacardSecureElement(shared_ptr<ITransport> transport)105     explicit JavacardSecureElement(shared_ptr<ITransport> transport)
106         : transport_(std::move(transport)),
107           isEarlyBootEndedPending(false),
108           isDeleteAllKeysPending(false),
109           isCardInitPending(true) {
110         transport_->openConnection();
111     }
~JavacardSecureElement()112     virtual ~JavacardSecureElement() { transport_->closeConnection(); }
113 
114     std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins,
115                                                                      const Array& request);
116     std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins);
117     std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(
118         Instruction ins, const std::vector<uint8_t>& command);
119 
120     std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequestSeHal(
121         Instruction ins, const std::vector<uint8_t>& command);
122     std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequestSeHal(Instruction ins);
123 
124     bool closeSEHal();
125 
126     keymaster_error_t sendData(Instruction ins, const std::vector<uint8_t>& inData,
127                                std::vector<uint8_t>& response);
128     keymaster_error_t constructApduMessage(Instruction& ins, const std::vector<uint8_t>& inputData,
129                                            std::vector<uint8_t>& apduOut);
130     keymaster_error_t initializeJavacard();
131     void sendPendingEvents();
132     void setEarlyBootEndedPending();
133     void setDeleteAllKeysPending();
134 #ifdef NXP_EXTNS
135     void setOperationState(CryptoOperationState state);
136 #endif
getApduStatus(std::vector<uint8_t> & inputData)137     inline uint16_t getApduStatus(std::vector<uint8_t>& inputData) {
138         // Last two bytes are the status SW0SW1
139         uint8_t SW0 = inputData.at(inputData.size() - 2);
140         uint8_t SW1 = inputData.at(inputData.size() - 1);
141         return (SW0 << 8 | SW1);
142     }
143 
144   private:
145     bool initSEHal();
146     keymaster_error_t sendData(const std::shared_ptr<ITransport>& transport, Instruction ins,
147                                const std::vector<uint8_t>& inData, std::vector<uint8_t>& response);
148     std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(
149         const std::shared_ptr<ITransport>& transport, Instruction ins,
150         const std::vector<uint8_t>& command);
151     shared_ptr<ITransport> transport_;
152     shared_ptr<ITransport> seHalTransport;
153     bool isEarlyBootEndedPending;
154     bool isDeleteAllKeysPending;
155     bool isCardInitPending;
156     CborConverter cbor_;
157 };
158 }  // namespace keymint::javacard
159