#!/bin/sh

#!/bin/sh
#@author: vincent.benoit <vincent.benoit@scle.fr>
#@date: 10/2023
#@brief: ecryptfs and TPM

check_tpm2() {
	if [ ! -e /sys/class/tpm ]; then
		echo "Linux TPM subsystem not found"
		exit 1
	fi
}

ecryptfs_enabled() {
	return 0
}

create_tpm_prim_key() {
	local dirpath=$1
	if [ -z ${dirpath} ]; then
		echo "err: dir path (${dirpath}) doesn't exist"
		exit 1
	fi

	check_tpm2

	local contextfile=${dirpath}/key.ctxt
	local ret=`/usr/bin/tpm2_createprimary --key-algorithm=rsa2048 --key-context=${contextfile} 2>/dev/null`
	if [ $? -ne 0 ]; then
		echo "err: create primary failed"
		exit 1
	fi
}

persistent_handle() {
	local handle=$1
	storage_prim_key=""
	local tmp_res=/tmp/persist.txt
	local ret=`/usr/bin/tpm2_evictcontrol -c ${handle} > ${tmp_res}`
	if [ $? -eq 0 ]; then
		local res=`cat ${tmp_res} | tail -1 | awk -F ": " '{print $2}'`
		if [ $res == "persisted" ]; then
			# store handle to var
			storage_prim_key=`cat ${tmp_res} | head -n 1 | awk -F ": " '{print $2}'`
		fi
	fi
}

load_trusted_blob() {
	local keypath=$1
	local handle=$2
	local blob=`cat ${keypath}`
	echo "add trusted blob to linux key"
	/bin/keyctl add trusted kmk-trusted "load ${blob} keyhandle=${handle}" @u
}

load_encrypted_blob() {
	local keypath=$1
	local blob=`cat ${keypath}`
	echo "add encrypted blob to linux key"
	/bin/keyctl add encrypted 1001100110011001 "load ${blob}" @u
}

create_key_master_key() {
	local handle=$1
	local keypath=$2

	if [ -z ${handle} ]; then
		echo "err: handle (${handle}) empty"
		exit 1
	fi

	echo "add kmk-trusted from TPM ..."
	local kmk=`/bin/keyctl add trusted kmk-trusted "new 32 keyhandle=${handle}" @u`
	if [ $? -eq 0 ]; then
		echo "pipe kmk-trusted to file ..."
		if [ -f "${keypath}" ]; then
			echo "warn: ${keypath} already exists"
		fi
		local res=`/bin/keyctl pipe ${kmk} > ${keypath}`
		if [ $? -eq 0 ]; then
			echo "revoke kmk-trusted"
			/bin/keyctl revoke "${kmk}"
			if [ $? -eq 0 ]; then
				load_trusted_blob "${keypath}" "${handle}"
			fi
		fi
	fi
}

create_encrypted_key() {
	local keypath=$1

	echo "add ecryptfs key from trusted kmk ..."
	local encrypted=`/bin/keyctl add encrypted 1001100110011001 "new ecryptfs trusted:kmk-trusted 64" @u`
	if [ $? -eq 0 ]; then
		echo "pipe encrypted key to file ..."
		if [ -f "${keypath}" ]; then
			echo "warn: ${keypath} already exists"
		fi
		local res=`/bin/keyctl pipe ${encrypted} > ${keypath}`
		if [ $? -eq 0 ]; then
			echo "revoke ecryptfs-encrypted key"
			/bin/keyctl revoke "${encrypted}"
			if [ $? -eq 0 ]; then
				load_encrypted_blob "${keypath}"
			fi
		fi
	fi
}

ecryptfs_run() {
	kmk_filename="kmk-trusted.blob"
	encrypted_filename="ecryptfs-encrypted.blob"

	if [ ! -f "$ROOTFS_DIR/etc/keys/${kmk_filename}" ] && [ ! -f "$ROOTFS_DIR/etc/keys/${kmk_filename}" ]; then
		echo "*-* create TPM primary key *-*"
		create_tpm_prim_key /tmp
		echo "*-* persistent handle *-*"
		persistent_handle /tmp/key.ctxt
		echo "*-* storage primary key: ${storage_prim_key} *-*"
		echo "${storage_prim_key}" > "$ROOTFS_DIR/etc/keys/tpm_key_handle"
		/bin/keyctl clear @u
		/bin/keyctl link @u @s
		echo "*-* create_key_master_key *-*"
		create_key_master_key ${storage_prim_key} "$ROOTFS_DIR/etc/keys/${kmk_filename}"
		echo "*-* create_encrypted_key *-*"
		create_encrypted_key "$ROOTFS_DIR/etc/keys/${encrypted_filename}"
	elif [ -f "$ROOTFS_DIR/etc/keys/${kmk_filename}" ] && [ -f "$ROOTFS_DIR/etc/keys/${kmk_filename}" ]; then
		load_trusted_blob "$ROOTFS_DIR/etc/keys/${kmk_filename}" `cat "$ROOTFS_DIR/etc/keys/tpm_key_handle"`
		load_encrypted_blob "$ROOTFS_DIR/etc/keys/${encrypted_filename}"
	fi
	echo "*-* END *-*"
}
