1 /*
2  * Copyright (C) 2024 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/libs/config/secure_hals.h"
17 
18 #include <cctype>
19 #include <set>
20 #include <string>
21 #include <unordered_map>
22 
23 #include <android-base/no_destructor.h>
24 #include <android-base/strings.h>
25 
26 #include "common/libs/utils/result.h"
27 
28 using android::base::NoDestructor;
29 using android::base::Tokenize;
30 
31 namespace cuttlefish {
32 namespace {
33 
__anonb8cfac940202null34 NoDestructor<std::unordered_map<std::string_view, SecureHal>> kMapping([] {
35   return std::unordered_map<std::string_view, SecureHal>{
36       {"keymint", SecureHal::kHostKeymintSecure},
37       {"host_secure_keymint", SecureHal::kHostKeymintSecure},
38       {"host_keymint_secure", SecureHal::kHostKeymintSecure},
39       {"guest_keymint_trusty_insecure", SecureHal::kGuestKeymintTrustyInsecure},
40       {"guest_keymint_insecure_trusty", SecureHal::kGuestKeymintTrustyInsecure},
41       {"guest_gatekeeper_insecure", SecureHal::kGuestGatekeeperInsecure},
42       {"guest_insecure_gatekeeper", SecureHal::kGuestGatekeeperInsecure},
43       {"guest_insecure_keymint", SecureHal::kGuestKeymintInsecure},
44       {"guest_keymint_insecure", SecureHal::kGuestKeymintInsecure},
45       {"gatekeeper", SecureHal::kHostGatekeeperSecure},
46       {"host_gatekeeper_secure", SecureHal::kHostGatekeeperSecure},
47       {"host_secure_gatekeeper", SecureHal::kHostGatekeeperSecure},
48       {"host_gatekeeper_insecure", SecureHal::kHostGatekeeperInsecure},
49       {"host_insecure_gatekeeper", SecureHal::kHostGatekeeperInsecure},
50       {"oemlock", SecureHal::kHostOemlockSecure},
51       {"host_oemlock_secure", SecureHal::kHostOemlockSecure},
52       {"host_secure_oemlock", SecureHal::kHostOemlockSecure},
53   };
54 }());
55 
56 }  // namespace
57 
ParseSecureHal(std::string mode)58 Result<SecureHal> ParseSecureHal(std::string mode) {
59   for (char& c : mode) {
60     c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
61   }
62   auto it = kMapping->find(mode);
63   CF_EXPECTF(it != kMapping->end(), "Unknown secure HAL '{}'", mode);
64   return it->second;
65 }
66 
ParseSecureHals(const std::string & hals)67 Result<std::set<SecureHal>> ParseSecureHals(const std::string& hals) {
68   std::set<SecureHal> args_set;
69   for (auto& hal : Tokenize(hals, ",:;|/\\+")) {
70     args_set.emplace(CF_EXPECT(ParseSecureHal(hal)));
71   }
72   return args_set;
73 }
74 
ValidateSecureHals(const std::set<SecureHal> & secure_hals)75 Result<void> ValidateSecureHals(const std::set<SecureHal>& secure_hals) {
76   auto keymint_impls =
77       secure_hals.count(SecureHal::kGuestKeymintInsecure) +
78       secure_hals.count(SecureHal::kGuestKeymintTrustyInsecure) +
79       secure_hals.count(SecureHal::kHostKeymintInsecure) +
80       secure_hals.count(SecureHal::kHostKeymintSecure);
81   CF_EXPECT_LE(keymint_impls, 1, "Choose at most one keymint implementation");
82 
83   auto gatekeeper_impls =
84       secure_hals.count(SecureHal::kGuestGatekeeperInsecure) +
85       secure_hals.count(SecureHal::kHostGatekeeperInsecure) +
86       secure_hals.count(SecureHal::kHostGatekeeperSecure);
87   CF_EXPECT_LE(gatekeeper_impls, 1,
88                "Choose at most one gatekeeper implementation");
89 
90   auto oemlock_impls = secure_hals.count(SecureHal::kHostOemlockInsecure) +
91                        secure_hals.count(SecureHal::kHostOemlockSecure);
92   CF_EXPECT_LE(oemlock_impls, 1, "Choose at most one oemlock implementation");
93 
94   return {};
95 }
96 
ToString(SecureHal hal_in)97 std::string ToString(SecureHal hal_in) {
98   switch (hal_in) {
99     case SecureHal::kGuestGatekeeperInsecure:
100       return "guest_gatekeeper_insecure";
101     case SecureHal::kGuestKeymintInsecure:
102       return "guest_keymint_insecure";
103     case SecureHal::kGuestKeymintTrustyInsecure:
104       return "guest_keymint_trusty_insecure";
105     case SecureHal::kHostKeymintInsecure:
106       return "host_keymint_insecure";
107     case SecureHal::kHostKeymintSecure:
108       return "host_keymint_secure";
109     case SecureHal::kHostGatekeeperInsecure:
110       return "host_gatekeeper_insecure";
111     case SecureHal::kHostGatekeeperSecure:
112       return "host_gatekeeper_secure";
113     case SecureHal::kHostOemlockInsecure:
114       return "host_oemlock_insecure";
115     case SecureHal::kHostOemlockSecure:
116       return "host_oemlock_secure";
117   }
118 }
119 
120 }  // namespace cuttlefish
121