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 #pragma once
18 #include <aidl/android/hardware/security/keymint/Certificate.h>
19 #include <aidl/android/hardware/security/keymint/IKeyMintDevice.h>
20 #include <aidl/android/hardware/security/secureclock/TimeStampToken.h>
21 #include <aidl/android/hardware/security/sharedsecret/ISharedSecret.h>
22 #include <cppbor.h>
23 #include <cppbor_parse.h>
24 #include <iostream>
25 #include <keymaster/android_keymaster_messages.h>
26 #include <memory>
27 #include <numeric>
28 #include <vector>
29
30 namespace keymint::javacard {
31 using namespace cppbor;
32 using namespace aidl::android::hardware::security::keymint;
33 using namespace aidl::android::hardware::security::secureclock;
34 using namespace aidl::android::hardware::security::sharedsecret;
35 using std::string;
36 using std::unique_ptr;
37 using std::vector;
38
39 class CborConverter {
40 public:
41 CborConverter() = default;
42 ~CborConverter() = default;
43 std::tuple<std::unique_ptr<Item>, keymaster_error_t>
44 decodeData(const std::vector<uint8_t>& response);
45
46 template <typename T>
47 bool getUint64(const std::unique_ptr<Item>& item, const uint32_t pos, T& value);
48
49 template <typename T> bool getUint64(const std::unique_ptr<Item>& item, T& value);
50
51 bool getSharedSecretParameters(const std::unique_ptr<Item>& item, const uint32_t pos,
52 SharedSecretParameters& params);
53 bool getBinaryArray(const std::unique_ptr<Item>& item, const uint32_t pos, string& value);
54
55 bool getBinaryArray(const std::unique_ptr<Item>& item, const uint32_t pos,
56 vector<uint8_t>& value);
57
58 bool getHardwareAuthToken(const std::unique_ptr<Item>& item, const uint32_t pos,
59 HardwareAuthToken& authType);
60
61 bool getKeyParameters(const std::unique_ptr<Item>& item, const uint32_t pos,
62 vector<KeyParameter>& keyParams);
63
64 bool addKeyparameters(Array& array, const vector<KeyParameter>& keyParams);
65
66 bool addAttestationKey(Array& array, const std::optional<AttestationKey>& attestationKey);
67
68 bool addHardwareAuthToken(Array& array, const HardwareAuthToken& authToken);
69
70 bool addSharedSecretParameters(Array& array, const vector<SharedSecretParameters>& params);
71
72 bool getTimeStampToken(const std::unique_ptr<Item>& item, const uint32_t pos,
73 TimeStampToken& token);
74
75 bool getKeyCharacteristics(const std::unique_ptr<Item>& item, const uint32_t pos,
76 vector<KeyCharacteristics>& keyCharacteristics);
77
78 bool getCertificateChain(const std::unique_ptr<Item>& item, const uint32_t pos,
79 vector<Certificate>& keyCharacteristics);
80
81 bool getMultiBinaryArray(const std::unique_ptr<Item>& item, const uint32_t pos,
82 vector<vector<uint8_t>>& data);
83
84 bool addTimeStampToken(Array& array, const TimeStampToken& token);
85
86 bool getMapItem(const std::unique_ptr<Item>& item, const uint32_t pos,
87 Map& map);
88
89 bool getArrayItem(const std::unique_ptr<Item>& item, const uint32_t pos,
90 Array& array);
91
getErrorCode(const std::unique_ptr<Item> & item,const uint32_t pos,keymaster_error_t & errorCode)92 inline bool getErrorCode(const std::unique_ptr<Item>& item, const uint32_t pos,
93 keymaster_error_t& errorCode) {
94 uint64_t errorVal;
95 if (!getUint64<uint64_t>(item, pos, errorVal)) {
96 return false;
97 }
98 errorCode = static_cast<keymaster_error_t>(0 - errorVal);
99 return true;
100 }
101
102 private:
103 /**
104 * Returns the negative value of the same number.
105 */
get2sCompliment(uint32_t value)106 inline int32_t get2sCompliment(uint32_t value) { return static_cast<int32_t>(~value + 1); }
107
108 /**
109 * Get the type of the Item pointer.
110 */
getType(const unique_ptr<Item> & item)111 inline MajorType getType(const unique_ptr<Item>& item) { return item.get()->type(); }
112
113 /**
114 * Construct Keyparameter structure from the pair of key and value. If TagType is ENUM_REP the
115 * value contains binary string. If TagType is UINT_REP or ULONG_REP the value contains Array of
116 * unsigned integers.
117 */
118 bool getKeyParameter(const std::pair<const unique_ptr<Item>&, const unique_ptr<Item>&> pair,
119 vector<KeyParameter>& keyParam);
120
121 /**
122 * Get the sub item pointer from the root item pointer at the given position.
123 */
getItemAtPos(const unique_ptr<Item> & item,const uint32_t pos,unique_ptr<Item> & subItem)124 inline void getItemAtPos(const unique_ptr<Item>& item, const uint32_t pos,
125 unique_ptr<Item>& subItem) {
126 Array* arr = nullptr;
127
128 if (MajorType::ARRAY != getType(item)) {
129 return;
130 }
131 arr = const_cast<Array*>(item.get()->asArray());
132 if (arr->size() < (pos + 1)) {
133 return;
134 }
135 subItem = std::move((*arr)[pos]);
136 }
137 };
138
getUint64(const unique_ptr<Item> & item,T & value)139 template <typename T> bool CborConverter::getUint64(const unique_ptr<Item>& item, T& value) {
140 bool ret = false;
141 if ((item == nullptr) || (std::is_unsigned<T>::value && (MajorType::UINT != getType(item))) ||
142 ((std::is_signed<T>::value && (MajorType::NINT != getType(item))))) {
143 return ret;
144 }
145
146 if (std::is_unsigned<T>::value) {
147 const Uint* uintVal = item.get()->asUint();
148 value = static_cast<T>(uintVal->value());
149 } else {
150 const Nint* nintVal = item.get()->asNint();
151 value = static_cast<T>(nintVal->value());
152 }
153 ret = true;
154 return ret; // success
155 }
156
157 template <typename T>
getUint64(const unique_ptr<Item> & item,const uint32_t pos,T & value)158 bool CborConverter::getUint64(const unique_ptr<Item>& item, const uint32_t pos, T& value) {
159 unique_ptr<Item> intItem(nullptr);
160 getItemAtPos(item, pos, intItem);
161 return getUint64(intItem, value);
162 }
163 } // namespace keymint::javacard
164