Files
Christopher Fahlin 01e26dd717 feat(openssl): upgrade from 3.0.8 to 3.1.2 (FIPS 140-3 Cert #4985)
- 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)
2026-05-09 12:38:27 -07:00
..
2026-05-04 19:34:28 -07:00
2026-05-04 19:34:28 -07:00
2026-05-04 19:34:28 -07:00

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.sh from the repo root first).
  • A fipsmodule.cnf for arm64-v8a exists in dist/arm64-v8a/fips/. Generate it via dist/arm64-v8a/fips/run_fipsinstall_on_device.sh on a matching-arch device or emulator (see the parent README, section 5).
  • mise install from the repo root (provides JDK 17, Gradle 8.10.2, cmake 3.29).
  • ANDROID_HOME / ANDROID_SDK_ROOT exported, and an Android SDK platform 34 + build-tools 34.0.0 installed.

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.