1 //
2 // Copyright (C) 2023 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 "host/commands/secure_env/oemlock/oemlock_responder.h"
17
18 #include "common/libs/security/oemlock.h"
19
20 namespace cuttlefish {
21 namespace oemlock {
22
OemLockResponder(transport::Channel & channel,OemLock & oemlock,std::timed_mutex & lock)23 OemLockResponder::OemLockResponder(transport::Channel& channel,
24 OemLock& oemlock, std::timed_mutex& lock)
25 : channel_(channel), oemlock_(oemlock), lock_(lock) {}
26
ProcessMessage()27 Result<void> OemLockResponder::ProcessMessage() {
28 CF_EXPECT(channel_.WaitForMessage(), "Could not receive message");
29
30 {
31 std::lock_guard lock(lock_);
32 LOG(DEBUG) << "Receiving oemlock command";
33 auto request =
34 CF_EXPECT(channel_.ReceiveMessage(), "Could not receive message");
35
36 bool result = false;
37 switch (secure_env::OemLockField(request->command)) {
38 case secure_env::OemLockField::ALLOWED_BY_CARRIER: {
39 if (request->payload_size == 0) {
40 result = CF_EXPECT(oemlock_.IsOemUnlockAllowedByCarrier());
41 } else if (request->payload_size == sizeof(bool)) {
42 result = *reinterpret_cast<bool*>(request->payload);
43 CF_EXPECT(oemlock_.SetOemUnlockAllowedByCarrier(result));
44 }
45 break;
46 }
47
48 case secure_env::OemLockField::ALLOWED_BY_DEVICE: {
49 if (request->payload_size == 0) {
50 result = CF_EXPECT(oemlock_.IsOemUnlockAllowedByDevice());
51 } else if (request->payload_size == sizeof(bool)) {
52 result = *reinterpret_cast<bool*>(request->payload);
53 CF_EXPECT(oemlock_.SetOemUnlockAllowedByDevice(result));
54 }
55 break;
56 }
57
58 case secure_env::OemLockField::ALLOWED: {
59 if (request->payload_size == 0) {
60 result = CF_EXPECT(oemlock_.IsOemUnlockAllowed());
61 }
62 break;
63 }
64
65 case secure_env::OemLockField::LOCKED: {
66 if (request->payload_size == 0) {
67 result = CF_EXPECT(oemlock_.IsOemLocked());
68 } else if (request->payload_size == sizeof(bool)) {
69 result = *reinterpret_cast<bool*>(request->payload);
70 CF_EXPECT(oemlock_.SetOemLocked(result));
71 }
72 break;
73 }
74
75 default:
76 return CF_ERR("Unrecognized message id "
77 << reinterpret_cast<uint32_t>(request->command));
78 }
79
80 auto message =
81 CF_EXPECT(transport::CreateMessage(request->command, sizeof(bool)),
82 "Failed to allocate message for oemlock response");
83 memcpy(message->payload, &result, sizeof(bool));
84 LOG(DEBUG) << "Sending oemlock response";
85 CF_EXPECT(channel_.SendResponse(*message),
86 "Could not answer to "
87 << reinterpret_cast<uint32_t>(request->command)
88 << " request");
89 }
90
91 return {};
92 }
93
94 } // namespace oemlock
95 } // namespace cuttlefish
96