diff options
author | Lans Zhang <jia.zhang@windriver.com> | 2017-06-22 15:22:01 +0800 |
---|---|---|
committer | Lans Zhang <jia.zhang@windriver.com> | 2017-06-22 15:24:04 +0800 |
commit | 1b3e5944491c315ca99b832bc3afdb6a19d81430 (patch) | |
tree | ffb3469d58e8e203e4bc8a37adc9fe81a48558fb /meta-encrypted-storage | |
download | meta-secure-core-1b3e5944491c315ca99b832bc3afdb6a19d81430.tar.gz |
meta-secure-core: initial commit
Signed-off-by: Lans Zhang <jia.zhang@windriver.com>
Diffstat (limited to 'meta-encrypted-storage')
11 files changed, 316 insertions, 0 deletions
diff --git a/meta-encrypted-storage/README.md b/meta-encrypted-storage/README.md new file mode 100644 index 0000000..989c8be --- /dev/null +++ b/meta-encrypted-storage/README.md | |||
@@ -0,0 +1,179 @@ | |||
1 | ### Storage Encryption | ||
2 | This feature provides secure storage for application data. Some applications | ||
3 | need secure storage for sensitive data which must not be accessible to another | ||
4 | device. For example, only an application with the right signature can update | ||
5 | the data on an encrypted SD card. If you move that SD card to another device, | ||
6 | the data cannot be either read or updated. One application of this capability | ||
7 | is a POS application. The application keeps tax information in secure storage | ||
8 | that cannot be modified by another device. | ||
9 | |||
10 | This feature gives 2 types of granularity for storage encryption. Data volume | ||
11 | encryption allows the user to create encryption partition with a passphrase | ||
12 | typed by the end user. Root filesystem encryption enables the data encryption | ||
13 | on the entire rootfs except the boot partition. | ||
14 | |||
15 | Both types of storage encryption are based on device-mapper crypt target, | ||
16 | which provides transparent encryption of block devices using the kernel crypto | ||
17 | API. Additionally, the utility cryptsetup is used to conveniently set up disk | ||
18 | encryption, aka LUKS partition, based on device-mapper crypt target. | ||
19 | |||
20 | Due to the use of TPM state to seal the passphrase used to encrypt the storage, | ||
21 | the encrypted storage cannot be accessed on another machine, preventing from | ||
22 | the so-called offline attack. | ||
23 | |||
24 | ### Dependency | ||
25 | This feature depends on meta-tpm2. | ||
26 | |||
27 | Note: | ||
28 | Even though the hardware doesn't have a TPM 2.0 device, this feature can still | ||
29 | run on it, although without the guarantee of compromise detection. | ||
30 | |||
31 | ### Limit | ||
32 | - TPM 2.0 is validated and officially supported. But TPM 1.2 device is not | ||
33 | supported by this feature. | ||
34 | |||
35 | ### Data Volume Encryption | ||
36 | #### Use case 1: manual operation | ||
37 | ##### Create the LUKS partition | ||
38 | ``` | ||
39 | # cryptsetup --type luks --cipher aes-xts-plain --hash sha256 \ | ||
40 | --use-random luksFormat /dev/$dev | ||
41 | ``` | ||
42 | where $dev is the device node of the partition to be encrypted. | ||
43 | |||
44 | This command initializes a LUKS partition and prompts to input an initial | ||
45 | passphrase used to encrypt the data. Don't disclose the passphrase used for | ||
46 | product. | ||
47 | |||
48 | ##### Open the LUKS partition | ||
49 | ``` | ||
50 | # cryptsetup luksOpen /dev/$dev $name | ||
51 | ``` | ||
52 | This command opens the LUKS device $dev and sets up a mapping $name after | ||
53 | successful verification of the supplied passphrase typed interactively. From | ||
54 | now on, the data written to /dev/mapper/$name is encrypted and the data | ||
55 | read back from /dev/mapper/$name is decrypted transparently and automatically. | ||
56 | |||
57 | ##### Create the filesystem on top of the LUKS partition | ||
58 | The user can run any available filesytem formatting program on | ||
59 | /dev/mapper/$name to create the filesytem with the data encryption. | ||
60 | |||
61 | ##### Close the LUKS partition | ||
62 | ``` | ||
63 | # cryptsetup luksClose $name | ||
64 | ``` | ||
65 | This command removes the existing mapping $name and wipes the key from kernel | ||
66 | memory. | ||
67 | |||
68 | To access the encryped partition, follow the instruction "Open the LUKS partition" | ||
69 | and then manually mount /dev/mapper/$name to a mount point. | ||
70 | |||
71 | #### Use case 2: luks-setup.sh | ||
72 | This script provides a semi automatic method to set up LUKS partition. The user | ||
73 | still needs to manually create the filesystem on top of the newly created LUKS | ||
74 | partition. | ||
75 | |||
76 | ##### LUKS partition creation | ||
77 | In runtime, for example, create LUKS partition on /dev/sdb1 with the | ||
78 | name "my_luks_part": | ||
79 | ``` | ||
80 | # luks-setup.sh -d /dev/sdb1 -n my_luks_name -e | ||
81 | ``` | ||
82 | Note: if TPM is detected, the passphrase will be generated automatically. | ||
83 | |||
84 | For more uses about luks-setup.sh, run it with -h option. | ||
85 | |||
86 | ##### Retrieve the passphrase | ||
87 | ``` | ||
88 | # cryptfs-tpm2 -q unseal passphrase -P sha1 -o /tmp/passphrase | ||
89 | ``` | ||
90 | This command will unseal the passphrase from TPM device and save the content | ||
91 | of passphrase to the file /tmp/passphrase. | ||
92 | |||
93 | The passphrase should not be disclosed and needs to be backed up to a off-line | ||
94 | storage. | ||
95 | |||
96 | ##### Open the LUKS partition | ||
97 | ``` | ||
98 | # cryptsetup luksOpen --key-file /tmp/passphrase /dev/$dev $name | ||
99 | ``` | ||
100 | ##### Mount the LUKS partition | ||
101 | ``` | ||
102 | # mount /dev/mapper/$name $mount_point | ||
103 | ``` | ||
104 | The remaining operations are left to the user. Don't forget to close the LUKS | ||
105 | partition if not used. | ||
106 | |||
107 | Note: | ||
108 | If TPM device exists in the system, the passphrase will be bound to PCR 7, | ||
109 | gating the unseal operation. If the value of PCR 7 when unsealing the | ||
110 | passphrase doesn't match up the value when creating the passphrase, the | ||
111 | passphrase cannot be unsealed. The value of PCR 7 is usually affected by the | ||
112 | status of UEFI secure boot. | ||
113 | |||
114 | ### Root Filesystem Encryption | ||
115 | This enables the data encryption on the rootfs without the need of a human | ||
116 | entering an user passphrase. Therefore, it is required to employ an initramfs | ||
117 | where the unique identity from the platform is collected from the devices on | ||
118 | the platform and used to unlock the root filesystem encryption. Meanwhile, use | ||
119 | TPM to protect the user passphrase for volume decryption to avoid disclosing | ||
120 | the user passphrase. If the TPM device is not detected, the end user will be | ||
121 | prompted to type the user passphrase. | ||
122 | |||
123 | #### Operations | ||
124 | Note: | ||
125 | The instructions below with the prefix "[TPM]" indicate the operation | ||
126 | requires TPM device. Oppositely, the prefix "[Non-TPM]" indicates this | ||
127 | operation is required if the target board doesn't have a TPM device. | ||
128 | |||
129 | - Ensure a hard drive is attached on target board | ||
130 | WARNNING: the following instructions will wipe all data in the hard drive. | ||
131 | |||
132 | - Create overc installer on a USB device | ||
133 | Refer to layers/meta-overc/README.install for the details about how to | ||
134 | run cubeit to install overc installer to a USB device. | ||
135 | |||
136 | - Attach the USB device to the board | ||
137 | |||
138 | - Power on | ||
139 | |||
140 | - [TPM] Clear TPM | ||
141 | Refer to meta-tpm2/README.md for the details. | ||
142 | |||
143 | - Boot to Linux | ||
144 | |||
145 | - Install overc runtime on the hard drive | ||
146 | Refer to layers/meta-overc/README.install for the details about how to | ||
147 | run cubeit-installer to install overc runtime to a hard drive. In | ||
148 | addition, beware of specifying "--encrypt" option to set up an | ||
149 | encrypted rootfs. | ||
150 | |||
151 | - Reboot | ||
152 | After reboot to initramfs, it employs a init script to transparently | ||
153 | unseal the passphrase and mount the rootfs without any interaction. | ||
154 | |||
155 | ### Best Practice | ||
156 | - The benefit of anchoring the TPM is that the machine status cannot be | ||
157 | compromised by any attack. If compromised, the system cannot boot up | ||
158 | due to the failure when mouting the rootfs, or access the encrypted partition | ||
159 | when mounting the LUKS partition. This is caused by the fact that the content | ||
160 | of PCR 7 is different with the value when creating the encrypted storage. | ||
161 | Usually, the content of PCR 7 is calculated based on the status of UEFI | ||
162 | secure boot. | ||
163 | |||
164 | Based on the above conclusion, it is recommended to provision UEFI secure | ||
165 | boot and turn on it prior to setting up the encrypted storage. | ||
166 | |||
167 | - The non-default seal secret is supported to provide extra protection, and it | ||
168 | is user configurable. Modify the values of CRYPTFS_TPM2_PRIMARY_KEY_SECRET | ||
169 | and CRYPTFS_TPM2_PASSPHRASE_SECRET in cryptfs-tpm2 with your preference. | ||
170 | |||
171 | ### Known Issues | ||
172 | - The default IMA rules provides the ability of measuring the boot components | ||
173 | and calculating the aggregate integrity value for attesting. However, this | ||
174 | function conflicts with this feature which employs PCR policy session to | ||
175 | retrieve the passphrase in a safe way. If the installer enables both of | ||
176 | them, the default IMA rules will be not used. | ||
177 | |||
178 | ### Reference | ||
179 | - [OpenEmbedded layer for TPM 2.0 enablement](https://github.com/jiazhang0/meta-tpm2) | ||
diff --git a/meta-encrypted-storage/conf/layer.conf b/meta-encrypted-storage/conf/layer.conf new file mode 100644 index 0000000..b24954c --- /dev/null +++ b/meta-encrypted-storage/conf/layer.conf | |||
@@ -0,0 +1,15 @@ | |||
1 | # We have a conf and classes directory, add to BBPATH | ||
2 | BBPATH .= ":${LAYERDIR}" | ||
3 | |||
4 | # We have recipes-* directories, add to BBFILES | ||
5 | BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ | ||
6 | ${LAYERDIR}/recipes-*/*/*.bbappend" | ||
7 | |||
8 | BBFILE_COLLECTIONS += "encrypted-storage" | ||
9 | BBFILE_PATTERN_encrypted-storage = "^${LAYERDIR}/" | ||
10 | BBFILE_PRIORITY_encrypted-storage = "10" | ||
11 | |||
12 | LAYERDEPENDS_encrypted-storage = "\ | ||
13 | core \ | ||
14 | tpm2 \ | ||
15 | " | ||
diff --git a/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage-initramfs.bb b/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage-initramfs.bb new file mode 100644 index 0000000..88e8f7f --- /dev/null +++ b/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage-initramfs.bb | |||
@@ -0,0 +1,8 @@ | |||
1 | include packagegroup-encrypted-storage.inc | ||
2 | |||
3 | DESCRIPTION = "The packages used for encrypted storage in initramfs." | ||
4 | |||
5 | RDEPENDS_${PN} += " \ | ||
6 | cryptfs-tpm2-initramfs \ | ||
7 | packagegroup-tpm2-initramfs \ | ||
8 | " | ||
diff --git a/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage.bb b/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage.bb new file mode 100644 index 0000000..225eb6a --- /dev/null +++ b/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage.bb | |||
@@ -0,0 +1,14 @@ | |||
1 | include packagegroup-encrypted-storage.inc | ||
2 | |||
3 | DESCRIPTION = "The packages used for encrypted storage." | ||
4 | |||
5 | # Install the minimal stuffs only for the linux rootfs. | ||
6 | # The common packages shared between initramfs and rootfs | ||
7 | # are listed in the .inc. | ||
8 | # @util-linux: fdisk | ||
9 | # @parted: parted | ||
10 | RDEPENDS_${PN} += " \ | ||
11 | util-linux-fdisk \ | ||
12 | parted \ | ||
13 | packagegroup-tpm2 \ | ||
14 | " | ||
diff --git a/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage.inc b/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage.inc new file mode 100644 index 0000000..ab4b778 --- /dev/null +++ b/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage.inc | |||
@@ -0,0 +1,25 @@ | |||
1 | LICENSE = "MIT" | ||
2 | LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \ | ||
3 | file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" | ||
4 | |||
5 | ALLOW_EMPTY_${PN} = "1" | ||
6 | |||
7 | S = "${WORKDIR}" | ||
8 | |||
9 | # Install the minimal stuffs for the common uses between initramfs | ||
10 | # and linux rootfs. | ||
11 | # @util-linux: mount, umount | ||
12 | # @cryptsetup: cryptsetup | ||
13 | # @cryptfs-tpm: tpm_gen_dmcrypt_key, tpm_unwrap_dmcrypt_key | ||
14 | # @kmod: modprobe | ||
15 | # @coreutils: cat, mkdir, mknod, cp, rm | ||
16 | # @trousers: tcsd | ||
17 | RDEPENDS_${PN} = " \ | ||
18 | util-linux-mount \ | ||
19 | util-linux-umount \ | ||
20 | cryptsetup \ | ||
21 | kmod \ | ||
22 | coreutils \ | ||
23 | cryptfs-tpm2 \ | ||
24 | procps \ | ||
25 | " | ||
diff --git a/meta-encrypted-storage/recipes-kernel/linux/linux-yocto-encrypted-storage.inc b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto-encrypted-storage.inc new file mode 100644 index 0000000..198c972 --- /dev/null +++ b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto-encrypted-storage.inc | |||
@@ -0,0 +1,6 @@ | |||
1 | FILESEXTRAPATHS_prepend := "${THISDIR}/linux-yocto:" | ||
2 | |||
3 | SRC_URI += " \ | ||
4 | ${@bb.utils.contains('DISTRO_FEATURES', 'encrypted-storage', \ | ||
5 | 'file://dmcrypt.scc file://dmcrypt.cfg', '', d)} \ | ||
6 | " | ||
diff --git a/meta-encrypted-storage/recipes-kernel/linux/linux-yocto-rt_%.bbappend b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto-rt_%.bbappend new file mode 100644 index 0000000..fc85431 --- /dev/null +++ b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto-rt_%.bbappend | |||
@@ -0,0 +1 @@ | |||
include linux-yocto-encrypted-storage.inc | |||
diff --git a/meta-encrypted-storage/recipes-kernel/linux/linux-yocto/dmcrypt.cfg b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto/dmcrypt.cfg new file mode 100644 index 0000000..cedfcea --- /dev/null +++ b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto/dmcrypt.cfg | |||
@@ -0,0 +1,11 @@ | |||
1 | # Enable device-mapper crypt target | ||
2 | CONFIG_DM_CRYPT=y | ||
3 | |||
4 | # Enable the default cipher-spec for LUKS | ||
5 | CONFIG_CRYPTO_AES=y | ||
6 | CONFIG_CRYPTO_AES_NI_INTEL=y | ||
7 | CONFIG_CRYPTO_XTS=y | ||
8 | |||
9 | # Use entropy-strong source for RNG | ||
10 | CONFIG_HW_RANDOM=y | ||
11 | CONFIG_HW_RANDOM_TPM=m | ||
diff --git a/meta-encrypted-storage/recipes-kernel/linux/linux-yocto/dmcrypt.scc b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto/dmcrypt.scc new file mode 100644 index 0000000..c549edd --- /dev/null +++ b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto/dmcrypt.scc | |||
@@ -0,0 +1 @@ | |||
kconf non-hardware dmcrypt.cfg | |||
diff --git a/meta-encrypted-storage/recipes-kernel/linux/linux-yocto_%.bbappend b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto_%.bbappend new file mode 100644 index 0000000..fc85431 --- /dev/null +++ b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto_%.bbappend | |||
@@ -0,0 +1 @@ | |||
include linux-yocto-encrypted-storage.inc | |||
diff --git a/meta-encrypted-storage/recipes-tpm/cryptfs-tpm2/cryptfs-tpm2_git.bb b/meta-encrypted-storage/recipes-tpm/cryptfs-tpm2/cryptfs-tpm2_git.bb new file mode 100644 index 0000000..2ad7ed1 --- /dev/null +++ b/meta-encrypted-storage/recipes-tpm/cryptfs-tpm2/cryptfs-tpm2_git.bb | |||
@@ -0,0 +1,55 @@ | |||
1 | SUMMARY = "A tool used to create, persist, evict a passphrase \ | ||
2 | for full-disk-encryption with TPM 2.0" | ||
3 | DESCRIPTION = " \ | ||
4 | This project provides with an implementation for \ | ||
5 | creating, persisting and evicting a passphrase with TPM 2.0. \ | ||
6 | The passphrase and its associated primary key are automatically \ | ||
7 | created by RNG engine in TPM. In order to avoid saving the \ | ||
8 | context file, the created passphrase and primary key are always \ | ||
9 | persistent in TPM. \ | ||
10 | " | ||
11 | SECTION = "devel" | ||
12 | LICENSE = "BSD-3-Clause" | ||
13 | LIC_FILES_CHKSUM = "file://${S}/LICENSE;md5=89c8ce1346a3dfe75379e84f3ba9d641" | ||
14 | |||
15 | SRC_URI = " \ | ||
16 | git://github.com/WindRiver-OpenSourceLabs/cryptfs-tpm2.git \ | ||
17 | " | ||
18 | SRCREV = "32b49092d54b3d59c482d77d5eb1e36993912e89" | ||
19 | PV = "0.6.0+git${SRCPV}" | ||
20 | |||
21 | DEPENDS += "tpm2.0-tss tpm2-abrmd pkgconfig-native" | ||
22 | RDEPENDS_${PN} += "libtss2 libtctidevice libtctisocket" | ||
23 | |||
24 | PACKAGES =+ " \ | ||
25 | ${PN}-initramfs \ | ||
26 | " | ||
27 | |||
28 | PARALLEL_MAKE = "" | ||
29 | |||
30 | S = "${WORKDIR}/git" | ||
31 | |||
32 | EXTRA_OEMAKE = " \ | ||
33 | sbindir="${sbindir}" \ | ||
34 | libdir="${libdir}" \ | ||
35 | includedir="${includedir}" \ | ||
36 | tpm2_tss_includedir="${STAGING_INCDIR}/sapi" \ | ||
37 | tpm2_tss_libdir="${STAGING_LIBDIR}" \ | ||
38 | tpm2_tabrmd_includedir="${STAGING_INCDIR}" \ | ||
39 | CC="${CC}" \ | ||
40 | PKG_CONFIG="${STAGING_BINDIR_NATIVE}/pkg-config" \ | ||
41 | EXTRA_CFLAGS="${CFLAGS}" \ | ||
42 | EXTRA_LDFLAGS="${LDFLAGS}" \ | ||
43 | " | ||
44 | |||
45 | do_install() { | ||
46 | oe_runmake install DESTDIR="${D}" | ||
47 | |||
48 | if [ x"${@bb.utils.contains('DISTRO_FEATURES', 'encrypted-storage', '1', '0', d)}" = x"1" ]; then | ||
49 | install -m 0500 ${S}/script/init.cryptfs ${D} | ||
50 | fi | ||
51 | } | ||
52 | |||
53 | FILES_${PN}-initramfs = "\ | ||
54 | /init.cryptfs \ | ||
55 | " | ||