authorization_set.cpp 20 KB

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