1 /* 2 * Copyright 2017 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 <keymasterV4_0/authorization_set.h> 18 19 #include <assert.h> 20 21 namespace android { 22 namespace hardware { 23 namespace keymaster { 24 namespace V4_0 { 25 26 inline bool keyParamLess(const KeyParameter& a, const KeyParameter& b) { 27 if (a.tag != b.tag) return a.tag < b.tag; 28 int retval; 29 switch (typeFromTag(a.tag)) { 30 case TagType::INVALID: 31 case TagType::BOOL: 32 return false; 33 case TagType::ENUM: 34 case TagType::ENUM_REP: 35 case TagType::UINT: 36 case TagType::UINT_REP: 37 return a.f.integer < b.f.integer; 38 case TagType::ULONG: 39 case TagType::ULONG_REP: 40 return a.f.longInteger < b.f.longInteger; 41 case TagType::DATE: 42 return a.f.dateTime < b.f.dateTime; 43 case TagType::BIGNUM: 44 case TagType::BYTES: 45 // Handle the empty cases. 46 if (a.blob.size() == 0) return b.blob.size() != 0; 47 if (b.blob.size() == 0) return false; 48 49 retval = memcmp(&a.blob[0], &b.blob[0], std::min(a.blob.size(), b.blob.size())); 50 // if one is the prefix of the other the longer wins 51 if (retval == 0) return a.blob.size() < b.blob.size(); 52 // Otherwise a is less if a is less. 53 else 54 return retval < 0; 55 } 56 return false; 57 } 58 59 inline bool keyParamEqual(const KeyParameter& a, const KeyParameter& b) { 60 if (a.tag != b.tag) return false; 61 62 switch (typeFromTag(a.tag)) { 63 case TagType::INVALID: 64 case TagType::BOOL: 65 return true; 66 case TagType::ENUM: 67 case TagType::ENUM_REP: 68 case TagType::UINT: 69 case TagType::UINT_REP: 70 return a.f.integer == b.f.integer; 71 case TagType::ULONG: 72 case TagType::ULONG_REP: 73 return a.f.longInteger == b.f.longInteger; 74 case TagType::DATE: 75 return a.f.dateTime == b.f.dateTime; 76 case TagType::BIGNUM: 77 case TagType::BYTES: 78 if (a.blob.size() != b.blob.size()) return false; 79 return a.blob.size() == 0 || memcmp(&a.blob[0], &b.blob[0], a.blob.size()) == 0; 80 } 81 return false; 82 } 83 84 void AuthorizationSet::Sort() { 85 std::sort(data_.begin(), data_.end(), keyParamLess); 86 } 87 88 void AuthorizationSet::Deduplicate() { 89 if (data_.empty()) return; 90 91 Sort(); 92 std::vector<KeyParameter> result; 93 94 auto curr = data_.begin(); 95 auto prev = curr++; 96 for (; curr != data_.end(); ++prev, ++curr) { 97 if (prev->tag == Tag::INVALID) continue; 98 99 if (!keyParamEqual(*prev, *curr)) { 100 result.emplace_back(std::move(*prev)); 101 } 102 } 103 result.emplace_back(std::move(*prev)); 104 105 std::swap(data_, result); 106 } 107 108 void AuthorizationSet::Union(const AuthorizationSet& other) { 109 data_.insert(data_.end(), other.data_.begin(), other.data_.end()); 110 Deduplicate(); 111 } 112 113 void AuthorizationSet::Subtract(const AuthorizationSet& other) { 114 Deduplicate(); 115 116 auto i = other.begin(); 117 while (i != other.end()) { 118 int pos = -1; 119 do { 120 pos = find(i->tag, pos); 121 if (pos != -1 && keyParamEqual(*i, data_[pos])) { 122 data_.erase(data_.begin() + pos); 123 break; 124 } 125 } while (pos != -1); 126 ++i; 127 } 128 } 129 130 KeyParameter& AuthorizationSet::operator[](int at) { 131 return data_[at]; 132 } 133 134 const KeyParameter& AuthorizationSet::operator[](int at) const { 135 return data_[at]; 136 } 137 138 void AuthorizationSet::Clear() { 139 data_.clear(); 140 } 141 142 size_t AuthorizationSet::GetTagCount(Tag tag) const { 143 size_t count = 0; 144 for (int pos = -1; (pos = find(tag, pos)) != -1;) ++count; 145 return count; 146 } 147 148 int AuthorizationSet::find(Tag tag, int begin) const { 149 auto iter = data_.begin() + (1 + begin); 150 151 while (iter != data_.end() && iter->tag != tag) ++iter; 152 153 if (iter != data_.end()) return iter - data_.begin(); 154 return -1; 155 } 156 157 bool AuthorizationSet::erase(int index) { 158 auto pos = data_.begin() + index; 159 if (pos != data_.end()) { 160 data_.erase(pos); 161 return true; 162 } 163 return false; 164 } 165 166 NullOr<const KeyParameter&> AuthorizationSet::GetEntry(Tag tag) const { 167 int pos = find(tag); 168 if (pos == -1) return {}; 169 return data_[pos]; 170 } 171 172 /** 173 * Persistent format is: 174 * | 32 bit indirect_size | 175 * -------------------------------- 176 * | indirect_size bytes of data | this is where the blob data is stored 177 * -------------------------------- 178 * | 32 bit element_count | number of entries 179 * | 32 bit elements_size | total bytes used by entries (entries have variable length) 180 * -------------------------------- 181 * | elementes_size bytes of data | where the elements are stored 182 */ 183 184 /** 185 * Persistent format of blobs and bignums: 186 * | 32 bit tag | 187 * | 32 bit blob_length | 188 * | 32 bit indirect_offset | 189 */ 190 191 struct OutStreams { 192 std::ostream& indirect; 193 std::ostream& elements; 194 }; 195 196 OutStreams& serializeParamValue(OutStreams& out, const hidl_vec<uint8_t>& blob) { 197 uint32_t buffer; 198 199 // write blob_length 200 auto blob_length = blob.size(); 201 if (blob_length > std::numeric_limits<uint32_t>::max()) { 202 out.elements.setstate(std::ios_base::badbit); 203 return out; 204 } 205 buffer = blob_length; 206 out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t)); 207 208 // write indirect_offset 209 auto offset = out.indirect.tellp(); 210 if (offset < 0 || offset > std::numeric_limits<uint32_t>::max() || 211 uint32_t(offset) + uint32_t(blob_length) < uint32_t(offset)) { // overflow check 212 out.elements.setstate(std::ios_base::badbit); 213 return out; 214 } 215 buffer = offset; 216 out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t)); 217 218 // write blob to indirect stream 219 if (blob_length) out.indirect.write(reinterpret_cast<const char*>(&blob[0]), blob_length); 220 221 return out; 222 } 223 224 template <typename T> 225 OutStreams& serializeParamValue(OutStreams& out, const T& value) { 226 out.elements.write(reinterpret_cast<const char*>(&value), sizeof(T)); 227 return out; 228 } 229 230 OutStreams& serialize(TAG_INVALID_t&&, OutStreams& out, const KeyParameter&) { 231 // skip invalid entries. 232 return out; 233 } 234 template <typename T> 235 OutStreams& serialize(T ttag, OutStreams& out, const KeyParameter& param) { 236 out.elements.write(reinterpret_cast<const char*>(¶m.tag), sizeof(int32_t)); 237 return serializeParamValue(out, accessTagValue(ttag, param)); 238 } 239 240 template <typename... T> 241 struct choose_serializer; 242 template <typename... Tags> 243 struct choose_serializer<MetaList<Tags...>> { 244 static OutStreams& serialize(OutStreams& out, const KeyParameter& param) { 245 return choose_serializer<Tags...>::serialize(out, param); 246 } 247 }; 248 249 template <> 250 struct choose_serializer<> { 251 static OutStreams& serialize(OutStreams& out, const KeyParameter&) { return out; } 252 }; 253 254 template <TagType tag_type, Tag tag, typename... Tail> 255 struct choose_serializer<TypedTag<tag_type, tag>, Tail...> { 256 static OutStreams& serialize(OutStreams& out, const KeyParameter& param) { 257 if (param.tag == tag) { 258 return V4_0::serialize(TypedTag<tag_type, tag>(), out, param); 259 } else { 260 return choose_serializer<Tail...>::serialize(out, param); 261 } 262 } 263 }; 264 265 OutStreams& serialize(OutStreams& out, const KeyParameter& param) { 266 return choose_serializer<all_tags_t>::serialize(out, param); 267 } 268 269 std::ostream& serialize(std::ostream& out, const std::vector<KeyParameter>& params) { 270 std::stringstream indirect; 271 std::stringstream elements; 272 OutStreams streams = {indirect, elements}; 273 for (const auto& param : params) { 274 serialize(streams, param); 275 } 276 if (indirect.bad() || elements.bad()) { 277 out.setstate(std::ios_base::badbit); 278 return out; 279 } 280 auto pos = indirect.tellp(); 281 if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) { 282 out.setstate(std::ios_base::badbit); 283 return out; 284 } 285 uint32_t indirect_size = pos; 286 pos = elements.tellp(); 287 if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) { 288 out.setstate(std::ios_base::badbit); 289 return out; 290 } 291 uint32_t elements_size = pos; 292 uint32_t element_count = params.size(); 293 294 out.write(reinterpret_cast<const char*>(&indirect_size), sizeof(uint32_t)); 295 296 pos = out.tellp(); 297 if (indirect_size) out << indirect.rdbuf(); 298 assert(out.tellp() - pos == indirect_size); 299 300 out.write(reinterpret_cast<const char*>(&element_count), sizeof(uint32_t)); 301 out.write(reinterpret_cast<const char*>(&elements_size), sizeof(uint32_t)); 302 303 pos = out.tellp(); 304 if (elements_size) out << elements.rdbuf(); 305 assert(out.tellp() - pos == elements_size); 306 307 return out; 308 } 309 310 struct InStreams { 311 std::istream& indirect; 312 std::istream& elements; 313 }; 314 315 InStreams& deserializeParamValue(InStreams& in, hidl_vec<uint8_t>* blob) { 316 uint32_t blob_length = 0; 317 uint32_t offset = 0; 318 in.elements.read(reinterpret_cast<char*>(&blob_length), sizeof(uint32_t)); 319 blob->resize(blob_length); 320 in.elements.read(reinterpret_cast<char*>(&offset), sizeof(uint32_t)); 321 in.indirect.seekg(offset); 322 in.indirect.read(reinterpret_cast<char*>(&(*blob)[0]), blob->size()); 323 return in; 324 } 325 326 template <typename T> 327 InStreams& deserializeParamValue(InStreams& in, T* value) { 328 in.elements.read(reinterpret_cast<char*>(value), sizeof(T)); 329 return in; 330 } 331 332 InStreams& deserialize(TAG_INVALID_t&&, InStreams& in, KeyParameter*) { 333 // there should be no invalid KeyParamaters but if handle them as zero sized. 334 return in; 335 } 336 337 template <typename T> 338 InStreams& deserialize(T&& ttag, InStreams& in, KeyParameter* param) { 339 return deserializeParamValue(in, &accessTagValue(ttag, *param)); 340 } 341 342 template <typename... T> 343 struct choose_deserializer; 344 template <typename... Tags> 345 struct choose_deserializer<MetaList<Tags...>> { 346 static InStreams& deserialize(InStreams& in, KeyParameter* param) { 347 return choose_deserializer<Tags...>::deserialize(in, param); 348 } 349 }; 350 template <> 351 struct choose_deserializer<> { 352 static InStreams& deserialize(InStreams& in, KeyParameter*) { 353 // encountered an unknown tag -> fail parsing 354 in.elements.setstate(std::ios_base::badbit); 355 return in; 356 } 357 }; 358 template <TagType tag_type, Tag tag, typename... Tail> 359 struct choose_deserializer<TypedTag<tag_type, tag>, Tail...> { 360 static InStreams& deserialize(InStreams& in, KeyParameter* param) { 361 if (param->tag == tag) { 362 return V4_0::deserialize(TypedTag<tag_type, tag>(), in, param); 363 } else { 364 return choose_deserializer<Tail...>::deserialize(in, param); 365 } 366 } 367 }; 368 369 InStreams& deserialize(InStreams& in, KeyParameter* param) { 370 in.elements.read(reinterpret_cast<char*>(¶m->tag), sizeof(Tag)); 371 return choose_deserializer<all_tags_t>::deserialize(in, param); 372 } 373 374 std::istream& deserialize(std::istream& in, std::vector<KeyParameter>* params) { 375 uint32_t indirect_size = 0; 376 in.read(reinterpret_cast<char*>(&indirect_size), sizeof(uint32_t)); 377 std::string indirect_buffer(indirect_size, '\0'); 378 if (indirect_buffer.size() != indirect_size) { 379 in.setstate(std::ios_base::badbit); 380 return in; 381 } 382 in.read(&indirect_buffer[0], indirect_buffer.size()); 383 384 uint32_t element_count = 0; 385 in.read(reinterpret_cast<char*>(&element_count), sizeof(uint32_t)); 386 uint32_t elements_size = 0; 387 in.read(reinterpret_cast<char*>(&elements_size), sizeof(uint32_t)); 388 389 std::string elements_buffer(elements_size, '\0'); 390 if (elements_buffer.size() != elements_size) { 391 in.setstate(std::ios_base::badbit); 392 return in; 393 } 394 in.read(&elements_buffer[0], elements_buffer.size()); 395 396 if (in.bad()) return in; 397 398 // TODO write one-shot stream buffer to avoid copying here 399 std::stringstream indirect(indirect_buffer); 400 std::stringstream elements(elements_buffer); 401 InStreams streams = {indirect, elements}; 402 403 params->resize(element_count); 404 405 for (uint32_t i = 0; i < element_count; ++i) { 406 deserialize(streams, &(*params)[i]); 407 } 408 return in; 409 } 410 411 void AuthorizationSet::Serialize(std::ostream* out) const { 412 serialize(*out, data_); 413 } 414 415 void AuthorizationSet::Deserialize(std::istream* in) { 416 deserialize(*in, &data_); 417 } 418 419 AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size, 420 uint64_t public_exponent) { 421 Authorization(TAG_ALGORITHM, Algorithm::RSA); 422 Authorization(TAG_KEY_SIZE, key_size); 423 Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent); 424 return *this; 425 } 426 427 AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) { 428 Authorization(TAG_ALGORITHM, Algorithm::EC); 429 Authorization(TAG_KEY_SIZE, key_size); 430 return *this; 431 } 432 433 AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(EcCurve curve) { 434 Authorization(TAG_ALGORITHM, Algorithm::EC); 435 Authorization(TAG_EC_CURVE, curve); 436 return *this; 437 } 438 439 AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) { 440 Authorization(TAG_ALGORITHM, Algorithm::AES); 441 return Authorization(TAG_KEY_SIZE, key_size); 442 } 443 444 AuthorizationSetBuilder& AuthorizationSetBuilder::TripleDesKey(uint32_t key_size) { 445 Authorization(TAG_ALGORITHM, Algorithm::TRIPLE_DES); 446 return Authorization(TAG_KEY_SIZE, key_size); 447 } 448 449 AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) { 450 Authorization(TAG_ALGORITHM, Algorithm::HMAC); 451 Authorization(TAG_KEY_SIZE, key_size); 452 return SigningKey(); 453 } 454 455 AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size, 456 uint64_t public_exponent) { 457 RsaKey(key_size, public_exponent); 458 return SigningKey(); 459 } 460 461 AuthorizationSetBuilder& AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size, 462 uint64_t public_exponent) { 463 RsaKey(key_size, public_exponent); 464 return EncryptionKey(); 465 } 466 467 AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) { 468 EcdsaKey(key_size); 469 return SigningKey(); 470 } 471 472 AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(EcCurve curve) { 473 EcdsaKey(curve); 474 return SigningKey(); 475 } 476 477 AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) { 478 AesKey(key_size); 479 return EncryptionKey(); 480 } 481 482 AuthorizationSetBuilder& AuthorizationSetBuilder::TripleDesEncryptionKey(uint32_t key_size) { 483 TripleDesKey(key_size); 484 return EncryptionKey(); 485 } 486 487 AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() { 488 Authorization(TAG_PURPOSE, KeyPurpose::SIGN); 489 return Authorization(TAG_PURPOSE, KeyPurpose::VERIFY); 490 } 491 492 AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() { 493 Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT); 494 return Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT); 495 } 496 497 AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() { 498 Authorization(TAG_DIGEST, Digest::NONE); 499 return Authorization(TAG_PADDING, PaddingMode::NONE); 500 } 501 502 AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() { 503 return Authorization(TAG_BLOCK_MODE, BlockMode::ECB); 504 } 505 506 AuthorizationSetBuilder& AuthorizationSetBuilder::GcmModeMinMacLen(uint32_t minMacLength) { 507 return BlockMode(BlockMode::GCM) 508 .Padding(PaddingMode::NONE) 509 .Authorization(TAG_MIN_MAC_LENGTH, minMacLength); 510 } 511 512 AuthorizationSetBuilder& AuthorizationSetBuilder::GcmModeMacLen(uint32_t macLength) { 513 return BlockMode(BlockMode::GCM) 514 .Padding(PaddingMode::NONE) 515 .Authorization(TAG_MAC_LENGTH, macLength); 516 } 517 518 AuthorizationSetBuilder& AuthorizationSetBuilder::BlockMode( 519 std::initializer_list<V4_0::BlockMode> blockModes) { 520 for (auto mode : blockModes) { 521 push_back(TAG_BLOCK_MODE, mode); 522 } 523 return *this; 524 } 525 526 AuthorizationSetBuilder& AuthorizationSetBuilder::Digest( 527 std::initializer_list<V4_0::Digest> digests) { 528 for (auto digest : digests) { 529 push_back(TAG_DIGEST, digest); 530 } 531 return *this; 532 } 533 534 AuthorizationSetBuilder& AuthorizationSetBuilder::Padding( 535 std::initializer_list<V4_0::PaddingMode> paddingModes) { 536 for (auto paddingMode : paddingModes) { 537 push_back(TAG_PADDING, paddingMode); 538 } 539 return *this; 540 } 541 542 } // namespace V4_0 543 } // namespace keymaster 544 } // namespace hardware 545 } // namespace android 546