1 /*
2 **
3 ** Copyright 2020, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 /******************************************************************************
18 *
19 * The original Work has been changed by NXP.
20 *
21 * Licensed under the Apache License, Version 2.0 (the "License");
22 * you may not use this file except in compliance with the License.
23 * You may obtain a copy of the License at
24 *
25 * http://www.apache.org/licenses/LICENSE-2.0
26 *
27 * Unless required by applicable law or agreed to in writing, software
28 * distributed under the License is distributed on an "AS IS" BASIS,
29 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30 * See the License for the specific language governing permissions and
31 * limitations under the License.
32 *
33 * Copyright 2023 NXP
34 *
35 ******************************************************************************/
36 #pragma once
37 #include <aidl/android/hardware/security/keymint/Certificate.h>
38 #include <aidl/android/hardware/security/keymint/IKeyMintDevice.h>
39 #include <aidl/android/hardware/security/secureclock/TimeStampToken.h>
40 #include <aidl/android/hardware/security/sharedsecret/ISharedSecret.h>
41 #include <cppbor.h>
42 #include <cppbor_parse.h>
43 #include <iostream>
44 #include <keymaster/android_keymaster_messages.h>
45 #include <memory>
46 #include <numeric>
47 #include <vector>
48
49 namespace keymint::javacard {
50 using aidl::android::hardware::security::keymint::AttestationKey;
51 using aidl::android::hardware::security::keymint::Certificate;
52 using aidl::android::hardware::security::keymint::HardwareAuthToken;
53 using aidl::android::hardware::security::keymint::KeyCharacteristics;
54 using aidl::android::hardware::security::keymint::KeyParameter;
55 using aidl::android::hardware::security::secureclock::TimeStampToken;
56 using aidl::android::hardware::security::sharedsecret::SharedSecretParameters;
57 using cppbor::Array;
58 using cppbor::Bstr;
59 using cppbor::Item;
60 using cppbor::MajorType;
61 using cppbor::Map;
62 using cppbor::Nint;
63 using cppbor::parse;
64 using cppbor::Uint;
65 using std::string;
66 using std::unique_ptr;
67 using std::vector;
68
69 class CborConverter {
70 public:
71 CborConverter() = default;
72 ~CborConverter() = default;
73 std::tuple<std::unique_ptr<Item>, keymaster_error_t>
74 decodeData(const std::vector<uint8_t>& response);
75
76 template <typename T>
77 bool getUint64(const std::unique_ptr<Item>& item, const uint32_t pos, T& value);
78
79 template <typename T> bool getUint64(const std::unique_ptr<Item>& item, T& value);
80
81 bool getSharedSecretParameters(const std::unique_ptr<Item>& item, const uint32_t pos,
82 SharedSecretParameters& params);
83 bool getBinaryArray(const std::unique_ptr<Item>& item, const uint32_t pos, string& value);
84
85 bool getBinaryArray(const std::unique_ptr<Item>& item, const uint32_t pos,
86 vector<uint8_t>& value);
87
88 bool getHardwareAuthToken(const std::unique_ptr<Item>& item, const uint32_t pos,
89 HardwareAuthToken& authType);
90
91 bool getKeyParameters(const std::unique_ptr<Item>& item, const uint32_t pos,
92 vector<KeyParameter>& keyParams);
93
94 bool addKeyparameters(Array& array, const vector<KeyParameter>& keyParams);
95
96 bool addAttestationKey(Array& array, const std::optional<AttestationKey>& attestationKey);
97
98 bool addHardwareAuthToken(Array& array, const HardwareAuthToken& authToken);
99
100 bool addSharedSecretParameters(Array& array, const vector<SharedSecretParameters>& params);
101
102 bool getTimeStampToken(const std::unique_ptr<Item>& item, const uint32_t pos,
103 TimeStampToken& token);
104
105 bool getKeyCharacteristics(const std::unique_ptr<Item>& item, const uint32_t pos,
106 vector<KeyCharacteristics>& keyCharacteristics);
107
108 bool getCertificateChain(const std::unique_ptr<Item>& item, const uint32_t pos,
109 vector<Certificate>& keyCharacteristics);
110
111 bool getMultiBinaryArray(const std::unique_ptr<Item>& item, const uint32_t pos,
112 vector<vector<uint8_t>>& data);
113
114 bool addTimeStampToken(Array& array, const TimeStampToken& token);
115
116 bool getMapItem(const std::unique_ptr<Item>& item, const uint32_t pos,
117 Map& map);
118
119 bool getArrayItem(const std::unique_ptr<Item>& item, const uint32_t pos,
120 Array& array);
121
getErrorCode(const std::unique_ptr<Item> & item,const uint32_t pos,keymaster_error_t & errorCode)122 inline bool getErrorCode(const std::unique_ptr<Item>& item, const uint32_t pos,
123 keymaster_error_t& errorCode) {
124 uint64_t errorVal;
125 if (!getUint64<uint64_t>(item, pos, errorVal)) {
126 return false;
127 }
128 errorCode = static_cast<keymaster_error_t>(0 - errorVal);
129 return true;
130 }
131
132 private:
133 /**
134 * Returns the negative value of the same number.
135 */
get2sCompliment(uint32_t value)136 inline int32_t get2sCompliment(uint32_t value) { return static_cast<int32_t>(~value + 1); }
137
138 /**
139 * Get the type of the Item pointer.
140 */
getType(const unique_ptr<Item> & item)141 inline MajorType getType(const unique_ptr<Item>& item) { return item.get()->type(); }
142
143 /**
144 * Construct Keyparameter structure from the pair of key and value. If TagType is ENUM_REP the
145 * value contains binary string. If TagType is UINT_REP or ULONG_REP the value contains Array of
146 * unsigned integers.
147 */
148 bool getKeyParameter(const std::pair<const unique_ptr<Item>&, const unique_ptr<Item>&> pair,
149 vector<KeyParameter>& keyParam);
150
151 /**
152 * Get the sub item pointer from the root item pointer at the given position.
153 */
getItemAtPos(const unique_ptr<Item> & item,const uint32_t pos,unique_ptr<Item> & subItem)154 inline void getItemAtPos(const unique_ptr<Item>& item, const uint32_t pos,
155 unique_ptr<Item>& subItem) {
156 Array* arr = nullptr;
157
158 if (MajorType::ARRAY != getType(item)) {
159 return;
160 }
161 arr = const_cast<Array*>(item.get()->asArray());
162 if (arr->size() < (pos + 1)) {
163 return;
164 }
165 subItem = std::move((*arr)[pos]);
166 }
167 };
168
getUint64(const unique_ptr<Item> & item,T & value)169 template <typename T> bool CborConverter::getUint64(const unique_ptr<Item>& item, T& value) {
170 bool ret = false;
171 if ((item == nullptr) || (std::is_unsigned<T>::value && (MajorType::UINT != getType(item))) ||
172 ((std::is_signed<T>::value && (MajorType::NINT != getType(item))))) {
173 return ret;
174 }
175
176 if (std::is_unsigned<T>::value) {
177 const Uint* uintVal = item.get()->asUint();
178 value = static_cast<T>(uintVal->value());
179 } else {
180 const Nint* nintVal = item.get()->asNint();
181 value = static_cast<T>(nintVal->value());
182 }
183 ret = true;
184 return ret; // success
185 }
186
187 template <typename T>
getUint64(const unique_ptr<Item> & item,const uint32_t pos,T & value)188 bool CborConverter::getUint64(const unique_ptr<Item>& item, const uint32_t pos, T& value) {
189 unique_ptr<Item> intItem(nullptr);
190 getItemAtPos(item, pos, intItem);
191 return getUint64(intItem, value);
192 }
193 } // namespace keymint::javacard
194