Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add first version of encrypted mounts #462

Merged
merged 5 commits into from
Apr 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions LibOS/shim/include/shim_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,13 @@ struct shim_fs_ops {
/* setflags: set flags of the file */
int (*setflags)(struct shim_handle* hdl, int flags);

/* hput: delete the handle and close the PAL handle. */
void (*hput)(struct shim_handle* hdl);
/*
* \brief Deallocate handle data.
*
* Deallocates any filesystem-specific resources associated with the handle. Called just before
* destroying the handle.
*/
void (*hdrop)(struct shim_handle* hdl);

/* lock and unlock the file */
int (*lock)(const char* trim_name);
Expand Down Expand Up @@ -394,7 +399,7 @@ struct shim_d_ops {

struct shim_fs {
/* Null-terminated, used in manifest and for uniquely identifying a filesystem. */
char name[8];
char name[16];
struct shim_fs_ops* fs_ops;
struct shim_d_ops* d_ops;
};
Expand Down Expand Up @@ -842,6 +847,7 @@ extern struct shim_fs_ops tmp_fs_ops;
extern struct shim_d_ops tmp_d_ops;

extern struct shim_fs chroot_builtin_fs;
extern struct shim_fs chroot_encrypted_builtin_fs;
extern struct shim_fs tmp_builtin_fs;
extern struct shim_fs pipe_builtin_fs;
extern struct shim_fs fifo_builtin_fs;
Expand Down Expand Up @@ -880,4 +886,15 @@ int fifo_setup_dentry(struct shim_dentry* dent, mode_t perm, int fd_read, int fd

int unix_socket_setup_dentry(struct shim_dentry* dent, mode_t perm);

/*
* Calculate the URI for a dentry. The URI scheme is determined by file type (`type` field). It
* needs to be passed separately (instead of using `dent->inode->type`) because the dentry might not
* have inode associated yet: we might be creating a new file, or looking up a file we don't know
* yet.
*/
int chroot_dentry_uri(struct shim_dentry* dent, mode_t type, char** out_uri);

int chroot_readdir(struct shim_dentry* dent, readdir_callback_t callback, void* arg);
int chroot_unlink(struct shim_dentry* dent);

#endif /* _SHIM_FS_H_ */
144 changes: 144 additions & 0 deletions LibOS/shim/include/shim_fs_encrypted.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/* Copyright (C) 2022 Intel Corporation
* Paweł Marczewski <[email protected]>
*/

/*
* This module implements encrypted files. It is a wrapper around the platform-independent
* `protected_files` module, and PAL handles.
*
* NOTE: There is currently no notion of file permissions, all files are open in read-write mode.
*/

#ifndef SHIM_FS_ENCRYPTED_
#define SHIM_FS_ENCRYPTED_

#include <stddef.h>

#include "list.h"
#include "pal.h"
#include "protected_files.h"
#include "shim_types.h"

/*
* Represents a named key for opening files. The key might not be set yet: value of a key can be
* specified in the manifest, or set using `set_encrypted_files_key`. Before the key is set,
* operations that use it will fail.
*/
DEFINE_LIST(shim_encrypted_files_key);
DEFINE_LISTP(shim_encrypted_files_key);
struct shim_encrypted_files_key {
char* name;
bool is_set;
pf_key_t pf_key;

LIST_TYPE(shim_encrypted_files_key) list;
};

/*
* Represents a specific encrypted file. The file is open as long as `use_count` is greater than 0.
* Note that the file can be open and closed multiple times before it's destroyed.
*
* Operations on a single `shim_encrypted_file` are NOT thread-safe, it is intended to be protected
* by a lock.
*/
struct shim_encrypted_file {
size_t use_count;
char* uri;
struct shim_encrypted_files_key* key;

/* `pf` and `pal_handle` are non-null as long as `use_count` is greater than 0 */
pf_context_t* pf;
PAL_HANDLE pal_handle;
};

/*
* \brief Initialize the encrypted files module.
*
* Performs necessary setup, including loading keys specified in manifest.
*/
int init_encrypted_files(void);

/*
* \brief Retrieve a key.
*
* Sets `*out_key` to a key with a given name. Note that the key might not be set yet (see
* `struct shim_encrypted_files_key`).
*
* This does not pass ownership of `*out_key`: the key objects are still managed by this module.
*/
int get_encrypted_files_key(const char* name, struct shim_encrypted_files_key** out_key);

/*
* \brief Update value of given key.
*
* \param key The key to update.
* \param key_str New value for the key. Must be a 32-char null-terminated hex string (AES-GCM
* encryption key).
*/
int update_encrypted_files_key(struct shim_encrypted_files_key* key, char* key_str);

/*
* \brief Open an existing encrypted file.
*
* \param uri PAL URI to open, has to begin with "file:".
* \param key Key, has to be already set.
* \param[out] out_enc On success, set to a newly created `shim_encrypted_file` object.
*
* `uri` has to correspond to an existing file that can be decrypted with `key`.
*
* The newly created `shim_encrypted_file` object will have `use_count` set to 1.
*/
int encrypted_file_open(const char* uri, struct shim_encrypted_files_key* key,
struct shim_encrypted_file** out_enc);

/*
* \brief Create a new encrypted file.
*
* \param uri PAL URI to open, has to begin with "file:".
* \param perm Permissions for the new file.
* \param key Key, has to be already set.
* \param[out] out_enc On success, set to a newly created `shim_encrypted_file` object.
*
* `uri` must not correspond to an existing file.
*
* The newly created `shim_encrypted_file` object will have `use_count` set to 1.
*/
int encrypted_file_create(const char* uri, mode_t perm, struct shim_encrypted_files_key* key,
struct shim_encrypted_file** out_enc);

/*
* \brief Deallocate an encrypted file.
*
* `enc` needs to have `use_count` set to 0.
*/
void encrypted_file_destroy(struct shim_encrypted_file* enc);

/*
* \brief Increase the use count of an encrypted file.
*
* This increases `use_count`, and opens the file if `use_count` was 0.
*/
int encrypted_file_get(struct shim_encrypted_file* enc);

/*
* \brief Decrease the use count of an encrypted file.
*
* This decreases `use_count`, and closes the file if it reaches 0.
*/
void encrypted_file_put(struct shim_encrypted_file* enc);

/*
* \brief Flush pending writes to an encrypted file.
*/
int encrypted_file_flush(struct shim_encrypted_file* enc);

int encrypted_file_read(struct shim_encrypted_file* enc, void* buf, size_t buf_size,
file_off_t offset, size_t* out_count);
int encrypted_file_write(struct shim_encrypted_file* enc, const void* buf, size_t buf_size,
file_off_t offset, size_t* out_count);

int encrypted_file_get_size(struct shim_encrypted_file* enc, file_off_t* out_size);
int encrypted_file_set_size(struct shim_encrypted_file* enc, file_off_t size);

#endif /* SHIM_FS_ENCRYPTED_ */
3 changes: 3 additions & 0 deletions LibOS/shim/include/shim_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
enum shim_handle_type {
/* Files: */
TYPE_CHROOT, /* host files, used by `chroot` filesystem */
TYPE_CHROOT_ENCRYPTED,
/* encrypted host files, used by `chroot_encrypted` filesystem */
TYPE_DEV, /* emulated devices, used by `dev` filesystem */
TYPE_STR, /* string-based files (with data inside handle), handled by `pseudo_*`
* functions */
Expand Down Expand Up @@ -208,6 +210,7 @@ struct shim_handle {
* by using assert()) */
union {
/* (no data) */ /* TYPE_CHROOT */
/* (no data) */ /* TYPE_CHROOT_ENCRYPTED */
/* (no data) */ /* TYPE_DEV */
struct shim_str_handle str; /* TYPE_STR */
/* (no data) */ /* TYPE_PSEUDO */
Expand Down
4 changes: 2 additions & 2 deletions LibOS/shim/src/bookkeep/shim_handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,8 @@ void put_handle(struct shim_handle* hdl) {
hdl->info.sock.peek_buffer = NULL;
}

if (hdl->fs && hdl->fs->fs_ops && hdl->fs->fs_ops->hput)
hdl->fs->fs_ops->hput(hdl);
if (hdl->fs && hdl->fs->fs_ops && hdl->fs->fs_ops->hdrop)
hdl->fs->fs_ops->hdrop(hdl);

free(hdl->uri);

Expand Down
Loading