1 /* 2 * Copyright (C) 2014 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 <keymaster/authorization_set.h> 18 19 #include <assert.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <stddef.h> 23 24 #include <new> 25 26 #include <keymaster/android_keymaster_utils.h> 27 #include <keymaster/logger.h> 28 29 namespace keymaster { 30 31 static inline bool is_blob_tag(keymaster_tag_t tag) { 32 return (keymaster_tag_get_type(tag) == KM_BYTES || keymaster_tag_get_type(tag) == KM_BIGNUM); 33 } 34 35 const size_t STARTING_ELEMS_CAPACITY = 8; 36 37 AuthorizationSet::AuthorizationSet(AuthorizationSetBuilder& builder) { 38 elems_ = builder.set.elems_; 39 builder.set.elems_ = NULL; 40 41 elems_size_ = builder.set.elems_size_; 42 builder.set.elems_size_ = 0; 43 44 elems_capacity_ = builder.set.elems_capacity_; 45 builder.set.elems_capacity_ = 0; 46 47 indirect_data_ = builder.set.indirect_data_; 48 builder.set.indirect_data_ = NULL; 49 50 indirect_data_capacity_ = builder.set.indirect_data_capacity_; 51 builder.set.indirect_data_capacity_ = 0; 52 53 indirect_data_size_ = builder.set.indirect_data_size_; 54 builder.set.indirect_data_size_ = 0; 55 56 error_ = builder.set.error_; 57 builder.set.error_ = OK; 58 } 59 60 AuthorizationSet::~AuthorizationSet() { 61 FreeData(); 62 } 63 64 bool AuthorizationSet::reserve_elems(size_t count) { 65 if (is_valid() != OK) 66 return false; 67 68 if (count >= elems_capacity_) { 69 keymaster_key_param_t* new_elems = new (std::nothrow) keymaster_key_param_t[count]; 70 if (new_elems == NULL) { 71 set_invalid(ALLOCATION_FAILURE); 72 return false; 73 } 74 memcpy(new_elems, elems_, sizeof(*elems_) * elems_size_); 75 delete[] elems_; 76 elems_ = new_elems; 77 elems_capacity_ = count; 78 } 79 return true; 80 } 81 82 bool AuthorizationSet::reserve_indirect(size_t length) { 83 if (is_valid() != OK) 84 return false; 85 86 if (length > indirect_data_capacity_) { 87 uint8_t* new_data = new (std::nothrow) uint8_t[length]; 88 if (new_data == NULL) { 89 set_invalid(ALLOCATION_FAILURE); 90 return false; 91 } 92 memcpy(new_data, indirect_data_, indirect_data_size_); 93 94 // Fix up the data pointers to point into the new region. 95 for (size_t i = 0; i < elems_size_; ++i) { 96 if (is_blob_tag(elems_[i].tag)) 97 elems_[i].blob.data = new_data + (elems_[i].blob.data - indirect_data_); 98 } 99 delete[] indirect_data_; 100 indirect_data_ = new_data; 101 indirect_data_capacity_ = length; 102 } 103 return true; 104 } 105 106 bool AuthorizationSet::Reinitialize(const keymaster_key_param_t* elems, const size_t count) { 107 FreeData(); 108 109 if (elems == NULL || count == 0) { 110 error_ = OK; 111 return true; 112 } 113 114 if (!reserve_elems(count)) 115 return false; 116 117 if (!reserve_indirect(ComputeIndirectDataSize(elems, count))) 118 return false; 119 120 memcpy(elems_, elems, sizeof(keymaster_key_param_t) * count); 121 elems_size_ = count; 122 CopyIndirectData(); 123 error_ = OK; 124 return true; 125 } 126 127 void AuthorizationSet::set_invalid(Error error) { 128 FreeData(); 129 error_ = error; 130 } 131 132 void AuthorizationSet::Deduplicate() { 133 qsort(elems_, elems_size_, sizeof(*elems_), 134 reinterpret_cast<int (*)(const void*, const void*)>(keymaster_param_compare)); 135 136 size_t invalid_count = 0; 137 for (size_t i = 1; i < size(); ++i) { 138 if (elems_[i - 1].tag == KM_TAG_INVALID) 139 ++invalid_count; 140 else if (keymaster_param_compare(elems_ + i - 1, elems_ + i) == 0) { 141 // Mark dups as invalid. Note that this "leaks" the data referenced by KM_BYTES and 142 // KM_BIGNUM entries, but those are just pointers into indirect_data_, so it will all 143 // get cleaned up. 144 elems_[i - 1].tag = KM_TAG_INVALID; 145 ++invalid_count; 146 } 147 } 148 if (size() > 0 && elems_[size() - 1].tag == KM_TAG_INVALID) 149 ++invalid_count; 150 151 if (invalid_count == 0) 152 return; 153 154 // Since KM_TAG_INVALID == 0, all of the invalid entries are first. 155 elems_size_ -= invalid_count; 156 memmove(elems_, elems_ + invalid_count, size() * sizeof(*elems_)); 157 } 158 159 void AuthorizationSet::CopyToParamSet(keymaster_key_param_set_t* set) const { 160 assert(set); 161 162 set->length = size(); 163 set->params = 164 reinterpret_cast<keymaster_key_param_t*>(malloc(sizeof(keymaster_key_param_t) * size())); 165 166 for (size_t i = 0; i < size(); ++i) { 167 const keymaster_key_param_t src = (*this)[i]; 168 keymaster_key_param_t& dst(set->params[i]); 169 170 dst = src; 171 keymaster_tag_type_t type = keymaster_tag_get_type(src.tag); 172 if (type == KM_BIGNUM || type == KM_BYTES) { 173 void* tmp = malloc(src.blob.data_length); 174 memcpy(tmp, src.blob.data, src.blob.data_length); 175 dst.blob.data = reinterpret_cast<uint8_t*>(tmp); 176 } 177 } 178 } 179 180 int AuthorizationSet::find(keymaster_tag_t tag, int begin) const { 181 if (is_valid() != OK) 182 return -1; 183 184 int i = ++begin; 185 while (i < (int)elems_size_ && elems_[i].tag != tag) 186 ++i; 187 if (i == (int)elems_size_) 188 return -1; 189 else 190 return i; 191 } 192 193 keymaster_key_param_t empty; 194 keymaster_key_param_t AuthorizationSet::operator[](int at) const { 195 if (is_valid() == OK && at < (int)elems_size_) { 196 return elems_[at]; 197 } 198 memset(&empty, 0, sizeof(empty)); 199 return empty; 200 } 201 202 bool AuthorizationSet::push_back(const keymaster_key_param_set_t& set) { 203 if (is_valid() != OK) 204 return false; 205 206 if (!reserve_elems(elems_size_ + set.length)) 207 return false; 208 209 if (!reserve_indirect(indirect_data_size_ + ComputeIndirectDataSize(set.params, set.length))) 210 return false; 211 212 for (size_t i = 0; i < set.length; ++i) 213 if (!push_back(set.params[i])) 214 return false; 215 216 return true; 217 } 218 219 bool AuthorizationSet::push_back(keymaster_key_param_t elem) { 220 if (is_valid() != OK) 221 return false; 222 223 if (elems_size_ >= elems_capacity_) 224 if (!reserve_elems(elems_capacity_ ? elems_capacity_ * 2 : STARTING_ELEMS_CAPACITY)) 225 return false; 226 227 if (is_blob_tag(elem.tag)) { 228 if (indirect_data_capacity_ - indirect_data_size_ < elem.blob.data_length) 229 if (!reserve_indirect(2 * (indirect_data_capacity_ + elem.blob.data_length))) 230 return false; 231 232 memcpy(indirect_data_ + indirect_data_size_, elem.blob.data, elem.blob.data_length); 233 elem.blob.data = indirect_data_ + indirect_data_size_; 234 indirect_data_size_ += elem.blob.data_length; 235 } 236 237 elems_[elems_size_++] = elem; 238 return true; 239 } 240 241 static size_t serialized_size(const keymaster_key_param_t& param) { 242 switch (keymaster_tag_get_type(param.tag)) { 243 case KM_INVALID: 244 return sizeof(uint32_t); 245 case KM_ENUM: 246 case KM_ENUM_REP: 247 case KM_UINT: 248 case KM_UINT_REP: 249 return sizeof(uint32_t) * 2; 250 case KM_ULONG: 251 case KM_ULONG_REP: 252 case KM_DATE: 253 return sizeof(uint32_t) + sizeof(uint64_t); 254 case KM_BOOL: 255 return sizeof(uint32_t) + 1; 256 case KM_BIGNUM: 257 case KM_BYTES: 258 return sizeof(uint32_t) * 3; 259 } 260 261 return sizeof(uint32_t); 262 } 263 264 static uint8_t* serialize(const keymaster_key_param_t& param, uint8_t* buf, const uint8_t* end, 265 const uint8_t* indirect_base) { 266 buf = append_uint32_to_buf(buf, end, param.tag); 267 switch (keymaster_tag_get_type(param.tag)) { 268 case KM_INVALID: 269 break; 270 case KM_ENUM: 271 case KM_ENUM_REP: 272 buf = append_uint32_to_buf(buf, end, param.enumerated); 273 break; 274 case KM_UINT: 275 case KM_UINT_REP: 276 buf = append_uint32_to_buf(buf, end, param.integer); 277 break; 278 case KM_ULONG: 279 case KM_ULONG_REP: 280 buf = append_uint64_to_buf(buf, end, param.long_integer); 281 break; 282 case KM_DATE: 283 buf = append_uint64_to_buf(buf, end, param.date_time); 284 break; 285 case KM_BOOL: 286 if (buf < end) 287 *buf = static_cast<uint8_t>(param.boolean); 288 buf++; 289 break; 290 case KM_BIGNUM: 291 case KM_BYTES: 292 buf = append_uint32_to_buf(buf, end, param.blob.data_length); 293 buf = append_uint32_to_buf(buf, end, param.blob.data - indirect_base); 294 break; 295 } 296 return buf; 297 } 298 299 static bool deserialize(keymaster_key_param_t* param, const uint8_t** buf_ptr, const uint8_t* end, 300 const uint8_t* indirect_base, const uint8_t* indirect_end) { 301 if (!copy_uint32_from_buf(buf_ptr, end, ¶m->tag)) 302 return false; 303 304 switch (keymaster_tag_get_type(param->tag)) { 305 case KM_INVALID: 306 return false; 307 case KM_ENUM: 308 case KM_ENUM_REP: 309 return copy_uint32_from_buf(buf_ptr, end, ¶m->enumerated); 310 case KM_UINT: 311 case KM_UINT_REP: 312 return copy_uint32_from_buf(buf_ptr, end, ¶m->integer); 313 case KM_ULONG: 314 case KM_ULONG_REP: 315 return copy_uint64_from_buf(buf_ptr, end, ¶m->long_integer); 316 case KM_DATE: 317 return copy_uint64_from_buf(buf_ptr, end, ¶m->date_time); 318 break; 319 case KM_BOOL: 320 if (*buf_ptr < end) { 321 param->boolean = static_cast<bool>(**buf_ptr); 322 (*buf_ptr)++; 323 return true; 324 } 325 return false; 326 327 case KM_BIGNUM: 328 case KM_BYTES: { 329 uint32_t offset; 330 if (!copy_uint32_from_buf(buf_ptr, end, ¶m->blob.data_length) || 331 !copy_uint32_from_buf(buf_ptr, end, &offset)) 332 return false; 333 if (param->blob.data_length + offset < param->blob.data_length || // Overflow check 334 static_cast<ptrdiff_t>(offset) > indirect_end - indirect_base || 335 static_cast<ptrdiff_t>(offset + param->blob.data_length) > indirect_end - indirect_base) 336 return false; 337 param->blob.data = indirect_base + offset; 338 return true; 339 } 340 } 341 342 return false; 343 } 344 345 size_t AuthorizationSet::SerializedSizeOfElements() const { 346 size_t size = 0; 347 for (size_t i = 0; i < elems_size_; ++i) { 348 size += serialized_size(elems_[i]); 349 } 350 return size; 351 } 352 353 size_t AuthorizationSet::SerializedSize() const { 354 return sizeof(uint32_t) + // Size of indirect_data_ 355 indirect_data_size_ + // indirect_data_ 356 sizeof(uint32_t) + // Number of elems_ 357 sizeof(uint32_t) + // Size of elems_ 358 SerializedSizeOfElements(); // elems_ 359 } 360 361 uint8_t* AuthorizationSet::Serialize(uint8_t* buf, const uint8_t* end) const { 362 buf = append_size_and_data_to_buf(buf, end, indirect_data_, indirect_data_size_); 363 buf = append_uint32_to_buf(buf, end, elems_size_); 364 buf = append_uint32_to_buf(buf, end, SerializedSizeOfElements()); 365 for (size_t i = 0; i < elems_size_; ++i) { 366 buf = serialize(elems_[i], buf, end, indirect_data_); 367 } 368 return buf; 369 } 370 371 bool AuthorizationSet::DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end) { 372 UniquePtr<uint8_t[]> indirect_buf; 373 if (!copy_size_and_data_from_buf(buf_ptr, end, &indirect_data_size_, &indirect_buf)) { 374 LOG_E("Malformed data found in AuthorizationSet deserialization", 0); 375 set_invalid(MALFORMED_DATA); 376 return false; 377 } 378 indirect_data_ = indirect_buf.release(); 379 return true; 380 } 381 382 bool AuthorizationSet::DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end) { 383 uint32_t elements_count; 384 uint32_t elements_size; 385 if (!copy_uint32_from_buf(buf_ptr, end, &elements_count) || 386 !copy_uint32_from_buf(buf_ptr, end, &elements_size)) { 387 LOG_E("Malformed data found in AuthorizationSet deserialization", 0); 388 set_invalid(MALFORMED_DATA); 389 return false; 390 } 391 392 // Note that the following validation of elements_count is weak, but it prevents allocation of 393 // elems_ arrays which are clearly too large to be reasonable. 394 if (static_cast<ptrdiff_t>(elements_size) > end - *buf_ptr || 395 elements_count * sizeof(uint32_t) > elements_size || 396 *buf_ptr + (elements_count * sizeof(*elems_)) < *buf_ptr) { 397 LOG_E("Malformed data found in AuthorizationSet deserialization", 0); 398 set_invalid(MALFORMED_DATA); 399 return false; 400 } 401 402 if (!reserve_elems(elements_count)) 403 return false; 404 405 uint8_t* indirect_end = indirect_data_ + indirect_data_size_; 406 const uint8_t* elements_end = *buf_ptr + elements_size; 407 for (size_t i = 0; i < elements_count; ++i) { 408 if (!deserialize(elems_ + i, buf_ptr, elements_end, indirect_data_, indirect_end)) { 409 LOG_E("Malformed data found in AuthorizationSet deserialization", 0); 410 set_invalid(MALFORMED_DATA); 411 return false; 412 } 413 } 414 elems_size_ = elements_count; 415 return true; 416 } 417 418 bool AuthorizationSet::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) { 419 FreeData(); 420 421 if (!DeserializeIndirectData(buf_ptr, end) || !DeserializeElementsData(buf_ptr, end)) 422 return false; 423 424 if (indirect_data_size_ != ComputeIndirectDataSize(elems_, elems_size_)) { 425 LOG_E("Malformed data found in AuthorizationSet deserialization", 0); 426 set_invalid(MALFORMED_DATA); 427 return false; 428 } 429 return true; 430 } 431 432 void AuthorizationSet::Clear() { 433 memset_s(elems_, 0, elems_size_ * sizeof(keymaster_key_param_t)); 434 memset_s(indirect_data_, 0, indirect_data_size_); 435 elems_size_ = 0; 436 indirect_data_size_ = 0; 437 } 438 439 void AuthorizationSet::FreeData() { 440 Clear(); 441 442 delete[] elems_; 443 delete[] indirect_data_; 444 445 elems_ = NULL; 446 indirect_data_ = NULL; 447 elems_capacity_ = 0; 448 indirect_data_capacity_ = 0; 449 error_ = OK; 450 } 451 452 /* static */ 453 size_t AuthorizationSet::ComputeIndirectDataSize(const keymaster_key_param_t* elems, size_t count) { 454 size_t size = 0; 455 for (size_t i = 0; i < count; ++i) { 456 if (is_blob_tag(elems[i].tag)) { 457 size += elems[i].blob.data_length; 458 } 459 } 460 return size; 461 } 462 463 void AuthorizationSet::CopyIndirectData() { 464 memset_s(indirect_data_, 0, indirect_data_capacity_); 465 466 uint8_t* indirect_data_pos = indirect_data_; 467 for (size_t i = 0; i < elems_size_; ++i) { 468 assert(indirect_data_pos <= indirect_data_ + indirect_data_capacity_); 469 if (is_blob_tag(elems_[i].tag)) { 470 memcpy(indirect_data_pos, elems_[i].blob.data, elems_[i].blob.data_length); 471 elems_[i].blob.data = indirect_data_pos; 472 indirect_data_pos += elems_[i].blob.data_length; 473 } 474 } 475 assert(indirect_data_pos == indirect_data_ + indirect_data_capacity_); 476 indirect_data_size_ = indirect_data_pos - indirect_data_; 477 } 478 479 size_t AuthorizationSet::GetTagCount(keymaster_tag_t tag) const { 480 size_t count = 0; 481 for (int pos = -1; (pos = find(tag, pos)) != -1;) 482 ++count; 483 return count; 484 } 485 486 bool AuthorizationSet::GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const { 487 int pos = find(tag); 488 if (pos == -1) { 489 return false; 490 } 491 *val = elems_[pos].enumerated; 492 return true; 493 } 494 495 bool AuthorizationSet::GetTagValueEnumRep(keymaster_tag_t tag, size_t instance, 496 uint32_t* val) const { 497 size_t count = 0; 498 int pos = -1; 499 while (count <= instance) { 500 pos = find(tag, pos); 501 if (pos == -1) { 502 return false; 503 } 504 ++count; 505 } 506 *val = elems_[pos].enumerated; 507 return true; 508 } 509 510 bool AuthorizationSet::GetTagValueInt(keymaster_tag_t tag, uint32_t* val) const { 511 int pos = find(tag); 512 if (pos == -1) { 513 return false; 514 } 515 *val = elems_[pos].integer; 516 return true; 517 } 518 519 bool AuthorizationSet::GetTagValueIntRep(keymaster_tag_t tag, size_t instance, 520 uint32_t* val) const { 521 size_t count = 0; 522 int pos = -1; 523 while (count <= instance) { 524 pos = find(tag, pos); 525 if (pos == -1) { 526 return false; 527 } 528 ++count; 529 } 530 *val = elems_[pos].integer; 531 return true; 532 } 533 534 bool AuthorizationSet::GetTagValueLong(keymaster_tag_t tag, uint64_t* val) const { 535 int pos = find(tag); 536 if (pos == -1) { 537 return false; 538 } 539 *val = elems_[pos].long_integer; 540 return true; 541 } 542 543 bool AuthorizationSet::GetTagValueLongRep(keymaster_tag_t tag, size_t instance, 544 uint64_t* val) const { 545 size_t count = 0; 546 int pos = -1; 547 while (count <= instance) { 548 pos = find(tag, pos); 549 if (pos == -1) { 550 return false; 551 } 552 ++count; 553 } 554 *val = elems_[pos].long_integer; 555 return true; 556 } 557 558 bool AuthorizationSet::GetTagValueDate(keymaster_tag_t tag, uint64_t* val) const { 559 int pos = find(tag); 560 if (pos == -1) { 561 return false; 562 } 563 *val = elems_[pos].date_time; 564 return true; 565 } 566 567 bool AuthorizationSet::GetTagValueBlob(keymaster_tag_t tag, keymaster_blob_t* val) const { 568 int pos = find(tag); 569 if (pos == -1) { 570 return false; 571 } 572 *val = elems_[pos].blob; 573 return true; 574 } 575 576 bool AuthorizationSet::GetTagValueBool(keymaster_tag_t tag) const { 577 int pos = find(tag); 578 if (pos == -1) { 579 return false; 580 } 581 assert(elems_[pos].boolean); 582 return elems_[pos].boolean; 583 } 584 585 bool AuthorizationSet::ContainsEnumValue(keymaster_tag_t tag, uint32_t value) const { 586 for (auto& entry : *this) 587 if (entry.tag == tag && entry.enumerated == value) 588 return true; 589 return false; 590 } 591 592 } // namespace keymaster 593