Make generateFsverityMetadata return on-disk data

It used to return fs-verity measurement, but we need the on-disk format
for setup.  The on-disk format just has extra algorithm ID and digest
length.

Test: Observe fs-verity setup happens, with backported fs-verity to Pixel 3
Bug: 112037636
Change-Id: I446656e42c05dad1ffa272c3e3d623006490b1cc
diff --git a/services/core/java/com/android/server/security/VerityUtils.java b/services/core/java/com/android/server/security/VerityUtils.java
index 8070f3a..514dfed 100644
--- a/services/core/java/com/android/server/security/VerityUtils.java
+++ b/services/core/java/com/android/server/security/VerityUtils.java
@@ -138,8 +138,8 @@
      * <p>It is worthy to note that {@code trackedBufferFactory} generates a "tracked" {@code
      * ByteBuffer}. The data will be used outside this method via the factory itself.
      *
-     * @return fs-verity measurement of {@code filePath}, which is a SHA-256 of fs-verity descriptor
-     *         and authenticated extensions.
+     * @return fs-verity signed data (struct fsverity_digest_disk) of {@code filePath}, which
+     *         includes SHA-256 of fs-verity descriptor and authenticated extensions.
      */
     private static byte[] generateFsverityMetadata(String filePath, String signaturePath,
             @NonNull TrackedShmBufferFactory trackedBufferFactory)
@@ -151,8 +151,10 @@
 
             ByteBuffer buffer = result.verityData;
             buffer.position(result.merkleTreeSize);
-            return generateFsverityDescriptorAndMeasurement(file, result.rootHash, signaturePath,
-                    buffer);
+
+            final byte[] measurement = generateFsverityDescriptorAndMeasurement(file,
+                    result.rootHash, signaturePath, buffer);
+            return constructFsveritySignedDataNative(measurement);
         }
     }
 
@@ -211,6 +213,7 @@
         return md.digest();
     }
 
+    private static native byte[] constructFsveritySignedDataNative(@NonNull byte[] measurement);
     private static native byte[] constructFsverityDescriptorNative(long fileSize);
     private static native byte[] constructFsverityExtensionNative(short extensionId,
             int extensionDataSize);
diff --git a/services/core/jni/com_android_server_security_VerityUtils.cpp b/services/core/jni/com_android_server_security_VerityUtils.cpp
index d0f173b..ec94e3c9 100644
--- a/services/core/jni/com_android_server_security_VerityUtils.cpp
+++ b/services/core/jni/com_android_server_security_VerityUtils.cpp
@@ -66,6 +66,30 @@
     jbyte* mElements;
 };
 
+jbyteArray constructFsveritySignedData(JNIEnv* env, jobject /* clazz */, jbyteArray digest) {
+#if HAS_FSVERITY
+    const int kSha256Bytes = 32;
+    auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_digest_disk) + kSha256Bytes);
+    fsverity_digest_disk* data = reinterpret_cast<fsverity_digest_disk*>(raii->getRaw());
+
+    data->digest_algorithm = FS_VERITY_ALG_SHA256;
+    data->digest_size = kSha256Bytes;
+    if (env->GetArrayLength(digest) != kSha256Bytes) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "Invalid hash size of %d",
+                          env->GetArrayLength(digest));
+        return 0;
+    }
+    const jbyte* src = env->GetByteArrayElements(digest, nullptr);
+    memcpy(data->digest, src, kSha256Bytes);
+
+    return raii->release();
+#else
+    LOG_ALWAYS_FATAL("fs-verity is used while not enabled");
+    return 0;
+#endif  // HAS_FSVERITY
+}
+
+
 jbyteArray constructFsverityDescriptor(JNIEnv* env, jobject /* clazz */, jlong fileSize) {
 #if HAS_FSVERITY
     auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_descriptor));
@@ -122,6 +146,7 @@
 }
 
 const JNINativeMethod sMethods[] = {
+    { "constructFsveritySignedDataNative", "([B)[B", (void *)constructFsveritySignedData },
     { "constructFsverityDescriptorNative", "(J)[B", (void *)constructFsverityDescriptor },
     { "constructFsverityExtensionNative", "(SI)[B", (void *)constructFsverityExtension },
     { "constructFsverityFooterNative", "(I)[B", (void *)constructFsverityFooter },