1 /*
2 * Copyright (C) 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 #include "JavacardKeyMintUtils.h"
18 #include <android-base/logging.h>
19 #include <cppbor.h>
20
21 namespace aidl::android::hardware::security::keymint::km_utils {
22
23 keymaster_key_param_t kInvalidTag{.tag = KM_TAG_INVALID, .integer = 0};
24
kmEnumParam2Aidl(const keymaster_key_param_t & param)25 KeyParameter kmEnumParam2Aidl(const keymaster_key_param_t& param) {
26 switch (param.tag) {
27 case KM_TAG_PURPOSE:
28 return KeyParameter{Tag::PURPOSE, KeyParameterValue::make<KeyParameterValue::keyPurpose>(
29 static_cast<KeyPurpose>(param.enumerated))};
30 case KM_TAG_ALGORITHM:
31 return KeyParameter{Tag::ALGORITHM, KeyParameterValue::make<KeyParameterValue::algorithm>(
32 static_cast<Algorithm>(param.enumerated))};
33 case KM_TAG_BLOCK_MODE:
34 return KeyParameter{Tag::BLOCK_MODE, KeyParameterValue::make<KeyParameterValue::blockMode>(
35 static_cast<BlockMode>(param.enumerated))};
36 case KM_TAG_DIGEST:
37 return KeyParameter{Tag::DIGEST, KeyParameterValue::make<KeyParameterValue::digest>(
38 static_cast<Digest>(param.enumerated))};
39 case KM_TAG_PADDING:
40 return KeyParameter{Tag::PADDING, KeyParameterValue::make<KeyParameterValue::paddingMode>(
41 static_cast<PaddingMode>(param.enumerated))};
42 case KM_TAG_EC_CURVE:
43 return KeyParameter{Tag::EC_CURVE, KeyParameterValue::make<KeyParameterValue::ecCurve>(
44 static_cast<EcCurve>(param.enumerated))};
45 case KM_TAG_USER_AUTH_TYPE:
46 return KeyParameter{Tag::USER_AUTH_TYPE,
47 KeyParameterValue::make<KeyParameterValue::hardwareAuthenticatorType>(
48 static_cast<HardwareAuthenticatorType>(param.enumerated))};
49 case KM_TAG_ORIGIN:
50 return KeyParameter{Tag::ORIGIN, KeyParameterValue::make<KeyParameterValue::origin>(
51 static_cast<KeyOrigin>(param.enumerated))};
52 case KM_TAG_BLOB_USAGE_REQUIREMENTS:
53 case KM_TAG_KDF:
54 default:
55 return KeyParameter{Tag::INVALID, false};
56 }
57 }
58
59
kmParam2Aidl(const keymaster_key_param_t & param)60 KeyParameter kmParam2Aidl(const keymaster_key_param_t& param) {
61 auto tag = legacy_enum_conversion(param.tag);
62 switch (typeFromTag(param.tag)) {
63 case KM_ENUM:
64 case KM_ENUM_REP:
65 return kmEnumParam2Aidl(param);
66 break;
67
68 case KM_UINT:
69 case KM_UINT_REP:
70 return KeyParameter{tag,
71 KeyParameterValue::make<KeyParameterValue::integer>(param.integer)};
72
73 case KM_ULONG:
74 case KM_ULONG_REP:
75 return KeyParameter{
76 tag, KeyParameterValue::make<KeyParameterValue::longInteger>(param.long_integer)};
77 break;
78
79 case KM_DATE:
80 return KeyParameter{tag,
81 KeyParameterValue::make<KeyParameterValue::dateTime>(param.date_time)};
82 break;
83
84 case KM_BOOL:
85 return KeyParameter{tag, param.boolean};
86 break;
87
88 case KM_BIGNUM:
89 case KM_BYTES:
90 return {tag, KeyParameterValue::make<KeyParameterValue::blob>(
91 std::vector(param.blob.data, param.blob.data + param.blob.data_length))};
92 break;
93
94 case KM_INVALID:
95 default:
96 CHECK(false) << "Unknown or unused tag type: Something is broken";
97 return KeyParameter{Tag::INVALID, false};
98 break;
99 }
100 }
101
kmParamSet2Aidl(const keymaster_key_param_set_t & set)102 vector<KeyParameter> kmParamSet2Aidl(const keymaster_key_param_set_t& set) {
103 vector<KeyParameter> result;
104 if (set.length == 0 || set.params == nullptr) return result;
105
106 result.reserve(set.length);
107 for (size_t i = 0; i < set.length; ++i) {
108 result.push_back(kmParam2Aidl(set.params[i]));
109 }
110 return result;
111 }
112
113 template <KeyParameterValue::Tag aidl_tag>
aidlEnumVal2Km(keymaster_tag_t km_tag,const KeyParameterValue & value)114 keymaster_key_param_t aidlEnumVal2Km(keymaster_tag_t km_tag, const KeyParameterValue& value) {
115 return value.getTag() == aidl_tag
116 ? keymaster_param_enum(km_tag, static_cast<uint32_t>(value.get<aidl_tag>()))
117 : kInvalidTag;
118 }
119
aidlEnumParam2Km(const KeyParameter & param)120 keymaster_key_param_t aidlEnumParam2Km(const KeyParameter& param) {
121 auto tag = legacy_enum_conversion(param.tag);
122 switch (tag) {
123 case KM_TAG_PURPOSE:
124 return aidlEnumVal2Km<KeyParameterValue::keyPurpose>(tag, param.value);
125 case KM_TAG_ALGORITHM:
126 return aidlEnumVal2Km<KeyParameterValue::algorithm>(tag, param.value);
127 case KM_TAG_BLOCK_MODE:
128 return aidlEnumVal2Km<KeyParameterValue::blockMode>(tag, param.value);
129 case KM_TAG_DIGEST:
130 case KM_TAG_RSA_OAEP_MGF_DIGEST:
131 return aidlEnumVal2Km<KeyParameterValue::digest>(tag, param.value);
132 case KM_TAG_PADDING:
133 return aidlEnumVal2Km<KeyParameterValue::paddingMode>(tag, param.value);
134 case KM_TAG_EC_CURVE:
135 return aidlEnumVal2Km<KeyParameterValue::ecCurve>(tag, param.value);
136 case KM_TAG_USER_AUTH_TYPE:
137 return aidlEnumVal2Km<KeyParameterValue::hardwareAuthenticatorType>(tag, param.value);
138 case KM_TAG_ORIGIN:
139 return aidlEnumVal2Km<KeyParameterValue::origin>(tag, param.value);
140 case KM_TAG_BLOB_USAGE_REQUIREMENTS:
141 case KM_TAG_KDF:
142 default:
143 CHECK(false) << "Unknown or unused enum tag: Something is broken";
144 return keymaster_param_enum(tag, false);
145 }
146 }
147
148
149
legacyHardwareAuthToken(const HardwareAuthToken & aidlToken,LegacyHardwareAuthToken * legacyToken)150 keymaster_error_t legacyHardwareAuthToken(const HardwareAuthToken& aidlToken,
151 LegacyHardwareAuthToken* legacyToken) {
152 legacyToken->challenge = aidlToken.challenge;
153 legacyToken->user_id = aidlToken.userId;
154 legacyToken->authenticator_id = aidlToken.authenticatorId;
155 legacyToken->authenticator_type =
156 static_cast<hw_authenticator_type_t>(aidlToken.authenticatorType);
157 legacyToken->timestamp = aidlToken.timestamp.milliSeconds;
158 Vec2KmBlob(aidlToken.mac, &legacyToken->mac);
159 return KM_ERROR_OK;
160 }
161
encodeTimestampToken(const TimeStampToken & timestampToken,vector<uint8_t> * encodedToken)162 keymaster_error_t encodeTimestampToken(const TimeStampToken& timestampToken,
163 vector<uint8_t>* encodedToken) {
164 cppbor::Array array;
165 ::keymaster::TimestampToken token;
166 array.add(static_cast<uint64_t>(timestampToken.challenge));
167 array.add(static_cast<uint64_t>(timestampToken.timestamp.milliSeconds));
168 array.add(timestampToken.mac);
169 *encodedToken = array.encode();
170 return KM_ERROR_OK;
171 }
172
aidlKeyParams2Km(const vector<KeyParameter> & keyParams)173 keymaster_key_param_set_t aidlKeyParams2Km(const vector<KeyParameter>& keyParams) {
174 keymaster_key_param_set_t set;
175
176 set.params = static_cast<keymaster_key_param_t*>(
177 malloc(keyParams.size() * sizeof(keymaster_key_param_t)));
178 set.length = keyParams.size();
179
180 for (size_t i = 0; i < keyParams.size(); ++i) {
181 const auto& param = keyParams[i];
182 auto tag = legacy_enum_conversion(param.tag);
183 switch (typeFromTag(tag)) {
184
185 case KM_ENUM:
186 case KM_ENUM_REP:
187 set.params[i] = aidlEnumParam2Km(param);
188 break;
189
190 case KM_UINT:
191 case KM_UINT_REP:
192 set.params[i] =
193 param.value.getTag() == KeyParameterValue::integer
194 ? keymaster_param_int(tag, param.value.get<KeyParameterValue::integer>())
195 : kInvalidTag;
196 break;
197
198 case KM_ULONG:
199 case KM_ULONG_REP:
200 set.params[i] =
201 param.value.getTag() == KeyParameterValue::longInteger
202 ? keymaster_param_long(tag, param.value.get<KeyParameterValue::longInteger>())
203 : kInvalidTag;
204 break;
205
206 case KM_DATE:
207 set.params[i] =
208 param.value.getTag() == KeyParameterValue::dateTime
209 ? keymaster_param_date(tag, param.value.get<KeyParameterValue::dateTime>())
210 : kInvalidTag;
211 break;
212
213 case KM_BOOL:
214 set.params[i] = keymaster_param_bool(tag);
215 break;
216
217 case KM_BIGNUM:
218 case KM_BYTES:
219 if (param.value.getTag() == KeyParameterValue::blob) {
220 const auto& value = param.value.get<KeyParameterValue::blob>();
221 uint8_t* copy = static_cast<uint8_t*>(malloc(value.size()));
222 std::copy(value.begin(), value.end(), copy);
223 set.params[i] = keymaster_param_blob(tag, copy, value.size());
224 } else {
225 set.params[i] = kInvalidTag;
226 }
227 break;
228
229 case KM_INVALID:
230 default:
231 CHECK(false) << "Invalid tag: Something is broken";
232 set.params[i].tag = KM_TAG_INVALID;
233 /* just skip */
234 break;
235 }
236 }
237
238 return set;
239 }
240
241 } // namespace aidl::android::hardware::security::keymint
242