Build Rust bindings

Converts the CMake build for Rust into an Android.bp one.
Resulting Rust bindings are only available to the `openssl` crate, as
they are raw bindings and should have a safe wrapper before anyone else
uses them.

Bug: 177080016
Test: mm
Change-Id: I81e85b663c6ac7539395b54dad7e224e2b3f5433
Merged-In: I81e85b663c6ac7539395b54dad7e224e2b3f5433
(cherry picked from commit aa347ab80ee55e0594c1988abf6fbcfb5cd80a11)
(cherry picked from commit 41f4133e1638629f03097fa20dae67eec8639ee1)
Merged-In: I81e85b663c6ac7539395b54dad7e224e2b3f5433
diff --git a/Android.bp b/Android.bp
index 84c70c7..3629a11 100644
--- a/Android.bp
+++ b/Android.bp
@@ -566,3 +566,63 @@
         "src/util/fipstools/test_fips.c",
     ],
 }
+
+// Rust bindings
+rust_bindgen {
+    name: "libbssl_sys_raw",
+    source_stem: "bindings",
+    crate_name: "bssl_sys_raw",
+    host_supported: true,
+    wrapper_src: "src/rust/wrapper.h",
+    bindgen_flags: [
+        "--no-derive-default",
+        "--enable-function-attribute-detection",
+        "--use-core",
+        "--size_t-is-usize",
+        "--default-macro-constant-type=signed",
+        "--rustified-enum=point_conversion_form_t",
+        // These are not BoringSSL symbols, they are from glibc
+        // and are not relevant to the build besides throwing warnings
+        // about their 'long double' (aka u128) not being FFI safe.
+        // We block those functions so that the build doesn't
+        // spam warnings.
+        //
+        // https://github.com/rust-lang/rust-bindgen/issues/1549 describes the current problem
+        // and other folks' solutions.
+        "--blocklist-function=strtold",
+        "--blocklist-function=qecvt",
+        "--blocklist-function=qecvt_r",
+        "--blocklist-function=qgcvt",
+        "--blocklist-function=qfcvt",
+        "--blocklist-function=qfcvt_r",
+    ],
+    shared_libs: [
+        "libcrypto",
+        "libssl",
+    ],
+}
+
+cc_library_static {
+    name: "libbssl_rust_support",
+    host_supported: true,
+    defaults: ["boringssl_flags"],
+    srcs: ["src/rust/rust_wrapper.c"],
+    shared_libs: [
+        "libcrypto",
+        "libssl",
+    ],
+}
+
+rust_library {
+    name: "libbssl_ffi",
+    host_supported: true,
+    crate_name: "bssl_ffi",
+    visibility: ["//external/rust/crates/openssl"],
+    srcs: ["src/rust/src/lib.rs"],
+    // Since libbssl_sys_raw is not publically visible, we can't
+    // accidentally force a double-link by linking statically, so do so.
+    rlibs: ["libbssl_sys_raw"],
+    static_libs: [
+        "libbssl_rust_support",
+    ],
+}
diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs
index d8c2c00..b691bab 100644
--- a/src/rust/src/lib.rs
+++ b/src/rust/src/lib.rs
@@ -2,8 +2,8 @@
 #![allow(non_camel_case_types)]
 #![allow(non_snake_case)]
 
-// populated by cmake
-${INCLUDES}
+// ANDROID: Use Soong-generated bindings rather than CMake-generated
+pub use bssl_sys_raw::*;
 
 pub fn ERR_GET_LIB(packed_error: u32) -> i32 {
     unsafe { ERR_GET_LIB_RUST(packed_error) }