From b4b1a20cc70996dc21004c4b5c173a4ef3d545fa Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Thu, 22 Jun 2017 16:14:38 +0200 Subject: [PATCH] core: REE FS: use RPMB for hash storage REE FS uses RPMB (if available) for storage of dirfile hash. Acked-by: Jerome Forissier Acked-by: Volodymyr Babchuk Signed-off-by: Jens Wiklander --- core/tee/tee_ree_fs.c | 54 ++++++++++++++++++++++++++++ core/tee/tee_svc.c | 4 +++ documentation/secure_storage.md | 16 ++------- documentation/secure_storage_rpmb.md | 6 ++++ 4 files changed, 67 insertions(+), 13 deletions(-) diff --git a/core/tee/tee_ree_fs.c b/core/tee/tee_ree_fs.c index 0b76cbf48ff..9ad3dbf7ed0 100644 --- a/core/tee/tee_ree_fs.c +++ b/core/tee/tee_ree_fs.c @@ -460,6 +460,59 @@ static const struct tee_fs_dirfile_operations ree_dirf_ops = { static struct tee_fs_dirfile_dirh *ree_fs_dirh; static size_t ree_fs_dirh_refcount; +#ifdef CFG_RPMB_FS +static struct tee_file_handle *ree_fs_rpmb_fh; + +static TEE_Result open_dirh(struct tee_fs_dirfile_dirh **dirh) +{ + TEE_Result res; + uint8_t hash[TEE_FS_HTREE_HASH_SIZE]; + uint8_t *hashp = NULL; + const char fname[] = "dirfile.db.hash"; + + res = tee_rpmb_fs_raw_open(fname, false, &ree_fs_rpmb_fh); + if (!res) { + size_t l = sizeof(hash); + + res = rpmb_fs_ops.read(ree_fs_rpmb_fh, 0, hash, &l); + if (res) + return res; + if (l == sizeof(hash)) + hashp = hash; + } else if (res == TEE_ERROR_ITEM_NOT_FOUND) { + res = tee_rpmb_fs_raw_open(fname, true, &ree_fs_rpmb_fh); + } + if (res) + return res; + + if (!tee_fs_dirfile_open(false, hashp, &ree_dirf_ops, dirh)) + return TEE_SUCCESS; + + res = tee_fs_dirfile_open(true, NULL, &ree_dirf_ops, dirh); + if (res) + rpmb_fs_ops.close(&ree_fs_rpmb_fh); + return res; +} + +static TEE_Result commit_dirh_writes(struct tee_fs_dirfile_dirh *dirh) +{ + TEE_Result res; + uint8_t hash[TEE_FS_HTREE_HASH_SIZE]; + + res = tee_fs_dirfile_commit_writes(dirh, hash); + if (res) + return res; + return rpmb_fs_ops.write(ree_fs_rpmb_fh, 0, hash, sizeof(hash)); +} + +static void close_dirh(struct tee_fs_dirfile_dirh **dirh) +{ + tee_fs_dirfile_close(*dirh); + *dirh = NULL; + rpmb_fs_ops.close(&ree_fs_rpmb_fh); +} + +#else /*!CFG_RPMB_FS*/ static TEE_Result open_dirh(struct tee_fs_dirfile_dirh **dirh) { if (!tee_fs_dirfile_open(false, NULL, &ree_dirf_ops, dirh)) @@ -477,6 +530,7 @@ static void close_dirh(struct tee_fs_dirfile_dirh **dirh) tee_fs_dirfile_close(*dirh); *dirh = NULL; } +#endif /*!CFG_RPMB_FS*/ static TEE_Result get_dirh(struct tee_fs_dirfile_dirh **dirh) { diff --git a/core/tee/tee_svc.c b/core/tee/tee_svc.c index 08fcd15b185..d064241bf16 100644 --- a/core/tee/tee_svc.c +++ b/core/tee/tee_svc.c @@ -103,7 +103,11 @@ static const uint32_t crypto_ecc_en; * 100: Antirollback enforced at REE level * 1000: Antirollback TEE-controlled hardware */ +#ifdef CFG_RPMB_FS +static const uint32_t ts_antiroll_prot_lvl = 1000; +#else static const uint32_t ts_antiroll_prot_lvl; +#endif /* Trusted OS implementation version */ static const char trustedos_impl_version[] = TO_STR(TEE_IMPL_VERSION); diff --git a/documentation/secure_storage.md b/documentation/secure_storage.md index 78893c2d624..1c84f86c550 100644 --- a/documentation/secure_storage.md +++ b/documentation/secure_storage.md @@ -74,8 +74,9 @@ Below is an excerpt from the specification listing the most vital requirements: Typically, an implementation may rely on the REE for that purpose (protection level 100) or on hardware assets controlled by the TEE (protection level 1000). - The current implementation does *not* provide any protection against - rollback, and therefore the protection level is set to 0. + If configured with CFG_RPMB_FS=y the protection against rollback is is + controlled by the TEE and is set to 1000. If CFG_RPMB_FS=n, there's no + protection against rollback, and the protection level is set to 0. ### TEE File Structure In Linux File System @@ -223,17 +224,6 @@ implementations in your platform code for: These implementations should fetch the key data from your SoC-specific e-fuses, or crypto unit according to the method defined by your SoC vendor. -## Future Work - -- **Rollback attack detection** - -An attacker can backup the whole `/data/tee` folder and restore it at later -time. - -The basic idea of detecting rollback attack is to store information -representing the state of `/data/tee/dirf.db` into another storage which has -anti-rollback capability such as the eMMC RPMB partition. - ## Reference * [Secure Storage Presentation](http://www.slideshare.net/linaroorg/sfo15503-secure-storage-in-optee) diff --git a/documentation/secure_storage_rpmb.md b/documentation/secure_storage_rpmb.md index 7ac2304a122..60f6305c8e5 100644 --- a/documentation/secure_storage_rpmb.md +++ b/documentation/secure_storage_rpmb.md @@ -132,6 +132,12 @@ CBC block encryption is used only for RPMB (the REE implementation uses GCM). The FAT is not encrypted. +## REE FS + +If configured with both CFG_REE_FS=y and CFG_RPMB_FS=y the REE FS will +create a special file, "dirfile.db.hash" in RPMB which hold a hash +representing the state of REE FS. + ## References - [1] _Embedded Multi-Media Card (e•MMC) Electrical Standard (5.1)_, JEDEC JESD84-B51, February 2015