- Bump OPENSSL_VERSION default from 3.0.8 to 3.1.2 - Update SHA256 hash for openssl-3.1.2.tar.gz - Update all compliance checks to validate OpenSSL 3.1.x series - Update docs: README, install.md, CLAUDE.md, test READMEs - Previous 3.0.8 had only FIPS 140-2 (Cert #4282); 3.1.2 is the first OpenSSL with full FIPS 140-3 validation (Cert #4985, valid through March 2030)
tests/android-fips
A minimal Android app that loads the FIPS-compliant OpenSSL + SQLCipher artifacts produced by the parent project, and runs a 6-check compliance suite against them at runtime. Mirrors the screenshots: a status card, a "Run Compliance Suite" button, per-check result cards, and a small encrypted-notes UI for round-trip verification.
Prerequisites
- The parent build has produced
dist/arm64-v8a/(run./build.shfrom the repo root first). - A
fipsmodule.cnfforarm64-v8aexists indist/arm64-v8a/fips/. Generate it viadist/arm64-v8a/fips/run_fipsinstall_on_device.shon a matching-arch device or emulator (see the parent README, section 5). mise installfrom the repo root (provides JDK 17, Gradle 8.10.2, cmake 3.29).ANDROID_HOME/ANDROID_SDK_ROOTexported, and an Android SDK platform34+ build-tools34.0.0installed.
One-time bootstrap
# From tests/android-fips/
./bootstrap.sh
bootstrap.sh runs gradle wrapper (using the mise-managed Gradle), then
./stage_fips.sh arm64-v8a to copy the prebuilt .so files, headers,
and .cnf files into the app module.
Build and install
./gradlew assembleDebug
./gradlew installDebug # requires a connected device/emulator
adb shell am start -n com.example.fipscompliance/.MainActivity
Or open tests/android-fips/ as a project in Android Studio Hedgehog+.
What the app does
| Check | What it asserts |
|---|---|
| FIPS Provider | OSSL_PROVIDER_available(NULL, "fips") == 1 |
| Self-Test (KAT) | OSSL_PROVIDER_self_test(fips_provider) == 1 |
| OpenSSL Version | OpenSSL_version(OPENSSL_VERSION) is in the OpenSSL 3.1.x line |
| Encrypted DB Write/Read | Native sqlite3_open -> sqlite3_key -> insert -> select round-trip |
| Passphrase Rotation | sqlite3_rekey succeeds and the new key opens the database |
| Wrong-Key Rejection | An incorrect passphrase fails to read sqlite_master |
The app talks to native libsqlcipher.so and libcrypto.so over JNI
(no Java SQLCipher wrapper) so the compliance signal is end-to-end through
the FIPS module that ships in libfips.so.
Layout
tests/android-fips/
├── README.md
├── bootstrap.sh # gradle wrapper + stage_fips.sh
├── stage_fips.sh # copy dist artifacts into the app module
├── settings.gradle.kts
├── build.gradle.kts # root
├── gradle.properties
├── gradle/
│ └── wrapper/
│ └── gradle-wrapper.properties
└── app/
├── build.gradle.kts
├── proguard-rules.pro
└── src/main/
├── AndroidManifest.xml
├── assets/fips/ # populated by stage_fips.sh (openssl.cnf, fipsmodule.cnf)
├── cpp/
│ ├── CMakeLists.txt
│ ├── appenv.c # setenv-only shim, no OpenSSL deps
│ ├── jni_bridge.c # FIPS checks + SQLCipher round-trips
│ └── include/ # populated by stage_fips.sh (openssl/, sqlite3.h)
├── jniLibs/<abi>/ # populated by stage_fips.sh (libcrypto, libsqlcipher, libfips)
├── kotlin/
│ └── com/example/fipscompliance/
│ ├── ComplianceSuite.kt
│ ├── FipsInitializer.kt
│ ├── MainActivity.kt
│ └── Native.kt
└── res/values/
├── strings.xml
└── themes.xml
Why a native JNI shim instead of net.zetetic:sqlcipher-android?
The Zetetic Android wrapper is convenient, but it bundles its own
non-FIPS libcrypto. To prove the compliance chain, this test app links
straight against the cross-built libsqlcipher.so and libcrypto.so from
dist/<abi>/, with the FIPS provider activated via OPENSSL_CONF. If
either the wrong libraries are loaded or the FIPS provider is unavailable,
the runtime probe in BuildSQLCipher.cmake aborts the process before the
UI even renders.