1*e1997b9aSAndroid Build Coastguard Worker /*
2*e1997b9aSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project
3*e1997b9aSAndroid Build Coastguard Worker *
4*e1997b9aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*e1997b9aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*e1997b9aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*e1997b9aSAndroid Build Coastguard Worker *
8*e1997b9aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*e1997b9aSAndroid Build Coastguard Worker *
10*e1997b9aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*e1997b9aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*e1997b9aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e1997b9aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*e1997b9aSAndroid Build Coastguard Worker * limitations under the License.
15*e1997b9aSAndroid Build Coastguard Worker */
16*e1997b9aSAndroid Build Coastguard Worker
17*e1997b9aSAndroid Build Coastguard Worker //! A wrapper library to use fs-verity
18*e1997b9aSAndroid Build Coastguard Worker
19*e1997b9aSAndroid Build Coastguard Worker mod sys;
20*e1997b9aSAndroid Build Coastguard Worker
21*e1997b9aSAndroid Build Coastguard Worker use crate::sys::*;
22*e1997b9aSAndroid Build Coastguard Worker use std::io;
23*e1997b9aSAndroid Build Coastguard Worker use std::os::fd::AsRawFd;
24*e1997b9aSAndroid Build Coastguard Worker use std::os::unix::io::BorrowedFd;
25*e1997b9aSAndroid Build Coastguard Worker
read_metadata(fd: i32, metadata_type: u64, offset: u64, buf: &mut [u8]) -> io::Result<usize>26*e1997b9aSAndroid Build Coastguard Worker fn read_metadata(fd: i32, metadata_type: u64, offset: u64, buf: &mut [u8]) -> io::Result<usize> {
27*e1997b9aSAndroid Build Coastguard Worker let mut arg = fsverity_read_metadata_arg {
28*e1997b9aSAndroid Build Coastguard Worker metadata_type,
29*e1997b9aSAndroid Build Coastguard Worker offset,
30*e1997b9aSAndroid Build Coastguard Worker length: buf.len() as u64,
31*e1997b9aSAndroid Build Coastguard Worker buf_ptr: buf.as_mut_ptr() as u64,
32*e1997b9aSAndroid Build Coastguard Worker __reserved: 0,
33*e1997b9aSAndroid Build Coastguard Worker };
34*e1997b9aSAndroid Build Coastguard Worker // SAFETY: the ioctl doesn't change the sematics in the current process
35*e1997b9aSAndroid Build Coastguard Worker Ok(unsafe { read_verity_metadata(fd, &mut arg) }? as usize)
36*e1997b9aSAndroid Build Coastguard Worker }
37*e1997b9aSAndroid Build Coastguard Worker
38*e1997b9aSAndroid Build Coastguard Worker /// Read the raw Merkle tree from the fd, if it exists. The API semantics is similar to a regular
39*e1997b9aSAndroid Build Coastguard Worker /// pread(2), and may not return full requested buffer.
read_merkle_tree(fd: i32, offset: u64, buf: &mut [u8]) -> io::Result<usize>40*e1997b9aSAndroid Build Coastguard Worker pub fn read_merkle_tree(fd: i32, offset: u64, buf: &mut [u8]) -> io::Result<usize> {
41*e1997b9aSAndroid Build Coastguard Worker read_metadata(fd, FS_VERITY_METADATA_TYPE_MERKLE_TREE, offset, buf)
42*e1997b9aSAndroid Build Coastguard Worker }
43*e1997b9aSAndroid Build Coastguard Worker
44*e1997b9aSAndroid Build Coastguard Worker /// Read the fs-verity signature from the fd (if exists). The returned signature should be complete.
read_signature(fd: i32, buf: &mut [u8]) -> io::Result<usize>45*e1997b9aSAndroid Build Coastguard Worker pub fn read_signature(fd: i32, buf: &mut [u8]) -> io::Result<usize> {
46*e1997b9aSAndroid Build Coastguard Worker read_metadata(fd, FS_VERITY_METADATA_TYPE_SIGNATURE, 0 /* offset */, buf)
47*e1997b9aSAndroid Build Coastguard Worker }
48*e1997b9aSAndroid Build Coastguard Worker
49*e1997b9aSAndroid Build Coastguard Worker /// Enable fs-verity to the `fd`, with sha256 hash algorithm and 4KB block size.
enable(fd: BorrowedFd) -> io::Result<()>50*e1997b9aSAndroid Build Coastguard Worker pub fn enable(fd: BorrowedFd) -> io::Result<()> {
51*e1997b9aSAndroid Build Coastguard Worker let arg = fsverity_enable_arg {
52*e1997b9aSAndroid Build Coastguard Worker version: 1,
53*e1997b9aSAndroid Build Coastguard Worker hash_algorithm: FS_VERITY_HASH_ALG_SHA256,
54*e1997b9aSAndroid Build Coastguard Worker block_size: 4096,
55*e1997b9aSAndroid Build Coastguard Worker salt_size: 0,
56*e1997b9aSAndroid Build Coastguard Worker salt_ptr: 0,
57*e1997b9aSAndroid Build Coastguard Worker sig_size: 0,
58*e1997b9aSAndroid Build Coastguard Worker __reserved1: 0,
59*e1997b9aSAndroid Build Coastguard Worker sig_ptr: 0,
60*e1997b9aSAndroid Build Coastguard Worker __reserved2: [0; 11],
61*e1997b9aSAndroid Build Coastguard Worker };
62*e1997b9aSAndroid Build Coastguard Worker // SAFETY: the ioctl doesn't change the sematics in the current process
63*e1997b9aSAndroid Build Coastguard Worker if unsafe { enable_verity(fd.as_raw_fd(), &arg) } == Ok(0) {
64*e1997b9aSAndroid Build Coastguard Worker Ok(())
65*e1997b9aSAndroid Build Coastguard Worker } else {
66*e1997b9aSAndroid Build Coastguard Worker Err(io::Error::last_os_error())
67*e1997b9aSAndroid Build Coastguard Worker }
68*e1997b9aSAndroid Build Coastguard Worker }
69