carloscn / blog

My blog
Apache License 2.0
134 stars 38 forks source link

[Embedded] cross-compile the cryptsetup on Xilinx ZYNQ aarch64 platform #169

Open carloscn opened 1 year ago

carloscn commented 1 year ago

[Embedded] cross-compile the cryptsetup on Xilinx ZYNQ aarch64 platform

1.1 Dev Env

This document is to describe how to transplant the cryptsetup (userspace) and dm-crypt (kernel space) to an aarch64 ARM platform. I'm holding a Xilinx # Zynq® UltraScale+™ MPSoC ZCU111 platform basing arm AARCH64 four Cortex-A53s. My target is enabling the cryptsetup and dm-crypt to encrypt the Linux rootfs in a SD card. The dev env of zynqmp is Petalinux 2021, please note that the version of glibc when you transplanted cryptsetup and its corresponding libraries.

1.2 Transplanting the cryptsetup on AARCH64

1.2.1 Toolschains

The AArch64 GNU/Linux toolchains (aarch64-none-linux-gnu) shall be required to cross-compile cryptsetup and its corresponding libraries. By now, glibc the newest the version is GLIBC 2.33, the executable files cross-compiled by it cannot be executed on Linux Runtime complied by the petalinux 2021. Therefore, the old toolchains should be downloaded by: gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu.tar.xz

For more information about toolchains configuration, please refer to the link: https://github.com/carloscn/blog/issues/26

The toolchains set:

1.2.2 libjson-c

libjson-c is required by cryptsetup, so we shall cross-compile the libjson-c for cryptsetup. We selected json-c-0.13.1.tar.gz on linuxfromscratch.org/blfs/view/svn/general/json-c.html. You can also get the tarball by following the command directly.

The compiling steps are shown as following:

wget "https://s3.amazonaws.com/json-c_releases/releases/json-c-0.13.1.tar.gz" --no-check-certificate

tar -xvf json-c-0.13.1.tar.gz && cd json-c-0.13.1

./configure --prefix=`pwd`/out --host=aarch64-none-linux-gnu

make

make install

The dynamic libraries are outputted by the building result:

1.2.3 util-linux

The util-linux provides libuuid and libblkid that are required by cryptsetup. You can get the util-linux source code by the link https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/

wget "https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.34/util-linux-2.34.tar.gz" --no-check-certificate

tar -xvf util-linux-2.34.tar.gz && cd util-linux-2.34

./configure --prefix=`pwd`/out --host=aarch64-none-linux-gnu --without-ncurses

make uuidd -j8

make blkid -j8

Because there is no libtinfo for aarch64 toolchains, we cannot make use of make install to gather the libraries. So the libraries shall be arranged manually.

cd out

mkdir lib

