1 /* 2 * Copyright (C) 2018 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 <hardware/hw_auth_token.h> 18 #include <keymasterV4_0/keymaster_utils.h> 19 20 namespace android { 21 namespace hardware { 22 23 inline static bool operator<(const hidl_vec<uint8_t>& a, const hidl_vec<uint8_t>& b) { 24 auto result = memcmp(a.data(), b.data(), std::min(a.size(), b.size())); 25 if (!result) return a.size() < b.size(); 26 return result < 0; 27 } 28 29 template <size_t SIZE> 30 inline static bool operator<(const hidl_array<uint8_t, SIZE>& a, 31 const hidl_array<uint8_t, SIZE>& b) { 32 return memcmp(a.data(), b.data(), SIZE) == -1; 33 } 34 35 namespace keymaster { 36 namespace V4_0 { 37 38 bool operator<(const HmacSharingParameters& a, const HmacSharingParameters& b) { 39 return std::tie(a.seed, a.nonce) < std::tie(b.seed, b.nonce); 40 } 41 42 namespace support { 43 44 template <typename T, typename InIter> 45 inline static InIter copy_bytes_from_iterator(T* value, InIter src) { 46 uint8_t* value_ptr = reinterpret_cast<uint8_t*>(value); 47 std::copy(src, src + sizeof(T), value_ptr); 48 return src + sizeof(T); 49 } 50 51 template <typename T, typename OutIter> 52 inline static OutIter copy_bytes_to_iterator(const T& value, OutIter dest) { 53 const uint8_t* value_ptr = reinterpret_cast<const uint8_t*>(&value); 54 return std::copy(value_ptr, value_ptr + sizeof(value), dest); 55 } 56 57 constexpr size_t kHmacSize = 32; 58 59 hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token) { 60 static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) + 61 sizeof(token.authenticatorId) + sizeof(token.authenticatorType) + 62 sizeof(token.timestamp) + kHmacSize == 63 sizeof(hw_auth_token_t), 64 "HardwareAuthToken content size does not match hw_auth_token_t size"); 65 66 hidl_vec<uint8_t> result; 67 result.resize(sizeof(hw_auth_token_t)); 68 auto pos = result.begin(); 69 *pos++ = 0; // Version byte 70 pos = copy_bytes_to_iterator(token.challenge, pos); 71 pos = copy_bytes_to_iterator(token.userId, pos); 72 pos = copy_bytes_to_iterator(token.authenticatorId, pos); 73 auto auth_type = htonl(static_cast<uint32_t>(token.authenticatorType)); 74 pos = copy_bytes_to_iterator(auth_type, pos); 75 auto timestamp = htonq(token.timestamp); 76 pos = copy_bytes_to_iterator(timestamp, pos); 77 if (token.mac.size() != kHmacSize) { 78 std::fill(pos, pos + kHmacSize, 0); 79 } else { 80 std::copy(token.mac.begin(), token.mac.end(), pos); 81 } 82 83 return result; 84 } 85 86 HardwareAuthToken hidlVec2AuthToken(const hidl_vec<uint8_t>& buffer) { 87 HardwareAuthToken token; 88 static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) + 89 sizeof(token.authenticatorId) + sizeof(token.authenticatorType) + 90 sizeof(token.timestamp) + kHmacSize == 91 sizeof(hw_auth_token_t), 92 "HardwareAuthToken content size does not match hw_auth_token_t size"); 93 94 if (buffer.size() != sizeof(hw_auth_token_t)) return {}; 95 96 auto pos = buffer.begin(); 97 ++pos; // skip first byte 98 pos = copy_bytes_from_iterator(&token.challenge, pos); 99 pos = copy_bytes_from_iterator(&token.userId, pos); 100 pos = copy_bytes_from_iterator(&token.authenticatorId, pos); 101 pos = copy_bytes_from_iterator(&token.authenticatorType, pos); 102 token.authenticatorType = static_cast<HardwareAuthenticatorType>( 103 ntohl(static_cast<uint32_t>(token.authenticatorType))); 104 pos = copy_bytes_from_iterator(&token.timestamp, pos); 105 token.timestamp = ntohq(token.timestamp); 106 token.mac.resize(kHmacSize); 107 std::copy(pos, pos + kHmacSize, token.mac.data()); 108 109 return token; 110 } 111 112 } // namespace support 113 } // namespace V4_0 114 } // namespace keymaster 115 } // namespace hardware 116 } // namespace android 117