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