WifiConfigStore: Encrypt credentials for networks (1/4)

Changes in the CL:
a) Introduced a new config store version.
The new version gets rid of the integrity computation & adds support for
encryption of credential data.
b) Changed DataIntegrityChecker to WifiConfigStoreEncryptionUtil to
help the different config store modules to encrypt/decrypt their
credential data to be stored.
c) Pass the version & the new EncryptionUtil to all the config store
modules. The version is needed for the modules to handle upgrades.
d) Use the WIFI_UID to store encryption key in keystore (to help ease
migrate keys if we move to a separate process in R)

Actual encryption of credential data/handling of upgrades will be
added in the next CL.

Bug: 140485110
Test: atest com.android.server.wifi
Change-Id: I522b11ef2ffbdbf0ff19ae4f2643023df3843e5e
Merged-In: I522b11ef2ffbdbf0ff19ae4f2643023df3843e5e
diff --git a/service/java/com/android/server/wifi/DeletedEphemeralSsidsStoreData.java b/service/java/com/android/server/wifi/DeletedEphemeralSsidsStoreData.java
index 0c06488..3575ff2 100644
--- a/service/java/com/android/server/wifi/DeletedEphemeralSsidsStoreData.java
+++ b/service/java/com/android/server/wifi/DeletedEphemeralSsidsStoreData.java
@@ -16,6 +16,9 @@
 
 package com.android.server.wifi;
 
+import android.annotation.NonNull;
+
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 import com.android.server.wifi.util.XmlUtil;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -44,7 +47,8 @@
     }
 
     @Override
