Merge "Support fs-verity setup with null/no signature" am: 52d2b21a47

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2351935

Change-Id: I230778fe755a7d0573eb91c22d186020b28b9946
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/core/java/com/android/internal/security/VerityUtils.java b/core/java/com/android/internal/security/VerityUtils.java
index 7f45c09..3ab11a8 100644
--- a/core/java/com/android/internal/security/VerityUtils.java
+++ b/core/java/com/android/internal/security/VerityUtils.java
@@ -17,6 +17,7 @@
 package com.android.internal.security;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.Build;
 import android.os.SystemProperties;
 import android.system.Os;
@@ -41,6 +42,7 @@
 import java.nio.ByteOrder;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
+import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
@@ -77,17 +79,23 @@
         return filePath + FSVERITY_SIGNATURE_FILE_EXTENSION;
     }
 
-    /** Enables fs-verity for the file with a PKCS#7 detached signature file. */
-    public static void setUpFsverity(@NonNull String filePath, @NonNull String signaturePath)
+    /** Enables fs-verity for the file with an optional PKCS#7 detached signature file. */
+    public static void setUpFsverity(@NonNull String filePath, @Nullable String signaturePath)
             throws IOException {
-        if (Files.size(Paths.get(signaturePath)) > MAX_SIGNATURE_FILE_SIZE_BYTES) {
-            throw new SecurityException("Signature file is unexpectedly large: " + signaturePath);
+        byte[] rawSignature = null;
+        if (signaturePath != null) {
+            Path path = Paths.get(signaturePath);
+            if (Files.size(path) > MAX_SIGNATURE_FILE_SIZE_BYTES) {
+                throw new SecurityException("Signature file is unexpectedly large: "
+                        + signaturePath);
+            }
+            rawSignature = Files.readAllBytes(path);
         }
-        setUpFsverity(filePath, Files.readAllBytes(Paths.get(signaturePath)));
+        setUpFsverity(filePath, rawSignature);
     }
 
-    /** Enables fs-verity for the file with a PKCS#7 detached signature bytes. */
-    public static void setUpFsverity(@NonNull String filePath, @NonNull byte[] pkcs7Signature)
+    /** Enables fs-verity for the file with an optional PKCS#7 detached signature bytes. */
+    public static void setUpFsverity(@NonNull String filePath, @Nullable byte[] pkcs7Signature)
             throws IOException {
         // This will fail if the public key is not already in .fs-verity kernel keyring.
         int errno = enableFsverityNative(filePath, pkcs7Signature);
@@ -227,7 +235,7 @@
     }
 
     private static native int enableFsverityNative(@NonNull String filePath,
-            @NonNull byte[] pkcs7Signature);
+            @Nullable byte[] pkcs7Signature);
     private static native int measureFsverityNative(@NonNull String filePath,
             @NonNull byte[] digest);
     private static native int statxForFsverityNative(@NonNull String filePath);
diff --git a/core/jni/com_android_internal_security_VerityUtils.cpp b/core/jni/com_android_internal_security_VerityUtils.cpp
index c5b3d8a..5553d28 100644
--- a/core/jni/com_android_internal_security_VerityUtils.cpp
+++ b/core/jni/com_android_internal_security_VerityUtils.cpp
@@ -48,10 +48,6 @@
     if (rfd.get() < 0) {
         return errno;
     }
-    ScopedByteArrayRO signature_bytes(env, signature);
-    if (signature_bytes.get() == nullptr) {
-        return EINVAL;
-    }
 
     fsverity_enable_arg arg = {};
     arg.version = 1;
@@ -59,8 +55,18 @@
     arg.block_size = 4096;
     arg.salt_size = 0;
     arg.salt_ptr = reinterpret_cast<uintptr_t>(nullptr);
-    arg.sig_size = signature_bytes.size();
-    arg.sig_ptr = reinterpret_cast<uintptr_t>(signature_bytes.get());
+
+    if (signature != nullptr) {
+        ScopedByteArrayRO signature_bytes(env, signature);
+        if (signature_bytes.get() == nullptr) {
+            return EINVAL;
+        }
+        arg.sig_size = signature_bytes.size();
+        arg.sig_ptr = reinterpret_cast<uintptr_t>(signature_bytes.get());
+    } else {
+        arg.sig_size = 0;
+        arg.sig_ptr = reinterpret_cast<uintptr_t>(nullptr);
+    }
 
     if (ioctl(rfd.get(), FS_IOC_ENABLE_VERITY, &arg) < 0) {
         return errno;