diff --git a/keystore2/src/database/versioning.rs b/keystore2/src/database/versioning.rs
new file mode 100644
index 0000000..e3a95c8
--- /dev/null
+++ b/keystore2/src/database/versioning.rs
@@ -0,0 +1,379 @@
+// Copyright 2021, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use anyhow::{anyhow, Context, Result};
+use rusqlite::{params, OptionalExtension, Transaction, NO_PARAMS};
+
+pub fn create_or_get_version(tx: &Transaction, current_version: u32) -> Result<u32> {
+    tx.execute(
+        "CREATE TABLE IF NOT EXISTS persistent.version (
+                id INTEGER PRIMARY KEY,
+                version INTEGER);",
+        NO_PARAMS,
+    )
+    .context("In create_or_get_version: Failed to create version table.")?;
+
+    let version = tx
+        .query_row("SELECT version FROM persistent.version WHERE id = 0;", NO_PARAMS, |row| {
+            row.get(0)
+        })
+        .optional()
+        .context("In create_or_get_version: Failed to read version.")?;
+
+    let version = if let Some(version) = version {
+        version
+    } else {
+        // If no version table existed it could mean one of two things:
+        // 1) This database is completely new. In this case the version has to be set
+        //    to the current version and the current version which also needs to be
+        //    returned.
+        // 2) The database predates db versioning. In this case the version needs to be
+        //    set to 0, and 0 needs to be returned.
+        let version = if tx
+            .query_row(
+                "SELECT name FROM persistent.sqlite_master
+                 WHERE type = 'table' AND name = 'keyentry';",
+                NO_PARAMS,
+                |_| Ok(()),
+            )
+            .optional()
+            .context("In create_or_get_version: Failed to check for keyentry table.")?
+            .is_none()
+        {
+            current_version
+        } else {
+            0
+        };
+
+        tx.execute("INSERT INTO persistent.version (id, version) VALUES(0, ?);", params![version])
+            .context("In create_or_get_version: Failed to insert initial version.")?;
+        version
+    };
+    Ok(version)
+}
+
+pub fn update_version(tx: &Transaction, new_version: u32) -> Result<()> {
+    let updated = tx
+        .execute("UPDATE persistent.version SET version = ? WHERE id = 0;", params![new_version])
+        .context("In update_version: Failed to update row.")?;
+    if updated == 1 {
+        Ok(())
+    } else {
+        Err(anyhow!("In update_version: No rows were updated."))
+    }
+}
+
+pub fn upgrade_database<F>(tx: &Transaction, current_version: u32, upgraders: &[F]) -> Result<()>
+where
+    F: Fn(&Transaction) -> Result<u32> + 'static,
+{
+    if upgraders.len() < current_version as usize {
+        return Err(anyhow!("In upgrade_database: Insufficient upgraders provided."));
+    }
+    let mut db_version = create_or_get_version(tx, current_version)
+        .context("In upgrade_database: Failed to get database version.")?;
+    while db_version < current_version {
+        db_version = upgraders[db_version as usize](tx).with_context(|| {
+            format!("In upgrade_database: Trying to upgrade from db version {}.", db_version)
+        })?;
+    }
+    update_version(tx, db_version).context("In upgrade_database.")
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use rusqlite::{Connection, TransactionBehavior, NO_PARAMS};
+
+    #[test]
+    fn upgrade_database_test() {
+        let mut conn = Connection::open_in_memory().unwrap();
+        conn.execute("ATTACH DATABASE 'file::memory:' as persistent;", NO_PARAMS).unwrap();
+
+        let upgraders: Vec<_> = (0..30_u32)
+            .map(move |i| {
+                move |tx: &Transaction| {
+                    tx.execute(
+                        "INSERT INTO persistent.test (test_field) VALUES(?);",
+                        params![i + 1],
+                    )
+                    .with_context(|| format!("In upgrade_from_{}_to_{}.", i, i + 1))?;
+                    Ok(i + 1)
+                }
+            })
+            .collect();
+
+        for legacy in &[false, true] {
+            if *legacy {
+                conn.execute(
+                    "CREATE TABLE IF NOT EXISTS persistent.keyentry (
+                        id INTEGER UNIQUE,
+                        key_type INTEGER,
+                        domain INTEGER,
+                        namespace INTEGER,
+                        alias BLOB,
+                        state INTEGER,
+                        km_uuid BLOB);",
+                    NO_PARAMS,
+                )
+                .unwrap();
+            }
+            for from in 1..29 {
+                for to in from..30 {
+                    conn.execute("DROP TABLE IF EXISTS persistent.version;", NO_PARAMS).unwrap();
+                    conn.execute("DROP TABLE IF EXISTS persistent.test;", NO_PARAMS).unwrap();
+                    conn.execute(
+                        "CREATE TABLE IF NOT EXISTS persistent.test (
+                            id INTEGER PRIMARY KEY,
+                            test_field INTEGER);",
+                        NO_PARAMS,
+                    )
+                    .unwrap();
+
+                    {
+                        let tx =
+                            conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+                        create_or_get_version(&tx, from).unwrap();
+                        tx.commit().unwrap();
+                    }
+                    {
+                        let tx =
+                            conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+                        upgrade_database(&tx, to, &upgraders).unwrap();
+                        tx.commit().unwrap();
+                    }
+
+                    // In the legacy database case all upgraders starting from 0 have to run. So
+                    // after the upgrade step, the expectations need to be adjusted.
+                    let from = if *legacy { 0 } else { from };
+
+                    // There must be exactly to - from rows.
+                    assert_eq!(
+                        to - from,
+                        conn.query_row(
+                            "SELECT COUNT(test_field) FROM persistent.test;",
+                            NO_PARAMS,
+                            |row| row.get(0)
+                        )
+                        .unwrap()
+                    );
+                    // Each row must have the correct relation between id and test_field. If this
+                    // is not the case, the upgraders were not executed in the correct order.
+                    assert_eq!(
+                        to - from,
+                        conn.query_row(
+                            "SELECT COUNT(test_field) FROM persistent.test
+                             WHERE id = test_field - ?;",
+                            params![from],
+                            |row| row.get(0)
+                        )
+                        .unwrap()
+                    );
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn create_or_get_version_new_database() {
+        let mut conn = Connection::open_in_memory().unwrap();
+        conn.execute("ATTACH DATABASE 'file::memory:' as persistent;", NO_PARAMS).unwrap();
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            let version = create_or_get_version(&tx, 3).unwrap();
+            tx.commit().unwrap();
+            assert_eq!(version, 3);
+        }
+
+        // Was the version table created as expected?
+        assert_eq!(
+            Ok("version".to_owned()),
+            conn.query_row(
+                "SELECT name FROM persistent.sqlite_master
+                 WHERE type = 'table' AND name = 'version';",
+                NO_PARAMS,
+                |row| row.get(0),
+            )
+        );
+
+        // There is exactly one row in the version table.
+        assert_eq!(
+            Ok(1),
+            conn.query_row("SELECT COUNT(id) from persistent.version;", NO_PARAMS, |row| row
+                .get(0))
+        );
+
+        // The version must be set to 3
+        assert_eq!(
+            Ok(3),
+            conn.query_row(
+                "SELECT version from persistent.version WHERE id = 0;",
+                NO_PARAMS,
+                |row| row.get(0)
+            )
+        );
+
+        // Will subsequent calls to create_or_get_version still return the same version even
+        // if the current version changes.
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            let version = create_or_get_version(&tx, 5).unwrap();
+            tx.commit().unwrap();
+            assert_eq!(version, 3);
+        }
+
+        // There is still exactly one row in the version table.
+        assert_eq!(
+            Ok(1),
+            conn.query_row("SELECT COUNT(id) from persistent.version;", NO_PARAMS, |row| row
+                .get(0))
+        );
+
+        // Bump the version.
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            update_version(&tx, 5).unwrap();
+            tx.commit().unwrap();
+        }
+
+        // Now the version should have changed.
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            let version = create_or_get_version(&tx, 7).unwrap();
+            tx.commit().unwrap();
+            assert_eq!(version, 5);
+        }
+
+        // There is still exactly one row in the version table.
+        assert_eq!(
+            Ok(1),
+            conn.query_row("SELECT COUNT(id) from persistent.version;", NO_PARAMS, |row| row
+                .get(0))
+        );
+
+        // The version must be set to 5
+        assert_eq!(
+            Ok(5),
+            conn.query_row(
+                "SELECT version from persistent.version WHERE id = 0;",
+                NO_PARAMS,
+                |row| row.get(0)
+            )
+        );
+    }
+
+    #[test]
+    fn create_or_get_version_legacy_database() {
+        let mut conn = Connection::open_in_memory().unwrap();
+        conn.execute("ATTACH DATABASE 'file::memory:' as persistent;", NO_PARAMS).unwrap();
+        // A legacy (version 0) database is detected if the keyentry table exists but no
+        // version table.
+        conn.execute(
+            "CREATE TABLE IF NOT EXISTS persistent.keyentry (
+             id INTEGER UNIQUE,
+             key_type INTEGER,
+             domain INTEGER,
+             namespace INTEGER,
+             alias BLOB,
+             state INTEGER,
+             km_uuid BLOB);",
+            NO_PARAMS,
+        )
+        .unwrap();
+
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            let version = create_or_get_version(&tx, 3).unwrap();
+            tx.commit().unwrap();
+            // In the legacy case, version 0 must be returned.
+            assert_eq!(version, 0);
+        }
+
+        // Was the version table created as expected?
+        assert_eq!(
+            Ok("version".to_owned()),
+            conn.query_row(
+                "SELECT name FROM persistent.sqlite_master
+                 WHERE type = 'table' AND name = 'version';",
+                NO_PARAMS,
+                |row| row.get(0),
+            )
+        );
+
+        // There is exactly one row in the version table.
+        assert_eq!(
+            Ok(1),
+            conn.query_row("SELECT COUNT(id) from persistent.version;", NO_PARAMS, |row| row
+                .get(0))
+        );
+
+        // The version must be set to 0
+        assert_eq!(
+            Ok(0),
+            conn.query_row(
+                "SELECT version from persistent.version WHERE id = 0;",
+                NO_PARAMS,
+                |row| row.get(0)
+            )
+        );
+
+        // Will subsequent calls to create_or_get_version still return the same version even
+        // if the current version changes.
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            let version = create_or_get_version(&tx, 5).unwrap();
+            tx.commit().unwrap();
+            assert_eq!(version, 0);
+        }
+
+        // There is still exactly one row in the version table.
+        assert_eq!(
+            Ok(1),
+            conn.query_row("SELECT COUNT(id) from persistent.version;", NO_PARAMS, |row| row
+                .get(0))
+        );
+
+        // Bump the version.
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            update_version(&tx, 5).unwrap();
+            tx.commit().unwrap();
+        }
+
+        // Now the version should have changed.
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            let version = create_or_get_version(&tx, 7).unwrap();
+            tx.commit().unwrap();
+            assert_eq!(version, 5);
+        }
+
+        // There is still exactly one row in the version table.
+        assert_eq!(
+            Ok(1),
+            conn.query_row("SELECT COUNT(id) from persistent.version;", NO_PARAMS, |row| row
+                .get(0))
+        );
+
+        // The version must be set to 5
+        assert_eq!(
+            Ok(5),
+            conn.query_row(
+                "SELECT version from persistent.version WHERE id = 0;",
+                NO_PARAMS,
+                |row| row.get(0)
+            )
+        );
+    }
+}
