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