blob: 356af9f28f01450cb144107c64c211c49314cbe6 [file] [log] [blame]
// Copyright 2025 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use linux_uapi::{
__IncompleteArrayField, __u8, __u32, FS_IOC_ADD_ENCRYPTION_KEY, FS_IOC_SET_ENCRYPTION_POLICY,
FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER, FSCRYPT_MODE_AES_256_CTS, FSCRYPT_MODE_AES_256_XTS,
FSCRYPT_POLICY_FLAGS_PAD_16, fscrypt_policy_v2,
};
use std::os::fd::AsRawFd;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
pub const MASTER_ENCRYPTION_KEY: [u8; 64] = [1; 64];
pub const LINK_FILE_NAME: &str = "link.txt";
pub const TARGET_FILE_NAME: &str = "foo.txt";
pub fn add_encryption_key_with_key_bytes(
root_dir: &std::fs::File,
raw_key: &[u8],
) -> (i32, Vec<u8>) {
let key_spec =
fscrypt_key_specifier { type_: FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER, ..Default::default() };
let arg = fscrypt_add_key_arg { key_spec: key_spec, raw_size: 64, ..Default::default() };
let mut arg_vec = arg.as_bytes().to_vec();
arg_vec.extend(raw_key);
// SAFETY: `arg_vec` is valid to write to for the first `sizeof(fscrypt_key_specifier)` bytes
let ret = unsafe {
libc::ioctl(
root_dir.as_raw_fd(),
FS_IOC_ADD_ENCRYPTION_KEY.try_into().unwrap(),
arg_vec.as_ptr(),
)
};
(ret, arg_vec)
}
pub fn set_encryption_policy(dir: &std::fs::File, identifier: [u8; 16]) -> i32 {
// SAFETY: basic FFI call with no invariants.
let ret = unsafe {
let policy = fscrypt_policy_v2 {
version: 2,
contents_encryption_mode: FSCRYPT_MODE_AES_256_XTS as u8,
filenames_encryption_mode: FSCRYPT_MODE_AES_256_CTS as u8,
flags: FSCRYPT_POLICY_FLAGS_PAD_16 as u8,
master_key_identifier: identifier,
..Default::default()
};
libc::ioctl(dir.as_raw_fd(), FS_IOC_SET_ENCRYPTION_POLICY.try_into().unwrap(), &policy)
};
ret
}
#[repr(C)]
#[derive(Copy, Clone, KnownLayout, FromBytes, Immutable, IntoBytes)]
pub struct fscrypt_key_specifier {
pub type_: __u32,
pub __reserved: __u32,
pub u: fscrypt_key_specifier__bindgen_ty_1,
}
#[repr(C)]
#[derive(Copy, Clone, KnownLayout, FromBytes, Immutable, IntoBytes)]
pub union fscrypt_key_specifier__bindgen_ty_1 {
pub __reserved: [__u8; 32usize],
pub descriptor: fscrypt_descriptor,
pub identifier: fscrypt_identifier,
}
#[repr(C)]
#[derive(Copy, Clone, Default, KnownLayout, FromBytes, Immutable, IntoBytes)]
pub struct fscrypt_descriptor {
pub value: [__u8; 8usize],
pub __bindgen_padding_0: [u8; 24usize],
}
#[repr(C)]
#[derive(Copy, Clone, Default, KnownLayout, FromBytes, Immutable, IntoBytes)]
pub struct fscrypt_identifier {
pub value: [__u8; 16usize],
pub __bindgen_padding_0: [u8; 16usize],
}
impl Default for fscrypt_key_specifier__bindgen_ty_1 {
fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
// SAFETY: FromBytes implies that any bit patterns are sound for this type
unsafe {
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
impl Default for fscrypt_key_specifier {
fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
// SAFETY: FromBytes implies that any bit patterns are sound for this type
unsafe {
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
#[repr(C)]
#[derive(Clone, KnownLayout, FromBytes, Immutable, IntoBytes)]
pub struct fscrypt_add_key_arg {
pub key_spec: fscrypt_key_specifier,
pub raw_size: __u32,
pub key_id: __u32,
pub __reserved: [__u32; 7usize],
pub __flags: __u32,
pub raw: __IncompleteArrayField<__u8>,
}
impl Default for fscrypt_add_key_arg {
fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
// SAFETY: FromBytes implies that any bit patterns are sound for this type
unsafe {
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}