Skip to content

Commit 102aecb

Browse files
committed
merge upstream master
2 parents ab6599a + 43d4845 commit 102aecb

4 files changed

Lines changed: 141 additions & 42 deletions

File tree

_posts/2020-04-13-Disk-Encryption.md

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ Create the RSA key<br>
107107
1. `tpm2_createprimary --hierarchy=o --key-algorithm=rsa --key-context=prim.ctx`<br>
108108

109109
Save it to the TPM persistent memory<br>
110+
{:start="2"}<br>
110111
2. `tpm2_evictcontrol --hierarchy=o --object-context=prim.ctx 0x81010001`<br>
111112

112113
NOTE:
@@ -139,6 +140,7 @@ first setup a disk image without encryption and see if we can extract user
139140
generated content.<br>
140141

141142
Create a disk image and write some content:<br>
143+
{:start="3"}<br>
142144
3. `dd if=/dev/zero of=plain.disk bs=1M count=10`<br>
143145
4. `mkfs.ext4 plain.disk`<br>
144146
5. `mkdir -p mountpoint`<br>
@@ -155,7 +157,7 @@ find the plain.txt. To do this simply do the following:<br>
155157
11. `strings plain.disk`<br>
156158

157159
NOTE:
158-
* Having a week authentication mechanism for login control is not mitigated by
160+
* Having a weak authentication mechanism for login control is not mitigated by
159161
disk encryption. Mounted encrypted volumes without user intervention are
160162
available in clear to the logged in user.
161163
* Data assets especially storage must remain confidential either with disk/ file
@@ -183,11 +185,13 @@ Let's setup a new LUKS volume with a simple passphrase as key protector:<br>
183185
At this point you have setup the luks volume and it should pop a warning about
184186
overriding the data. Next let's open the LUKS volume by authenticating with the
185187
disk.key and complete the setting up the disk with a filesystem.<br>
188+
{:start="16"}<br>
186189
16. `sudo cryptsetup luksOpen --key-file=disk.key $loopdevice enc_volume`<br>
187190
17. `sudo mkfs.ext4 -j /dev/mapper/enc_volume`<br>
188191
18. `sudo mount /dev/mapper/enc_volume mountpoint`<br>
189192

190193
Now lets create a plain text file again and add user content to it:<br>
194+
{:start="19"}<br>
191195
19. `sudo touch mountpoint/plain.txt`<br>
192196
20. `sudo chmod 777 mountpoint/plain.txt`<br>
193197
21. `sudo echo "This is my plain text" > mountpoint/plain.txt`<br>
@@ -197,6 +201,7 @@ Now lets create a plain text file again and add user content to it:<br>
197201

198202
You will now see that you cannot dump the information from the disk image simply
199203
: <br>
204+
{:start="25"}<br>
200205
25. `strings enc.disk | grep -i plain`<br>
201206

202207
NOTE:
@@ -217,35 +222,33 @@ Solution:<br>
217222
a. Seal the secret into a TPM device.<br>
218223
b. Unseal the secret in memory and pass it to cryptsetup.<br>
219224

