[bssl] Add HKDF wrapper to libbssl

Test: atest libbssl_avf_nostd.test
Bug: 301068421
Change-Id: Iffe99f3cb609215680b7d44bde8ae0ee5c502171
diff --git a/libs/bssl/src/digest.rs b/libs/bssl/src/digest.rs
index 47e4aba..49e66e6 100644
--- a/libs/bssl/src/digest.rs
+++ b/libs/bssl/src/digest.rs
@@ -32,7 +32,6 @@
     }
 
     /// Returns a `Digester` implementing `SHA-512` algorithm.
-    #[allow(dead_code)]
     pub fn sha512() -> Self {
         // SAFETY: This function does not access any Rust variables and simply returns
         // a pointer to the static variable in BoringSSL.
diff --git a/libs/bssl/src/hkdf.rs b/libs/bssl/src/hkdf.rs
new file mode 100644
index 0000000..5dc6876
--- /dev/null
+++ b/libs/bssl/src/hkdf.rs
@@ -0,0 +1,49 @@
+// Copyright 2023, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Wrappers of the HKDF functions in BoringSSL hkdf.h.
+
+use crate::digest::Digester;
+use crate::util::check_int_result;
+use bssl_avf_error::{ApiName, Result};
+use bssl_ffi::HKDF;
+
+/// Computes HKDF (as specified by [RFC 5869]) of initial keying material `secret` with
+/// `salt` and `info` using the given `digester`.
+///
+/// [RFC 5869]: https://www.rfc-editor.org/rfc/rfc5869.html
+pub fn hkdf<const N: usize>(
+    secret: &[u8],
+    salt: &[u8],
+    info: &[u8],
+    digester: Digester,
+) -> Result<[u8; N]> {
+    let mut key = [0u8; N];
+    // SAFETY: Only reads from/writes to the provided slices and the digester was non-null.
+    let ret = unsafe {
+        HKDF(
+            key.as_mut_ptr(),
+            key.len(),
+            digester.0,
+            secret.as_ptr(),
+            secret.len(),
+            salt.as_ptr(),
+            salt.len(),
+            info.as_ptr(),
+            info.len(),
+        )
+    };
+    check_int_result(ret, ApiName::HKDF)?;
+    Ok(key)
+}
diff --git a/libs/bssl/src/lib.rs b/libs/bssl/src/lib.rs
index 1824080..4b9ff59 100644
--- a/libs/bssl/src/lib.rs
+++ b/libs/bssl/src/lib.rs
@@ -21,10 +21,13 @@
 mod cbb;
 mod digest;
 mod ec_key;
+mod hkdf;
 mod hmac;
 mod util;
 
 pub use bssl_avf_error::{ApiName, Error, Result};
 pub use cbb::CbbFixed;
+pub use digest::Digester;
 pub use ec_key::{EcKey, ZVec};
+pub use hkdf::hkdf;
 pub use hmac::hmac_sha256;