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 #include "include/KeyMintAidlUtils.h"
19 
20 namespace aidl {
21 namespace android {
22 namespace hardware {
23 namespace keymint {
24 
25 using namespace ::keymaster;
26 
authToken2AidlVec(const HardwareAuthToken & token)27 vector<uint8_t> authToken2AidlVec(const HardwareAuthToken& token) {
28     static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
29                           sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
30                           sizeof(token.timestamp) + 32 /* HMAC size */
31                       == sizeof(hw_auth_token_t),
32                   "HardwareAuthToken content size does not match hw_auth_token_t size");
33 
34     vector<uint8_t> result;
35 
36     if (token.mac.size() <= 32) return result;
37 
38     result.resize(sizeof(hw_auth_token_t));
39     auto pos = result.begin();
40     *pos++ = 0;  // Version byte
41     pos = copy_bytes_to_iterator(token.challenge, pos);
42     pos = copy_bytes_to_iterator(token.userId, pos);
43     pos = copy_bytes_to_iterator(token.authenticatorId, pos);
44     pos = copy_bytes_to_iterator(token.authenticatorType, pos);
45     pos = copy_bytes_to_iterator(token.timestamp, pos);
46     pos = std::copy(token.mac.data(), token.mac.data() + token.mac.size(), pos);
47 
48     return result;
49 }
50 
51 // TODO(seleneh): This needs to be modified depends on how aidl support for union came out to
52 // be.
kmParamSet2Aidl(const keymaster_key_param_set_t & set)53 vector<KeyParameter> kmParamSet2Aidl(const keymaster_key_param_set_t& set) {
54     vector<KeyParameter> result;
55     if (set.length == 0 || set.params == nullptr) return result;
56 
57     result.resize(set.length);
58     keymaster_key_param_t* params = set.params;
59     for (size_t i = 0; i < set.length; ++i) {
60         auto tag = params[i].tag;
61         result[i].tag = legacy_enum_conversion(tag);
62         switch (typeFromTag(tag)) {
63         case KM_ENUM:
64         case KM_ENUM_REP:
65             result[i].integer = params[i].enumerated;
66             break;
67         case KM_UINT:
68         case KM_UINT_REP:
69             result[i].integer = params[i].integer;
70             break;
71         case KM_ULONG:
72         case KM_ULONG_REP:
73             result[i].longInteger = params[i].long_integer;
74             break;
75         case KM_DATE:
76             result[i].longInteger = params[i].date_time;
77             break;
78         case KM_BOOL:
79             result[i].boolValue = params[i].boolean;
80             break;
81         case KM_BIGNUM:
82         case KM_BYTES:
83             result[i].blob.assign(params[i].blob.data,
84                                   params[i].blob.data + params[i].blob.data_length);
85             break;
86         case KM_INVALID:
87         default:
88             params[i].tag = KM_TAG_INVALID;
89             /* just skip */
90             break;
91         }
92     }
93     return result;
94 }
95 
96 // TODO(seleneh): This needs to be modified depends on how aidl support for union came out to
97 // be.
aidlKeyParams2Km(const vector<KeyParameter> & keyParams)98 keymaster_key_param_set_t aidlKeyParams2Km(const vector<KeyParameter>& keyParams) {
99     keymaster_key_param_set_t set;
100 
101     set.params = new keymaster_key_param_t[keyParams.size()];
102     set.length = keyParams.size();
103 
104     for (size_t i = 0; i < keyParams.size(); ++i) {
105         auto tag = legacy_enum_conversion(keyParams[i].tag);
106         switch (typeFromTag(tag)) {
107         case KM_ENUM:
108         case KM_ENUM_REP:
109             set.params[i] = keymaster_param_enum(tag, keyParams[i].integer);
110             break;
111         case KM_UINT:
112         case KM_UINT_REP:
113             set.params[i] = keymaster_param_int(tag, keyParams[i].integer);
114             break;
115         case KM_ULONG:
116         case KM_ULONG_REP:
117             set.params[i] = keymaster_param_long(tag, keyParams[i].longInteger);
118             break;
119         case KM_DATE:
120             set.params[i] = keymaster_param_date(tag, keyParams[i].longInteger);
121             break;
122         case KM_BOOL:
123             if (keyParams[i].boolValue)
124                 set.params[i] = keymaster_param_bool(tag);
125             else
126                 set.params[i].tag = KM_TAG_INVALID;
127             break;
128         case KM_BIGNUM:
129         case KM_BYTES:
130             set.params[i] =
131                 keymaster_param_blob(tag, keyParams[i].blob.data(), keyParams[i].blob.size());
132             break;
133         case KM_INVALID:
134         default:
135             set.params[i].tag = KM_TAG_INVALID;
136             /* just skip */
137             break;
138         }
139     }
140 
141     return set;
142 }
143 
144 }  // namespace keymint
145 }  // namespace hardware
146 }  // namespace android
147 }  // namespace aidl
148