Introduction

This document provides installation and configuration guidelines for the SQLCipher for Android FIPS package. It should be used to supplement the SQLCipher for Android integration instructions.

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

Library installation

Extract the sqlcipher-android-fips-X.X.X.zip package.

Copy the sqlcipher-android-fips-X.X.X.aar file into the app/libs directory of your application. Create the folder if it does not exist.

Update settings.gradle

Modify the project’s settings.gradle file to add the following flatDir element under the repositories block, as follows.

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        flatDir {
            dirs 'app/libs'
        }
    }
}

Update build.gradle

Edit the application module build.gradle, add the following to the dependencies block, being careful to update the X.X.X of the version number to match the package version:

dependencies {
  implementation(name: 'sqlcipher-android-fips-X.X.X', ext: 'aar')
  implementation 'androidx.sqlite:sqlite:2.22.0'
}

Next, add the keepDebugSymbols and useLegacyPackaging elements inside the android, packagingOptions, jniLibs block:

android {
  packagingOptions {
      jniLibs {  
      keepDebugSymbols += ['*/*/libfips.so', '*/*/libfipscnf.so']
      useLegacyPackaging = true
    }
  }
}

These settings are required:

  1. keepDebugSymbols - ensures that the FIPS module libraries are not “stripped” which would modify the files and invalidate Power on Self Test signatures.
  2. useLegacyPackaging - ensures that .so files are extracted on install so that Power on Self Test signature verification run on the libraries.

Apply License Code

Retrieve the license code from the SQLCipher fulfillment site:

https://license.zetetic.net/request-account/

The license code must be provided when opening a connection via SQLiteDatabaseHook. Create the hook object and replace the PRAGMA cipher_license = ... string with the value issued to your organization.

Finally, pass the hook object as a parameter to openOrCreateDatabase. This will ensure that the license code is applied to the application prior to using SQLCipher’s features.

SQLiteDatabaseHook hook = new SQLiteDatabaseHook() {
  public void preKey(SQLiteConnection connection) {
    connection.executeForString("PRAGMA cipher_license = 'OmNpZD...';", new Object[]{}, null);
  }
  public void postKey(SQLiteConnection connection) {}
};

SQLiteDatabase database =
  SQLiteDatabase.openOrCreateDatabase(databasePath.getAbsolutePath(), password, null, null, hook);

Alternately the hook can be provided as a constructor argument when deriving from a SQLiteOpenHelper class.

public class SqlCipherOpenHelper extends SQLiteOpenHelper { 
  public SqlCipherOpenHelper(Context context, String databasePath, String password, SQLiteDatabaseHook hook) { 
    super(context, databasePath, password, null, 1, 1, (db, ex) -> Log.e("SQLCipherOpenHelper", "onCorruption()"), hook, false);
  } 
}

Note that if the license code is not properly applied, your application will receive not authorized or SQLITE_AUTH (23) errors.

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 important step ensures that the FIPS-enabled library has been integrated into the application, that it has been loaded properly at runtime, that all Power On Self Tests have completed successfully, and that the library is running in FIPS mode.

Cursor cursor = database.query("PRAGMA cipher_fips_status;", new String[]{});

String value = "";
if(cursor != null){
  cursor.moveToFirst();
  value = cursor.getString(0);
  cursor.close();
}
if("1".equals(value)) {
  // operating in FIPS mode
} else {
  // not operating in FIPS mode - throw error
}

Reference Application

A complete reference application is available in the examples folder of the sqlcipher-android-fips-X.X.X.zip package. This reference application incorporates all of the required configurations and can be used for testing or comparison purposes.

Troubleshooting

The following outline possible error conditions and resolutions.

  1. SQLiteOutOfMemoryException or unknown error (code 7) - this indicates that the Power On Self Test failed to verify the FIPS library. Check the build.gradle to ensure all the required settings are properly applied.
  2. not authorized or SQLITE_AUTH (23) errors - this indicates that the License Code was not supplied, is not valid, or has expired. Check that the application is applying the license code in the preKey hook.
  3. UnsatisfiedLinkError: or library "libsqlcipher.so" not found error - The SQLCipher library is not available for the given architecture. Note that SQLCipher for Android FIPS does not support x86 emulators, so you should either use an 64 bit x86_64 emulator or ARM devices for testing purposes. Also, check abiFilters to ensure that the platform specific libraries are not being excluded.

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