vmbase: Configure stack guard from Rust

Move the thorough validation of the availability of TRNG that was
performed in assembly to Rust and call rand::init() from the entry code
of vmbase to unify the implementations.

Use TRNG from rust_entry() to configure the stack guard (see the comment
about rust_entry() ever returning). As a result, failing to configure
it will now result in a logged error message as, previously,
vmbase-based code would silently reboot, making it impossible to find
out which check had failed (see b/267262026#comment89).

Furthermore, failing to read the entropy for the u64 stack guard due to
NO_ENTROPY will now result in vmbase retrying the HVC where it
previously would abort the VM's boot.

This implementation now only accepts versions of SMCCC between 1.1 and
2.0 (excl.) and TRNG between 1.0 and 2.0 (excl.) instead of resp. 1.1
and above and 1.0 and above.

Bug: 274561905
Test: atest DebugPolicyHostTests#testNoAdbInDebugPolicy_withDebugLevelNone_boots
Test: atest rialto_test vmbase_example.integration_test
Change-Id: I5b95e77732e10ddfbc4476b6d7c698c5dc5f3b6e
diff --git a/vmbase/src/entry.rs b/vmbase/src/entry.rs
index 3e826a2..24b5035 100644
--- a/vmbase/src/entry.rs
+++ b/vmbase/src/entry.rs
@@ -15,9 +15,11 @@
 //! Rust entry point.
 
 use crate::{
-    console, heap, logger,
+    bionic, console, heap, logger,
     power::{reboot, shutdown},
+    rand,
 };
+use core::mem::size_of;
 use hyp::{self, get_mmio_guard};
 
 fn try_console_init() -> Result<(), hyp::Error> {
@@ -45,6 +47,18 @@
     logger::init().expect("Failed to initialize the logger");
     // We initialize the logger to Off (like the log crate) and clients should log::set_max_level.
 
+    const SIZE_OF_STACK_GUARD: usize = size_of::<u64>();
+    let mut stack_guard = [0u8; SIZE_OF_STACK_GUARD];
+    // We keep a null byte at the top of the stack guard to act as a string terminator.
+    let random_guard = &mut stack_guard[..(SIZE_OF_STACK_GUARD - 1)];
+
+    rand::init().expect("Failed to initialize a source of entropy");
+    rand::fill_with_entropy(random_guard).expect("Failed to get stack canary entropy");
+    bionic::__get_tls().stack_guard = u64::from_ne_bytes(stack_guard);
+
+    // Note: If rust_entry ever returned (which it shouldn't by being -> !), the compiler-injected
+    // stack guard comparison would detect a mismatch and call __stack_chk_fail.
+
     // SAFETY: `main` is provided by the application using the `main!` macro, and we make sure it
     // has the right type.
     unsafe {