-    public void serializeData(XmlSerializer out)
+    public void serializeData(XmlSerializer out,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         if (mSsidToTimeMap != null) {
             XmlUtil.writeNextValue(out, XML_TAG_SSID_LIST, mSsidToTimeMap);
@@ -52,7 +56,9 @@
     }
 
     @Override
-    public void deserializeData(XmlPullParser in, int outerTagDepth)
+    public void deserializeData(XmlPullParser in, int outerTagDepth,
+            @WifiConfigStore.Version int version,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         // Ignore empty reads.
         if (in == null) {
diff --git a/service/java/com/android/server/wifi/NetworkListStoreData.java b/service/java/com/android/server/wifi/NetworkListStoreData.java
index 6966471..981e97c 100644
--- a/service/java/com/android/server/wifi/NetworkListStoreData.java
+++ b/service/java/com/android/server/wifi/NetworkListStoreData.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wifi;
 
+import android.annotation.NonNull;
 import android.content.Context;
 import android.net.IpConfiguration;
 import android.net.wifi.WifiConfiguration;
@@ -25,6 +26,7 @@
 import android.util.Log;
 import android.util.Pair;
 
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 import com.android.server.wifi.util.XmlUtil;
 import com.android.server.wifi.util.XmlUtil.IpConfigurationXmlUtil;
 import com.android.server.wifi.util.XmlUtil.NetworkSelectionStatusXmlUtil;
@@ -66,13 +68,16 @@
     }
 
     @Override
-    public void serializeData(XmlSerializer out)
+    public void serializeData(XmlSerializer out,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         serializeNetworkList(out, mConfigurations);
     }
 
     @Override
-    public void deserializeData(XmlPullParser in, int outerTagDepth)
+    public void deserializeData(XmlPullParser in, int outerTagDepth,
+            @WifiConfigStore.Version int version,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         // Ignore empty reads.
         if (in == null) {
diff --git a/service/java/com/android/server/wifi/NetworkRequestStoreData.java b/service/java/com/android/server/wifi/NetworkRequestStoreData.java
index 8d1244f..3a5143f 100644
--- a/service/java/com/android/server/wifi/NetworkRequestStoreData.java
+++ b/service/java/com/android/server/wifi/NetworkRequestStoreData.java
@@ -16,10 +16,12 @@
 
 package com.android.server.wifi;
 
+import android.annotation.NonNull;
 import android.net.MacAddress;
 import android.util.Log;
 
 import com.android.server.wifi.WifiNetworkFactory.AccessPoint;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 import com.android.server.wifi.util.XmlUtil;
 import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;
 
@@ -87,13 +89,16 @@
     }
 
     @Override
-    public void serializeData(XmlSerializer out)
+    public void serializeData(XmlSerializer out,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         serializeApprovedAccessPointsMap(out, mDataSource.toSerialize());
     }
 
     @Override
-    public void deserializeData(XmlPullParser in, int outerTagDepth)
+    public void deserializeData(XmlPullParser in, int outerTagDepth,
+            @WifiConfigStore.Version int version,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         // Ignore empty reads.
         if (in == null) {
diff --git a/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java b/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
index 9627a9d..e9503b7 100644
--- a/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
+++ b/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wifi;
 
+import android.annotation.NonNull;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiEnterpriseConfig;
 import android.net.wifi.WifiNetworkSuggestion;
@@ -26,6 +27,7 @@
 import com.android.internal.util.XmlUtils;
 import com.android.server.wifi.WifiNetworkSuggestionsManager.ExtendedWifiNetworkSuggestion;
 import com.android.server.wifi.WifiNetworkSuggestionsManager.PerAppInfo;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 import com.android.server.wifi.util.XmlUtil;
 import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;
 
@@ -98,13 +100,16 @@
     }
 
     @Override
-    public void serializeData(XmlSerializer out)
+    public void serializeData(XmlSerializer out,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         serializeNetworkSuggestionsMap(out, mDataSource.toSerialize());
     }
 
     @Override
-    public void deserializeData(XmlPullParser in, int outerTagDepth)
+    public void deserializeData(XmlPullParser in, int outerTagDepth,
+            @WifiConfigStore.Version int version,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         // Ignore empty reads.
         if (in == null) {
diff --git a/service/java/com/android/server/wifi/RandomizedMacStoreData.java b/service/java/com/android/server/wifi/RandomizedMacStoreData.java
index 1e4d972..8e47ee7 100644
--- a/service/java/com/android/server/wifi/RandomizedMacStoreData.java
+++ b/service/java/com/android/server/wifi/RandomizedMacStoreData.java
@@ -16,6 +16,9 @@
 
 package com.android.server.wifi;
 
+import android.annotation.NonNull;
+
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 import com.android.server.wifi.util.XmlUtil;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -40,7 +43,8 @@
     RandomizedMacStoreData() {}
 
     @Override
-    public void serializeData(XmlSerializer out)
+    public void serializeData(XmlSerializer out,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         if (mMacMapping != null) {
             XmlUtil.writeNextValue(out, XML_TAG_MAC_MAP, mMacMapping);
@@ -48,7 +52,9 @@
     }
 
     @Override
-    public void deserializeData(XmlPullParser in, int outerTagDepth)
+    public void deserializeData(XmlPullParser in, int outerTagDepth,
+            @WifiConfigStore.Version int version,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         // Ignore empty reads.
         if (in == null) {
diff --git a/service/java/com/android/server/wifi/SsidSetStoreData.java b/service/java/com/android/server/wifi/SsidSetStoreData.java
index 7d1b993..1339dae 100644
--- a/service/java/com/android/server/wifi/SsidSetStoreData.java
+++ b/service/java/com/android/server/wifi/SsidSetStoreData.java
@@ -16,8 +16,10 @@
 
 package com.android.server.wifi;
 
+import android.annotation.NonNull;
 import android.text.TextUtils;
 
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 import com.android.server.wifi.util.XmlUtil;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -74,7 +76,8 @@
     }
 
     @Override
-    public void serializeData(XmlSerializer out)
+    public void serializeData(XmlSerializer out,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         Set<String> ssidSet = mDataSource.getSsids();
         if (ssidSet != null && !ssidSet.isEmpty()) {
@@ -83,7 +86,9 @@
     }
 
     @Override
-    public void deserializeData(XmlPullParser in, int outerTagDepth)
+    public void deserializeData(XmlPullParser in, int outerTagDepth,
+            @WifiConfigStore.Version int version,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         // Ignore empty reads.
         if (in == null) {
diff --git a/service/java/com/android/server/wifi/WakeupConfigStoreData.java b/service/java/com/android/server/wifi/WakeupConfigStoreData.java
index d191ee3..1d146a0 100644
--- a/service/java/com/android/server/wifi/WakeupConfigStoreData.java
+++ b/service/java/com/android/server/wifi/WakeupConfigStoreData.java
@@ -16,10 +16,12 @@
 
 package com.android.server.wifi;
 
+import android.annotation.NonNull;
 import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.server.wifi.WifiConfigStore.StoreData;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 import com.android.server.wifi.util.XmlUtil;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -94,7 +96,8 @@
     }
 
     @Override
-    public void serializeData(XmlSerializer out)
+    public void serializeData(XmlSerializer out,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         writeFeatureState(out);
 
@@ -141,7 +144,9 @@
     }
 
     @Override
-    public void deserializeData(XmlPullParser in, int outerTagDepth)
+    public void deserializeData(XmlPullParser in, int outerTagDepth,
+            @WifiConfigStore.Version int version,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         if (!mHasBeenRead) {
             Log.d(TAG, "WifiWake user data has been read");
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java
index e189d00..efe4a4c 100644
--- a/service/java/com/android/server/wifi/WifiConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiConfigStore.java
@@ -35,8 +35,8 @@
 import com.android.internal.os.AtomicFile;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.Preconditions;
-import com.android.server.wifi.util.DataIntegrityChecker;
 import com.android.server.wifi.util.EncryptedData;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 import com.android.server.wifi.util.XmlUtil;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -53,7 +53,6 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -106,17 +105,33 @@
     /**
      * Current config store data version. This will be incremented for any additions.
      */
-    private static final int CURRENT_CONFIG_STORE_DATA_VERSION = 2;
+    private static final int CURRENT_CONFIG_STORE_DATA_VERSION = 3;
     /** This list of older versions will be used to restore data from older config store. */
     /**
      * First version of the config store data format.
      */
-    private static final int INITIAL_CONFIG_STORE_DATA_VERSION = 1;
+    public static final int INITIAL_CONFIG_STORE_DATA_VERSION = 1;
     /**
      * Second version of the config store data format, introduced:
      *  - Integrity info.
      */
-    private static final int INTEGRITY_CONFIG_STORE_DATA_VERSION = 2;
+    public static final int INTEGRITY_CONFIG_STORE_DATA_VERSION = 2;
+    /**
+     * Third version of the config store data format,
+     * introduced:
+     *  - Encryption of credentials
+     * removed:
+     *  - Integrity info.
+     */
+    public static final int ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION = 3;
+
+    @IntDef(suffix = { "_VERSION" }, value = {
+            INITIAL_CONFIG_STORE_DATA_VERSION,
+            INTEGRITY_CONFIG_STORE_DATA_VERSION,
+            ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Version { }
 
     /**
      * Alarm tag to use for starting alarms for buffering file writes.
@@ -291,8 +306,9 @@
             }
         }
         File file = new File(storeDir, STORE_ID_TO_FILE_NAME.get(fileId));
-        DataIntegrityChecker dataIntegrityChecker = new DataIntegrityChecker(file.getName());
-        return new StoreFile(file, fileId, dataIntegrityChecker);
+        WifiConfigStoreEncryptionUtil encryptionUtil =
+                new WifiConfigStoreEncryptionUtil(file.getName());
+        return new StoreFile(file, fileId, encryptionUtil);
     }
 
     /**
@@ -427,88 +443,18 @@
         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         out.setOutput(outputStream, StandardCharsets.UTF_8.name());
 
-        // To compute integrity, write zeroes in the integrity fields. Once the integrity is
-        // computed, go back and modfiy the XML fields in place with the computed values.
-        writeDocumentMetadata(out, ZEROED_ENCRYPTED_DATA);
-        for (StoreData storeData : storeDataList) {
-            String tag = storeData.getName();
-            XmlUtil.writeNextSectionStart(out, tag);
-            storeData.serializeData(out);
-            XmlUtil.writeNextSectionEnd(out, tag);
-        }
-        XmlUtil.writeDocumentEnd(out, XML_TAG_DOCUMENT_HEADER);
-
-        byte[] outBytes = outputStream.toByteArray();
-        EncryptedData encryptedData = storeFile.computeIntegrity(outBytes);
-        if (encryptedData == null) {
-            // should never happen, this is a fatal failure. Abort file write.
-            Log.wtf(TAG, "Failed to compute integrity, failing write");
-            return null;
-        }
-        return rewriteDocumentMetadataRawBytes(outBytes, encryptedData);
-    }
-
-    /**
-     * Helper method to write the metadata at the start of every config store file.
-     * The metadata consists of:
-     * a) Version
-     * b) Integrity data computed on the data contents.
-     */
-    private void writeDocumentMetadata(XmlSerializer out, EncryptedData encryptedData)
-            throws XmlPullParserException, IOException {
         // First XML header.
         XmlUtil.writeDocumentStart(out, XML_TAG_DOCUMENT_HEADER);
         // Next version.
         XmlUtil.writeNextValue(out, XML_TAG_VERSION, CURRENT_CONFIG_STORE_DATA_VERSION);
-
-        // Next integrity data.
-        XmlUtil.writeNextSectionStart(out, XML_TAG_HEADER_INTEGRITY);
-        XmlUtil.writeNextValue(out, XML_TAG_INTEGRITY_ENCRYPTED_DATA,
-                encryptedData.getEncryptedData());
-        XmlUtil.writeNextValue(out, XML_TAG_INTEGRITY_IV, encryptedData.getIv());
-        XmlUtil.writeNextSectionEnd(out, XML_TAG_HEADER_INTEGRITY);
-    }
-
-    /**
-     * Helper method to generate the raw bytes containing the the metadata at the start of every
-     * config store file.
-     *
-     * NOTE: This does not create a fully formed XML document (the start tag is not closed for
-     * example). This only creates the top portion of the XML which contains the modified
-     * integrity data & version along with the XML prolog (metadata):
-     * <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
-     * <WifiConfigStoreData>
-     * <int name="Version" value="2" />
-     * <Integrity>
-     * <byte-array name="EncryptedData" num="48">!EncryptedData!</byte-array>
-     * <byte-array name="IV" num="12">!IV!</byte-array>
-     * </Integrity>
-     */
-    private byte[] generateDocumentMetadataRawBytes(EncryptedData encryptedData)
-            throws XmlPullParserException, IOException {
-        final XmlSerializer outXml = new FastXmlSerializer();
-        final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
-        outXml.setOutput(outStream, StandardCharsets.UTF_8.name());
-        writeDocumentMetadata(outXml, encryptedData);
-        outXml.endDocument();
-        return outStream.toByteArray();
-    }
-
-    /**
-     * Helper method to rewrite the existing document metadata in the incoming raw bytes in
-     * |inBytes| with the new document metadata created with the provided |encryptedData|.
-     *
-     * NOTE: This assumes that the metadata in existing XML inside |inBytes| aligns exactly
-     * with the new metadata created. So, a simple in place rewrite of the first few bytes (
-     * corresponding to metadata section of the document) from |inBytes| will preserve the overall
-     * document structure.
-     */
-    private byte[] rewriteDocumentMetadataRawBytes(byte[] inBytes, EncryptedData encryptedData)
-            throws XmlPullParserException, IOException {
-        byte[] replaceMetadataBytes = generateDocumentMetadataRawBytes(encryptedData);
-        ByteBuffer outByteBuffer = ByteBuffer.wrap(inBytes);
-        outByteBuffer.put(replaceMetadataBytes);
-        return outByteBuffer.array();
+        for (StoreData storeData : storeDataList) {
+            String tag = storeData.getName();
+            XmlUtil.writeNextSectionStart(out, tag);
+            storeData.serializeData(out, storeFile.getEncryptionUtil());
+            XmlUtil.writeNextSectionEnd(out, tag);
+        }
+        XmlUtil.writeDocumentEnd(out, XML_TAG_DOCUMENT_HEADER);
+        return outputStream.toByteArray();
     }
 
     /**
@@ -629,10 +575,11 @@
     }
 
     // Inform all the provided store data clients that there is nothing in the store for them.
-    private void indicateNoDataForStoreDatas(Collection<StoreData> storeDataSet)
+    private void indicateNoDataForStoreDatas(Collection<StoreData> storeDataSet,
+            @Version int version, @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         for (StoreData storeData : storeDataSet) {
-            storeData.deserializeData(null, 0);
+            storeData.deserializeData(null, 0, version, encryptionUtil);
         }
     }
 
@@ -654,7 +601,8 @@
             throws XmlPullParserException, IOException {
         List<StoreData> storeDataList = retrieveStoreDataListForStoreFile(storeFile);
         if (dataBytes == null) {
-            indicateNoDataForStoreDatas(storeDataList);
+            indicateNoDataForStoreDatas(storeDataList, -1 /* unknown */,
+                    storeFile.getEncryptionUtil());
             return;
         }
         final XmlPullParser in = Xml.newPullParser();
@@ -665,21 +613,10 @@
         int rootTagDepth = in.getDepth() + 1;
         XmlUtil.gotoDocumentStart(in, XML_TAG_DOCUMENT_HEADER);
 
-        int version = parseVersionFromXml(in);
-        // Version 2 onwards contains integrity data, so check the integrity of the file.
-        if (version >= INTEGRITY_CONFIG_STORE_DATA_VERSION) {
-            EncryptedData integrityData = parseIntegrityDataFromXml(in, rootTagDepth);
-            // To compute integrity, write zeroes in the integrity fields.
-            dataBytes = rewriteDocumentMetadataRawBytes(dataBytes, ZEROED_ENCRYPTED_DATA);
-            if (!storeFile.checkIntegrity(dataBytes, integrityData)) {
-                Log.wtf(TAG, "Integrity mismatch, discarding data from " + storeFile.mFileName);
-                return;
-            }
-        } else {
-            // When integrity checking is introduced. The existing data will have no related
-            // integrity file for validation. Thus, we will assume the existing data is correct.
-            // Integrity will be computed for the next write.
-            Log.d(TAG, "No integrity data to check; thus vacously true");
+        @Version int version = parseVersionFromXml(in);
+        // Version 2 contains the now unused integrity data, parse & then discard the information.
+        if (version == INTEGRITY_CONFIG_STORE_DATA_VERSION) {
+            parseAndDiscardIntegrityDataFromXml(in, rootTagDepth);
         }
 
         String[] headerName = new String[1];
@@ -695,14 +632,15 @@
                 throw new XmlPullParserException("Unknown store data: " + headerName[0]
                         + ". List of store data: " + storeDataList);
             }
-            storeData.deserializeData(in, rootTagDepth + 1);
+            storeData.deserializeData(in, rootTagDepth + 1, version,
+                    storeFile.getEncryptionUtil());
             storeDatasInvoked.add(storeData);
         }
         // Inform all the other registered store data clients that there is nothing in the store
         // for them.
         Set<StoreData> storeDatasNotInvoked = new HashSet<>(storeDataList);
         storeDatasNotInvoked.removeAll(storeDatasInvoked);
-        indicateNoDataForStoreDatas(storeDatasNotInvoked);
+        indicateNoDataForStoreDatas(storeDatasNotInvoked, version, storeFile.getEncryptionUtil());
     }
 
     /**
@@ -712,7 +650,7 @@
      * @param in XmlPullParser instance pointing to the XML stream.
      * @return version number retrieved from the Xml stream.
      */
-    private static int parseVersionFromXml(XmlPullParser in)
+    private static @Version int parseVersionFromXml(XmlPullParser in)
             throws XmlPullParserException, IOException {
         int version = (int) XmlUtil.readNextValueWithName(in, XML_TAG_VERSION);
         if (version < INITIAL_CONFIG_STORE_DATA_VERSION
@@ -723,22 +661,16 @@
     }
 
     /**
-     * Parse the integrity data structure from the XML stream.
-     * This is used for both the shared and user config store data.
+     * Parse the integrity data structure from the XML stream and discard it.
      *
      * @param in XmlPullParser instance pointing to the XML stream.
      * @param outerTagDepth Outer tag depth.
-     * @return Instance of {@link EncryptedData} retrieved from the Xml stream.
      */
-    private static @NonNull EncryptedData parseIntegrityDataFromXml(
-            XmlPullParser in, int outerTagDepth)
+    private static void parseAndDiscardIntegrityDataFromXml(XmlPullParser in, int outerTagDepth)
             throws XmlPullParserException, IOException {
         XmlUtil.gotoNextSectionWithName(in, XML_TAG_HEADER_INTEGRITY, outerTagDepth);
-        byte[] encryptedData =
-                (byte[]) XmlUtil.readNextValueWithName(in, XML_TAG_INTEGRITY_ENCRYPTED_DATA);
-        byte[] iv =
-                (byte[]) XmlUtil.readNextValueWithName(in, XML_TAG_INTEGRITY_IV);
-        return new EncryptedData(encryptedData, iv);
+        XmlUtil.readNextValueWithName(in, XML_TAG_INTEGRITY_ENCRYPTED_DATA);
+        XmlUtil.readNextValueWithName(in, XML_TAG_INTEGRITY_IV);
     }
 
     /**
@@ -790,14 +722,14 @@
         /**
          * Integrity checking for the store file.
          */
-        private final DataIntegrityChecker mDataIntegrityChecker;
+        private final WifiConfigStoreEncryptionUtil mEncryptionUtil;
 
         public StoreFile(File file, @StoreFileId int fileId,
-                         @NonNull DataIntegrityChecker dataIntegrityChecker) {
+                @NonNull WifiConfigStoreEncryptionUtil encryptionUtil) {
             mAtomicFile = new AtomicFile(file);
             mFileName = file.getAbsolutePath();
             mFileId = fileId;
-            mDataIntegrityChecker = dataIntegrityChecker;
+            mEncryptionUtil = encryptionUtil;
         }
 
         /**
@@ -810,6 +742,13 @@
         }
 
         /**
+         * @return Returns the encryption util used for this store file.
+         */
+        public @NonNull WifiConfigStoreEncryptionUtil getEncryptionUtil() {
+            return mEncryptionUtil;
+        }
+
+        /**
          * Read the entire raw data from the store file and return in a byte array.
          *
          * @return raw data read from the file or null if the file is not found or the data has
@@ -862,33 +801,6 @@
             // Reset the pending write data after write.
             mWriteData = null;
         }
-
-        /**
-         * Compute integrity of |dataWithZeroedIntegrityFields| to be written to the file.
-         *
-         * @param dataWithZeroedIntegrityFields raw data to be written to the file with the
-         *                                      integrity fields zeroed out for integrity
-         *                                      calculation.
-         * @return Instance of {@link EncryptedData} holding the encrypted integrity data for the
-         * raw data to be written to the file.
-         */
-        public EncryptedData computeIntegrity(byte[] dataWithZeroedIntegrityFields) {
-            return mDataIntegrityChecker.compute(dataWithZeroedIntegrityFields);
-        }
-
-        /**
-         * Check integrity of |dataWithZeroedIntegrityFields| read from the file with the integrity
-         * data parsed from the file.
-         * @param dataWithZeroedIntegrityFields raw data read from the file with the integrity
-         *                                      fields zeroed out for integrity calculation.
-         * @param parsedEncryptedData Instance of {@link EncryptedData} parsed from the integrity
-         *                            fields in the raw data.
-         * @return true if the integrity matches, false otherwise.
-         */
-        public boolean checkIntegrity(byte[] dataWithZeroedIntegrityFields,
-                                      EncryptedData parsedEncryptedData) {
-            return mDataIntegrityChecker.isOk(dataWithZeroedIntegrityFields, parsedEncryptedData);
-        }
     }
 
     /**
@@ -908,8 +820,9 @@
          * Serialize a XML data block to the output stream.
          *
          * @param out The output stream to serialize the data to
+         * @param encryptionUtil Utility to help encrypt any credential data.
          */
-        void serializeData(XmlSerializer out)
+        void serializeData(XmlSerializer out, @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
                 throws XmlPullParserException, IOException;
 
         /**
@@ -918,10 +831,14 @@
          * @param in The input stream to read the data from. This could be null if there is
          *           nothing in the store.
          * @param outerTagDepth The depth of the outer tag in the XML document
+         * @param version Version of config store file.
+         * @param encryptionUtil Utility to help decrypt any credential data.
+         *
          * Note: This will be invoked every time a store file is read, even if there is nothing
          *                      in the store for them.
          */
-        void deserializeData(@Nullable XmlPullParser in, int outerTagDepth)
+        void deserializeData(@Nullable XmlPullParser in, int outerTagDepth, @Version int version,
+                @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
                 throws XmlPullParserException, IOException;
 
         /**
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreData.java b/service/java/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreData.java
index 419ea79..9abccb9 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreData.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreData.java
@@ -16,7 +16,10 @@
 
 package com.android.server.wifi.hotspot2;
 
+import android.annotation.NonNull;
+
 import com.android.server.wifi.WifiConfigStore;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 import com.android.server.wifi.util.XmlUtil;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -72,13 +75,16 @@
     }
 
     @Override
-    public void serializeData(XmlSerializer out)
+    public void serializeData(XmlSerializer out,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         serializeShareData(out);
     }
 
     @Override
-    public void deserializeData(XmlPullParser in, int outerTagDepth)
+    public void deserializeData(XmlPullParser in, int outerTagDepth,
+            @WifiConfigStore.Version int version,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         // Ignore empty reads.
         if (in == null) {
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java b/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java
index 0114cfb..1001b11 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wifi.hotspot2;
 
+import android.annotation.NonNull;
 import android.net.wifi.hotspot2.PasspointConfiguration;
 import android.text.TextUtils;
 
@@ -23,6 +24,7 @@
 import com.android.server.wifi.SIMAccessor;
 import com.android.server.wifi.WifiConfigStore;
 import com.android.server.wifi.WifiKeyStore;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 import com.android.server.wifi.util.XmlUtil;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -103,13 +105,16 @@
     }
 
     @Override
-    public void serializeData(XmlSerializer out)
+    public void serializeData(XmlSerializer out,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         serializeUserData(out);
     }
 
     @Override
-    public void deserializeData(XmlPullParser in, int outerTagDepth)
+    public void deserializeData(XmlPullParser in, int outerTagDepth,
+            @WifiConfigStore.Version int version,
+            @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
             throws XmlPullParserException, IOException {
         // Ignore empty reads.
         if (in == null) {
diff --git a/service/java/com/android/server/wifi/util/DataIntegrityChecker.java b/service/java/com/android/server/wifi/util/WifiConfigStoreEncryptionUtil.java
similarity index 60%
rename from service/java/com/android/server/wifi/util/DataIntegrityChecker.java
rename to service/java/com/android/server/wifi/util/WifiConfigStoreEncryptionUtil.java
index 6f03a48..2f9b08f 100644
--- a/service/java/com/android/server/wifi/util/DataIntegrityChecker.java
+++ b/service/java/com/android/server/wifi/util/WifiConfigStoreEncryptionUtil.java
@@ -17,22 +17,22 @@
 package com.android.server.wifi.util;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Process;
 import android.os.SystemProperties;
+import android.security.keystore.AndroidKeyStoreProvider;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
 import android.text.TextUtils;
 import android.util.Log;
 
-import java.io.IOException;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
-import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.UnrecoverableEntryException;
-import java.security.cert.CertificateException;
 
 import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
@@ -43,34 +43,26 @@
 import javax.crypto.spec.GCMParameterSpec;
 
 /**
- * Tools to provide integrity checking of byte arrays based on NIAP Common Criteria Protection
- * Profile <a href="https://www.niap-ccevs.org/MMO/PP/-417-/#FCS_STG_EXT.3.1">FCS_STG_EXT.3.1</a>.
+ * Tools to help encrypt/decrypt
  */
-public class DataIntegrityChecker {
-    private static final String TAG = "DataIntegrityChecker";
+public class WifiConfigStoreEncryptionUtil {
+    private static final String TAG = "WifiConfigStoreEncryptionUtil";
 
-    private static final String ALIAS_SUFFIX = ".data-integrity-checker-key";
+    private static final String ALIAS_SUFFIX = ".data-encryption-key";
     private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";
-    private static final String DIGEST_ALGORITHM = "SHA-256";
     private static final int GCM_TAG_LENGTH = 128;
     private static final String KEY_STORE = "AndroidKeyStore";
 
-    /**
-     * When KEYSTORE_FAILURE_RETURN_VALUE is true, all cryptographic operation failures will not
-     * enforce security and {@link #isOk(byte[], EncryptedData)} always return true.
-     */
-    private static final boolean KEYSTORE_FAILURE_RETURN_VALUE = true;
-
     private final String mDataFileName;
 
     /**
-     * Construct a new integrity checker to update and check if/when a data file was altered
-     * outside expected conditions.
+     * Construct a new util to help {@link com.android.server.wifi.WifiConfigStore.StoreData}
+     * modules to encrypt/decrypt credential data written/read from this config store file.
      *
-     * @param dataFileName The full path of the data file for which integrity check is performed.
+     * @param dataFileName The full path of the data file.
      * @throws NullPointerException When data file is empty string.
      */
-    public DataIntegrityChecker(@NonNull String dataFileName) {
+    public WifiConfigStoreEncryptionUtil(@NonNull String dataFileName) {
         if (TextUtils.isEmpty(dataFileName)) {
             throw new NullPointerException("dataFileName must not be null or the empty "
                     + "string");
@@ -83,80 +75,16 @@
     }
 
     /**
-     * Computes a digest of a byte array, encrypt it, and store the result
+     * Encrypt the provided data blob.
      *
-     * Call this method immediately before storing the byte array
-     *
-     * @param data The data desired to ensure integrity
-     * @return Instance of {@link EncryptedData} containing the encrypted integrity data.
+     * @param data Data blob to be encrypted.
+     * @return Instance of {@link EncryptedData} containing the encrypted info.
      */
-    public EncryptedData compute(byte[] data) {
-        if (data == null || data.length < 1) {
-            reportException(new Exception("No data to compute"), "No data to compute.");
-            return null;
-        }
-        byte[] digest = getDigest(data);
-        if (digest == null || digest.length < 1) {
-            reportException(new Exception("digest null in compute"),
-                    "digest null in compute");
-            return null;
-        }
-        EncryptedData integrityData = encrypt(digest, getKeyAlias());
-        if (integrityData == null) {
-            reportException(new Exception("integrityData null in compute"),
-                    "integrityData null in compute");
-        }
-        return integrityData;
-    }
-
-
-    /**
-     * Check the integrity of a given byte array
-     *
-     * Call this method immediately before trusting the byte array. This method will return false
-     * when the integrity data calculated on the byte array does not match the encrypted integrity
-     * data provided to compare or if there is an underlying issue with the cryptographic functions
-     * or the key store.
-     *
-     * @param data The data to check if its been altered.
-     * @param integrityData Encrypted integrity data to be used for comparison.
-     * @return true if the integrity data computed on |data| matches the provided |integrityData|.
-     */
-    public boolean isOk(@NonNull byte[] data, @NonNull EncryptedData integrityData) {
-        if (data == null || data.length < 1) {
-            return KEYSTORE_FAILURE_RETURN_VALUE;
-        }
-        byte[] currentDigest = getDigest(data);
-        if (currentDigest == null || currentDigest.length < 1) {
-            reportException(new Exception("current digest null"), "current digest null");
-            return KEYSTORE_FAILURE_RETURN_VALUE;
-        }
-        if (integrityData == null) {
-            reportException(new Exception("integrityData null in isOk"),
-                    "integrityData null in isOk");
-            return KEYSTORE_FAILURE_RETURN_VALUE;
-        }
-        byte[] storedDigest = decrypt(integrityData, getKeyAlias());
-        if (storedDigest == null) {
-            return KEYSTORE_FAILURE_RETURN_VALUE;
-        }
-        return constantTimeEquals(storedDigest, currentDigest);
-    }
-
-    private byte[] getDigest(byte[] data) {
-        try {
-            return MessageDigest.getInstance(DIGEST_ALGORITHM).digest(data);
-        } catch (NoSuchAlgorithmException e) {
-            reportException(e, "getDigest could not find algorithm: " + DIGEST_ALGORITHM);
-            return null;
-        }
-    }
-
-    private EncryptedData encrypt(byte[] data, String keyAlias) {
+    public @Nullable EncryptedData encrypt(byte[] data) {
         EncryptedData encryptedData = null;
         try {
             Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
-            SecretKey secretKeyReference = getOrCreateSecretKey(keyAlias);
+            SecretKey secretKeyReference = getOrCreateSecretKey(getKeyAlias());
             if (secretKeyReference != null) {
                 cipher.init(Cipher.ENCRYPT_MODE, secretKeyReference);
                 encryptedData = new EncryptedData(cipher.doFinal(data), cipher.getIV());
@@ -178,12 +106,18 @@
         return encryptedData;
     }
 
-    private byte[] decrypt(EncryptedData encryptedData, String keyAlias) {
+    /**
+     * Decrypt the original data blob from the provided {@link EncryptedData}.
+     *
+     * @param encryptedData Instance of {@link EncryptedData} containing the encrypted info.
+     * @return Original data blob that was encrypted.
+     */
+    public @Nullable byte[] decrypt(@NonNull EncryptedData encryptedData) {
         byte[] decryptedData = null;
         try {
             Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
             GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH, encryptedData.getIv());
-            SecretKey secretKeyReference = getOrCreateSecretKey(keyAlias);
+            SecretKey secretKeyReference = getOrCreateSecretKey(getKeyAlias());
             if (secretKeyReference != null) {
                 cipher.init(Cipher.DECRYPT_MODE, secretKeyReference, spec);
                 decryptedData = cipher.doFinal(encryptedData.getEncryptedData());
@@ -207,8 +141,7 @@
     private SecretKey getOrCreateSecretKey(String keyAlias) {
         SecretKey secretKey = null;
         try {
-            KeyStore keyStore = KeyStore.getInstance(KEY_STORE);
-            keyStore.load(null);
+            KeyStore keyStore = AndroidKeyStoreProvider.getKeyStoreForUid(Process.WIFI_UID);
             if (keyStore.containsAlias(keyAlias)) { // The key exists in key store. Get the key.
                 KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore
                         .getEntry(keyAlias, null);
@@ -227,17 +160,14 @@
                         KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                         .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                        .setUid(Process.WIFI_UID)
                         .build();
 
                 keyGenerator.init(keyGenParameterSpec);
                 secretKey = keyGenerator.generateKey();
             }
-        } catch (CertificateException e) {
-            reportException(e, "getOrCreateSecretKey had a certificate exception.");
         } catch (InvalidAlgorithmParameterException e) {
             reportException(e, "getOrCreateSecretKey had an invalid algorithm parameter");
-        } catch (IOException e) {
-            reportException(e, "getOrCreateSecretKey had an IO exception.");
         } catch (KeyStoreException e) {
             reportException(e, "getOrCreateSecretKey cannot find the keystore: " + KEY_STORE);
         } catch (NoSuchAlgorithmException e) {
@@ -250,22 +180,6 @@
         return secretKey;
     }
 
-    private boolean constantTimeEquals(byte[] a, byte[] b) {
-        if (a == null && b == null) {
-            return true;
-        }
-
-        if (a == null || b == null || a.length != b.length) {
-            return false;
-        }
-
-        byte differenceAccumulator = 0;
-        for (int i = 0; i < a.length; ++i) {
-            differenceAccumulator |= a[i] ^ b[i];
-        }
-        return (differenceAccumulator == 0);
-    }
-
     /* TODO(b/128526030): Remove this error reporting code upon resolving the bug. */
     private static final boolean REQUEST_BUG_REPORT = false;
     private void reportException(Exception exception, String error) {
@@ -275,4 +189,5 @@
             SystemProperties.set("ctl.start", "bugreport");
         }
     }
+
 }
diff --git a/service/tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java
index 702aa99..17b9d1c 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java
@@ -24,6 +24,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -78,7 +79,8 @@
         final XmlSerializer out = new FastXmlSerializer();
         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         out.setOutput(outputStream, StandardCharsets.UTF_8.name());
-        mDeletedEphemeralSsidsStoreData.serializeData(out);
+        mDeletedEphemeralSsidsStoreData.serializeData(
+                out, mock(WifiConfigStoreEncryptionUtil.class));
         out.flush();
         return outputStream.toByteArray();
     }
@@ -94,7 +96,9 @@
         final XmlPullParser in = Xml.newPullParser();
         final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
         in.setInput(inputStream, StandardCharsets.UTF_8.name());
-        mDeletedEphemeralSsidsStoreData.deserializeData(in, in.getDepth());
+        mDeletedEphemeralSsidsStoreData.deserializeData(in, in.getDepth(),
+                WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+                mock(WifiConfigStoreEncryptionUtil.class));
         return mDeletedEphemeralSsidsStoreData.getSsidToTimeMap();
     }
 
diff --git a/service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java
index 7336c41..20b6c4f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java
@@ -31,6 +31,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 import com.android.server.wifi.util.XmlUtilTest;
 
 import org.junit.Before;
@@ -213,7 +214,7 @@
         final XmlSerializer out = new FastXmlSerializer();
         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         out.setOutput(outputStream, StandardCharsets.UTF_8.name());
-        mNetworkListSharedStoreData.serializeData(out);
+        mNetworkListSharedStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
         out.flush();
         return outputStream.toByteArray();
     }
@@ -229,7 +230,9 @@
         final XmlPullParser in = Xml.newPullParser();
         final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
         in.setInput(inputStream, StandardCharsets.UTF_8.name());
-        mNetworkListSharedStoreData.deserializeData(in, in.getDepth());
+        mNetworkListSharedStoreData.deserializeData(in, in.getDepth(),
+                WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+                mock(WifiConfigStoreEncryptionUtil.class));
         return mNetworkListSharedStoreData.getConfigurations();
     }
 
diff --git a/service/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java
index f40f71b..c0f0350 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java
@@ -27,6 +27,7 @@
 
 import com.android.internal.util.FastXmlSerializer;
 import com.android.server.wifi.WifiNetworkFactory.AccessPoint;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -80,7 +81,7 @@
         final XmlSerializer out = new FastXmlSerializer();
         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         out.setOutput(outputStream, StandardCharsets.UTF_8.name());
-        mNetworkRequestStoreData.serializeData(out);
+        mNetworkRequestStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
         out.flush();
         return outputStream.toByteArray();
     }
@@ -92,7 +93,9 @@
         final XmlPullParser in = Xml.newPullParser();
         final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
         in.setInput(inputStream, StandardCharsets.UTF_8.name());
-        mNetworkRequestStoreData.deserializeData(in, in.getDepth());
+        mNetworkRequestStoreData.deserializeData(in, in.getDepth(),
+                WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+                mock(WifiConfigStoreEncryptionUtil.class));
     }
 
     /**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java
index 5c1dcb4..a35c510 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java
@@ -28,6 +28,7 @@
 import com.android.internal.util.FastXmlSerializer;
 import com.android.server.wifi.WifiNetworkSuggestionsManager.ExtendedWifiNetworkSuggestion;
 import com.android.server.wifi.WifiNetworkSuggestionsManager.PerAppInfo;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -119,7 +120,7 @@
         final XmlSerializer out = new FastXmlSerializer();
         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         out.setOutput(outputStream, StandardCharsets.UTF_8.name());
-        mNetworkSuggestionStoreData.serializeData(out);
+        mNetworkSuggestionStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
         out.flush();
         return outputStream.toByteArray();
     }
@@ -131,7 +132,9 @@
         final XmlPullParser in = Xml.newPullParser();
         final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
         in.setInput(inputStream, StandardCharsets.UTF_8.name());
-        mNetworkSuggestionStoreData.deserializeData(in, in.getDepth());
+        mNetworkSuggestionStoreData.deserializeData(in, in.getDepth(),
+                WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+                mock(WifiConfigStoreEncryptionUtil.class));
     }
 
     /**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java
index 4df560f..cdd4e6c 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java
@@ -24,6 +24,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -62,7 +63,7 @@
         final XmlSerializer out = new FastXmlSerializer();
         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         out.setOutput(outputStream, StandardCharsets.UTF_8.name());
-        mRandomizedMacStoreData.serializeData(out);
+        mRandomizedMacStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
         out.flush();
         return outputStream.toByteArray();
     }
@@ -78,7 +79,9 @@
         final XmlPullParser in = Xml.newPullParser();
         final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
         in.setInput(inputStream, StandardCharsets.UTF_8.name());
-        mRandomizedMacStoreData.deserializeData(in, in.getDepth());
+        mRandomizedMacStoreData.deserializeData(in, in.getDepth(),
+                WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+                mock(WifiConfigStoreEncryptionUtil.class));
         return mRandomizedMacStoreData.getMacMapping();
     }
 
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java
index ac6ae21..feedc0d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -29,6 +30,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -80,7 +82,7 @@
         final XmlSerializer out = new FastXmlSerializer();
         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         out.setOutput(outputStream, StandardCharsets.UTF_8.name());
-        mSsidSetStoreData.serializeData(out);
+        mSsidSetStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
         out.flush();
         return outputStream.toByteArray();
     }
@@ -95,7 +97,9 @@
         final XmlPullParser in = Xml.newPullParser();
         final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
         in.setInput(inputStream, StandardCharsets.UTF_8.name());
-        mSsidSetStoreData.deserializeData(in, in.getDepth());
+        mSsidSetStoreData.deserializeData(in, in.getDepth(),
+                WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+                mock(WifiConfigStoreEncryptionUtil.class));
     }
 
     /**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java
index c814aef..df93eb4 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -28,6 +29,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 
 import com.google.android.collect.Sets;
 
@@ -74,7 +76,7 @@
         final XmlSerializer out = new FastXmlSerializer();
         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         out.setOutput(outputStream, StandardCharsets.UTF_8.name());
-        mWakeupConfigData.serializeData(out);
+        mWakeupConfigData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
         out.flush();
         return outputStream.toByteArray();
     }
@@ -88,7 +90,9 @@
         final XmlPullParser in = Xml.newPullParser();
         final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
         in.setInput(inputStream, StandardCharsets.UTF_8.name());
-        mWakeupConfigData.deserializeData(in, in.getDepth());
+        mWakeupConfigData.deserializeData(in, in.getDepth(),
+                WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+                mock(WifiConfigStoreEncryptionUtil.class));
     }
 
     /**
@@ -177,7 +181,9 @@
      */
     @Test
     public void hasBeenReadIsTrueWhenUserStoreIsLoaded() throws Exception {
-        mWakeupConfigData.deserializeData(null /* in */, 0 /* outerTagDepth */);
+        mWakeupConfigData.deserializeData(null /* in */, 0 /* outerTagDepth */,
+                WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+                mock(WifiConfigStoreEncryptionUtil.class));
         assertTrue(mWakeupConfigData.hasBeenRead());
     }
 
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
index 009429b..a004995 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -38,6 +39,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.server.wifi.util.ScanResultUtil;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -149,7 +151,9 @@
 
     private void readUserStore() {
         try {
-            mWakeupConfigStoreData.deserializeData(null, 0);
+            mWakeupConfigStoreData.deserializeData(null, 0,
+                    WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+                    mock(WifiConfigStoreEncryptionUtil.class));
         } catch (XmlPullParserException | IOException e) {
             // unreachable
         }
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
index b59e367..9c16b12 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
@@ -21,7 +21,6 @@
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 
-import android.app.test.MockAnswerUtil.AnswerWithArguments;
 import android.app.test.TestAlarmManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -34,8 +33,8 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.server.wifi.WifiConfigStore.StoreData;
 import com.android.server.wifi.WifiConfigStore.StoreFile;
-import com.android.server.wifi.util.DataIntegrityChecker;
 import com.android.server.wifi.util.EncryptedData;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 import com.android.server.wifi.util.XmlUtil;
 
 import libcore.util.HexEncoding;
@@ -43,7 +42,6 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.xmlpull.v1.XmlPullParser;
@@ -73,13 +71,7 @@
     private static final String TEST_DATA_XML_STRING_FORMAT =
             "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
                     + "<WifiConfigStoreData>\n"
-                    + "<int name=\"Version\" value=\"2\" />\n"
-                    + "<Integrity>\n"
-                    + "<byte-array name=\"EncryptedData\" num=\"48\">000000000000000000000000000000"
-                    + "000000000000000000000000000000000000000000000000000000000000000000"
-                    + "</byte-array>\n"
-                    + "<byte-array name=\"IV\" num=\"12\">000000000000000000000000</byte-array>\n"
-                    + "</Integrity>\n"
+                    + "<int name=\"Version\" value=\"3\" />\n"
                     + "<NetworkList>\n"
                     + "<Network>\n"
                     + "<WifiConfiguration>\n"
@@ -172,7 +164,7 @@
     private TestLooper mLooper;
     @Mock private Clock mClock;
     @Mock private WifiMetrics mWifiMetrics;
-    @Mock private DataIntegrityChecker mDataIntegrityChecker;
+    @Mock private WifiConfigStoreEncryptionUtil mEncryptionUtil;
     private MockStoreFile mSharedStore;
     private MockStoreFile mUserStore;
     private MockStoreFile mUserNetworkSuggestionsStore;
@@ -196,10 +188,10 @@
                 .thenReturn(mAlarmManager.getAlarmManager());
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mPackageManager.getNameForUid(anyInt())).thenReturn(TEST_CREATOR_NAME);
-        when(mDataIntegrityChecker.compute(any(byte[].class)))
+        when(mEncryptionUtil.encrypt(any(byte[].class)))
                 .thenReturn(ZEROED_ENCRYPTED_DATA);
-        when(mDataIntegrityChecker.isOk(any(byte[].class), any(EncryptedData.class)))
-                .thenReturn(true);
+        when(mEncryptionUtil.decrypt(any(EncryptedData.class)))
+                .thenReturn(new byte[0]);
         mSharedStore = new MockStoreFile(WifiConfigStore.STORE_FILE_SHARED_GENERAL);
         mUserStore = new MockStoreFile(WifiConfigStore.STORE_FILE_USER_GENERAL);
         mUserNetworkSuggestionsStore =
@@ -432,9 +424,9 @@
 
         // Ensure that we got the call to deserialize empty shared data, but no user data.
         verify(sharedStoreData).resetData();
-        verify(sharedStoreData).deserializeData(eq(null), anyInt());
+        verify(sharedStoreData).deserializeData(eq(null), anyInt(), anyInt(), any());
         verify(userStoreData, never()).resetData();
-        verify(userStoreData, never()).deserializeData(any(), anyInt());
+        verify(userStoreData, never()).deserializeData(any(), anyInt(), anyInt(), any());
     }
 
     /**
@@ -462,9 +454,9 @@
 
         // Ensure that we got the call to deserialize empty shared & user data.
         verify(userStoreData).resetData();
-        verify(userStoreData).deserializeData(eq(null), anyInt());
+        verify(userStoreData).deserializeData(eq(null), anyInt(), anyInt(), any());
         verify(sharedStoreData).resetData();
-        verify(sharedStoreData).deserializeData(eq(null), anyInt());
+        verify(sharedStoreData).deserializeData(eq(null), anyInt(), anyInt(), any());
     }
 
     /**
@@ -639,9 +631,9 @@
         mUserStore.storeRawDataToWrite(null);
 
         mWifiConfigStore.read();
-        verify(storeData1).deserializeData(notNull(), anyInt());
-        verify(storeData1, never()).deserializeData(eq(null), anyInt());
-        verify(storeData2).deserializeData(eq(null), anyInt());
+        verify(storeData1).deserializeData(notNull(), anyInt(), anyInt(), any());
+        verify(storeData1, never()).deserializeData(eq(null), anyInt(), anyInt(), any());
+        verify(storeData2).deserializeData(eq(null), anyInt(), anyInt(), any());
         reset(storeData1, storeData2);
 
         // Scenario 2: StoreData2 in user store file.
@@ -655,9 +647,9 @@
         mUserStore.storeRawDataToWrite(fileContentsXmlStringWithOnlyStoreData2.getBytes());
 
         mWifiConfigStore.read();
-        verify(storeData1).deserializeData(eq(null), anyInt());
-        verify(storeData2).deserializeData(notNull(), anyInt());
-        verify(storeData2, never()).deserializeData(eq(null), anyInt());
+        verify(storeData1).deserializeData(eq(null), anyInt(), anyInt(), any());
+        verify(storeData2).deserializeData(notNull(), anyInt(), anyInt(), any());
+        verify(storeData2, never()).deserializeData(eq(null), anyInt(), anyInt(), any());
         reset(storeData1, storeData2);
 
         // Scenario 3: StoreData1 in shared store file & StoreData2 in user store file.
@@ -671,10 +663,10 @@
         mUserStore.storeRawDataToWrite(fileContentsXmlStringWithOnlyStoreData2.getBytes());
 
         mWifiConfigStore.read();
-        verify(storeData1).deserializeData(notNull(), anyInt());
-        verify(storeData1, never()).deserializeData(eq(null), anyInt());
-        verify(storeData2).deserializeData(notNull(), anyInt());
-        verify(storeData2, never()).deserializeData(eq(null), anyInt());
+        verify(storeData1).deserializeData(notNull(), anyInt(), anyInt(), any());
+        verify(storeData1, never()).deserializeData(eq(null), anyInt(), anyInt(), any());
+        verify(storeData2).deserializeData(notNull(), anyInt(), anyInt(), any());
+        verify(storeData2, never()).deserializeData(eq(null), anyInt(), anyInt(), any());
         reset(storeData1, storeData2);
 
         // Scenario 4: StoreData1 & StoreData2 in shared store file.
@@ -689,10 +681,10 @@
         mUserStore.storeRawDataToWrite(null);
 
         mWifiConfigStore.read();
-        verify(storeData1).deserializeData(notNull(), anyInt());
-        verify(storeData1, never()).deserializeData(eq(null), anyInt());
-        verify(storeData2).deserializeData(notNull(), anyInt());
-        verify(storeData2, never()).deserializeData(eq(null), anyInt());
+        verify(storeData1).deserializeData(notNull(), anyInt(), anyInt(), any());
+        verify(storeData1, never()).deserializeData(eq(null), anyInt(), anyInt(), any());
+        verify(storeData2).deserializeData(notNull(), anyInt(), anyInt(), any());
+        verify(storeData2, never()).deserializeData(eq(null), anyInt(), anyInt(), any());
         reset(storeData1, storeData2);
     }
 
@@ -739,9 +731,9 @@
         verify(userStoreNetworkSuggestionsData).hasNewDataToSerialize();
 
         // Verify that we serialized data from the first 2 data source, but not from the last one.
-        verify(sharedStoreData).serializeData(any());
-        verify(userStoreData).serializeData(any());
-        verify(userStoreNetworkSuggestionsData, never()).serializeData(any());
+        verify(sharedStoreData).serializeData(any(), any());
+        verify(userStoreData).serializeData(any(), any());
+        verify(userStoreNetworkSuggestionsData, never()).serializeData(any(), any());
     }
 
     /**
@@ -815,188 +807,19 @@
         // Read and verify the data content in the store file (metadata stripped out) has been sent
         // to the corresponding store data when integrity check passes.
         mWifiConfigStore.read();
-        verify(sharedStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
-        verify(userStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
-
-        // We shouldn't perform any data integrity checks on version 1 file.
-        verifyZeroInteractions(mDataIntegrityChecker);
+        verify(sharedStoreData, times(1)).deserializeData(
+                any(XmlPullParser.class), anyInt(),
+                eq(WifiConfigStore.INITIAL_CONFIG_STORE_DATA_VERSION), any());
+        verify(userStoreData, times(1)).deserializeData(
+                any(XmlPullParser.class), anyInt(),
+                eq(WifiConfigStore.INITIAL_CONFIG_STORE_DATA_VERSION), any());
     }
 
     /**
-     * Tests the read API behaviour when integrity check fails.
-     * Expected behaviour: The read should return an empty store data.
+     * Tests the read API behaviour to ensure that the integrity data is parsed from the file.
      */
     @Test
-    public void testReadWhenIntegrityCheckFails() throws Exception {
-        // Register data container.
-        StoreData sharedStoreData = mock(StoreData.class);
-        when(sharedStoreData.getStoreFileId())
-                .thenReturn(WifiConfigStore.STORE_FILE_SHARED_GENERAL);
-        when(sharedStoreData.getName()).thenReturn(TEST_SHARE_DATA);
-        StoreData userStoreData = mock(StoreData.class);
-        when(userStoreData.getStoreFileId())
-                .thenReturn(WifiConfigStore.STORE_FILE_USER_GENERAL);
-        when(userStoreData.getName()).thenReturn(TEST_USER_DATA);
-        mWifiConfigStore.registerStoreData(sharedStoreData);
-        mWifiConfigStore.registerStoreData(userStoreData);
-
-        // Read both share and user config store.
-        mWifiConfigStore.setUserStores(mUserStores);
-
-        // Now store some content in the shared and user data files.
-        mUserStore.storeRawDataToWrite(
-                String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
-                        HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getEncryptedData()),
-                        HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getIv()),
-                        TEST_USER_DATA).getBytes());
-        mSharedStore.storeRawDataToWrite(
-                String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
-                        HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getEncryptedData()),
-                        HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getIv()),
-                        TEST_SHARE_DATA).getBytes());
-
-        // Read and verify the data content in the store file (metadata stripped out) has been sent
-        // to the corresponding store data when integrity check passes.
-        mWifiConfigStore.read();
-        verify(sharedStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
-        verify(userStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
-
-        // Read and verify the data content in the store file (metadata stripped out) has not been
-        // sent to the corresponding store data when integrity check fails.
-        when(mDataIntegrityChecker.isOk(any(byte[].class), any(EncryptedData.class)))
-                .thenReturn(false);
-        mWifiConfigStore.read();
-        verify(sharedStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
-        verify(userStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
-    }
-
-    /**
-     * Tests the write API behaviour when integrity check fails.
-     * Expected behaviour: The read should return an empty store data.
-     */
-    @Test
-    public void testWriteWhenIntegrityComputeFails() throws Exception {
-        // Register data container.
-        StoreData sharedStoreData = mock(StoreData.class);
-        when(sharedStoreData.getStoreFileId())
-                .thenReturn(WifiConfigStore.STORE_FILE_SHARED_GENERAL);
-        when(sharedStoreData.getName()).thenReturn(TEST_SHARE_DATA);
-        when(sharedStoreData.hasNewDataToSerialize()).thenReturn(true);
-        StoreData userStoreData = mock(StoreData.class);
-        when(userStoreData.getStoreFileId())
-                .thenReturn(WifiConfigStore.STORE_FILE_USER_GENERAL);
-        when(userStoreData.getName()).thenReturn(TEST_USER_DATA);
-        when(userStoreData.hasNewDataToSerialize()).thenReturn(true);
-        mWifiConfigStore.registerStoreData(sharedStoreData);
-        mWifiConfigStore.registerStoreData(userStoreData);
-
-        // Read both share and user config store.
-        mWifiConfigStore.setUserStores(mUserStores);
-
-        // Reset store file contents & ensure that the user and store data files are empty.
-        mUserStore.storeRawDataToWrite(null);
-        mSharedStore.storeRawDataToWrite(null);
-        assertNull(mUserStore.getStoreBytes());
-        assertNull(mSharedStore.getStoreBytes());
-
-        // Write and verify that the data is written to the config store file when integrity
-        // computation passes.
-        mWifiConfigStore.write(true);
-        assertNotNull(mUserStore.getStoreBytes());
-        assertNotNull(mSharedStore.getStoreBytes());
-        assertTrue(new String(mUserStore.getStoreBytes()).contains(TEST_USER_DATA));
-        assertTrue(new String(mSharedStore.getStoreBytes()).contains(TEST_SHARE_DATA));
-
-        // Reset store file contents & ensure that the user and store data files are empty.
-        mUserStore.storeRawDataToWrite(null);
-        mSharedStore.storeRawDataToWrite(null);
-        assertNull(mUserStore.getStoreBytes());
-        assertNull(mSharedStore.getStoreBytes());
-
-        // Write and verify that the data is not written to the config store file when integrity
-        // computation fails.
-        when(mDataIntegrityChecker.compute(any(byte[].class))).thenReturn(null);
-        mWifiConfigStore.write(true);
-        assertNull(mUserStore.getStoreBytes());
-        assertNull(mSharedStore.getStoreBytes());
-    }
-
-    /**
-     * Tests the write API behaviour to ensure that the integrity data is written to the file.
-     */
-    @Test
-    public void testWriteContainsIntegrityData() throws Exception {
-        byte[] encryptedData = new byte[EncryptedData.ENCRYPTED_DATA_LENGTH];
-        byte[] iv = new byte[EncryptedData.IV_LENGTH];
-        Random random = new Random();
-        random.nextBytes(encryptedData);
-        random.nextBytes(iv);
-        final EncryptedData testEncryptedData = new EncryptedData(encryptedData, iv);
-
-        doAnswer(new AnswerWithArguments() {
-            public EncryptedData answer(byte[] data) {
-                String storeXmlString = new String(data);
-                // Verify that we fill in zeros to the data when we compute integrity.
-                if (storeXmlString.contains(TEST_SHARE_DATA)) {
-                    assertEquals(String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
-                            HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getEncryptedData()),
-                            HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getIv()),
-                            TEST_SHARE_DATA), storeXmlString);
-                } else if (storeXmlString.contains(TEST_USER_DATA)) {
-                    assertEquals(String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
-                            HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getEncryptedData()),
-                            HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getIv()),
-                            TEST_USER_DATA), storeXmlString);
-                }
-                return testEncryptedData;
-            }
-        }).when(mDataIntegrityChecker).compute(any(byte[].class));
-
-        // Register data container.
-        StoreData sharedStoreData = mock(StoreData.class);
-        when(sharedStoreData.getStoreFileId())
-                .thenReturn(WifiConfigStore.STORE_FILE_SHARED_GENERAL);
-        when(sharedStoreData.getName()).thenReturn(TEST_SHARE_DATA);
-        when(sharedStoreData.hasNewDataToSerialize()).thenReturn(true);
-        StoreData userStoreData = mock(StoreData.class);
-        when(userStoreData.getStoreFileId())
-                .thenReturn(WifiConfigStore.STORE_FILE_USER_GENERAL);
-        when(userStoreData.getName()).thenReturn(TEST_USER_DATA);
-        when(userStoreData.hasNewDataToSerialize()).thenReturn(true);
-        mWifiConfigStore.registerStoreData(sharedStoreData);
-        mWifiConfigStore.registerStoreData(userStoreData);
-
-        // Read both share and user config store.
-        mWifiConfigStore.setUserStores(mUserStores);
-
-        // Write and verify that the data is written to the config store file when integrity
-        // computation passes.
-        mWifiConfigStore.write(true);
-
-        // Verify that we fill in zeros to the data when we computed integrity.
-        verify(mDataIntegrityChecker, times(2)).compute(any(byte[].class));
-
-        // Verify the parsed integrity data
-        assertNotNull(mUserStore.getStoreBytes());
-        assertNotNull(mSharedStore.getStoreBytes());
-        String userStoreXmlString = new String(mUserStore.getStoreBytes());
-        String sharedStoreXmlString = new String(mSharedStore.getStoreBytes());
-        assertEquals(String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
-                HexEncoding.encodeToString(encryptedData).toLowerCase(),
-                HexEncoding.encodeToString(iv).toLowerCase(),
-                TEST_USER_DATA), userStoreXmlString);
-        assertEquals(String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
-                HexEncoding.encodeToString(encryptedData).toLowerCase(),
-                HexEncoding.encodeToString(iv).toLowerCase(),
-                TEST_SHARE_DATA), sharedStoreXmlString);
-    }
-
-    /**
-     * Tests the read API behaviour to ensure that the integrity data is parsed from the file and
-     * used for checking integrity of the file.
-     */
-    @Test
-    public void testReadParsesIntegrityData() throws Exception {
+    public void testReadVersion2StoreFile() throws Exception {
         byte[] encryptedData = new byte[EncryptedData.ENCRYPTED_DATA_LENGTH];
         byte[] iv = new byte[EncryptedData.IV_LENGTH];
         Random random = new Random();
@@ -1033,40 +856,14 @@
                         TEST_SHARE_DATA).getBytes());
 
         // Read and verify the data content in the store file (metadata stripped out) has been sent
-        // to the corresponding store data when integrity check passes.
+        // to the corresponding store data.
         mWifiConfigStore.read();
-        verify(sharedStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
-        verify(userStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
-
-        // Verify that we parsed the integrity data and used it for checking integrity of the file.
-        ArgumentCaptor<EncryptedData> integrityCaptor =
-                ArgumentCaptor.forClass(EncryptedData.class);
-        ArgumentCaptor<byte[]> dataCaptor = ArgumentCaptor.forClass(byte[].class);
-        // Will be invoked twice for each file - shared & user store file.
-        verify(mDataIntegrityChecker, times(2)).isOk(
-                dataCaptor.capture(), integrityCaptor.capture());
-        // Verify the parsed integrity data
-        assertEquals(2, integrityCaptor.getAllValues().size());
-        EncryptedData parsedEncryptedData1 = integrityCaptor.getAllValues().get(0);
-        assertArrayEquals(encryptedData, parsedEncryptedData1.getEncryptedData());
-        assertArrayEquals(iv, parsedEncryptedData1.getIv());
-        EncryptedData parsedEncryptedData2 = integrityCaptor.getAllValues().get(1);
-        assertArrayEquals(encryptedData, parsedEncryptedData2.getEncryptedData());
-        assertArrayEquals(iv, parsedEncryptedData2.getIv());
-
-        // Verify that we fill in zeros to the data when we performed integrity checked.
-        assertEquals(2, dataCaptor.getAllValues().size());
-        String sharedStoreXmlStringWithZeroedIntegrity =
-                new String(dataCaptor.getAllValues().get(0));
-        assertEquals(String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
-                HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getEncryptedData()),
-                HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getIv()),
-                TEST_SHARE_DATA), sharedStoreXmlStringWithZeroedIntegrity);
-        String userStoreXmlStringWithZeroedIntegrity = new String(dataCaptor.getAllValues().get(1));
-        assertEquals(String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
-                HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getEncryptedData()),
-                HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getIv()),
-                TEST_USER_DATA), userStoreXmlStringWithZeroedIntegrity);
+        verify(sharedStoreData, times(1))
+                .deserializeData(any(XmlPullParser.class), anyInt(),
+                        eq(WifiConfigStore.INTEGRITY_CONFIG_STORE_DATA_VERSION), any());
+        verify(userStoreData, times(1))
+                .deserializeData(any(XmlPullParser.class), anyInt(),
+                        eq(WifiConfigStore.INTEGRITY_CONFIG_STORE_DATA_VERSION), any());
     }
 
     /**
@@ -1078,7 +875,7 @@
         private boolean mStoreWritten;
 
         MockStoreFile(@WifiConfigStore.StoreFileId int fileId) {
-            super(new File("MockStoreFile"), fileId, mDataIntegrityChecker);
+            super(new File("MockStoreFile"), fileId, mEncryptionUtil);
         }
 
         @Override
@@ -1129,13 +926,14 @@
         }
 
         @Override
-        public void serializeData(XmlSerializer out)
+        public void serializeData(XmlSerializer out, WifiConfigStoreEncryptionUtil encryptionUtil)
                 throws XmlPullParserException, IOException {
             XmlUtil.writeNextValue(out, XML_TAG_TEST_DATA, mData);
         }
 
         @Override
-        public void deserializeData(XmlPullParser in, int outerTagDepth)
+        public void deserializeData(XmlPullParser in, int outerTagDepth, int version,
+                WifiConfigStoreEncryptionUtil encryptionUtil)
                 throws XmlPullParserException, IOException {
             if (in == null) {
                 return;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
index 222c495..d20c99c 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
@@ -68,6 +68,7 @@
 import com.android.server.wifi.WifiNetworkFactory.AccessPoint;
 import com.android.server.wifi.nano.WifiMetricsProto;
 import com.android.server.wifi.util.ScanResultUtil;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 import com.android.server.wifi.util.WifiPermissionsUtil;
 
 import org.junit.After;
@@ -2932,7 +2933,7 @@
         final XmlSerializer out = new FastXmlSerializer();
         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         out.setOutput(outputStream, StandardCharsets.UTF_8.name());
-        mNetworkRequestStoreData.serializeData(out);
+        mNetworkRequestStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
         out.flush();
         return outputStream.toByteArray();
     }
@@ -2947,6 +2948,8 @@
         final XmlPullParser in = Xml.newPullParser();
         final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
         in.setInput(inputStream, StandardCharsets.UTF_8.name());
-        mNetworkRequestStoreData.deserializeData(in, in.getDepth());
+        mNetworkRequestStoreData.deserializeData(in, in.getDepth(),
+                WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+                mock(WifiConfigStoreEncryptionUtil.class));
     }
 }
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java
index c76e2c8..7a81500 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java
@@ -25,6 +25,7 @@
 
 import com.android.internal.util.FastXmlSerializer;
 import com.android.server.wifi.WifiConfigStore;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -62,7 +63,7 @@
         final XmlSerializer out = new FastXmlSerializer();
         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         out.setOutput(outputStream, StandardCharsets.UTF_8.name());
-        mConfigStoreData.serializeData(out);
+        mConfigStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
         out.flush();
         return outputStream.toByteArray();
     }
@@ -77,7 +78,9 @@
         final XmlPullParser in = Xml.newPullParser();
         final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
         in.setInput(inputStream, StandardCharsets.UTF_8.name());
-        mConfigStoreData.deserializeData(in, in.getDepth());
+        mConfigStoreData.deserializeData(in, in.getDepth(),
+                WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+                mock(WifiConfigStoreEncryptionUtil.class));
     }
 
     /**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
index 82cdb5a..5278e19 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
@@ -32,6 +32,7 @@
 import com.android.server.wifi.SIMAccessor;
 import com.android.server.wifi.WifiConfigStore;
 import com.android.server.wifi.WifiKeyStore;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -213,7 +214,7 @@
         final XmlSerializer out = new FastXmlSerializer();
         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         out.setOutput(outputStream, StandardCharsets.UTF_8.name());
-        mConfigStoreData.serializeData(out);
+        mConfigStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
         out.flush();
         return outputStream.toByteArray();
     }
@@ -228,7 +229,9 @@
         final XmlPullParser in = Xml.newPullParser();
         final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
         in.setInput(inputStream, StandardCharsets.UTF_8.name());
-        mConfigStoreData.deserializeData(in, in.getDepth());
+        mConfigStoreData.deserializeData(in, in.getDepth(),
+                WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+                mock(WifiConfigStoreEncryptionUtil.class));
     }
 
     /**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/DataIntegrityCheckerTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/DataIntegrityCheckerTest.java
deleted file mode 100644
index c281b64..0000000
--- a/service/tests/wifitests/src/com/android/server/wifi/util/DataIntegrityCheckerTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-package com.android.server.wifi.util;
-
-import static org.junit.Assert.*;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
-import java.io.File;
-
-/**
- * Unit tests for {@link com.android.server.wifi.util.DataIntegrityChecker}.
- */
-public class DataIntegrityCheckerTest {
-    private static byte[] sGoodData = {1, 2, 3, 4};
-    private static byte[] sBadData = {5, 6, 7, 8};
-
-    /**
-     * Verify that updating the integrity token with known data and alias will
-     * pass the integrity test. This test ensure the expected outcome for
-     * unedited data succeeds.
-     *
-     * @throws Exception
-     */
-    @Test
-    @Ignore
-    public void testIntegrityWithKnownDataAndKnownAlias() throws Exception {
-        File integrityFile = File.createTempFile("testIntegrityWithKnownDataAndKnownAlias",
-                ".tmp");
-        DataIntegrityChecker dataIntegrityChecker = new DataIntegrityChecker(
-                integrityFile.getParent());
-        EncryptedData encryptedData = dataIntegrityChecker.compute(sGoodData);
-        assertTrue(dataIntegrityChecker.isOk(sGoodData, encryptedData));
-    }
-
-    /**
-     * Verify that checking the integrity of unknown data and a known alias
-     * will fail the integrity test. This test ensure the expected failure for
-     * altered data, in fact, fails.
-     *
-     *
-     * @throws Exception
-     */
-    @Test
-    @Ignore
-    public void testIntegrityWithUnknownDataAndKnownAlias() throws Exception {
-        File integrityFile = File.createTempFile("testIntegrityWithUnknownDataAndKnownAlias",
-                ".tmp");
-        DataIntegrityChecker dataIntegrityChecker = new DataIntegrityChecker(
-                integrityFile.getParent());
-        EncryptedData encryptedData = dataIntegrityChecker.compute(sGoodData);
-        assertFalse(dataIntegrityChecker.isOk(sBadData, encryptedData));
-    }
-}