termux / termux-packages

A package build system for Termux.
https://termux.dev
Other
12.93k stars 2.98k forks source link

Package Request: CryFS #10178

Open piratecaveman opened 4 years ago

piratecaveman commented 4 years ago

Package description CryFS encrypts your files, so you can safely store them anywhere. It works well together with cloud services like Dropbox, iCloud, OneDrive and others.

Link to home page and sources

  1. Home page: https://www.cryfs.org/
  2. Source code: https://github.com/cryfs/cryfs

Additional information Have you compiled or tried to compile the package on device?

ghost commented 4 years ago

Moved to root packages since cryfs relies on libfuse.

FreddieOliveira commented 4 years ago

@xeffyr @Grimler91 I have great news on this, I was able to successfully compile and run CryFS and EncFS inside termux. This is great because both of them requires libfuse, which I was also able to compile a fully working port of it, finally. Last time I checked the status of libfuse it was stalled in the disabled packages along with EncFS, but not anymore!

Grimler91 commented 4 years ago

Great! Could you share all the patches you had to apply? (And perhaps open a PR to add the packages?)

FreddieOliveira commented 4 years ago

Sure, it's my pleasure. I spent the day further investigating about this. Here are some important considerations regarding libfuse:

  1. Libfuse uses pthread, which is not fully implemented in the Android SDK (and probably will never be), so some pthread functions used by libfuse are not presented, more specifically pthread_cancel and pthread_setcancelstate in lib/fuse.c and lib/fuse_loop_mt.c. That means these files need to be patched. There are basically two ways of replacing pthread_cancel:

    1. Make usage of signals. This option is not that hacky, au contraire. In fact, GNU/Linux pthread implementation itself does actually implement pthread_cancel this way using real time signals or SIGUSR if real time are not available. This workaround idea is to send a signal to the thread to be cancelled and that thread catches the signal and calls pthread_exit.

    2. Using a watch variable. This is no doubt a hack. The idea is to have a variable that is constantly read by the thread which is to be cancelled. If the variable is true then it calls pthread_exit for itself.

Basically the options are interruption vs polling. Which workaround to use depends on the complexity of the code to be patched. fuse.c and fuse_loop_my.c are quite simple (at least the functions using pthread_exit and pthread_setcancelstate), so both workarounds are acceptable in my opinion in this scenario. And actually both of them were already implemented, the first one by Cyanogen/Lineage ROM and the second one by vishalbiswas.

Another not so safe option would be to call pthread_kill with the SIGKILL or SIGTERM signal for the thread to be terminated instead of calling pthread_cancel for it. I didn't tried this strategy and I'm not inclined to do so, simply because this is not safe. If pthread_kill was the same as pthread_cancel, then there would be no need for the later to exist. This is similar to what was done by you. Your patch didn't work because you're sending 0 as the signal number and when called with 0 pthread_kill actually doesn't do anything, so the thread that was supposed to be terminated will continue running.

Excerpt from pthread_kill man:

The pthread_kill() function sends the signal sig to thread, a thread in the same process as the caller. The signal is asynchronously directed to thread. If sig is 0, then no signal is sent, but error checking is still performed.

  1. Libfuse has two major mainstream versions: v2.x and v3.x. They are different and incompatible with each other. So, if a program was designed to be used with libfuse2 it probably won't work with libfuse3. That's the case of CryFS and EncFS, btw. So, if including both of them in termux, it's necessary to make two different packages, one for each version, the same way Ubuntu does (Screenshot taken from https://packages.ubuntu.com/focal/allpackages):
  1. I use a custom rooted ROM based on Android 10 with a custom kernel. Not sure if this interfered with anything, because I don't have others devices to test. But I think libfuse should work well for everyone (as long as the device is rooted), since libfuse is supported by the official Android kernel since Android version 4.4 (KitKat).

I'll study more carefully which pthread_cancel workaround is more suitable for our case and will open two issues for package request, one for each libfuse version along with building instructions. We can use CryFS and EncFS along with the test suit that comes with the libfuse source to test it on others devices.

FreddieOliveira commented 4 years ago

@xeffyr @Grimler91 Finally done 😃 Libfuse2: termux/termux-root-packages#188 Libfuse3: termux/termux-root-packages#189

