Merge "Calculate correct checksum." into tm-dev am: 83962ee99c am: e2e8dfeb0b
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18493400 Change-Id: Idb4d68dbd153ffea6c38cea93dbe510ea72afb85 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -77,6 +77,7 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.file.Files;
|
||||
import java.security.DigestException;
|
||||
import java.security.InvalidParameterException;
|
||||
@@ -584,7 +585,7 @@ public class ApkChecksums {
|
||||
});
|
||||
checksums.put(TYPE_WHOLE_MERKLE_ROOT_4K_SHA256,
|
||||
new ApkChecksum(split, TYPE_WHOLE_MERKLE_ROOT_4K_SHA256,
|
||||
generatedRootHash));
|
||||
verityHashForFile(file, generatedRootHash)));
|
||||
} catch (IOException | NoSuchAlgorithmException | DigestException e) {
|
||||
Slog.e(TAG, "Error calculating WHOLE_MERKLE_ROOT_4K_SHA256", e);
|
||||
}
|
||||
@@ -649,19 +650,20 @@ public class ApkChecksums {
|
||||
// Skip /product folder.
|
||||
// TODO(b/231354111): remove this hack once we are allowed to change SELinux rules.
|
||||
if (!containsFile(Environment.getProductDirectory(), filePath)) {
|
||||
byte[] hash = VerityUtils.getFsverityRootHash(filePath);
|
||||
if (hash != null) {
|
||||
return new ApkChecksum(split, TYPE_WHOLE_MERKLE_ROOT_4K_SHA256, hash);
|
||||
byte[] verityHash = VerityUtils.getFsverityRootHash(filePath);
|
||||
if (verityHash != null) {
|
||||
return new ApkChecksum(split, TYPE_WHOLE_MERKLE_ROOT_4K_SHA256, verityHash);
|
||||
}
|
||||
}
|
||||
// v4 next
|
||||
try {
|
||||
ApkSignatureSchemeV4Verifier.VerifiedSigner signer =
|
||||
ApkSignatureSchemeV4Verifier.extractCertificates(filePath);
|
||||
byte[] hash = signer.contentDigests.getOrDefault(CONTENT_DIGEST_VERITY_CHUNKED_SHA256,
|
||||
null);
|
||||
if (hash != null) {
|
||||
return new ApkChecksum(split, TYPE_WHOLE_MERKLE_ROOT_4K_SHA256, hash);
|
||||
byte[] rootHash = signer.contentDigests.getOrDefault(
|
||||
CONTENT_DIGEST_VERITY_CHUNKED_SHA256, null);
|
||||
if (rootHash != null) {
|
||||
return new ApkChecksum(split, TYPE_WHOLE_MERKLE_ROOT_4K_SHA256,
|
||||
verityHashForFile(new File(filePath), rootHash));
|
||||
}
|
||||
} catch (SignatureNotFoundException e) {
|
||||
// Nothing
|
||||
@@ -671,6 +673,41 @@ public class ApkChecksums {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns fs-verity digest as described in
|
||||
* https://www.kernel.org/doc/html/latest/filesystems/fsverity.html#fs-verity-descriptor
|
||||
* @param file the Merkle tree is built over
|
||||
* @param rootHash Merkle tree root hash
|
||||
*/
|
||||
static byte[] verityHashForFile(File file, byte[] rootHash) {
|
||||
try {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(256); // sizeof(fsverity_descriptor)
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.put((byte) 1); // __u8 version, must be 1
|
||||
buffer.put((byte) 1); // __u8 hash_algorithm, FS_VERITY_HASH_ALG_SHA256
|
||||
buffer.put((byte) 12); // __u8, FS_VERITY_LOG_BLOCKSIZE
|
||||
buffer.put((byte) 0); // __u8, size of salt in bytes; 0 if none
|
||||
buffer.putInt(0); // __le32 __reserved_0x04, must be 0
|
||||
buffer.putLong(file.length()); // __le64 data_size
|
||||
buffer.put(rootHash); // root_hash, first 32 bytes
|
||||
final int padding = 32 + 32 + 144; // root_hash, last 32 bytes, we are using sha256.
|
||||
// salt, 32 bytes
|
||||
// reserved, 144 bytes
|
||||
for (int i = 0; i < padding; ++i) {
|
||||
buffer.put((byte) 0);
|
||||
}
|
||||
|
||||
buffer.flip();
|
||||
|
||||
final MessageDigest md = MessageDigest.getInstance(ALGO_SHA256);
|
||||
md.update(buffer);
|
||||
return md.digest();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
Slog.e(TAG, "Device does not support MessageDigest algorithm", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<Integer, ApkChecksum> extractHashFromV2V3Signature(
|
||||
String split, String filePath, int types) {
|
||||
Map<Integer, byte[]> contentDigests = null;
|
||||
|
||||
@@ -1069,7 +1069,7 @@ public class PackageManagerServiceUtils {
|
||||
if (ArrayUtils.isEmpty(hashInfo.rawRootHash)) {
|
||||
throw new IOException("Root has not present");
|
||||
}
|
||||
return hashInfo.rawRootHash;
|
||||
return ApkChecksums.verityHashForFile(new File(filename), hashInfo.rawRootHash);
|
||||
} catch (IOException ignore) {
|
||||
Slog.e(TAG, "ERROR: could not load root hash from incremental install");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user