220-
Please note that there is an upstreaming effort in the cryptsetup
221-
[feature-branch](https://gitlab.com/cryptsetup/cryptsetup/-/tree/wip-tpm) to
222-
enable tpm2 as a key protector built natively in to libcryptsetup as well as
223-
cryptsetup. It does so by adding a new keyslot-handler internally and extending
224-
the libcryptsetup API. In this tutorial however, we will be using tpm2-tools
225-
with cryptsetup that does not have built-in tpm2 support.<br>
226-
227225
Let's start with creating and persisting a sealing object and sealing a random
228226
byte sequence as the disk key.<br>
227+
{:start="26"}<br>
229228
26. `tpm2_createprimary -Q -C o -c prim.ctx`<br>
230229
27. `dd if=/dev/urandom bs=1 count=32 status=none | tpm2_create -Q -g sha256 -u seal.pub -r seal.priv -i- -C prim.ctx`<br>
231230
28. `tpm2_load -Q -C prim.ctx -u seal.pub -r seal.priv -n seal.name -c seal.ctx`<br>
232231
29. `tpm2_evictcontrol -C o -c seal.ctx 0x81010001`<br>
233232

234233
Now lets change the authentication from previously created disk.key to the new
235234
sealed secret and after that shred the disk.key since it's no longer useful:<br>
235+
{:start="30"}
236236
30. `tpm2_unseal -Q -c 0x81010001 | sudo cryptsetup luksChangeKey enc.disk --key-file disk.key`<br>
237237
31. `shred disk.key; rm -f disk.key`<br>
238238

239239
Now let's mount the volume with the new authentication sealed up in the tpm:<br>
240+
{:start="32"}<br>
240241
32. `sudo losetup $loopdevice enc.disk`<br>
241242
33. `tpm2_unseal -Q -c 0x81010001 |sudo cryptsetup luksOpen --key-file=- $loopdevice enc_volume`<br>
242243
34. `sudo mount /dev/mapper/enc_volume mountpoint`<br>
243244

244245
You can now see that disk access is granted with the new secret:<br>
246+
{:start="35"}<br>
245247
35. `ls mountpoint`
246248
<br>
247249

248250
Finally unmount the disk:<br>
251+
{:start="36"}<br>
249252
36. `sudo umount mountpoint`<br>
250253
37. `sudo cryptsetup remove enc_volume`<br>
251254
38. `sudo losetup -d $loopdevice`<br>
@@ -280,13 +283,15 @@ c. After unsealing the pass-phrase; extend the sealing PCRs so that the
280283
pass-phrase cannot be unsealed gain.<br>
281284

282285
Let's begin with creating a pcr policy with current value in PCR0 sha256 bank<br>
286+
{:start="39"}<br>
283287
39. `tpm2_startauthsession -S session.ctx`<br>
284288
40. `tpm2_policypcr -Q -S session.ctx -l sha256:0 -L pcr0.sha256.policy`<br>
285289
41. `tpm2_flushcontext session.ctx`<br>
286290

287291
Now replace the seal object in TPM NV memory protecting the disk encryption
288292
secret with a new one that adds the pcr policy we just created as an
289293
authentication mechanism to access the sealed secret.<br>
294+
{:start="42"}<br>
290295
42. `tpm2_unseal -c 0x81010001 | tpm2_create -Q -g sha256 -u pcr_seal_key.pub -r pcr_seal_key.priv -i- -C prim.ctx -L pcr0.sha256.policy `<br>
291296
43. `tpm2_evictcontrol -C o -c 0x81010001`<br>
292297
44. `tpm2_load -Q -C prim.ctx -u pcr_seal_key.pub -r pcr_seal_key.priv -n pcr_seal_key.name -c pcr_seal_key.ctx`<br>
@@ -296,6 +301,7 @@ Now let's try to mount the encrypted disk again but this time the secret is
296301
unsealed off a TPM object whose unsealing operation can only be accessed by
297302
satisfying the PCR policy; in other words authenticating by virtue of intended
298303
system software state being unchanged as reflected by the PCR value.<br>
304+
{:start="46"}<br>
299305
46. `sudo losetup $loopdevice enc.disk`<br>
300306
47. `tpm2_startauthsession --policy-session -S session.ctx `<br>
301307
48. `tpm2_policypcr -Q -S session.ctx -l sha256:0`<br>
@@ -306,6 +312,7 @@ directly to the cryptsetup app like this --> "tpm2_unseal -p session:session.ctx
306312
However for the purpose of demonstrating flexible PCR in a later section we will
307313
make a copy of the unsealed secret at this point to seal it with a new object
308314
with flexible pcr policy. This breakdown to two steps<br>
315+
{:start="49"}<br>
309316
49. `tpm2_unseal -p session:session.ctx -c 0x81010001 > disk_secret.bkup`<br>
310317
50. `cat disk_secret.bkup | sudo cryptsetup luksOpen --key-file=- $loopdevice enc_volume`<br>
311318
51. `tpm2_flushcontext session.ctx `<br>
@@ -321,16 +328,19 @@ consequence of failed policy check and thus a failed unsealing attempt.<br>
321328

322329
Let's look at the PCR state prior to extending it and then again after
323330
extending: <br>
331+
{:start="54"}<br>
324332
54. `tpm2_pcrlist -l sha256:0`<br>
325333
55. `tpm2_pcrextend 0:sha256=0000000000000000000000000000000000000000000000000000000000000000`<br>
326334
56. `tpm2_pcrlist -l sha256:0`<br>
327335

328336
Now let's try to unseal the sealed disk encryption secret with the dirty
329337
PCR:<br>
338+
{:start="57"}<br>
330339
57. `tpm2_startauthsession --policy-session -S session.ctx `<br>
331340
58. `tpm2_policypcr -Q -S session.ctx -l sha256:0`<br>
332341
The following operation should result in policy check failure preventing the
333342
unseal operation:<br>
343+
{:start="59"}<br>
334344
59. `tpm2_unseal -p session:session.ctx -c 0x81010001`<br>
335345
60. `tpm2_flushcontext session.ctx`<br>
336346

@@ -355,6 +365,7 @@ PCR signature. The PCR sets are signed by the system designer and verified by
355365
the TPM. This is achieved in following steps:
356366

357367
__a. Get the new set of PCR and sign the pcr policy with signer private key.__<br>
368+
{:start="61"}<br>
358369
61. `tpm2_startauthsession -S session.ctx`<br>
359370
62. `tpm2_policypcr -Q -S session.ctx -l sha256:0 -L set2.pcr.policy`<br>
360371
63. `tpm2_flushcontext session.ctx`<br>
@@ -363,9 +374,11 @@ __a. Get the new set of PCR and sign the pcr policy with signer private key.__<b
363374

364375
We now need the name which is a digest of the TCG public key format of the
365376
public key to include in the policy. We can use the loadexternal tool for this:<br>
377+
{:start="66"}<br>
366378
66. `tpm2_loadexternal -G rsa -C o -u signing_key_public.pem -c signing_key.ctx -n signing_key.name`<br>
367379

368380
Let's now create the signer policy:<br>
381+
{:start="67"}<br>
369382
67. `tpm2_startauthsession -S session.ctx`<br>
370383
68. `tpm2_policyauthorize -S session.ctx -L authorized.policy -n signing_key.name -i set2.pcr.policy`<br>
371384
69. `tpm2_flushcontext session.ctx`<br>
@@ -374,10 +387,12 @@ Let's create a new sealing object with the authorized policy which will also
374387
require the sealing secret for which we will use the disk_secret.bkup we created
375388
at #49 earlier to avoid rebooting the platform to match the PCR we originally
376389
had prior to extending.<br>
390+
{:start="70"}<br>
377391
70. `cat disk_secret.bkup | tpm2_create -g sha256 -u auth_pcr_seal_key.pub -r auth_pcr_seal_key.priv -i- -C prim.ctx -L authorized.policy`<br>
378392

379393
Let's replace the old persistent sealing object with the one we created
380394
above with policy_authorize policy associated with signer public key:<br>
395+
{:start="71"}<br>
381396
71. `tpm2_evictcontrol -C o -c 0x81010001`<br>
382397
72. `tpm2_load -Q -C prim.ctx -u auth_pcr_seal_key.pub -r auth_pcr_seal_key.priv -n auth_pcr_seal_key.name -c auth_pcr_seal_key.ctx`<br>
383398
73. `tpm2_evictcontrol -c auth_pcr_seal_key.ctx 0x81010001 -C o`<br>
@@ -386,15 +401,18 @@ Let's now sign the pcr_policy with the signer private key:<br>
386401

387402
__b. Load the signer public key to the tpm and verify the signature on the pcr
388403
and get the tpm verification tkt:__<br>
404+
{:start="75"}<br>
389405
75. `tpm2_loadexternal -G rsa -C o -u signing_key_public.pem -c signing_key.ctx -n signing_key.name`<br>
390406
76. `tpm2_verifysignature -c signing_key.ctx -g sha256 -m set2.pcr.policy -s set2.pcr.signature -t verification.tkt -f rsassa`<br>
391407

392408
__c. Satisfy the authorized policy and then run policyauthorize:__<br>
409+
{:start="77"}<br>
393410
77. `tpm2_startauthsession --policy-session -S session.ctx`<br>
394411
78. `tpm2_policypcr -l sha256:0 -S session.ctx`<br>
395412
79. `tpm2_policyauthorize -S session.ctx -i set2.pcr.policy -n signing_key.name -t verification.tkt`<br>
396413

397414
__d. Pipe unseal output to the cryptsetup application:__<br>
415+
{:start="80"}<br>
398416
80. `sudo losetup $loopdevice enc.disk`<br>
399417
81. `tpm2_unseal -p session:session.ctx -c 0x81010001 | sudo cryptsetup luksOpen --key-file=- $loopdevice enc_volume`<br>
400418
82. `tpm2_flushcontext session.ctx `<br>

0 commit comments

Comments
 (0)