FreddieOliveira commented 4 years ago

CryFS build instructions

Intro

CryFS uses scrypt as the key derivation function. Scrypt by design uses a lot of resources (RAM and processing) to prevent brute forcing. Unfortunately, CryFS doesn't offer a way to adjust this resource usage, so we need to patch the source to fine tune this. The first patch limits the max RAM usage to 1GB. Note that this doesn't lower the security of the key derivation function, since it uses a trade-off between memory and processing. So, with less RAM the effect will be it will take a little longer.

The second patch is to fix a bug. Applying it will allow CryFS to use the built-in CRC functions from the armv8 processor, if available. See https://github.com/cryfs/cryfs/issues/345

Here's the Ubuntu package page for reference: https://packages.ubuntu.com/focal/cryfs

Building

Dependencies

These are the libs it depends upon:

libboost_filesystem.so.1.73.0
libboost_system.so.1.73.0
libboost_thread.so.1.73.0
libboost_program_options.so.1.73.0
libboost_chrono.so.1.73.0
libcurl.so
libdl.so
libc.so
libfuse.so.2
libc++_shared.so
libm.so

CryFS also needs some source files from the Android NDK, so it's necessary to download it and extract some of its files.

Steps

All the steps above were executed from within termux using the latest stable version of both NDK and CryFS. First download the patches, then run:

$ wget https://github.com/cryfs/cryfs/releases/download/0.10.2/cryfs-0.10.2.tar.xz
$ wget https://dl.google.com/android/repository/android-ndk-r21-linux-x86_64.zip
$ mkdir -p cryfs-0.10.2/build
$ tar xf cryfs-0.10.2.tar.xz -C cryfs-0.10.2
$ unzip android-ndk-r21-linux-x86_64.zip
$ cd cryfs-0.10.2/build
$ cp ../../android-ndk-r21/sources/android/cpufeatures/cpu-features.* ../vendor/cryptopp/vendor_cryptopp/
$ patch ../src/cpp-utils/crypto/kdf/Scrypt.h ../../Scrypt.h.patch
$ patch ../vendor/cryptopp/vendor_cryptopp/config.h ../../config.h.patch
$ cmake -DCMAKE_BUILD_TYPE=Release -DBoost_USE_STATIC_LIBS=off -DCRYFS_UPDATE_CHECKS=off -DCMAKE_INSTALL_PREFIX=/data/data/com.termux/files/usr ..
$ make -j8
$ make install/strip

Testing

CryFS comes with a test suite. This is good, because libfuse2 doesn't come with any tests, so we can use the CryFS ones to check if libfuse2 is working correctly. To compile it just pass the aditional -DBUILD_TESTING=on flag to cmake, which is off by default. After building it, run sudo test/fspp/fspp-test. This will run 964 integration tests with libfuse2. On my phone, from the 964 tests:

Aditional info

So far, everything seems to be working as expected. This is the list of files added to the system when installed:

files
└── usr
    ├── bin
    │   ├── cryfs
    │   └── cryfs-unmount
    └── share
        └── man
            └── man1
                └── cryfs.1.gz

5 directories, 3 files

Attachments

config.h.patch.txt Scrypt.h.patch.txt

TimFW commented 3 years ago

I was having issues with the patches but think I got a working build so far inside termus

I hope this can eventually morph into an app that can work on even non rooted versions of Android.

Presently the next closest thing to a modern version of EncFS is GoCrypFS but CryFS I think is superior and prefer. All that's really missing for most Linux users is an android version for their phones.

From a security standpoint a rooted phone as a your main daily user that will have data on it worth securing with encryption, IMO, presents way to many security risks. Unless you can be sure all apps are 100% safe which is almost impossible especially if your running google services.

Cletip commented 6 months ago

Hello,

Sorry to reopen the conversation like this, but is there any news?

Thank you in advance for your reply.

automorphism88 commented 4 months ago

Hello,

Sorry to reopen the conversation like this, but is there any news?

Thank you in advance for your reply.

I recently tried to build cryfs from source myself using the instructions in another comment. The latest 0.11.x has new dependencies without termux packages, in particular range-v3. I tried to build range-v3 from source and confirm it was the only dependency missing, but ran into build errors. Possibly fixable with compiler options disabling certain warnings being treated as errors.