idsig: Migrate from ring to the openssl crate

Bug: 232676161
Test: atest libidsig.test
Change-Id: Icdda672a802e24f13ca071312d40bc1b44665155
diff --git a/libs/idsig/Android.bp b/libs/idsig/Android.bp
index 3f70a64..2e9c663 100644
--- a/libs/idsig/Android.bp
+++ b/libs/idsig/Android.bp
@@ -11,8 +11,8 @@
     rustlibs: [
         "libanyhow",
         "libbyteorder",
-        "libring",
         "libnum_traits",
+        "libopenssl",
     ],
     proc_macros: ["libnum_derive"],
 }
diff --git a/libs/idsig/src/apksigv4.rs b/libs/idsig/src/apksigv4.rs
index a5578d8..3004ed1 100644
--- a/libs/idsig/src/apksigv4.rs
+++ b/libs/idsig/src/apksigv4.rs
@@ -175,7 +175,7 @@
 
         // Create hash tree (and root hash)
         let algorithm = match algorithm {
-            HashAlgorithm::SHA256 => &ring::digest::SHA256,
+            HashAlgorithm::SHA256 => openssl::hash::MessageDigest::sha256(),
         };
         let hash_tree = HashTree::from(&mut apk, size, salt, block_size, algorithm)?;
 
diff --git a/libs/idsig/src/hashtree.rs b/libs/idsig/src/hashtree.rs
index 63f83ea..038f839 100644
--- a/libs/idsig/src/hashtree.rs
+++ b/libs/idsig/src/hashtree.rs
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-pub use ring::digest::{Algorithm, Digest};
-
-use ring::digest;
+use openssl::hash::{DigestBytes, Hasher, MessageDigest};
 use std::io::{Cursor, Read, Result, Write};
 
 /// `HashTree` is a merkle tree (and its root hash) that is compatible with fs-verity.
@@ -35,7 +33,7 @@
         input_size: usize,
         salt: &[u8],
         block_size: usize,
-        algorithm: &'static Algorithm,
+        algorithm: MessageDigest,
     ) -> Result<Self> {
         let salt = zero_pad_salt(salt, algorithm);
         let tree = generate_hash_tree(input, input_size, &salt, block_size, algorithm)?;
@@ -45,10 +43,10 @@
         let root_hash = if tree.is_empty() {
             let mut data = Vec::new();
             input.read_to_end(&mut data)?;
-            hash_one_block(&data, &salt, block_size, algorithm).as_ref().to_vec()
+            hash_one_block(&data, &salt, block_size, algorithm)?.as_ref().to_vec()
         } else {
             let first_block = &tree[0..block_size];
-            hash_one_block(first_block, &salt, block_size, algorithm).as_ref().to_vec()
+            hash_one_block(first_block, &salt, block_size, algorithm)?.as_ref().to_vec()
         };
         Ok(HashTree { tree, root_hash })
     }
@@ -69,9 +67,9 @@
     input_size: usize,
     salt: &[u8],
     block_size: usize,
-    algorithm: &'static Algorithm,
+    algorithm: MessageDigest,
 ) -> Result<Vec<u8>> {
-    let digest_size = algorithm.output_len;
+    let digest_size = algorithm.size();
     let levels = calc_hash_levels(input_size, block_size, digest_size);
     let tree_size = levels.iter().map(|r| r.len()).sum();
 
@@ -89,7 +87,7 @@
             let mut num_blocks = (input_size + block_size - 1) / block_size;
             while num_blocks > 0 {
                 input.read_exact(&mut a_block)?;
-                let h = hash_one_block(&a_block, salt, block_size, algorithm);
+                let h = hash_one_block(&a_block, salt, block_size, algorithm)?;
                 level0.write_all(h.as_ref()).unwrap();
                 num_blocks -= 1;
             }
@@ -102,10 +100,10 @@
             let cur_and_prev = &mut hash_tree[cur.start..prev.end];
             let (cur, prev) = cur_and_prev.split_at_mut(prev.start - cur.start);
             let mut cur = Cursor::new(cur);
-            prev.chunks(block_size).for_each(|data| {
-                let h = hash_one_block(data, salt, block_size, algorithm);
+            for data in prev.chunks(block_size) {
+                let h = hash_one_block(data, salt, block_size, algorithm)?;
                 cur.write_all(h.as_ref()).unwrap();
-            });
+            }
         }
     }
     Ok(hash_tree)
@@ -117,14 +115,14 @@
     input: &[u8],
     salt: &[u8],
     block_size: usize,
-    algorithm: &'static Algorithm,
-) -> Digest {
-    let mut ctx = digest::Context::new(algorithm);
-    ctx.update(salt);
-    ctx.update(input);
+    algorithm: MessageDigest,
+) -> Result<DigestBytes> {
+    let mut ctx = Hasher::new(algorithm)?;
+    ctx.update(salt)?;
+    ctx.update(input)?;
     let pad_size = block_size - input.len();
-    ctx.update(&vec![0; pad_size]);
-    ctx.finish()
+    ctx.update(&vec![0; pad_size])?;
+    Ok(ctx.finish()?)
 }
 
 type Range = std::ops::Range<usize>;
@@ -180,11 +178,11 @@
 /// If a salt was specified, then it’s zero-padded to the closest multiple of the input size of the
 /// hash algorithm’s compression function, e.g. 64 bytes for SHA-256 or 128 bytes for SHA-512. The
 /// padded salt is prepended to every data or Merkle tree block that is hashed.
-fn zero_pad_salt(salt: &[u8], algorithm: &Algorithm) -> Vec<u8> {
+fn zero_pad_salt(salt: &[u8], algorithm: MessageDigest) -> Vec<u8> {
     if salt.is_empty() {
         salt.to_vec()
     } else {
-        let padded_len = round_to_multiple(salt.len(), algorithm.block_len);
+        let padded_len = round_to_multiple(salt.len(), algorithm.block_size());
         let mut salt = salt.to_vec();
         salt.resize(padded_len, 0);
         salt
@@ -194,7 +192,7 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use ring::digest;
+    use openssl::hash::MessageDigest;
     use std::fs::{self, File};
 
     #[test]
@@ -210,7 +208,7 @@
 
             let size = std::fs::metadata(&input_name)?.len() as usize;
             let salt = vec![1, 2, 3, 4, 5, 6];
-            let ht = HashTree::from(&mut input, size, &salt, 4096, &digest::SHA256)?;
+            let ht = HashTree::from(&mut input, size, &salt, 4096, MessageDigest::sha256())?;
 
             assert_eq!(golden_hash_tree.as_slice(), ht.tree.as_slice());
             assert_eq!(golden_root_hash, ht.root_hash.as_slice());