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 
17 //! KeyMint helper functions that are only suitable for non-secure environments
18 //! such as Cuttlefish.
19 
20 use kmr_hal::env::get_property;
21 use log::error;
22 
23 /// Populate attestation ID information based on properties (where available).
24 /// Retrieving the serial number requires SELinux permission.
attestation_id_info() -> kmr_wire::AttestationIdInfo25 pub fn attestation_id_info() -> kmr_wire::AttestationIdInfo {
26     let prop = |name| {
27         get_property(name)
28             .unwrap_or_else(|_| format!("{} unavailable", name))
29             .as_bytes()
30             .to_vec()
31     };
32     kmr_wire::AttestationIdInfo {
33         brand: prop("ro.product.brand"),
34         device: prop("ro.product.device"),
35         product: prop("ro.product.name"),
36         serial: prop("ro.serialno"),
37         manufacturer: prop("ro.product.manufacturer"),
38         model: prop("ro.product.model"),
39         // Currently modem_simulator always returns one fixed value. See `handleGetIMEI` in
40         // device/google/cuttlefish/host/commands/modem_simulator/misc_service.cpp for more details.
41         // TODO(b/263188546): Use device-specific IMEI values when available.
42         imei: b"867400022047199".to_vec(),
43         imei2: b"867400022047199".to_vec(),
44         meid: vec![],
45     }
46 }
47 
48 /// Get boot information based on system properties.
get_boot_info() -> kmr_wire::SetBootInfoRequest49 pub fn get_boot_info() -> kmr_wire::SetBootInfoRequest {
50     // No access to a verified boot key.
51     let verified_boot_key = vec![0; 32];
52     let vbmeta_digest = get_property("ro.boot.vbmeta.digest").unwrap_or_else(|_| "00".repeat(32));
53     let verified_boot_hash = hex::decode(&vbmeta_digest).unwrap_or_else(|_e| {
54         error!("failed to parse hex data in '{}'", vbmeta_digest);
55         vec![0; 32]
56     });
57     let device_boot_locked = match get_property("ro.boot.vbmeta.device_state")
58         .unwrap_or_else(|_| "no-prop".to_string())
59         .as_str()
60     {
61         "locked" => true,
62         "unlocked" => false,
63         v => {
64             error!("Unknown device_state '{}', treating as unlocked", v);
65             false
66         }
67     };
68     let verified_boot_state = match get_property("ro.boot.verifiedbootstate")
69         .unwrap_or_else(|_| "no-prop".to_string())
70         .as_str()
71     {
72         "green" => 0,  // Verified
73         "yellow" => 1, // SelfSigned
74         "orange" => 2, // Unverified,
75         "red" => 3,    // Failed,
76         v => {
77             error!("Unknown boot state '{}', treating as Unverified", v);
78             2
79         }
80     };
81 
82     // Attempt to get the boot patchlevel from a system property.  This requires an SELinux
83     // permission, so fall back to re-using the OS patchlevel if this can't be done.
84     let boot_patchlevel_prop = get_property("ro.vendor.boot_security_patch").unwrap_or_else(|e| {
85         error!("Failed to retrieve boot patchlevel: {:?}", e);
86         get_property(kmr_hal::env::OS_PATCHLEVEL_PROPERTY)
87             .unwrap_or_else(|_| "1970-09-19".to_string())
88     });
89     let boot_patchlevel =
90         kmr_hal::env::extract_patchlevel(&boot_patchlevel_prop).unwrap_or(19700919);
91 
92     kmr_wire::SetBootInfoRequest {
93         verified_boot_key,
94         device_boot_locked,
95         verified_boot_state,
96         verified_boot_hash,
97         boot_patchlevel,
98     }
99 }
100