gaspard1283
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    ###### Thibault Vadon & Luc Riedhauser # SSHD, FileSystem, Firewall, TPM ## SSHD ### Signature check - Download `openssh-8.8p1.tar.gz` and `openssh-8.8p1.tar.gz.asc` from www.openssh.com - When `gpg --verify openssh-8.8p1.tar.gz.asc` : ![](https://i.imgur.com/NNPtMCY.png) - So one needs to get the key with `gpg --keyserver keyserver.ubuntu.com --search-keys 7168B983815A5EEF59A4ADFD2A3F414E736060BA` and then `gpg --verify openssh-8.8p1.tar.gz.asc` again. ![](https://i.imgur.com/s6kk2ig.png) ### Configure package Use `tar -xvzf openssh-8.8p1.tar.gz` to unzip the package. 1. We need to add hardening options. Some options are actually already added, one could choose to remove them: - `--without-stackprotect` : Don't use compiler's stack protection - `--without-hardening` : Don't use toolchain hardening flags We can see with `./configure` which flags are used. In this image we see that hardening options are installed. ![](https://i.imgur.com/2n0vxL7.png) 2. Also, we have to install in a choosen directory. To choose the path for the binaries, use `./configure --prefix=home/lmi/install_PC`. 3. Lets generate code using `make` and `make install`. To check if the files are stripped, use the command `file`. ![](https://i.imgur.com/OkGhFBO.png) ### For NanoPi For this installation we need to change the default directory so we do not mix up the version for Intel with the version for arm. We also need to change the host option. Lets use `./configure --host=aarch64-none-linux-gnu --prefix=/home/lmi/install_NanoPi`. Then generate code using `make` and `make install`. Unfortunatly we get an error : ![](https://i.imgur.com/he9tRFN.png) This error comes from the fact that we need to change the strip command to a strip command that understands executable files intended for the target host (ARM aarch64). After some research, we found that we need to modify the STRIP_OPT variable to `STRIP_OPT=-s --strip-program=/home/lmi/workspace/nano/buildroot/output/host/bin/aarch64-none-linux-gnu-strip` in the `Makefile`. Then use `make install-nokeys` since we will generate the keys on another host (namely the NanoPi). To check if the files are stripped, use the command `file`. ![](https://i.imgur.com/b7RxyZi.png) ### Install on NanoPi To copy files on NanoPi we will use the `scp` command. It's a ssh command to transfer files. Files to transfer : - `/home/lmi/install_NanoPi/sbin/sshd` - `/home/lmi/install_NanoPi/bin/ssh-keygen` - `/home/lmi/install_NanoPi/etc/moduli` - `/home/lmi/install_NanoPi/etc/sshd_config` These files will be transfered to the directory `/root/sshd` of the NanoPi. You have to create this directory. Use the command `scp sshd root@192.168.0.100:/root/sshd/`. ![](https://i.imgur.com/QFGOe1b.png) Do the same for the others files. Then, one can verify if the files have been copied: ![](https://i.imgur.com/mSX0yHz.png) ### Create keys To generate a key, use `./ssh-keygen -b XXXX -t YYYY -f ZZZZ`. Replace `XXXX` with the key length, `YYYY` with the key type and `ZZZZ` with the file location. Keys to generate and store in `/root/sshd`: - `rsa` 4096 bits - `dsa` 1024 bits - `ecdsa` 521 bits - `ed25519` 256 bits ![](https://i.imgur.com/pykvxx7.png) ### Configure sshd https://www.ssh.com/academy/ssh/sshd_config Some modifications must be done in the `sshd_config` file. The commented values are the default settings. One should override some settings by removing the #. ![](https://i.imgur.com/eyyeWOv.png) To start the new ssh server, the old one must be stopped. To find what version of ssh is running, use `ssh -V`. We can see that `Dropbear v2020.81` is the actual version running. To stop it use the command `/etc/init.d/S50dropbear stop`. Then start the ssh deamon by typing: `/root/sshd/sshd -f /root/sshd/sshd_config -h /root/sshd/rsa4096`. It will tell you `Privilege separation user sshd does not exist`. So one needs to add the user sshd: `adduser sshd`. It will ask you for a password (no password is not accepted). We chose `sshd`. Then run `/root/sshd/sshd -f /root/sshd/sshd_config -h /root/sshd/rsa4096` again. This time it will tell you that the directory `/var/empty/` does not exist. Just create it. Now if you run `/root/sshd/sshd -f /root/sshd/sshd_config -h /root/sshd/rsa4096` again, it should start the deamon. Open a new terminal and type `ssh sshd@192.168.0.100`. It will tell you the following: ![](https://i.imgur.com/5lZ5mvl.png) One needs to type `ssh-keygen -R 192.168.0.100` to remove the host key of the previous ssh deamon. Then reconnect to the server. After typing the password one should get access to the NanoPi. ![](https://i.imgur.com/KAOAhcd.png) One can see the banner, and access to root directory is denied. To disconnect type 'exit'. On the NanoPi, if one wants to shut down de ssh deamon: ![](https://i.imgur.com/WKj1jRc.png) ### Server without version (optional) Typing `nmap -sV -p 22 192.168.0.200` produces the following output: ![](https://i.imgur.com/EjzL4tu.png) https://support.hpe.com/hpesc/public/docDisplay?docId=emr_na-c02655633 ![](https://i.imgur.com/aeABgcL.png) ![](https://i.imgur.com/Zj95lTs.png) One can also modify the file `version.h` and recompile everything ```c /* $OpenBSD: version.h,v 1.92 2021/09/26 14:01:11 djm Exp $ */ #define SSH_VERSION "It is a ssh server without version" #define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE ``` It will produce the same result. What is important to understand is that the command nmap only recognizes some service versions. If it is not able to recognize the version, it will leave the version field blank. Services can be added here: https://nmap.org/cgi-bin/submit.cgi?new-service. ## FileSystem ### Question 1 : EXT4 #### How does the Kernel know that rootfs is in partition 2 ? U-boot tells the Kernel where the rootfs is located via the bootargs. One can verify that by looking at the `boot.cmd` file: ![](https://i.imgur.com/41Tmhm5.png) Looking at the manual page bootparam, one can read what the argument root does: ![](https://i.imgur.com/2HqTmxL.png) So the kernel knows now that rootfs is located in the MMC, block 0, partition 2 which is obviously the second partition of the SD card. #### Mounting partition 1 of SD card on /mnt Let's `ls /dev`. One can see that `mmcblk0p1` is present. Let's mount it with `mount -t ext4 /dev/mmcblk0p1 /mnt`. Let's check if the content of partition 1 is in `/mnt`: ![](https://i.imgur.com/UHIcRCN.png) > [name=Luc] Dans `/dev` ya mmcblk2*, c'est quoi? C'est la deuxième SD card qui est soudée sur la NanoPI #### What are the major and minor numbers of the node file managing the SD card ? ![](https://i.imgur.com/tUKNINf.png) The major number is 179 and the minor number is 0. The kernel uses the major number at open time to dispatch execution to the appropriate driver. The minor number is used only by the driver specified by the major number. ### Question 2: btrfs, f2fs, nilfs2, xfs #### 1. First of all, one needs to unmount the SD card with `umount /dev/sdb1` and `umount /dev/sdb2`. Let's start fdisk on `sdb` with `sudo fdisk /dev/sdb`, then type `n` to add a new partition. Then, follow the instructions: ![](https://i.imgur.com/q2FEXDv.png) Do the same for the last partition. Then you can print the partition table with the command `p`: ![](https://i.imgur.com/IRJQEyH.png) Finally, write the table to disk and exit with the command `w`. #### 2. To format the third partition with btrfs execute `sudo mkfs.btrfs /dev/sdb3`. To format the fourth partition with f2fs execute `sudo mkfs.f2fs /dev/sdb4`. You may need to install f2fs-tools (`sudo dnf install f2fs-tools`). Let's disconnect the SD card and plug it in again. Type `mount`: ![](https://i.imgur.com/7616wFW.png) > [name=Luc]Ce qui est bizarre c'est que `umount /dev/sdb3` me donne une erreur: `Error finding object for block device 0:63`. Je suis obligé de le `sudo umount /dev/sdb3`. Pourquoi? Parce que pour btrfs on a besoin d'être super user pour executer certaines commandes. #### 3. Using the program skeleton given and after some modifications, we get these outputs. On btrfs Luc: ![](https://i.imgur.com/IwBperV.png) On f2fs Luc: ![](https://i.imgur.com/BWaX4OO.png) On ext4 Luc: ![](https://i.imgur.com/JuIIvCP.png) > [Luc]En vrai ya beaucoup trop de variabilité entre différentes executions du programme. J'imagine que le temps d'accès au bus de données n'est pas toujours le même. > pour f2fs par exemple j'ai: > ![](https://i.imgur.com/T30JxbT.png) > Comment peut-on comparer quoique ce soit avec des valeurs qui changent à ce point. On btrfs Thibault: ![](https://i.imgur.com/4eUrOQg.png) On f2fs Thibault: ![](https://i.imgur.com/2RsuESD.png) It is possible to conclude that btrfs is better to write big files and f2fs is better to write small files. However, comparing these times is not determinist. As shown before, these numbers can vary. Here are the modifications to be done in `write_skeleton.c`. ```c int writeSmallFiles() { int numfiles = 1000; int sizeInB = 1024; char buffer[sizeInB]; FILE *files[numfiles]; for (int i = 0; i < numfiles; i++) { char filename[20]; sprintf(filename, "smallFile%d", i); files[i] = fopen(filename, "w"); for (int j = 0; j < sizeInB; ++j) buffer[j] = 'F'; fwrite(buffer, sizeof(char), sizeInB, files[i]); } return 0; } int writeBigFile() { int numfiles = 1; int sizeInMB = 1; char buffer[sizeInMB*1000*1000]; FILE *files[numfiles]; for (int i = 0; i < numfiles; i++) { char filename[20]; sprintf(filename, "BigFile%d", i); files[i] = fopen(filename, "w"); for (int j = 0; j < sizeInMB*1000*1000; ++j) buffer[j] = 'F'; fwrite(buffer, sizeof(char), sizeInMB*1000*1000, files[i]); } return 0; } ``` ### Question 3: LUKS, cryptsetup, dmcrypt #### 1. First of all, one needs to unmount the SD card with `umount /dev/sdb1` and `umount /dev/sdb2`. Let's start fdisk on `sdb` with `sudo fdisk /dev/sdb`, then type `n` to add a new partition. Then, follow the instructions: ![](https://i.imgur.com/yxAKrx7.png) Finally, write the table to disk and exit with the command `w`. ### Question 3.2: LUKS Test 1 - Let's define `DEVICE=/dev/sdb3` first. Then type `sudo cryptsetup --debug --pbkdf pbkdf2 luksFormat $DEVICE`. Create a passphrase when asked. - Create a mapping which will create a node file: `sudo cryptsetup --debug open --type luks $DEVICE usrfs1`. The passphrase defined in the previous step is needed. - Format it as ext4 with `sudo mkfs.ext4 /dev/mapper/usrfs1` - And mount it to `/mnt/usr` with `sudo mount /dev/mapper/usrfs1 /mnt/usr`. The directory `/mnt/usr` must be created using `cd /mnt/` and `sudo mkdir usr`. - We can now copy files to the partition. For example: `cp data.txt /mnt/usr`. - To add another passphrase let's first unmount the partition: `sudo umount /dev/mapper/usrfs1` and remove the node file since we will create a new one with two keys: `sudo cryptsetup close usrfs1` - Now, let's add a new key with: `sudo cryptsetup luksAddKey $DEVICE` and give a new passphrase when asked. - Let's check with `sudo cryptsetup luksDump $DEVICE`: ![](https://i.imgur.com/GaKdW4n.png) We notice that the second key needs argon2i algorithm. Hence this key may not work on the NanoPi since its RAM is too small. - To dump the encrypted master key type `sudo cryptsetup luksDump --dump-master-key $DEVICE`: ![](https://i.imgur.com/0fOouE1.png) - Let's dump 1MB of the partition to a file: `sudo dd if=/dev/sdb3 of=dump bs=1024 count=1` - Using `hexedit dump`, it is possible to see that the master key is still crypted. ![](https://i.imgur.com/KRQnfI3.png) - Plug SD card in NanoPi and use`cryptsetup --debug open --type luks /dev/mmcblk0p3 usrfs1`. Once this is done, we need to mount it to `/mnt/usr` with `mount /dev/mapper/usrfs1 /mnt/usr`. Now one has access to the partition: ![](https://i.imgur.com/kLiuXj1.png) Do not forget to give the passphrase of the first keyslot since the second one needs argon2 (which may not work). ### Question 3.3: rootfs in a luks partition - To generate a random passphrase in a file, use `dd if=/dev/urandom of=passphrase bs=64 count=1`. To see the passphrase, use `hexdump passphrase`. ![](https://i.imgur.com/ufX00Fx.png) - To initialize a LUKS partition with correct options, use `sudo cryptsetup --debug --pbkdf pbkdf2 --key-size 512 luksFormat $DEVICE passphrase` in the directory where the file "passphrase" is stored. - Create mapping using `sudo cryptsetup --debug --key-file passphrase open --type luks $DEVICE usrfs1`. - Format it as ext4 with `sudo mkfs.ext4 /dev/mapper/usrfs1`. - Finally, copy the rootfs to the partition with `sudo dd if=~/workspace/nano/buildroot/output/images/rootfs.ext4 of=/dev/mapper/usrfs1 bs=4M`. #### On NanoPi - First of all, one needs to copy the passphrase file to the NanoPi via `scp passphrase root@192.168.0.200:/root`. ATTENTION, SUPPRIMER LA CLE DE L'ANCIEN SSHD. rm /etc/ssh/none/kwkey - Then, declare the variable `DEVICE=/dev/mmcblk0p3`. - Execute `cryptsetup --debug --key-file /root/passphrase open --type luks $DEVICE usrfs1` - Mount it to `/mnt/usr` with `mount /dev/mapper/usrfs1 /mnt/usr`. Now one has access to the partition: ![](https://i.imgur.com/CoYvxvF.png) - Let's create a script named `S40luks`: ```shell #!/bin/sh # # mount luks partition # DEVICE=/dev/mmcblk0p3 cryptsetup --debug --key-file /root/passphrase open --type luks $DEVICE usrfs1 mount /dev/mapper/usrfs1 /mnt/usr ``` - Copy it to /etc/init.d/ via ssh: `scp S40luks root@192.168.0.200:/etc/init.d` - And `chmod 755 S40luks` on the nanoPi. - Restart the nanoPi, and we can see in the following screen shot that the partition has been mounted on startup. ![](https://i.imgur.com/UWgztkg.png) - Still, Let's login and check: ![](https://i.imgur.com/aF1Tovq.png) ### Question 4: initramfs - To generate an initramfs, use the code given during the course. The code is given in annex as `buildRamfs.sh`. Note that at line 63, `exec sh` is active but `# exec switch_root /newroot /sbin/init` is commented. This means that the kernel will start a shell instead of mounting the rootfs directly. - Create the script `bootramfs.cmd` : ```shell= setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait ext4load mmc 0 $kernel_addr_r Image ext4load mmc 0 $fdt_addr_r nanopi-neo-plus2.dtb ext4load mmc 0 0x50000000 uInitrd booti $kernel_addr_r 0x50000000 $fdt_addr_r ``` - Then use `mkimage -C none -A arm64 -T script -d bootramfs.cmd ~/workspace/nano/buildroot/output/images/boot.scr` to generate the boot file. It MUST have the name `boot.scr`. - Add the following line to your SD card flashing script: ![](https://i.imgur.com/GvRa8dg.png) - Once the SD card has been flashed, plugged into the NanoPi, start it and you should obtain this output: ![](https://i.imgur.com/9Xl6rj2.png) Indeed we have an initram file system. This, before the kernel attaches the rootfs. Now, one can execute `exec switch_root /newroot /sbin/init` to attach the rootfs and start the system as usual: ![](https://i.imgur.com/1MqiO9A.png) ### Question 5: initramfs-LUKS partition Let's imagine one wants to work on a crypted rootfs. Therefore one needs to decrypt the LUKS partition before attaching it. This is done in the initramfs with cryptsetup. But we need to install cryptsetup into initramfs. In order to have a functional cryptsetup one needs to add some things to the initramfs script: - Add a `run` directory to ramfs ![](https://i.imgur.com/SIyIkyb.png) - Copy `cryptsetup` to ramfs. Be careful, always use binaries and libraries compiled for your target (NanoPi in this case). ![](https://i.imgur.com/2mQLcKj.png) - Copy the passphrase file to ramfs ![](https://i.imgur.com/DQjJmpR.png) - Copy the needed libraries to ramfs. To know which libraries cryptsetup is using, one can run `strace` or `strings | grep lib` on the NanoPi. Anyways, cryptsetup will tell you if it misses something at execution. ![](https://i.imgur.com/Ovt4znI.png) Now, generate uInitrd again and copy it to the BOOT partition of the SD card again. From the shell on the initramfs run `cryptsetup --debug --key-file /root/passphrase_luks open --type luks /dev/mmcblk0p3 usrfs1 ` If this was successfull, one should see the nodefile in `/dev/mapper` Now, let's mount the partition to `/newroot` with `mount /dev/mapper/usrfs1 /newroot`. Of course, this means that `/dev/mmcblk0p2` must not be mounted to `newroot` in the init script. Finally `exec switch_root /newroot /sbin/init` to have access to the crypted rootfs. --- The following script generates an `uInitrd` file which initializes automatically a LUKS crypted rootfs partition: ```shell= #!/bin/bash ROOTFSLOC=ramfs cd $HOME mkdir $ROOTFSLOC mkdir -p $ROOTFSLOC/{bin,dev,etc,home,lib,lib64,newroot,proc \ ,root,sbin,sys,run} #added run for cryptsetup echo "About to copy the passphrase into root dir" cd $ROOTFSLOC/root cp ~/Documents/passphrase_luks . echo "Passphrase copied" cd $HOME cd $ROOTFSLOC/dev sudo mknod null c 1 3 sudo mknod tty c 5 0 sudo mknod console c 5 1 sudo mknod random c 1 8 sudo mknod urandom c 1 9 sudo mknod mmcblk0p b 179 0 sudo mknod mmcblk0p1 b 179 1 sudo mknod mmcblk0p2 b 179 2 sudo mknod mmcblk0p3 b 179 3 sudo mknod mmcblk0p4 b 179 4 sudo mknod ttyS0 c 4 64 sudo mknod ttyS1 c 4 65 sudo mknod ttyS2 c 4 66 sudo mknod ttyS3 c 4 67 echo "1. nodes done" cd ../bin cp ~/workspace/nano/buildroot/output/target/bin/busybox . ln -s busybox ls ln -s busybox mkdir ln -s busybox ln ln -s busybox mknod ln -s busybox mount ln -s busybox umount ln -s busybox sh ln -s busybox sleep ln -s busybox dmesg cp ~/workspace/nano/buildroot/output/target/usr/bin/strace . echo "2. bin busybox symblink done" cd ../sbin ln -s ../bin/busybox switch_root echo "2.1. adding cryptsetup" cp ~/workspace/nano/buildroot/output/target/usr/sbin/cryptsetup . echo "2.2. added cryptsetup" echo "3. sbin done" cd ../lib64 cp ~/workspace/nano/buildroot/output/target/lib64/ld-2.31.so . cp ~/workspace/nano/buildroot/output/target/lib64/libresolv-2.31.so . cp ~/workspace/nano/buildroot/output/target/lib64/libc-2.31.so . ln -s libresolv-2.31.so libresolv.so.2 ln -s libc-2.31.so libc.so.6 ln -s ../lib64/ld-2.31.so ld-linux-aarch64.so.1 echo "3.1 copy and linking lib64 for cryptsetup" cp ~/workspace/nano/buildroot/output/target/usr/lib64/libcryptsetup.so . ln -s libcryptsetup.so libcryptsetup.so.12 cp ~/workspace/nano/buildroot/output/target/usr/lib64/libpopt.so . ln -s libpopt.so libpopt.so.0 cp ~/workspace/nano/buildroot/output/target/lib64/libm-2.31.so . ln -s libm-2.31.so libm.so.6 cp ~/workspace/nano/buildroot/output/target/usr/lib64/libuuid.so . ln -s libuuid.so libuuid.so.1 cp ~/workspace/nano/buildroot/output/target/usr/lib64/libblkid.so . ln -s libblkid.so libblkid.so.1 cp ~/workspace/nano/buildroot/output/target/usr/lib64/libdevmapper.so . ln -s libdevmapper.so libdevmapper.so.1.02 cp ~/workspace/nano/buildroot/output/target/usr/lib64/libssl.so . ln -s libssl.so libssl.so.1.1 cp ~/workspace/nano/buildroot/output/target/usr/lib64/libcrypto.so . ln -s libcrypto.so libcrypto.so.1.1 cp ~/workspace/nano/buildroot/output/target/usr/lib64/libargon2.so . ln -s libargon2.so libargon2.so.1 cp ~/workspace/nano/buildroot/output/target/lib64/librt-2.31.so . ln -s librt-2.31.so librt.so.1 cp ~/workspace/nano/buildroot/output/target/lib64/libdl-2.31.so . ln -s libdl-2.31.so libdl.so.2 cp ~/workspace/nano/buildroot/output/target/usr/lib64/libjson-c.so . ln -s libjson-c.so libjson-c.so.5 cp ~/workspace/nano/buildroot/output/target/lib64/libpthread-2.31.so . ln -s libpthread-2.31.so libpthread.so.0 cp ~/workspace/nano/buildroot/output/target/lib64/libatomic.so.1 . echo "3.2 finished copying and linking for cryptsetup" cd ../lib cp ~/workspace/nano/buildroot/output/target/lib64/ld-2.31.so . ln -s ../lib64/ld-2.31.so ld-linux-aarch64.so.1 echo "4. shared libraries done" cd .. cat > init << endofinput #!/bin/busybox sh mount -t proc none /proc mount -t sysfs none /sys cryptsetup --key-file /root/passphrase_luks open --type luks \ /dev/mmcblk0p3 usrfs1 mount /dev/mapper/usrfs1 /newroot mount -n -t devtmpfs devtmpfs /newroot/dev # exec sh exec switch_root /newroot /sbin/init endofinput ###### chmod 755 init echo "5. init done" cd .. sudo chown -R 0:0 $ROOTFSLOC echo "6. change owner done" cd $ROOTFSLOC find . | cpio --quiet -o -H newc > ../Initrd cd .. gzip -9 -c Initrd > Initrd.gz mkimage -A arm -T ramdisk -C none -d Initrd.gz uInitrd echo "7. creation of uInitrd done" ``` > [Luc] Le symbolic linking ne m'est pas très clair. Pourquoi on copie tjrs une_certaine_librairies.so, puis on la link à une_certaine_librairies.so.X.Y.Z. Pourquoi ne pas copier directement la bonne librairie (cad une_certaine_librairies.so.X.Y.Z). > [Luc] En ce qui concerne les bootargs, dans boot.cmd il y a tjrs `boot=/dev/mmcblk0p2` mais vu que maintenant on boot sur la mmcblk0p3 ce bootarg n'est plus valid. Du coup mon hypothèse est que les bootargs sont ignorés lorsqu'on execute switch_root au lieu de booti. ## TPM `swtpm socket --tpmstate dir=/home/lmi/swtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear` ### Question 1 : create-load-save primary keys - To create a primary key in owner hierarchy with key parameter: rsa 2048 bits, use the command `tpm2_createprimary -C o -G rsa2048 -c o_primary.ctx`. - To check the handles-transient area use `tpm2_getcap handles-transient`. To check the handles-persistent area, `tpm2_getcap handles-persistent`. - To flush the handle-transient area use `tpm2_flushcontext -t`. - To save the primary key to the NV-Ram use `tpm2_evictcontrol -c o_primary.ctx` (or `tpm2_evictcontrol -c 0x80000000` if the index exists in the handles-transient area.) - Again, to check the handles-transient area use `tpm2_getcap handles-transient`. To check the handles-persistent area, `tpm2_getcap handles-persistent`. ### Question 2 : create-load-save child keys - To create child key in owner hierarchy with key parameter rsa 2048 bits use `tpm2_create -C o_primary.ctx -G rsa2048 -u child_public -r child_private` if `o_primary.ctx` is your reference file. - To check the handles-transient area use `tpm2_getcap handles-transient`. ![](https://i.imgur.com/DdweNZb.png) `0x80000000` is the index of primary key `0x80000001` is the index of child key - To check the handles-persistent area, `tpm2_getcap handles-persistent`. ![](https://i.imgur.com/2bl3XUr.png) `0x81000000` is the index of primary key in the NV-RAM - To flush the handle-transient area use `tpm2_flushcontext -t`. - To load child keys to TPM use `tpm2_load -C o_primary.ctx -u child_public -r child_private -c child`. - To save the child key to the NV-Ram use `tpm2_evictcontrol –c child`. - Again, to check the handles-transient area use `tpm2_getcap handles-transient`. ![](https://i.imgur.com/Gyj6D1w.png) - To check the handles-persistent area, `tpm2_getcap handles-persistent`. ![](https://i.imgur.com/TBdNWoz.png) ### Question 3 : decrypt on TPM The file `encryptedtex` has been encrypted by the public key `rsa_key.pem`. To decrypt this file on the TPM: - Download the rsa_key.pem and encryptedtext from moodle - Let's cat the rsa_key.pem ![](https://i.imgur.com/DOhQgSM.png) - Since a private key can only be imported on the NULL hierarchy, let's run `tpm2_loadexternal -C n -Grsa -r rsa_key.pem -c key.ctx` - If one executes `tpm2_getcap handles-transient` the index to this key has been added. - `tpm2_rsadecrypt -c key.ctx -s rsaes encryptedtext -o cleartext` will decrypt `encryptedtext`. - Let's `cat cleartext`: ![](https://i.imgur.com/q3a6W5D.png) Thank you!! ### Question 4 : PCR policy To simulate how u-boot shoud check the Linux kernel integrity with PCR registers and pcrpolicy: - Let's find the `Image` file and hash it. The `Image` file is located in `/home/lmi/workspace/nano/buildroot/output/images`. ![](https://i.imgur.com/srbh1st.png) - After reading `man tpm2_pcrreset`, only PCR 16 and 23 are resetable. So let's reset PCR 16: `tpm2_pcrreset 16`. - Then, extend PCR16 with `tpm2_pcrextend 16:sha256=962f4b6aeb8b2d74dc595257cb4384fc266283816acc4940622f29ad748bcb6e` - Let's verify with `tpm2_pcrread sha256:16`: ![](https://i.imgur.com/kr0tNSh.png) - `tpm2_createprimary -C o -G rsa2048 -c primary` - `tpm2_startauthsession -S session` - `tpm2_policypcr -S session -l sha256:16 -L pcr16_policy` - `tpm2_flushcontext session` Until now we have only a hashed PCR16 stored in pcr16_policy file. Now, we need to seal this hash. One may add some secret data to the seal (like a password). Let's just create a file with a success message since we do not need a password to unlock anything. - `echo "Integrity check SUCCEEDED" > data` - `tpm2_create -C primary -g sha256 -u pcr16.pub -r pcr16.priv -i data -L pcr16_policy` - (You may need to flush the RAM with `tpm2_flushcontext -t` before going on) - `tpm2_load -C primary -u pcr16.pub -r pcr16.priv -c pcr16` - `tpm2_evictcontrol -c pcr16 0x81010000 -C o` We've created a sealing object that we stored on the NV-RAM. Now, let's simulate a boot: - stop swtpm socket and restart it: ![](https://i.imgur.com/E1p04SV.png) - hash `Image` again: `openssl dgst -sha256 Image` - Then, extend PCR16 with this hash - And now start a policy session with `tpm2_startauthsession --policy-session -S session` - `tpm2_policypcr -S session -l sha256:16` to include the PCR value into the session - `tpm2_unseal -p session:session -c 0x81010000` will unseal the object and return the data. Let's check. Let's create two scripts, one that creates the policy and another one that performs an integrity check. It is essentially the same code as above but without explanations. #### `pcr_policy.sh` ```shell= #!/bin/sh hash=($(sha256sum Image)) tpm2_pcrreset 16 tpm2_pcrextend 16:sha256=$hash echo $(tpm2_pcrread sha256:16) tpm2_createprimary -C o -G rsa2048 -c primary tpm2_startauthsession -S session tpm2_policypcr -S session -l sha256:16 -L pcr16_policy tpm2_flushcontext session tpm2_create -C primary -g sha256 -u pcr16.pub -r pcr16.priv \ -i data -L pcr16_policy tpm2_flushcontext -t tpm2_load -C primary -u pcr16.pub -r pcr16.priv -c pcr16 tpm2_evictcontrol -c pcr16 0x81010000 -C o echo "created a sealing object and stored it on the NV-RAM!" ``` #### `integrity_test.sh` ```shell= #!/bin/sh tpm2_pcrreset 16 tpm2_flushcontext -t hash=($(sha256sum Image)) tpm2_pcrextend 16:sha256=$hash tpm2_startauthsession --policy-session -S session tpm2_policypcr -S session -l sha256:16 tpm2_unseal -p session:session -c 0x81010000 ``` If the `Image` file stays the same: ![](https://i.imgur.com/qqjn24w.png) If the `Image` file has changed: ![](https://i.imgur.com/cEWvSVH.png) Now let's imagine we update the `Image` file. Next time one boots the system, the policy check fails. It is expected but not wanted. How to bypass this check without compromising the system security? To achieve this, a trusted administrator must add a PCR signature to the PCR values. But first let's define a pcr-signed policy. Whether the `Image` file changes or not, the following script will update the sealing object: ```shell= #!/bin/sh hash=($(sha256sum Image)) tpm2_pcrreset 16 echo $(tpm2_pcrread sha256:16) tpm2_pcrextend 16:sha256=$hash echo $(tpm2_pcrread sha256:16) echo "create primary owner key" tpm2_createprimary -C o -G rsa2048 -c primary echo "pcr policy" tpm2_startauthsession -S session tpm2_policypcr -Q -S session -l sha256:16 -L pcr16_policy tpm2_flushcontext session echo "rsa key creation" openssl genrsa -out signing_key_private.pem 2048 openssl rsa -in signing_key_private.pem -out signing_key_public.pem -pubout echo "create a name for public key (for later use)" tpm2_loadexternal -G rsa -C o -u signing_key_public.pem -c signing_key.ctx \ -n signing_key.name echo "signer policy" tpm2_startauthsession -S session echo "create a new policy (authorized.policy)" tpm2_policyauthorize -S session -L authorized.policy -n signing_key.name \ -i pcr16_policy tpm2_flushcontext session tpm2_flushcontext -t echo "creation of the new sealing object" tpm2_create -g sha256 -u auth_pcr_seal_key.pub -r auth_pcr_seal_key.priv \ -i data -C primary -L authorized.policy tpm2_flushcontext -t echo "make it persistent" tpm2_evictcontrol -C o -c 0x81010001 tpm2_load -Q -C primary -u auth_pcr_seal_key.pub -r auth_pcr_seal_key.priv \ -c auth_pcr_seal_key.ctx tpm2_evictcontrol -c auth_pcr_seal_key.ctx 0x81010001 -C o echo "flush RAM" tpm2_flushcontext -t echo "sign pcr_policy with the private key" #you can comment or uncomment this line to see what happens if you #sign the policy or not openssl dgst -sha256 -sign signing_key_private.pem -out pcr16_policy.signature \ pcr16_policy echo "DONE" ``` Let's explain the script above: 1. We define a pcr policy as before 2. We "wrap" the pcr policy into an authorization policy that binds the pcr policy with the administrator's public key. This binding is very important because it garantees that the authorization has been satisfied with the right key (namely the one of the administrator). This will be clearer later. 3. We create a new sealing object as before 4. We make the sealing object persistent. The following script checks whether the pcr policy change is authorized. If yes, it unseals the sealed object. ```shell= #!/bin/sh echo "load external public key of administrator" tpm2_loadexternal -G rsa -C o -u signing_key_public.pem -c signing_key.ctx \ -n signing_key.name echo "verifying the signature with public of administrator" tpm2_verifysignature -c signing_key.ctx -g sha256 -m pcr16_policy \ -s pcr16_policy.signature -t verification.tkt -f rsassa echo "start a policy-session" tpm2_startauthsession --policy-session -S session echo "include the actual pcr value into the session" tpm2_policypcr -l sha256:16 -S session echo "authorizing the pcr policy to change with the current \ session IF the signing_key.name corresponds and IF verification.tkt allows it" tpm2_policyauthorize -S session -i pcr16_policy -n signing_key.name \ -t verification.tkt tpm2_unseal -p session:session -c 0x81010001 tpm2_flushcontext session tpm2_flushcontext -t ``` Explanation: 1. We load the administrator's public key 2. We verify the signature on the pcr policy and issue a verification ticket that tells if the pcr policy has been signed by the administrator or not. 3. We authorize the pcr policy to change if the signing key corresponds and if the verification.tkt allows it. 4. We try to unseal the object. If authorization has been granted in the previous step, it should pass. Otherwise, if the `Image` file changed it should fail. Else if the Image file did not change, it should pass. Now, **the most important thing**: in order to pass the signature verification, the administrator needs to sign the pcr policy with his **private** key if he wants to update the `Image` file: `openssl dgst -sha256 -sign signing_key_private.pem -out pcr16_policy.signature pcr16_policy` Let's make some tests: 1. No `Image` file change, no signature of the administrator (should pass): ![](https://i.imgur.com/YakJGGA.png) 2. `Image` file change, no signature of the administrator (should fail): ![](https://i.imgur.com/T6nBBp0.png) 3. No `Image` file change, signature of the administrator (should pass): ![](https://i.imgur.com/YakJGGA.png) 4. `Image` file change, signature of the administrator (should pass): ![](https://i.imgur.com/YakJGGA.png) ## Annexes ### `buildRamfs.sh` ```shell= #!/bin/bash ROOTFSLOC=ramfs cd $HOME mkdir $ROOTFSLOC mkdir -p $ROOTFSLOC/{bin,dev,etc,home,lib,lib64,newroot,proc,root,sbin,sys} cd $ROOTFSLOC/dev sudo mknod null c 1 3 sudo mknod tty c 5 0 sudo mknod console c 5 1 sudo mknod random c 1 8 sudo mknod urandom c 1 9 sudo mknod mmcblk0p b 179 0 sudo mknod mmcblk0p1 b 179 1 sudo mknod mmcblk0p2 b 179 2 sudo mknod mmcblk0p3 b 179 3 sudo mknod mmcblk0p4 b 179 4 sudo mknod ttyS0 c 4 64 sudo mknod ttyS1 c 4 65 sudo mknod ttyS2 c 4 66 sudo mknod ttyS3 c 4 67 echo "1. nodes done" cd ../bin cp ~/workspace/nano/buildroot/output/target/bin/busybox . ln -s busybox ls ln -s busybox mkdir ln -s busybox ln ln -s busybox mknod ln -s busybox mount ln -s busybox umount ln -s busybox sh ln -s busybox sleep ln -s busybox dmesg cp ~/workspace/nano/buildroot/output/target/usr/bin/strace . echo "2. bin busybox symblink done" cd ../sbin ln -s ../bin/busybox switch_root echo "3. sbin done" cd ../lib64 cp ~/workspace/nano/buildroot/output/target/lib64/ld-2.31.so . cp ~/workspace/nano/buildroot/output/target/lib64/libresolv-2.31.so . cp ~/workspace/nano/buildroot/output/target/lib64/libc-2.31.so . ln -s libresolv-2.31.so libresolv.so.2 ln -s libc-2.31.so libc.so.6 ln -s ../lib64/ld-2.31.so ld-linux-aarch64.so.1 cd ../lib cp ~/workspace/nano/buildroot/output/target/lib64/ld-2.31.so . ln -s ../lib64/ld-2.31.so ld-linux-aarch64.so.1 echo "4. shared libraries done" cd .. cat > init << endofinput #!/bin/busybox sh mount -t proc none /proc mount -t sysfs none /sys mount -t ext4 /dev/mmcblk0p2 /newroot mount -n -t devtmpfs devtmpfs /newroot/dev exec sh # exec switch_root /newroot /sbin/init endofinput ###### chmod 755 init echo "5. init done" cd .. sudo chown -R 0:0 $ROOTFSLOC echo "6. change owner done" cd $ROOTFSLOC find . | cpio --quiet -o -H newc > ../Initrd cd .. gzip -9 -c Initrd > Initrd.gz mkimage -A arm -T ramdisk -C none -d Initrd.gz uInitrd echo "7. creation of uInitrd done" ```

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully