diff --git a/examples/lock-app/silabs/include/LockManager.h b/examples/lock-app/silabs/include/LockManager.h
index 671aedb81c4e56..1334a84fd29d7c 100644
--- a/examples/lock-app/silabs/include/LockManager.h
+++ b/examples/lock-app/silabs/include/LockManager.h
@@ -27,7 +27,9 @@
 #include <cmsis_os2.h>
 #include <lib/core/CHIPError.h>
 
-struct WeekDaysScheduleInfo
+#include <lib/support/DefaultStorageKeyAllocator.h>
+
+struct WeekDayScheduleInfo
 {
     DlScheduleStatus status;
     EmberAfPluginDoorLockWeekDaySchedule schedule;
@@ -112,6 +114,30 @@ class ParamBuilder
 using namespace ::chip;
 using namespace EFR32DoorLock::ResourceRanges;
 
+struct LockUserInfo
+{
+    char userName[DOOR_LOCK_USER_NAME_BUFFER_SIZE]; 
+    size_t userNameSize;
+    uint32_t userUniqueId; 
+    UserStatusEnum userStatus; 
+    UserTypeEnum userType;
+    CredentialRuleEnum credentialRule;
+    chip::EndpointId endpointId;
+    chip::FabricIndex createdBy;
+    chip::FabricIndex lastModifiedBy;
+    uint16_t currentCredentialCount;
+};
+
+struct LockCredentialInfo
+{
+    DlCredentialStatus status;
+    CredentialTypeEnum credentialType;
+    chip::FabricIndex createdBy;
+    chip::FabricIndex lastModifiedBy;
+    uint8_t credentialData[kMaxCredentialSize];
+    size_t credentialDataSize;
+};
+
 class LockManager
 {
 public:
@@ -192,8 +218,6 @@ class LockManager
                       OperationErrorEnum & err);
     const char * lockStateToString(DlLockState lockState) const;
 
-    bool ReadConfigValues();
-
     void UnlockAfterUnlatch();
 
 private:
@@ -244,17 +268,24 @@ class LockManager
     static void ActuatorMovementTimerEventHandler(AppEvent * aEvent);
 
     osTimerId_t mLockTimer;
-    EmberAfPluginDoorLockUserInfo mLockUsers[kMaxUsers];
-    EmberAfPluginDoorLockCredentialInfo mLockCredentials[kNumCredentialTypes][kMaxCredentials];
-    WeekDaysScheduleInfo mWeekdaySchedule[kMaxUsers][kMaxWeekdaySchedulesPerUser];
-    YearDayScheduleInfo mYeardaySchedule[kMaxUsers][kMaxYeardaySchedulesPerUser];
-    HolidayScheduleInfo mHolidaySchedule[kMaxHolidaySchedules];
-
-    char mUserNames[MATTER_ARRAY_SIZE(mLockUsers)][DOOR_LOCK_MAX_USER_NAME_SIZE];
-    uint8_t mCredentialData[kNumCredentialTypes][kMaxCredentials][kMaxCredentialSize];
-    CredentialStruct mCredentials[kMaxUsers][kMaxCredentials];
 
     EFR32DoorLock::LockInitParams::LockParam LockParams;
+
+    static StorageKeyName LockUserEndpoint(uint16_t userIndex, chip::EndpointId endpoint) { return StorageKeyName::Formatted("g/lu/%x/e/%x", userIndex, endpoint); }
+    static StorageKeyName LockCredentialEndpoint(uint16_t credentialIndex, chip::EndpointId endpoint) { return StorageKeyName::Formatted("g/lc/%x/e/%x", credentialIndex, endpoint); }
+    static StorageKeyName LockUserCredentialMap(uint16_t userIndex) { return StorageKeyName::Formatted("g/lu/%x/lc", userIndex); } // Stores all the credential indices that belong to a user    
+    static StorageKeyName LockUserWeekDayScheduleEndpoint(uint16_t userIndex, uint16_t scheduleIndex, chip::EndpointId endpoint) { return StorageKeyName::Formatted("g/lu/%x/lw/%x/e/%x", userIndex, scheduleIndex, endpoint); }
+    static StorageKeyName LockUserYearDayScheduleEndpoint(uint16_t userIndex, uint16_t scheduleIndex, chip::EndpointId endpoint) { return StorageKeyName::Formatted("g/lu/%x/ly/%x/e/%x", userIndex, scheduleIndex, endpoint); }
+    static StorageKeyName LockHolidayScheduleEndpoint(uint16_t scheduleIndex, chip::EndpointId endpoint) { return StorageKeyName::Formatted("g/lh/%x/e/%x", scheduleIndex, endpoint); }
+
+    LockUserInfo userInStorage;
+    LockCredentialInfo credentialInStorage;    
+    WeekDayScheduleInfo weekDayScheduleInStorage;
+    YearDayScheduleInfo yearDayScheduleInStorage;
+    HolidayScheduleInfo holidayScheduleInStorage;
+    CredentialStruct mCredential;
+    CredentialStruct mCredentials[kMaxCredentialsPerUser];
+
 };
 
 LockManager & LockMgr();
diff --git a/examples/lock-app/silabs/src/AppTask.cpp b/examples/lock-app/silabs/src/AppTask.cpp
index 3dd0a0ba7c9c69..78cac4b8eef312 100644
--- a/examples/lock-app/silabs/src/AppTask.cpp
+++ b/examples/lock-app/silabs/src/AppTask.cpp
@@ -37,9 +37,9 @@
 #include <app-common/zap-generated/cluster-objects.h>
 
 #include <app/clusters/door-lock-server/door-lock-server.h>
+#include <setup_payload/OnboardingCodesUtil.h>
 #include <app/server/Server.h>
 #include <app/util/attribute-storage.h>
-#include <setup_payload/OnboardingCodesUtil.h>
 
 #include <assert.h>
 
@@ -266,8 +266,6 @@ void AppTask::AppTaskMain(void * pvParameter)
 
     SILABS_LOG("App Task started");
 
-    // Users and credentials should be checked once from nvm flash on boot
-    LockMgr().ReadConfigValues();
 
     while (true)
     {
@@ -412,3 +410,4 @@ void AppTask::UpdateClusterState(intptr_t context)
         SILABS_LOG("ERR: updating lock state %x", to_underlying(status));
     }
 }
+ 
\ No newline at end of file
diff --git a/examples/lock-app/silabs/src/LockManager.cpp b/examples/lock-app/silabs/src/LockManager.cpp
index 66050da62a1bec..f2643ac13b5270 100644
--- a/examples/lock-app/silabs/src/LockManager.cpp
+++ b/examples/lock-app/silabs/src/LockManager.cpp
@@ -21,10 +21,12 @@
 
 #include "AppConfig.h"
 #include "AppTask.h"
+#include <app/server/Server.h>
 #include <app-common/zap-generated/attributes/Accessors.h>
 #include <cstring>
 #include <lib/support/logging/CHIPLogging.h>
 
+using chip::app::DataModel::MakeNullable;
 using namespace ::chip::DeviceLayer::Internal;
 using namespace EFR32DoorLock::LockInitParams;
 
@@ -136,41 +138,6 @@ bool LockManager::IsValidHolidayScheduleIndex(uint8_t scheduleIndex)
     return (scheduleIndex < kMaxHolidaySchedules);
 }
 
-bool LockManager::ReadConfigValues()
-{
-    size_t outLen;
-    SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_LockUser, reinterpret_cast<uint8_t *>(&mLockUsers),
-                                     sizeof(EmberAfPluginDoorLockUserInfo) * MATTER_ARRAY_SIZE(mLockUsers), outLen);
-
-    SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_Credential, reinterpret_cast<uint8_t *>(&mLockCredentials),
-                                     sizeof(EmberAfPluginDoorLockCredentialInfo) * kMaxCredentials * kNumCredentialTypes, outLen);
-
-    SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_LockUserName, reinterpret_cast<uint8_t *>(mUserNames),
-                                     sizeof(mUserNames), outLen);
-
-    SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_CredentialData, reinterpret_cast<uint8_t *>(mCredentialData),
-                                     sizeof(mCredentialData), outLen);
-
-    SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_UserCredentials, reinterpret_cast<uint8_t *>(mCredentials),
-                                     sizeof(CredentialStruct) * LockParams.numberOfUsers * LockParams.numberOfCredentialsPerUser,
-                                     outLen);
-
-    SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_WeekDaySchedules, reinterpret_cast<uint8_t *>(mWeekdaySchedule),
-                                     sizeof(EmberAfPluginDoorLockWeekDaySchedule) * LockParams.numberOfWeekdaySchedulesPerUser *
-                                         LockParams.numberOfUsers,
-                                     outLen);
-
-    SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_YearDaySchedules, reinterpret_cast<uint8_t *>(mYeardaySchedule),
-                                     sizeof(EmberAfPluginDoorLockYearDaySchedule) * LockParams.numberOfYeardaySchedulesPerUser *
-                                         LockParams.numberOfUsers,
-                                     outLen);
-
-    SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_HolidaySchedules, reinterpret_cast<uint8_t *>(&(mHolidaySchedule)),
-                                     sizeof(EmberAfPluginDoorLockHolidaySchedule) * LockParams.numberOfHolidaySchedules, outLen);
-
-    return true;
-}
-
 void LockManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB)
 {
     mActionInitiated_CB = aActionInitiated_CB;
@@ -353,6 +320,8 @@ bool LockManager::Unbolt(chip::EndpointId endpointId, const Nullable<chip::Fabri
 
 bool LockManager::GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user)
 {
+    CHIP_ERROR error;
+
     VerifyOrReturnValue(userIndex > 0, false); // indices are one-indexed
 
     userIndex--;
@@ -361,26 +330,70 @@ bool LockManager::GetUser(chip::EndpointId endpointId, uint16_t userIndex, Ember
 
     ChipLogProgress(Zcl, "Door Lock App: LockManager::GetUser [endpoint=%d,userIndex=%hu]", endpointId, userIndex);
 
-    const auto & userInDb = mLockUsers[userIndex];
+    chip::StorageKeyName userKey = LockUserEndpoint(userIndex, endpointId);
+
+    uint16_t size  = static_cast<uint16_t>(sizeof(LockUserInfo));
 
-    user.userStatus = userInDb.userStatus;
-    if (UserStatusEnum::kAvailable == user.userStatus)
+    error = chip::Server::GetInstance().GetPersistentStorage().SyncGetKeyValue(userKey.KeyName(), &userInStorage, size);
+    // If no data is found at user key
+    if(error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
     {
-        ChipLogDetail(Zcl, "Found unoccupied user [endpoint=%d]", endpointId);
+        user.userStatus = UserStatusEnum::kAvailable;
+
+        ChipLogError(Zcl, "No user data found");
         return true;
     }
+    // Else if KVS read was successful
+    else if(error == CHIP_NO_ERROR)
+    {
+        user.userStatus = userInStorage.userStatus;
 
-    user.userName       = chip::CharSpan(userInDb.userName.data(), userInDb.userName.size());
-    user.credentials    = chip::Span<const CredentialStruct>(mCredentials[userIndex], userInDb.credentials.size());
-    user.userUniqueId   = userInDb.userUniqueId;
-    user.userType       = userInDb.userType;
-    user.credentialRule = userInDb.credentialRule;
+        if(userInStorage.userStatus == UserStatusEnum::kAvailable)
+        {
+            ChipLogDetail(Zcl, "Found unoccupied user [endpoint=%d]", endpointId);
+            return true;
+        }
+
+    }
+    else
+    {
+        ChipLogError(Zcl, "Error reading from KVS key");
+        return false;
+    }
+
+    user.userName       = chip::CharSpan(userInStorage.userName, userInStorage.userNameSize);
+    user.userUniqueId   = userInStorage.userUniqueId;
+    user.userType       = userInStorage.userType;
+    user.credentialRule = userInStorage.credentialRule;
     // So far there's no way to actually create the credential outside Matter, so here we always set the creation/modification
     // source to Matter
     user.creationSource     = DlAssetSource::kMatterIM;
-    user.createdBy          = userInDb.createdBy;
+    user.createdBy          = userInStorage.createdBy;
     user.modificationSource = DlAssetSource::kMatterIM;
-    user.lastModifiedBy     = userInDb.lastModifiedBy;
+    user.lastModifiedBy     = userInStorage.lastModifiedBy;
+    
+    // Get credential struct from nvm3
+    chip::StorageKeyName credentialKey = LockUserCredentialMap(userIndex);
+
+    uint16_t credentialSize = static_cast<uint16_t>(sizeof(CredentialStruct)*userInStorage.currentCredentialCount);
+
+    error = chip::Server::GetInstance().GetPersistentStorage().SyncGetKeyValue(credentialKey.KeyName(), &mCredential, credentialSize);
+
+    // If no data is found at credential key
+    if(error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
+    {
+        // No credentials found for this user
+    }
+    // Else if KVS read was successful
+    else if(error == CHIP_NO_ERROR)
+    {
+        user.credentials = chip::Span<const CredentialStruct> {&mCredential, userInStorage.currentCredentialCount};
+    }
+    else
+    {
+        ChipLogError(Zcl, "Error reading KVS key");
+        return false;        
+    }
 
     ChipLogDetail(Zcl,
                   "Found occupied user "
@@ -397,6 +410,9 @@ bool LockManager::SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip:
                           const chip::CharSpan & userName, uint32_t uniqueId, UserStatusEnum userStatus, UserTypeEnum usertype,
                           CredentialRuleEnum credentialRule, const CredentialStruct * credentials, size_t totalCredentials)
 {
+
+    CHIP_ERROR error;
+
     ChipLogProgress(Zcl,
                     "Door Lock App: LockManager::SetUser "
                     "[endpoint=%d,userIndex=%d,creator=%d,modifier=%d,userName=%s,uniqueId=%ld "
@@ -409,8 +425,8 @@ bool LockManager::SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip:
     userIndex--;
 
     VerifyOrReturnValue(IsValidUserIndex(userIndex), false);
-
-    auto & userInStorage = mLockUsers[userIndex];
+    
+    VerifyOrReturnValue(kInvalidEndpointId != endpointId, false);
 
     if (userName.size() > DOOR_LOCK_MAX_USER_NAME_SIZE)
     {
@@ -425,8 +441,8 @@ bool LockManager::SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip:
         return false;
     }
 
-    chip::Platform::CopyString(mUserNames[userIndex], userName);
-    userInStorage.userName       = chip::CharSpan(mUserNames[userIndex], userName.size());
+    chip::Platform::CopyString(userInStorage.userName, userName.data());
+    userInStorage.userNameSize   = userName.size();
     userInStorage.userUniqueId   = uniqueId;
     userInStorage.userStatus     = userStatus;
     userInStorage.userType       = usertype;
@@ -434,22 +450,29 @@ bool LockManager::SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip:
     userInStorage.lastModifiedBy = modifier;
     userInStorage.createdBy      = creator;
 
-    for (size_t i = 0; i < totalCredentials; ++i)
-    {
-        mCredentials[userIndex][i] = credentials[i];
-    }
+    userInStorage.currentCredentialCount = totalCredentials;
 
-    userInStorage.credentials = chip::Span<const CredentialStruct>(mCredentials[userIndex], totalCredentials);
+    // Save credential struct in nvm3
+    chip::StorageKeyName credentialKey = LockUserCredentialMap(userIndex);
 
-    // Save user information in NVM flash
-    SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_LockUser, reinterpret_cast<const uint8_t *>(&mLockUsers),
-                                      sizeof(EmberAfPluginDoorLockUserInfo) * LockParams.numberOfUsers);
+    error = chip::Server::GetInstance().GetPersistentStorage().SyncSetKeyValue(credentialKey.KeyName(), credentials, static_cast<uint16_t>(sizeof(CredentialStruct)*totalCredentials));
+
+    if((error != CHIP_NO_ERROR))
+    {
+        ChipLogError(Zcl, "Error reading from KVS key");
+        return false;     
+    }
+    
+    // Save user in nvm3
+    chip::StorageKeyName userKey = LockUserEndpoint(userIndex, endpointId);
 
-    SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_UserCredentials, reinterpret_cast<const uint8_t *>(mCredentials),
-                                      sizeof(CredentialStruct) * LockParams.numberOfUsers * LockParams.numberOfCredentialsPerUser);
+    error = chip::Server::GetInstance().GetPersistentStorage().SyncSetKeyValue(userKey.KeyName(), &userInStorage, static_cast<uint16_t>(sizeof(LockUserInfo)));
 
-    SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_LockUserName, reinterpret_cast<const uint8_t *>(mUserNames),
-                                      sizeof(mUserNames));
+    if((error != CHIP_NO_ERROR))
+    {
+        ChipLogError(Zcl, "Error reading from KVS key");
+        return false;     
+    }    
 
     ChipLogProgress(Zcl, "Successfully set the user [mEndpointId=%d,index=%d]", endpointId, userIndex);
 
@@ -459,6 +482,7 @@ bool LockManager::SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip:
 bool LockManager::GetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, CredentialTypeEnum credentialType,
                                 EmberAfPluginDoorLockCredentialInfo & credential)
 {
+    CHIP_ERROR error;
 
     VerifyOrReturnValue(IsValidCredentialType(credentialType), false);
 
@@ -475,10 +499,32 @@ bool LockManager::GetCredential(chip::EndpointId endpointId, uint16_t credential
     ChipLogProgress(Zcl, "Lock App: LockManager::GetCredential [credentialType=%u], credentialIndex=%d",
                     to_underlying(credentialType), credentialIndex);
 
-    const auto & credentialInStorage = mLockCredentials[to_underlying(credentialType)][credentialIndex];
+    uint16_t size  = static_cast<uint16_t>(sizeof(LockCredentialInfo));
 
-    credential.status = credentialInStorage.status;
-    ChipLogDetail(Zcl, "CredentialStatus: %d, CredentialIndex: %d ", (int) credential.status, credentialIndex);
+    chip::StorageKeyName key = LockCredentialEndpoint(credentialIndex, endpointId);
+
+    error = chip::Server::GetInstance().GetPersistentStorage().SyncGetKeyValue(key.KeyName(), &credentialInStorage, size);
+
+    // If no data is found at credential key
+    if(error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
+    {
+        // No credentials found
+        credential.status = DlCredentialStatus::kAvailable;
+
+        return true;
+    }
+    // Else if KVS read was successful
+    else if(error == CHIP_NO_ERROR)
+    {
+        credential.status = credentialInStorage.status;
+        ChipLogDetail(Zcl, "CredentialStatus: %d, CredentialIndex: %d ", (int) credential.status, credentialIndex);
+
+    }
+    else
+    {
+        ChipLogError(Zcl, "Error reading KVS key");
+        return false;        
+    }
 
     if (DlCredentialStatus::kAvailable == credential.status)
     {
@@ -486,7 +532,7 @@ bool LockManager::GetCredential(chip::EndpointId endpointId, uint16_t credential
         return true;
     }
     credential.credentialType = credentialInStorage.credentialType;
-    credential.credentialData = credentialInStorage.credentialData;
+    credential.credentialData = chip::ByteSpan{ credentialInStorage.credentialData, credentialInStorage.credentialDataSize };
     credential.createdBy      = credentialInStorage.createdBy;
     credential.lastModifiedBy = credentialInStorage.lastModifiedBy;
     // So far there's no way to actually create the credential outside Matter, so here we always set the creation/modification
@@ -504,6 +550,7 @@ bool LockManager::SetCredential(chip::EndpointId endpointId, uint16_t credential
                                 chip::FabricIndex modifier, DlCredentialStatus credentialStatus, CredentialTypeEnum credentialType,
                                 const chip::ByteSpan & credentialData)
 {
+    CHIP_ERROR error;
 
     VerifyOrReturnValue(IsValidCredentialType(credentialType), false);
 
@@ -522,23 +569,29 @@ bool LockManager::SetCredential(chip::EndpointId endpointId, uint16_t credential
                     "[credentialStatus=%u,credentialType=%u,credentialDataSize=%u,creator=%d,modifier=%d]",
                     to_underlying(credentialStatus), to_underlying(credentialType), credentialData.size(), creator, modifier);
 
-    auto & credentialInStorage = mLockCredentials[to_underlying(credentialType)][credentialIndex];
-
     credentialInStorage.status         = credentialStatus;
     credentialInStorage.credentialType = credentialType;
     credentialInStorage.createdBy      = creator;
     credentialInStorage.lastModifiedBy = modifier;
+    credentialInStorage.credentialDataSize = credentialData.size();
 
-    memcpy(mCredentialData[to_underlying(credentialType)][credentialIndex], credentialData.data(), credentialData.size());
-    credentialInStorage.credentialData =
-        chip::ByteSpan{ mCredentialData[to_underlying(credentialType)][credentialIndex], credentialData.size() };
+    memcpy(credentialInStorage.credentialData, credentialData.data(), credentialInStorage.credentialDataSize);
 
-    // Save credential information in NVM flash
-    SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_Credential, reinterpret_cast<const uint8_t *>(&mLockCredentials),
-                                      sizeof(EmberAfPluginDoorLockCredentialInfo) * kMaxCredentials * kNumCredentialTypes);
+    chip::StorageKeyName key = LockCredentialEndpoint(credentialIndex, endpointId);
 
-    SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_CredentialData, reinterpret_cast<const uint8_t *>(&mCredentialData),
-                                      sizeof(mCredentialData));
+    if((error != CHIP_NO_ERROR))
+    {
+        ChipLogError(Zcl, "Error reading from KVS key");
+        return false;     
+    }
+
+    chip::Server::GetInstance().GetPersistentStorage().SyncSetKeyValue(key.KeyName(), &credentialInStorage, static_cast<uint16_t>(sizeof(LockCredentialInfo)));
+
+    if((error != CHIP_NO_ERROR))
+    {
+        ChipLogError(Zcl, "Error reading from KVS key");
+        return false;     
+    }
 
     ChipLogProgress(Zcl, "Successfully set the credential [credentialType=%u]", to_underlying(credentialType));
 
@@ -548,6 +601,7 @@ bool LockManager::SetCredential(chip::EndpointId endpointId, uint16_t credential
 DlStatus LockManager::GetWeekdaySchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
                                          EmberAfPluginDoorLockWeekDaySchedule & schedule)
 {
+    CHIP_ERROR error;
 
     VerifyOrReturnValue(weekdayIndex > 0, DlStatus::kFailure); // indices are one-indexed
     VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure);    // indices are one-indexed
@@ -558,13 +612,36 @@ DlStatus LockManager::GetWeekdaySchedule(chip::EndpointId endpointId, uint8_t we
     VerifyOrReturnValue(IsValidWeekdayScheduleIndex(weekdayIndex), DlStatus::kFailure);
     VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure);
 
-    const auto & scheduleInStorage = mWeekdaySchedule[userIndex][weekdayIndex];
-    if (DlScheduleStatus::kAvailable == scheduleInStorage.status)
+    // Get schedule data from nvm3
+    chip::StorageKeyName scheduleDataKey = LockUserWeekDayScheduleEndpoint(userIndex, weekdayIndex, endpointId);
+
+    uint16_t scheduleSize = static_cast<uint16_t>(sizeof(WeekDayScheduleInfo));
+
+    error = chip::Server::GetInstance().GetPersistentStorage().SyncGetKeyValue(scheduleDataKey.KeyName(), &weekDayScheduleInStorage, scheduleSize);
+
+    // If no data is found at scheduleUserMapKey key
+    if(error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
     {
+        ChipLogError(Zcl, "No schedule data found for user");
         return DlStatus::kNotFound;
     }
+    // Else if KVS read was successful
+    else if(error == CHIP_NO_ERROR)
+    {
+
+        if (weekDayScheduleInStorage.status == DlScheduleStatus::kAvailable)
+        {
+            return DlStatus::kNotFound;
+        }
+    
+    }
+    else
+    {
+        ChipLogError(Zcl, "Error reading from KVS key");
+        return DlStatus::kFailure;
+    }
 
-    schedule = scheduleInStorage.schedule;
+    schedule = weekDayScheduleInStorage.schedule;
 
     return DlStatus::kSuccess;
 }
@@ -573,6 +650,7 @@ DlStatus LockManager::SetWeekdaySchedule(chip::EndpointId endpointId, uint8_t we
                                          DlScheduleStatus status, DaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute,
                                          uint8_t endHour, uint8_t endMinute)
 {
+    CHIP_ERROR error;
 
     VerifyOrReturnValue(weekdayIndex > 0, DlStatus::kFailure); // indices are one-indexed
     VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure);    // indices are one-indexed
@@ -583,19 +661,23 @@ DlStatus LockManager::SetWeekdaySchedule(chip::EndpointId endpointId, uint8_t we
     VerifyOrReturnValue(IsValidWeekdayScheduleIndex(weekdayIndex), DlStatus::kFailure);
     VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure);
 
-    auto & scheduleInStorage = mWeekdaySchedule[userIndex][weekdayIndex];
+    weekDayScheduleInStorage.schedule.daysMask    = daysMask;
+    weekDayScheduleInStorage.schedule.startHour   = startHour;
+    weekDayScheduleInStorage.schedule.startMinute = startMinute;
+    weekDayScheduleInStorage.schedule.endHour     = endHour;
+    weekDayScheduleInStorage.schedule.endMinute   = endMinute;
+    weekDayScheduleInStorage.status               = status;
+
+    // Save schedule data in nvm3
+    chip::StorageKeyName scheduleDataKey = LockUserWeekDayScheduleEndpoint(userIndex, weekdayIndex, endpointId);
 
-    scheduleInStorage.schedule.daysMask    = daysMask;
-    scheduleInStorage.schedule.startHour   = startHour;
-    scheduleInStorage.schedule.startMinute = startMinute;
-    scheduleInStorage.schedule.endHour     = endHour;
-    scheduleInStorage.schedule.endMinute   = endMinute;
-    scheduleInStorage.status               = status;
+    error = chip::Server::GetInstance().GetPersistentStorage().SyncSetKeyValue(scheduleDataKey.KeyName(), &weekDayScheduleInStorage, static_cast<uint16_t>(sizeof(WeekDayScheduleInfo)));
 
-    // Save schedule information in NVM flash
-    SilabsConfig::WriteConfigValueBin(
-        SilabsConfig::kConfigKey_WeekDaySchedules, reinterpret_cast<const uint8_t *>(mWeekdaySchedule),
-        sizeof(EmberAfPluginDoorLockWeekDaySchedule) * LockParams.numberOfWeekdaySchedulesPerUser * LockParams.numberOfUsers);
+    if((error != CHIP_NO_ERROR))
+    {
+        ChipLogError(Zcl, "Error reading from KVS key");
+        return DlStatus::kFailure;     
+    }  
 
     return DlStatus::kSuccess;
 }
@@ -603,6 +685,8 @@ DlStatus LockManager::SetWeekdaySchedule(chip::EndpointId endpointId, uint8_t we
 DlStatus LockManager::GetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
                                          EmberAfPluginDoorLockYearDaySchedule & schedule)
 {
+    CHIP_ERROR error;
+
     VerifyOrReturnValue(yearDayIndex > 0, DlStatus::kFailure); // indices are one-indexed
     VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure);    // indices are one-indexed
 
@@ -612,13 +696,36 @@ DlStatus LockManager::GetYeardaySchedule(chip::EndpointId endpointId, uint8_t ye
     VerifyOrReturnValue(IsValidYeardayScheduleIndex(yearDayIndex), DlStatus::kFailure);
     VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure);
 
-    const auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex];
-    if (DlScheduleStatus::kAvailable == scheduleInStorage.status)
+    // Get schedule data from nvm3
+    chip::StorageKeyName scheduleDataKey = LockUserYearDayScheduleEndpoint(userIndex, yearDayIndex, endpointId);
+
+    uint16_t scheduleSize = static_cast<uint16_t>(sizeof(YearDayScheduleInfo));
+
+    error = chip::Server::GetInstance().GetPersistentStorage().SyncGetKeyValue(scheduleDataKey.KeyName(), &yearDayScheduleInStorage, scheduleSize);
+
+    // If no data is found at scheduleUserMapKey key
+    if(error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
     {
+        ChipLogError(Zcl, "No schedule data found for user");
         return DlStatus::kNotFound;
     }
+    // Else if KVS read was successful
+    else if(error == CHIP_NO_ERROR)
+    {
 
-    schedule = scheduleInStorage.schedule;
+        if (yearDayScheduleInStorage.status == DlScheduleStatus::kAvailable)
+        {
+            return DlStatus::kNotFound;
+        }
+    
+    }
+    else
+    {
+        ChipLogError(Zcl, "Error reading from KVS key");
+        return DlStatus::kFailure;
+    }
+
+    schedule = yearDayScheduleInStorage.schedule;
 
     return DlStatus::kSuccess;
 }
@@ -626,6 +733,8 @@ DlStatus LockManager::GetYeardaySchedule(chip::EndpointId endpointId, uint8_t ye
 DlStatus LockManager::SetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
                                          DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime)
 {
+    CHIP_ERROR error;
+
     VerifyOrReturnValue(yearDayIndex > 0, DlStatus::kFailure); // indices are one-indexed
     VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure);    // indices are one-indexed
 
@@ -635,16 +744,20 @@ DlStatus LockManager::SetYeardaySchedule(chip::EndpointId endpointId, uint8_t ye
     VerifyOrReturnValue(IsValidYeardayScheduleIndex(yearDayIndex), DlStatus::kFailure);
     VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure);
 
-    auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex];
+    yearDayScheduleInStorage.schedule.localStartTime = localStartTime;
+    yearDayScheduleInStorage.schedule.localEndTime   = localEndTime;
+    yearDayScheduleInStorage.status                  = status;
 
-    scheduleInStorage.schedule.localStartTime = localStartTime;
-    scheduleInStorage.schedule.localEndTime   = localEndTime;
-    scheduleInStorage.status                  = status;
+    // Save schedule data in nvm3
+    chip::StorageKeyName scheduleDataKey = LockUserYearDayScheduleEndpoint(userIndex, yearDayIndex, endpointId);
 
-    // Save schedule information in NVM flash
-    SilabsConfig::WriteConfigValueBin(
-        SilabsConfig::kConfigKey_YearDaySchedules, reinterpret_cast<const uint8_t *>(mYeardaySchedule),
-        sizeof(EmberAfPluginDoorLockYearDaySchedule) * LockParams.numberOfYeardaySchedulesPerUser * LockParams.numberOfUsers);
+    error = chip::Server::GetInstance().GetPersistentStorage().SyncSetKeyValue(scheduleDataKey.KeyName(), &yearDayScheduleInStorage, static_cast<uint16_t>(sizeof(YearDayScheduleInfo)));
+
+    if((error != CHIP_NO_ERROR))
+    {
+        ChipLogError(Zcl, "Error reading from KVS key");
+        return DlStatus::kFailure;     
+    } 
 
     return DlStatus::kSuccess;
 }
@@ -652,19 +765,44 @@ DlStatus LockManager::SetYeardaySchedule(chip::EndpointId endpointId, uint8_t ye
 DlStatus LockManager::GetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex,
                                          EmberAfPluginDoorLockHolidaySchedule & schedule)
 {
+    CHIP_ERROR error;
+
     VerifyOrReturnValue(holidayIndex > 0, DlStatus::kFailure); // indices are one-indexed
 
     holidayIndex--;
 
     VerifyOrReturnValue(IsValidHolidayScheduleIndex(holidayIndex), DlStatus::kFailure);
 
-    const auto & scheduleInStorage = mHolidaySchedule[holidayIndex];
-    if (DlScheduleStatus::kAvailable == scheduleInStorage.status)
+    // Get schedule data from nvm3
+    chip::StorageKeyName scheduleDataKey = LockHolidayScheduleEndpoint(holidayIndex, endpointId);
+
+    uint16_t scheduleSize = static_cast<uint16_t>(sizeof(HolidayScheduleInfo));
+
+    error = chip::Server::GetInstance().GetPersistentStorage().SyncGetKeyValue(scheduleDataKey.KeyName(), &holidayScheduleInStorage, scheduleSize);
+
+    // If no data is found at scheduleUserMapKey key
+    if(error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
     {
+        ChipLogError(Zcl, "No schedule data found for user");
         return DlStatus::kNotFound;
     }
+    // Else if KVS read was successful
+    else if(error == CHIP_NO_ERROR)
+    {
 
-    schedule = scheduleInStorage.schedule;
+        if (holidayScheduleInStorage.status == DlScheduleStatus::kAvailable)
+        {
+            return DlStatus::kNotFound;
+        }
+    
+    }
+    else
+    {
+        ChipLogError(Zcl, "Error reading from KVS key");
+        return DlStatus::kFailure;
+    }
+
+    schedule = holidayScheduleInStorage.schedule;
 
     return DlStatus::kSuccess;
 }
@@ -672,23 +810,29 @@ DlStatus LockManager::GetHolidaySchedule(chip::EndpointId endpointId, uint8_t ho
 DlStatus LockManager::SetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status,
                                          uint32_t localStartTime, uint32_t localEndTime, OperatingModeEnum operatingMode)
 {
+    CHIP_ERROR error;
+
     VerifyOrReturnValue(holidayIndex > 0, DlStatus::kFailure); // indices are one-indexed
 
     holidayIndex--;
 
     VerifyOrReturnValue(IsValidHolidayScheduleIndex(holidayIndex), DlStatus::kFailure);
 
-    auto & scheduleInStorage = mHolidaySchedule[holidayIndex];
+    holidayScheduleInStorage.schedule.localStartTime = localStartTime;
+    holidayScheduleInStorage.schedule.localEndTime   = localEndTime;
+    holidayScheduleInStorage.schedule.operatingMode  = operatingMode;
+    holidayScheduleInStorage.status                  = status;
 
-    scheduleInStorage.schedule.localStartTime = localStartTime;
-    scheduleInStorage.schedule.localEndTime   = localEndTime;
-    scheduleInStorage.schedule.operatingMode  = operatingMode;
-    scheduleInStorage.status                  = status;
+    // Save schedule data in nvm3
+    chip::StorageKeyName scheduleDataKey = LockHolidayScheduleEndpoint(holidayIndex, endpointId);
 
-    // Save schedule information in NVM flash
-    SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_HolidaySchedules,
-                                      reinterpret_cast<const uint8_t *>(&(mHolidaySchedule)),
-                                      sizeof(EmberAfPluginDoorLockHolidaySchedule) * LockParams.numberOfHolidaySchedules);
+    error = chip::Server::GetInstance().GetPersistentStorage().SyncSetKeyValue(scheduleDataKey.KeyName(), &holidayScheduleInStorage, static_cast<uint16_t>(sizeof(HolidayScheduleInfo)));
+
+    if((error != CHIP_NO_ERROR))
+    {
+        ChipLogError(Zcl, "Error reading from KVS key");
+        return DlStatus::kFailure;     
+    } 
 
     return DlStatus::kSuccess;
 }
@@ -717,6 +861,8 @@ bool LockManager::setLockState(chip::EndpointId endpointId, const Nullable<chip:
                                OperationErrorEnum & err)
 {
 
+    CHIP_ERROR error;
+
     // Assume pin is required until told otherwise
     bool requirePin = true;
     chip::app::Clusters::DoorLock::Attributes::RequirePINforRemoteOperation::Get(endpointId, &requirePin);
@@ -743,25 +889,77 @@ bool LockManager::setLockState(chip::EndpointId endpointId, const Nullable<chip:
         return false;
     }
 
-    // Check the PIN code
-    for (const auto & currentCredential : mLockCredentials[to_underlying(CredentialTypeEnum::kPin)])
+    // Check all pin codes associated to all users to see if this pin code exists
+    for(int userIndex = 0; userIndex < kMaxUsers; userIndex++)
     {
+        // Get user data to obtain currentCredentialCount
+        chip::StorageKeyName userKey = LockUserEndpoint(userIndex, endpointId);
 
-        if (currentCredential.status == DlCredentialStatus::kAvailable)
-        {
+        uint16_t size  = static_cast<uint16_t>(sizeof(LockUserInfo));
+
+        error = chip::Server::GetInstance().GetPersistentStorage().SyncGetKeyValue(userKey.KeyName(), &userInStorage, size);
+
+        // No user exists at this index
+        if(error != CHIP_NO_ERROR)
+        {            
             continue;
         }
 
-        if (currentCredential.credentialData.data_equal(pin.Value()))
-        {
-            ChipLogDetail(Zcl,
-                          "Lock App: specified PIN code was found in the database, setting lock state to \"%s\" [endpointId=%d]",
-                          lockStateToString(lockState), endpointId);
+        chip::StorageKeyName credentialKey = LockUserCredentialMap(userIndex);
 
-            DoorLockServer::Instance().SetLockState(endpointId, lockState, OperationSourceEnum::kRemote, NullNullable, NullNullable,
-                                                    fabricIdx, nodeId);
+        uint16_t credentialSize = static_cast<uint16_t>(sizeof(CredentialStruct)*userInStorage.currentCredentialCount);
 
-            return true;
+        // Get array of credential indices and types associated to user
+        error = chip::Server::GetInstance().GetPersistentStorage().SyncGetKeyValue(credentialKey.KeyName(), &mCredentials, credentialSize);
+
+        // No credential data associated with user
+        if(error != CHIP_NO_ERROR)
+        {            
+            continue;
+        }
+
+        for(int j = 0; j < userInStorage.currentCredentialCount; j++)
+        {
+            // If the current credential is a pin type, then check it against pin input. Otherwise ignore
+            if(mCredentials[j].credentialType == CredentialTypeEnum::kPin)
+            {
+                // Read the individual credential at credentialIndex j
+                uint16_t size  = static_cast<uint16_t>(sizeof(LockCredentialInfo));
+
+                chip::StorageKeyName key = LockCredentialEndpoint(mCredentials[j].credentialIndex, endpointId);
+
+                error = chip::Server::GetInstance().GetPersistentStorage().SyncGetKeyValue(key.KeyName(), &credentialInStorage, size);
+
+                if(error != CHIP_NO_ERROR)
+                {            
+                    ChipLogError(Zcl, "Error reading credential");
+                    return false;
+                }
+
+               // See if it matches the provided PIN
+               if (credentialInStorage.status == DlCredentialStatus::kAvailable)
+               {
+                   continue;
+               }
+
+               chip::ByteSpan currentCredential = chip::ByteSpan{ credentialInStorage.credentialData, credentialInStorage.credentialDataSize };
+       
+               if (currentCredential.data_equal(pin.Value()))
+               {
+                   ChipLogDetail(Zcl,
+                                 "Lock App: specified PIN code was found in the database, setting lock state to \"%s\" [endpointId=%d]",
+                                 lockStateToString(lockState), endpointId);
+
+                    LockOpCredentials userCredential[] = { { CredentialTypeEnum::kPin, mCredentials[j].credentialIndex } };
+                    auto userCredentials               = MakeNullable<List<const LockOpCredentials>>(userCredential);
+       
+                   DoorLockServer::Instance().SetLockState(endpointId, lockState, OperationSourceEnum::kRemote, userIndex, userCredentials,
+                                                           fabricIdx, nodeId);
+       
+                   return true;
+               }               
+
+            }
         }
     }