blob: e35fdd36d5bf9acdcef8b057983db43b426816aa [file] [log] [blame]
Shawn Willden98b998b2018-01-20 11:48:53 -07001/*
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
20namespace android {
21namespace hardware {
Shawn Willdenf0f05d42018-05-01 17:08:39 -060022
23inline static bool operator<(const hidl_vec<uint8_t>& a, const hidl_vec<uint8_t>& b) {
Janis Danisevskis93c72762018-06-17 14:06:20 -070024 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;
Shawn Willdenf0f05d42018-05-01 17:08:39 -060027}
28
29template <size_t SIZE>
30inline 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
Shawn Willden98b998b2018-01-20 11:48:53 -070035namespace keymaster {
36namespace V4_0 {
Shawn Willdenf0f05d42018-05-01 17:08:39 -060037
38bool operator<(const HmacSharingParameters& a, const HmacSharingParameters& b) {
39 return std::tie(a.seed, a.nonce) < std::tie(b.seed, b.nonce);
40}
41
Shawn Willden98b998b2018-01-20 11:48:53 -070042namespace support {
43
44template <typename T, typename InIter>
45inline 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
51template <typename T, typename OutIter>
52inline 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
57constexpr size_t kHmacSize = 32;
58
59hidl_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
86HardwareAuthToken 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