SQLCipher for Android .NET FIPS

Introduction

This document describes the steps that differ from the standard SQLCipher for .NET integration instructions when using the FIPS package for Android. Follow the base documentation for nuget.config setup, SQLitePCLRaw providers, runtime activation, linker settings, and client library integration (sqlite-net / EF Core / ADO.NET), and apply the changes below.

SQLCipher for Android .NET FIPS uses an embedded FIPS validated cryptographic module per FIPS Implementation Guidance.

Package Contents

Extract the sqlcipher-android-net-fips-4.14.0.zip package. It contains:

  • sqlcipher-android-fips.4.14.0.nupkg: FIPS-enabled native SQLCipher library package for Android
  • sqlcipher-sqlite-net-base.4.14.0.nupkg: SQLite-net base library (only needed if using the sqlite-net data access API)
  • examples/SQLCipher.Example/: reference solution with sample projects demonstrating sqlite-net, Entity Framework Core, ADO.NET, and MAUI integration

Package Integration

Copy both .nupkg files into the local NuGet package source directory configured in your nuget.config (as described in the base Project Setup).

When installing SQLCipher at the Application project level, substitute the FIPS package name:

  • Use sqlcipher-android-fips in place of sqlcipher-android

The FIPS package embeds the FIPS-validated AAR along with MSBuild targets that automatically include the native FIPS libraries in your application output; no additional manual steps are required to deploy fips.so or related files.

All other steps from the base .NET documentation apply, including:

  • Adding SQLitePCLRaw.provider.sqlcipher
  • Calling SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_sqlcipher()) early in application startup
  • Applying the license code via PRAGMA cipher_license

Set SQLCIPHER_TMP to the Application Cache Directory

The FIPS module writes temporary integrity-check artifacts to a working directory at runtime. On Android this directory is not writable by default, so the application must set the SQLCIPHER_TMP environment variable to its cache directory before calling SetProvider:

/* for SQLCipher Android FIPS, set SQLCIPHER_TMP to the cache directory */
Environment.SetEnvironmentVariable(
    "SQLCIPHER_TMP",
    FileSystem.Current.CacheDirectory,
    EnvironmentVariableTarget.Process);

SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_sqlcipher());

In MAUI, FileSystem.Current.CacheDirectory resolves to the platform cache directory. For classic Xamarin.Android or non-MAUI projects, use Android.Content.Context.CacheDir.AbsolutePath from an Activity or Application context instead.

The FIPS package defines the SQLCIPHER_ANDROID_FIPS preprocessor symbol automatically, which is useful if your codebase shares startup logic across FIPS and non-FIPS Android builds:

#if SQLCIPHER_ANDROID_FIPS
Environment.SetEnvironmentVariable(
    "SQLCIPHER_TMP",
    FileSystem.Current.CacheDirectory,
    EnvironmentVariableTarget.Process);
#endif

Failing to set SQLCIPHER_TMP before provider initialization will cause the FIPS Power On Self Test to fail and the library to refuse to load.

Check FIPS Mode

Applications using a FIPS 140 validated cryptographic module should, as a matter of practice, check that the library is operating in FIPS mode early in the application lifecycle. This ensures that the FIPS-enabled library has been integrated, loaded properly at runtime, that all Power On Self Tests have completed successfully, and that the library is running in FIPS mode.

After opening the database, keying, and applying the license code, query PRAGMA cipher_fips_status. A result of 1 indicates FIPS mode:

using (var command = connection.CreateCommand())
{
  command.CommandText = "PRAGMA cipher_fips_status;";
  var status = command.ExecuteScalar() as string;
  if (status != "1")
  {
    throw new InvalidOperationException("SQLCipher is not operating in FIPS mode");
  }
}

Reference Application

A complete reference solution is available under examples/SQLCipher.Example/ in the sqlcipher-android-net-fips-4.14.0.zip package. It includes MAUI, Console, and WinUI projects that demonstrate multiple data access APIs (sqlite-net, Entity Framework Core, ADO.NET) with the FIPS status check in place.

Troubleshooting

  1. Not Authorized / SQLITE_AUTH (23): the License Code was not supplied, is not valid, or has expired. Check that PRAGMA cipher_license is applied before any other database operations.
  2. FIPS Mode Validation Failure: a cipher_fips_status result other than 1 indicates the FIPS module did not load or the Power On Self Test did not pass. Confirm SQLCIPHER_TMP is set to a writable directory (typically the application cache) before SetProvider is called, that the sqlcipher-android-fips package is referenced by the Application project (not a shared class library), and that no conflicting SQLitePCLRaw bundles such as SQLitePCLRaw.bundle_e_sqlcipher are present.
  3. Conflicting SQLite Packages: see NuGet Package Conflicts in the base documentation to exclude transitive SQLite dependencies that can mask the FIPS native library.

Please contact support@zetetic.net with any questions or to receive private support.