I am writing a Python script that needs to use the FS_IOC_ADD_ENCRYPTION_KEY
ioctl.
This ioctl expects an argument of type fscrypt_add_key_arg*
:
struct fscrypt_add_key_arg {
struct fscrypt_key_specifier key_spec;
__u32 raw_size;
__u32 key_id;
__u32 __reserved[8];
__u8 raw[];
};
#define FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR 1
#define FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER 2
struct fscrypt_key_specifier {
__u32 type; /* one of FSCRYPT_KEY_SPEC_TYPE_* */
__u32 __reserved;
union {
__u8 __reserved[32]; /* reserve some extra space */
__u8 descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE];
__u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE];
} u;
};
This is my Python code:
import fcntl
import struct
FS_IOC_ADD_ENCRYPTION_KEY = 0xc0506617
policy_data.key_descriptor: str = get_key_descriptor()
policy_key: bytes = get_policy_key(policy_data)
fscrypt_key_specifier = struct.pack(
'II16s',
0x2,
0,
bytes.fromhex(policy_data.key_descriptor)
)
fscrypt_add_key_arg = struct.pack(
f'{len(fscrypt_key_specifier)}sII8I{len(policy_key)}s',
fscrypt_key_specifier,
len(policy_key),
0,
0, 0, 0, 0, 0, 0, 0, 0,
policy_key
)
fd = os.open('/mnt/external', os.O_RDONLY)
res = fcntl.ioctl(fd, FS_IOC_ADD_ENCRYPTION_KEY, fscrypt_add_key_arg)
print(res)
When I execute this code I get an OSError
:
Traceback (most recent call last):
File "/home/foo/fscryptdump/./main.py", line 101, in <module>
res = fcntl.ioctl(fd, FS_IOC_ADD_ENCRYPTION_KEY, fscrypt_add_key_arg)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 22] Invalid argument
I have double-checked the documentation of that ioctl and I thunk the values I am passing are correct, but there probably is a problem in the way they are packed.
How can I solve this?