cp -Lvr ../.libs/* ./lib

mkdir include && mkdir include/uuid && mkdir include/blkid

cp -r ../libuuid/src/uuid.h ./include/uuid

cp -r ../libblkid/src/blkid.h ./include/blkid

1.2.4 libpopt

wget "http://jaist.dl.sourceforge.net/project/cross-stuff/cross-stuff/1.0/popt-1.7.tar.gz" --no-check-certificate

tar -xvf popt-1.7.tar.gz && cd popt-1.7

./configure --prefix=`pwd`/out --host=aarch64-none-linux-gnu

The makefile system of libpopt cannot setup an aarch64 host, we need to add aarch64 to the makefile system manually.

rm -rf config.guess config.sub

wget -O config.guess 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'

wget -O config.sub 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'

Then re-execute ./configure --prefix=`pwd`/out --host=aarch64-none-linux-gnu

make -j8

make install

1.2.5 libdevmapper

libdevmapper is required by cryptsetup, so we shall cross-compile the libdevmapper for cryptsetup. We selected 2.02.133-1ubuntu10 on https://launchpad.net/ubuntu/+source/lvm2. You can also get the tarball by the following command direclty.

wget "https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/lvm2/2.02.133-1ubuntu10/lvm2_2.02.133.orig.tar.xz" --no-check-certificate

tar -xvf lvm2_2.02.133.orig.tar.xz && cd lvm2-2.02.133

The just compiled libuuid and libblkid are requried by the libdevmapper. The configure cmd shall be "./configure --prefix=`pwd`/out --host=aarch64-none-linux-gnu CFLAGS="-I/home/haochenwei/work/temp/cryptsetup_build/tools/util-linux-2.34/out/include" LDFLAGS="-L/home/haochenwei/work/temp/cryptsetup_build/tools/util-linux-2.34/out/lib"", make use of C_FLAGS and LD_FLAGS to specify the libuuid and libblkid just compiled. Note the C_FLAGS and LD_FLAGS shall use the absolute path.

Then the config files are generated by the configure cmd. We need to modify the include/configure.h and comment the two lines:

Modify the ./lib/filters/filter-sysfs.c to add the two lines:

#include <sys/types.h>
#include <sys/sysmacros.h>

Then make -j8

make install

The errors of make install will prompt permission denial. You need to sudo chown -R yourname:yourname /etc/lvm.

Then make install

1.2.6 libssl

The openssl will provide the libssl, so we just need to compile the openssl for AARCH64. We use the openssl 1.1.1s on https://www.openssl.org/source/openssl-1.1.1s.tar.gz.

wget "https://www.openssl.org/source/openssl-1.1.1s.tar.gz" --no-check-certificate

tar -xvf openssl-1.1.1s.tar.gz && cd openssl-1.1.1s

CC=aarch64-none-linux-gnu-gcc ./config --prefix=`pwd`/out no-asm

Furtherly, we need to change the Makefile:

make -j8

make install -j8

1.2.7 cryptsetup

Now, we cross-compile the cryptsetup:

wget "https://gitlab.com/cryptsetup/cryptsetup/-/archive/v2.2.x/cryptsetup-v2.2.x.tar.gz" --no-check-certificate

Before the cross-compiling, we need to arrange out compiled libraries above. The libraries source code on my host are shown as following:

We'd better create a deps directory to store the above libraries.

cd deps

cp -Lvr ../json-c-0.13.1/out/* .

cp -Lvr ../lvm2-2.02.133/out/* .

cp -Lvr ../openssl-1.1.1s/out/* .

cp -Lvr ../popt-1.7/out/* .

cp -Lvr ../util-linux-2.34/out/* .

Then copy the all include files and libraries to toolchains usr:

cp -r include/* ~/opt/cross-compile/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/include/

cp -r lib/* ~/opt/cross-compile/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/lib/

Now, we will compile the cryptsetup:

tar -xvf cryptsetup-v2.2.x.tar.gz && cd cryptsetup-v2.2.x

We need to change the /run/cryptsetup -> /etc/cryptsetup by grep -rni -s "/run" | grep config

./autogen.sh

Then we need to config the makefile by:

`./configure --host=aarch64-none-linux-gnu --prefix=pwd/out

Before the make install, we need to change the Makefile:

make install

Returning to the deps dir, cp -Lvr ../cryptsetup-v2.2.x/out/* . to copy all files.

Besides, we need to copy the libgcc_s.so.1 of toolchains to the lib. cp -Lvr /home/haochenwei/opt/cross-compile/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/lib64/libgcc_s.so* .

1.3 Enabling dm-crypt and AES engine on Linux Kernel

petalinux-config -c kernel

[*] Enable loadable module support
Device Drivers --->
    [*] Multiple devices driver support (RAID and LVM) --->
        <*> Device mapper support
        <*>   Crypt target support

image-20230101182215875

Next, the Linux kernel needs to support the set of cryptographic APIs that the administrator wants to use for encryption. These can be found under the Cryptographic API section:

[*] Cryptographic API --->
    <*> XTS support
    <*> SHA224 and SHA256 digest algorithm
    <*> AES cipher algorithms
    <*> User-space interface for hash algorithms
    <*> User-space interface for symmetric key cipher algorithms

Then config the Xilinx AES accelerator, https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/64749783/ZynqMP+AES+Driver to use the Xilinx AES engine. For more information about Xilinx AES engine, https://www.xilinx.com/content/dam/xilinx/support/documents/ip_documentation/aes/v1_1/pg383-aes.pdf

1.4 Transforming the files to rootfs

The built files can be set to a rootfs or a ramdisk.

Then run the rootfs, the cryptsetup can be used normally:

image-20230101194936257

^1

Ref