Skip to content

Commit

Permalink
CryFS
Browse files Browse the repository at this point in the history
  • Loading branch information
hardcore-sushi committed Jun 26, 2022
1 parent cb56795 commit cf4927a
Show file tree
Hide file tree
Showing 52 changed files with 1,439 additions and 823 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "libpdfviewer"]
path = libpdfviewer
url = https://forge.chapril.org/hardcoresushi/libpdfviewer.git
[submodule "app/libcryfs"]
path = app/libcryfs
url = https://forge.chapril.org/hardcoresushi/libcryfs.git
108 changes: 108 additions & 0 deletions BUILD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Introduction
DroidFS relies on modified versions of the original encrypted filesystems programs to open volumes. [CryFS](https://github.com/cryfs/cryfs) is written in C++ while [gocryptfs](https://github.com/rfjakob/gocryptfs) is written in [Go](https://golang.org). Thus, building DroidFS requires the compilation of native code. However, for the sake of simplicity, the application has been designed in a modular way: you can build a version of DroidFS that supports both Gocryptfs and CryFS, or only one of the two.

Moreover, DroidFS aims to be accessible to as many people as possible. If you encounter any problems or need help with the build, feel free to open an issue, a discussion, or contact me by [email](mailto:[email protected]) or on [Matrix](https://matrix.org): @hardcoresushi:matrix.underworld.fr

# Setup
Install required packages:
```
$ sudo apt-get install openjdk-11-jdk-headless build-essential pkg-config git gnupg2 wget apksigner
```
You also need to manually install the [Android SDK](https://developer.android.com/studio/index.html#command-tools) and the [Android Native Development Kit (NDK)](https://developer.android.com/ndk/downloads) (r23 versions are recommended).

If you want a support for Gocryptfs volumes, you must install [Go](https://golang.org/doc/install) and libssl:
```
$ sudo apt-get install golang-go libssl-dev
```
The code should be authenticated before being built. To verify the signatures, you will need my PGP key:
```
$ gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys AFE384344A45E13A
```
Fingerprint: `B64E FE86 CEE1 D054 F082 1711 AFE3 8434 4A45 E13A` \
Email: `Hardcore Sushi <[email protected]>`

# Download sources
Download DroidFS source code:
```
$ git clone --depth=1 https://github.com/hardcore-sushi/DroidFS.git
```
Verify sources:
```
$ cd DroidFS
$ git verify-commit HEAD
```
__Don't continue if the verification fails!__

Initialize submodules:
```
$ git submodule update --depth=1 --init
```
[FFmpeg](https://ffmpeg.org) is needed to record encrypted video:
```
$ cd app/ffmpeg
$ git clone --depth=1 https://git.ffmpeg.org/ffmpeg.git
```
If you want Gocryptfs support, you need to download OpenSSL:
```
$ cd ../libgocryptfs
$ wget https://www.openssl.org/source/openssl-1.1.1p.tar.gz
```
Verify OpenSSL signature:
```
$ wget https://www.openssl.org/source/openssl-1.1.1p.tar.gz.asc
$ gpg --verify openssl-1.1.1p.tar.gz.asc openssl-1.1.1p.tar.gz
```
Continue **ONLY** if the signature is **VALID**.
```
$ tar -xzf openssl-1.1.1p.tar.gz
```
If you want CryFS support, initialize libcryfs:
```
$ cd app/libcryfs
$ git submodule update --depth=1 --init
```

# Build
Retrieve your Android NDK installation path, usually something like `/home/\<user\>/Android/SDK/ndk/\<NDK version\>`. Then, make it available in your shell:
```
$ export ANDROID_NDK_HOME="<your ndk path>"
```
Start by compiling FFmpeg:
```
$ cd app/ffmpeg
$ ./build.sh ffmpeg
```
## libgocryptfs
This step is only required if you want Gocryptfs support.
```
$ cd app/libgocryptfs
$ OPENSSL_PATH="./openssl-1.1.1p" ./build.sh
```
## Compile APKs
Gradle build libgocryptfs and libcryfs by default.

To build DroidFS without Gocryptfs support, run:
```
$ ./gradlew assembleRelease -PdisableGocryptfs=true
```
To build DroidFS without CryFS support, run:
```
$ ./gradlew assembleRelease -PdisableCryFS=true
```
If you want to build DroidFS with support for both Gocryptfs and CryFS, just run:
```
$ ./gradlew assembleRelease
```

# Sign APKs
If the build succeeds, you will find the unsigned APKs in `app/build/outputs/apk/release/`. These APKs need to be signed in order to be installed on an Android device.

If you don't already have a keystore, you can create a new one by running:
```
$ keytool -genkey -keystore <output file> -alias <key alias> -keyalg EC -validity 10000
```
Then, sign the APK with:
```
$ apksigner sign --out droidfs.apk -v --ks <keystore> app/build/outputs/apk/release/<unsigned apk file>
```
Now you can install `droidfs.apk` on your device.
79 changes: 10 additions & 69 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# DroidFS
DroidFS is an alternative way to use encrypted overlay filesystems on Android that uses its own internal file explorer instead of mounting virtual volumes.
It currently only works with [gocryptfs](https://github.com/rfjakob/gocryptfs) but support for [CryFS](https://github.com/cryfs/cryfs) could be added in the future.
It currently supports [gocryptfs](https://github.com/rfjakob/gocryptfs) and [CryFS](https://github.com/cryfs/cryfs) (alpha).

<p align="center">
<img src="https://forge.chapril.org/hardcoresushi/DroidFS/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png" height="500">
Expand Down Expand Up @@ -46,7 +46,7 @@ It is strongly recommended to read the documentation of a feature before enablin
<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" height="75">
</a>

You can download DroidFS from [F-Droid](https://f-droid.org/packages/sushi.hardcore.droidfs) or from the "Releases" section in the repo.
You can download DroidFS from [F-Droid](https://f-droid.org/packages/sushi.hardcore.droidfs) or from the "Releases" section in this repository.

APKs available here are signed with my PGP key available on keyservers:

Expand Down Expand Up @@ -83,83 +83,24 @@ DroidFS need some permissions to work properly. Here is why:
</ul>

# Limitations
DroidFS use some parts of the original gocryptfs code, which is designed to run on Linux x86 systems: it accesses the underlying file system with file paths and syscalls. However in Android, you can't access other apps files with file paths. Instead, you must use the [ContentProvider](https://developer.android.com/guide/topics/providers/content-providers) API. And obviously, the original gocryptfs code doesn't work with this API. This is why DroidFS can't open volumes provided by other applications, such as cloud storage clients. You can only use DroidFS with volumes located on shared storage or in the app's internal storage (hidden volumes). External storage such as SD cards are only supported in read-only access for now.
DroidFS works as a wrapper around modified versions of the original encrypted container implementations ([libgocryptfs](https://forge.chapril.org/hardcoresushi/libgocryptfs) and [libcryfs](https://forge.chapril.org/hardcoresushi/libcryfs)). These programs were designed to run on standard x86 Linux systems: they access the underlying file system with file paths and syscalls. However, on Android, you can't access files from other applications using file paths. Instead, one has to use the [ContentProvider](https://developer.android.com/guide/topics/providers/content-providers) API. Obviously, neither Gocryptfs nor CryFS support this API. As a result, DroidFS cannot open volumes provided by other applications (such as cloud storage clients), nor can it allow other applications to access encrypted volumes once opened.

# Build
Most of the original gocryptfs code was used as is (written in Go) and compiled to native code. That's why you need [Go](https://golang.org) and the [Android Native Development Kit (NDK)](https://developer.android.com/ndk/) to build DroidFS from source.
Due to Android's storage restrictions, encrypted volumes located on SD cards must be placed under `/Android/data/sushi.hardcore.droidfs/` if you want DroidFS to be able to modify them.

#### Install dependencies
On debian:
```
$ sudo apt-get install build-essential pkg-config libssl-dev
```
Install [Go](https://golang.org/doc/install):
```
$ sudo apt-get install golang-go
```
You also need to install the Android SDK build tools and the [Android NDK](https://developer.android.com/studio/projects/install-ndk).

#### Download Sources
```
$ git clone --recurse-submodules https://github.com/hardcore-sushi/DroidFS.git
$ cd DroidFS
```
[libgocryptfs](https://forge.chapril.org/hardcoresushi/libgocryptfs) needs OpenSSL:
```
$ cd app/libgocryptfs
$ wget https://www.openssl.org/source/openssl-1.1.1n.tar.gz
```
Verify OpenSSL signature:
```
$ wget https://www.openssl.org/source/openssl-1.1.1n.tar.gz.asc
$ gpg --verify openssl-1.1.1n.tar.gz.asc openssl-1.1.1n.tar.gz
```
Continue **ONLY** if the signature is **VALID**.
```
$ tar -xvzf openssl-1.1.1n.tar.gz
```
DroidFS also need [FFmpeg](https://ffmpeg.org) to record encrypted video:
```
$ cd app/ffmpeg
$ git clone --depth=1 https://git.ffmpeg.org/ffmpeg.git
```

#### Generate a keystore
APKs must be signed to be installed on an Android device. If you don't already have a keystore, you can generate one by running:
```
$ keytool -genkey -keystore <output file> -alias <key alias> -keyalg EC -validity 10000
```

#### Build
Retrieve your Android NDK installation path, usually something like "/home/\<user\>/Android/SDK/ndk/\<NDK version\>". Now you can build libgocryptfs:
```
$ cd DroidFS/app/libgocryptfs
$ env ANDROID_NDK_HOME="<your ndk path>" OPENSSL_PATH="./openssl-1.1.1n" ./build.sh
```
Then FFmpeg:
```
$ cd app/ffmpeg
$ env ANDROID_NDK_HOME="<your ndk path>" ./build.sh ffmpeg
```
Finally, compile the app:
```
$ ./gradlew assembleRelease
```
If the build succeeds, you will find the unsigned APKs in `app/build/outputs/apk/release/`. You need to sign them in order to install the app:
```
$ apksigner sign --out droidfs.apk -v --ks <keystore> app/build/outputs/apk/release/<unsigned apk file>
```
Now you can install `droidfs.apk` on your device.
# Building from source
You can follow the instructions in [BUILD.md](BUILD.md) to build DroidFS from source.

# Third party code
Thanks to these open source projects that DroidFS uses:

### Modified code:
- [libgocryptfs](https://forge.chapril.org/hardcoresushi/libgocryptfs) (forked from [gocryptfs](https://github.com/rfjakob/gocryptfs)) to encrypt your data
- Encrypted filesystems (to protect your data):
- [libgocryptfs](https://forge.chapril.org/hardcoresushi/libgocryptfs) (forked from [gocryptfs](https://github.com/rfjakob/gocryptfs))
- [libcryfs](https://forge.chapril.org/hardcoresushi/libcryfs) (forked from [CryFS](https://github.com/cryfs/cryfs))
- [libpdfviewer](https://forge.chapril.org/hardcoresushi/libpdfviewer) (forked from [PdfViewer](https://github.com/GrapheneOS/PdfViewer)) to open PDF files
- [DoubleTapPlayerView](https://github.com/vkay94/DoubleTapPlayerView) to add double-click controls to the video player
### Borrowed code:
- [MaterialFiles](https://github.com/zhanghai/MaterialFiles) for kotlin natural sorting implementation
- [MaterialFiles](https://github.com/zhanghai/MaterialFiles) for Kotlin natural sorting implementation
### Libraries:
- [Glide](https://github.com/bumptech/glide/) to display pictures
- [ExoPlayer](https://github.com/google/ExoPlayer) to play media files
45 changes: 21 additions & 24 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
cmake_minimum_required(VERSION 3.10)

add_library(
gocryptfs
SHARED
IMPORTED
)
project(DroidFS)

set_target_properties(
gocryptfs
PROPERTIES IMPORTED_LOCATION
${PROJECT_SOURCE_DIR}/libgocryptfs/build/${ANDROID_ABI}/libgocryptfs.so
)
option(GOCRYPTFS "build libgocryptfs" ON)
option(CRYFS "build libcryfs" ON)

add_library(
gocryptfs_jni
SHARED
src/main/native/gocryptfs_jni.c
)
if (GOCRYPTFS)
add_library(gocryptfs SHARED IMPORTED)
set_target_properties(
gocryptfs
PROPERTIES IMPORTED_LOCATION
${PROJECT_SOURCE_DIR}/libgocryptfs/build/${ANDROID_ABI}/libgocryptfs.so
)
add_library(gocryptfs_jni SHARED src/main/native/gocryptfs_jni.c)
target_include_directories(gocryptfs_jni PRIVATE ${PROJECT_SOURCE_DIR}/libgocryptfs/build/${ANDROID_ABI})
target_link_libraries(gocryptfs_jni gocryptfs)
endif()

target_link_libraries(
gocryptfs_jni
gocryptfs
)
if (CRYFS)
add_subdirectory(${PROJECT_SOURCE_DIR}/libcryfs)
add_library(cryfs_jni SHARED src/main/native/libcryfs.c)
target_link_libraries(cryfs_jni libcryfs-jni)
endif()

add_library(
avformat
Expand Down Expand Up @@ -65,14 +65,11 @@ add_library(
src/main/native/libmux.c
)

target_include_directories(mux PRIVATE ${PROJECT_SOURCE_DIR}/ffmpeg/build/${ANDROID_ABI})

target_link_libraries(
mux
avformat
avcodec
avutil
)

include_directories(
${PROJECT_SOURCE_DIR}/libgocryptfs/build/${ANDROID_ABI}
${PROJECT_SOURCE_DIR}/ffmpeg/build/${ANDROID_ABI}
)
37 changes: 32 additions & 5 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

if (hasProperty("disableCryFS")) {
ext.disableCryFS = getProperty("disableCryFS")
} else {
ext.disableCryFS = false
}

if (hasProperty("disableGocryptfs")) {
ext.disableGocryptfs = getProperty("disableGocryptfs")
} else {
ext.disableGocryptfs = false
}

android {
compileSdkVersion 31
buildToolsVersion "31"
Expand All @@ -15,12 +27,21 @@ android {
minSdkVersion 21
//noinspection ExpiredTargetSdkVersion
targetSdkVersion 29
versionCode 27
versionName "1.10.1"
versionCode 28
versionName "2.0.0-alpha1"

ndk {
abiFilters "x86", "x86_64", "armeabi-v7a", "arm64-v8a"
}

externalNativeBuild.cmake {
if (project.ext.disableGocryptfs) {
arguments "-DGOCRYPTFS=OFF"
}
if (project.ext.disableCryFS) {
arguments "-DCRYFS=OFF"
}
}
}

if (!file("fdroid").exists()) {
Expand All @@ -34,6 +55,8 @@ android {

applicationVariants.all { variant ->
variant.resValue "string", "versionName", variant.versionName
buildConfigField "boolean", "CRYFS_DISABLED", "${project.ext.disableCryFS}"
buildConfigField "boolean", "GOCRYPTFS_DISABLED", "${project.ext.disableGocryptfs}"
}

buildFeatures {
Expand All @@ -42,9 +65,13 @@ android {

buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
postprocessing {
removeUnusedCode true
removeUnusedResources true
obfuscate false
optimizeCode true
proguardFiles 'proguard-rules.pro'
}
}
}

Expand Down
1 change: 1 addition & 0 deletions app/libcryfs
Submodule libcryfs added at 356cf8
2 changes: 1 addition & 1 deletion app/libgocryptfs
Submodule libgocryptfs updated from 9e9819 to e6e4c2
Loading

0 comments on commit cf4927a

Please sign in to comment.