Skip to content

Commit

Permalink
Use randomly generated key in image-rs to secure image layers in sefs
Browse files Browse the repository at this point in the history
Signed-off-by: piotrpalcz <[email protected]>
  • Loading branch information
piotrpalcz committed Dec 21, 2023
1 parent 8a75340 commit 50d59ed
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 10 deletions.
58 changes: 50 additions & 8 deletions image-rs/src/snapshots/occlum/unionfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// This unionfs file is used for occlum only

use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::sync::atomic::AtomicUsize;

Expand All @@ -14,6 +16,8 @@ use fs_extra;
use fs_extra::dir;
use nix::mount::MsFlags;

use ocicrypt_rs::blockcipher::rand::rand_bytes;

use crate::snapshots::{MountPoint, Snapshotter};

const LD_LIB: &str = "ld-linux-x86-64.so.2";
Expand Down Expand Up @@ -47,6 +51,21 @@ fn create_dir(create_path: &Path) -> Result<()> {
Ok(())
}

// returns randomly generted random 128 bit key
fn generate_random_key() -> String {
let mut key: [u8; 16] = [0u8; 16];

rand_bytes(&mut key).expect("Random fill failed");

let formatted_key = key
.iter()
.map(|byte| format!("{:02x}", byte))
.collect::<Vec<String>>()
.join("-");

formatted_key
}

fn create_environment(mount_path: &Path) -> Result<()> {
let mut from_paths = Vec::new();
let mut copy_options = dir::CopyOptions::new();
Expand All @@ -69,7 +88,6 @@ fn create_environment(mount_path: &Path) -> Result<()> {
if fs::symlink_metadata(ld_lib.as_path()).is_ok() {
fs::remove_file(ld_lib)?;
}

fs_extra::copy_items(&from_paths, &path_lib64, &copy_options)?;
from_paths.clear();

Expand Down Expand Up @@ -112,6 +130,7 @@ impl Snapshotter for Unionfs {
fn mount(&mut self, layer_path: &[&str], mount_path: &Path) -> Result<MountPoint> {
let fs_type = String::from("sefs");
let source = Path::new(&fs_type);
let flags = MsFlags::empty();

if !mount_path.exists() {
fs::create_dir_all(mount_path)?;
Expand All @@ -124,18 +143,41 @@ impl Snapshotter for Unionfs {
.file_name()
.ok_or(anyhow!("Unknown error: file name parse fail"))?;

// For mounting trusted UnionFS at runtime of occlum,
// you can refer to https://github.com/occlum/occlum/blob/master/docs/runtime_mount.md#1-mount-trusted-unionfs-consisting-of-sefss.
// "c7-32-b3-ed-44-df-ec-7b-25-2d-9a-32-38-8d-58-61" is a hardcode key used to encrypt or decrypt the FS currently,
// and it will be replaced with dynamic key in the near future.
let key_mount_options = format!(
"dir={}",
Path::new("/images")
.join(cid)
.join("keys/sefs/lower")
.display()
);

let keys_mount_path = Path::new("/keys");
nix::mount::mount(
Some(source),
keys_mount_path,
Some(fs_type.as_str()),
flags,
Some(key_mount_options.as_str()),
)
.map_err(|e| {
anyhow!(
"failed to mount {:?} to {:?}, with error: {}",
source,
keys_mount_path,
e
)
})?;

let random_key = generate_random_key();
std::fs::write(&PathBuf::from(&keys_mount_path.join("key.txt")), &random_key)?;
nix::mount::umount(keys_mount_path)?;

let options = format!(
"dir={},key={}",
Path::new("/images").join(cid).join("sefs/lower").display(),
"c7-32-b3-ed-44-df-ec-7b-25-2d-9a-32-38-8d-58-61"
random_key
);

let flags = MsFlags::empty();

nix::mount::mount(
Some(source),
mount_path,
Expand Down
2 changes: 1 addition & 1 deletion ocicrypt-rs/src/blockcipher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
mod aes_ctr;
use aes_ctr::AESCTRBlockCipher;

mod rand;
pub mod rand;

/// Type of the cipher algorithm used to encrypt/decrypt image layers.
pub type LayerCipherType = String;
Expand Down
2 changes: 1 addition & 1 deletion ocicrypt-rs/src/blockcipher/rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use anyhow::Result;

/// Fill the given slice with cryptographically generated random numbers
pub(crate) fn rand_bytes(data: &mut [u8]) -> Result<()> {
pub fn rand_bytes(data: &mut [u8]) -> Result<()> {
cfg_if::cfg_if! {
if #[cfg(feature = "block-cipher-openssl")] {
openssl::rand::rand_bytes(&mut data[..])?;
Expand Down

0 comments on commit 50d59ed

Please sign in to comment.