• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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