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 },