diff --git a/pw_kvs/public/pw_kvs/flash.h b/pw_kvs/public/pw_kvs/flash.h
new file mode 100644
index 0000000..5cb80cd
--- /dev/null
+++ b/pw_kvs/public/pw_kvs/flash.h
@@ -0,0 +1,33 @@
+// Copyright 2020 The Pigweed Authors
+//
+// 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
+//
+//     https://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.
+#pragma once
+
+#include "pw_kvs/devices/flash_memory.h"
+
+namespace pw {
+
+// Writes a buffer which is not guaranteed to be aligned, pads remaining
+// bytes with 0.
+Status PaddedWrite(FlashPartition* partition,
+                   FlashPartition::Address address,
+                   const uint8_t* buffer,
+                   uint16_t size);
+
+// Read into a buffer when size is not guaranteed to be aligned.
+Status UnalignedRead(FlashPartition* partition,
+                     uint8_t* buffer,
+                     FlashPartition::Address address,
+                     uint16_t size);
+
+}  // namespace pw
diff --git a/pw_kvs/public/pw_kvs/flash_memory.h b/pw_kvs/public/pw_kvs/flash_memory.h
new file mode 100644
index 0000000..707f128
--- /dev/null
+++ b/pw_kvs/public/pw_kvs/flash_memory.h
@@ -0,0 +1,377 @@
+// Copyright 2020 The Pigweed Authors
+//
+// 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
+//
+//     https://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.
+#pragma once
+
+#include <algorithm>
+
+#include "pw_kvs/assert.h"
+#include "pw_kvs/logging.h"
+#include "pw_kvs/peripherals/partition_table_entry.h"
+#include "pw_kvs/status.h"
+#include "pw_kvs/status_macros.h"
+
+namespace pw {
+class FlashMemory {
+ public:
+  // The flash address is in the range of: 0 to FlashSize.
+  typedef uint32_t Address;
+  constexpr FlashMemory(uint32_t sector_size,
+                        uint32_t sector_count,
+                        uint8_t alignment,
+                        uint32_t start_address = 0,
+                        uint32_t sector_start = 0,
+                        uint8_t erased_memory_content = 0xFF)
+      : sector_size_(sector_size),
+        flash_sector_count_(sector_count),
+        alignment_(alignment),
+        start_address_(start_address),
+        sector_start_(sector_start),
+        erased_memory_content_(erased_memory_content) {}
+
+  virtual Status Enable() = 0;
+  virtual Status Disable() = 0;
+  virtual bool IsEnabled() const = 0;
+  virtual Status SelfTest() { return Status::UNIMPLEMENTED; }
+
+  // Erase num_sectors starting at a given address. Blocking call.
+  // Address should be on a sector boundary.
+  // Returns: OK, on success.
+  //          TIMEOUT, on timeout.
+  //          INVALID_ARGUMENT, if address or sector count is invalid.
+  //          UNKNOWN, on HAL error
+  virtual Status Erase(Address flash_address, uint32_t num_sectors) = 0;
+
+  // Reads bytes from flash into buffer. Blocking call.
+  // Returns: OK, on success.
+  //          TIMEOUT, on timeout.
+  //          INVALID_ARGUMENT, if address or length is invalid.
+  //          UNKNOWN, on HAL error
+  virtual Status Read(uint8_t* destination_ram_address,
+                      Address source_flash_address,
+                      uint32_t len) = 0;
+
+  // Writes bytes to flash. Blocking call.
+  // Returns: OK, on success.
+  //          TIMEOUT, on timeout.
+  //          INVALID_ARGUMENT, if address or length is invalid.
+  //          UNKNOWN, on HAL error
+  virtual Status Write(Address destination_flash_address,
+                       const uint8_t* source_ram_address,
+                       uint32_t len) = 0;
+
+  // Convert an Address to an MCU pointer, this can be used for memory
+  // mapped reads. Return NULL if the memory is not memory mapped.
+  virtual uint8_t* FlashAddressToMcuAddress(Address address) const {
+    return nullptr;
+  }
+
+  // GetStartSector() is useful for FlashMemory instances where the
+  // sector start is not 0. (ex.: cases where there are portions of flash
+  // that should be handled independently).
+  constexpr uint32_t GetStartSector() const { return sector_start_; }
+  constexpr uint32_t GetSectorSizeBytes() const { return sector_size_; }
+  constexpr uint32_t GetSectorCount() const { return flash_sector_count_; }
+  constexpr uint8_t GetAlignmentBytes() const { return alignment_; }
+  constexpr uint32_t GetSizeBytes() const {
+    return sector_size_ * flash_sector_count_;
+  }
+  // Address of the start of flash (the address of sector 0)
+  constexpr uint32_t GetStartAddress() const { return start_address_; }
+  constexpr uint8_t GetErasedMemoryContent() const {
+    return erased_memory_content_;
+  }
+
+ private:
+  const uint32_t sector_size_;
+  const uint32_t flash_sector_count_;
+  const uint8_t alignment_;
+  const uint32_t start_address_;
+  const uint32_t sector_start_;
+  const uint8_t erased_memory_content_;
+};
+
+// Exposes a sub-sector sized region of flash memory that cannot be erased.
+// It can be thought of as one pseudo-sector that is sized exactly as provided.
+//
+// TODO(b/117553777): This makes a little more sense as a SubSectorPartition,
+// but PartitionTableEntry currently assumes all partitions fill entire sectors.
+// Revisit when PartitionTable is refactored.
+class FlashMemorySubSector : public FlashMemory {
+ public:
+  constexpr FlashMemorySubSector(FlashMemory* flash,
+                                 uint32_t start_address,
+                                 uint32_t size)
+      : FlashMemory(size,
+                    1,  // Round up to "1" sector.
+                    flash->GetAlignmentBytes(),
+                    start_address,
+                    // Calculate the sector for this start address.
+                    flash->GetStartSector() +
+                        ((start_address - flash->GetStartAddress()) /
+                         flash->GetSectorSizeBytes())),
+        flash_(*CHECK_NOTNULL(flash)),
+        base_offset_(start_address - flash->GetStartAddress()) {
+    // Make sure we're not specifying a region of flash larger than
+    // that which the underlying FlashMemory supports.
+    CHECK(start_address >= flash->GetStartAddress());
+    CHECK(size <= flash->GetSectorSizeBytes());
+    CHECK(start_address + size <=
+          flash->GetStartAddress() + flash->GetSizeBytes());
+    CHECK_EQ(0, start_address % flash->GetAlignmentBytes());
+    CHECK_EQ(0, size % flash->GetAlignmentBytes());
+  }
+
+  Status Enable() override { return flash_.Enable(); }
+  Status Disable() override { return flash_.Disable(); }
+  bool IsEnabled() const override { return flash_.IsEnabled(); }
+  Status SelfTest() override { return flash_.SelfTest(); }
+
+  Status Erase(Address flash_address, uint32_t num_sectors) override {
+    return Status::UNIMPLEMENTED;
+  }
+
+  Status Read(uint8_t* destination_ram_address,
+              Address source_flash_address,
+              uint32_t len) override {
+    return flash_.Read(destination_ram_address, source_flash_address, len);
+  }
+
+  Status Write(Address destination_flash_address,
+               const uint8_t* source_ram_address,
+               uint32_t len) override {
+    return flash_.Write(destination_flash_address, source_ram_address, len);
+  }
+
+  uint8_t* FlashAddressToMcuAddress(Address address) const override {
+    return flash_.FlashAddressToMcuAddress(base_offset_ + address);
+  }
+
+ private:
+  FlashMemory& flash_;
+  // Value to add to addresses to get to the underlying flash_ address.
+  const Address base_offset_;
+};
+
+class FlashPartition {
+ public:
+  // The flash address is in the range of: 0 to PartitionSize.
+  typedef uint32_t Address;
+
+  constexpr FlashPartition(
+      FlashMemory* flash,
+      uint32_t start_sector_index,
+      uint32_t sector_count,
+      PartitionPermission permission = PartitionPermission::kReadAndWrite)
+      : flash_(*flash),
+        start_sector_index_(start_sector_index),
+        sector_count_(sector_count),
+        permission_(permission) {}
+
+  constexpr FlashPartition(FlashMemory* flash, PartitionTableEntry entry)
+      : flash_(*flash),
+        start_sector_index_(entry.partition_start_sector_index),
+        sector_count_(entry.partition_end_sector_index -
+                      entry.partition_start_sector_index + 1),
+        permission_(entry.partition_permission) {}
+
+  // Erase num_sectors starting at a given address. Blocking call.
+  // Address should be on a sector boundary.
+  // Returns: OK, on success.
+  //          TIMEOUT, on timeout.
+  //          INVALID_ARGUMENT, if address or sector count is invalid.
+  //          PERMISSION_DENIED, if partition is read only.
+  //          UNKNOWN, on HAL error
+  virtual Status Erase(Address address, uint32_t num_sectors) {
+    RETURN_STATUS_IF(permission_ == PartitionPermission::kReadOnly,
+                     Status::PERMISSION_DENIED);
+    RETURN_IF_ERROR(CheckBounds(address, num_sectors * GetSectorSizeBytes()));
+    return flash_.Erase(PartitionToFlashAddress(address), num_sectors);
+  }
+
+  // Reads bytes from flash into buffer. Blocking call.
+  // Returns: OK, on success.
+  //          TIMEOUT, on timeout.
+  //          INVALID_ARGUMENT, if address or length is invalid.
+  //          UNKNOWN, on HAL error
+  virtual Status Read(uint8_t* destination_ram_address,
+                      Address source_flash_address,
+                      uint32_t len) {
+    RETURN_IF_ERROR(CheckBounds(source_flash_address, len));
+    return flash_.Read(destination_ram_address,
+                       PartitionToFlashAddress(source_flash_address),
+                       len);
+  }
+
+  // Writes bytes to flash. Blocking call.
+  // Returns: OK, on success.
+  //          TIMEOUT, on timeout.
+  //          INVALID_ARGUMENT, if address or length is invalid.
+  //          PERMISSION_DENIED, if partition is read only.
+  //          UNKNOWN, on HAL error
+  virtual Status Write(Address destination_flash_address,
+                       const uint8_t* source_ram_address,
+                       uint32_t len) {
+    RETURN_STATUS_IF(permission_ == PartitionPermission::kReadOnly,
+                     Status::PERMISSION_DENIED);
+    RETURN_IF_ERROR(CheckBounds(destination_flash_address, len));
+    return flash_.Write(PartitionToFlashAddress(destination_flash_address),
+                        source_ram_address,
+                        len);
+  }
+
+  // Check to see if chunk of flash memory is erased. Address and len need to
+  // be aligned with FlashMemory.
+  // Returns: OK, on success.
+  //          TIMEOUT, on timeout.
+  //          INVALID_ARGUMENT, if address or length is invalid.
+  //          UNKNOWN, on HAL error
+  virtual Status IsChunkErased(Address source_flash_address,
+                               uint32_t len,
+                               bool* is_erased) {
+    // Max alignment is artifical to keep the stack usage low for this
+    // function. Using 16 because it's the alignment of encrypted flash.
+    const uint8_t kMaxAlignment = 16;
+    // Relying on Read() to check address and len arguments.
+    RETURN_STATUS_IF(!is_erased, Status::INVALID_ARGUMENT);
+    uint8_t alignment = GetAlignmentBytes();
+    RETURN_STATUS_IF(alignment > kMaxAlignment, Status::INVALID_ARGUMENT);
+    RETURN_STATUS_IF(kMaxAlignment % alignment, Status::INVALID_ARGUMENT);
+    RETURN_STATUS_IF(len % alignment, Status::INVALID_ARGUMENT);
+
+    uint8_t buffer[kMaxAlignment];
+    uint8_t erased_pattern_buffer[kMaxAlignment];
+    size_t offset = 0;
+    memset(erased_pattern_buffer,
+           flash_.GetErasedMemoryContent(),
+           sizeof(erased_pattern_buffer));
+    *is_erased = false;
+    while (len > 0) {
+      // Check earlier that len is aligned, no need to round up
+      uint16_t read_size = std::min(static_cast<uint32_t>(sizeof(buffer)), len);
+      RETURN_IF_ERROR(Read(buffer, source_flash_address + offset, read_size));
+      if (memcmp(buffer, erased_pattern_buffer, read_size)) {
+        // Detected memory chunk is not entirely erased
+        return Status::OK;
+      }
+      offset += read_size;
+      len -= read_size;
+    }
+    *is_erased = true;
+    return Status::OK;
+  }
+
+  constexpr uint32_t GetSectorSizeBytes() const {
+    return flash_.GetSectorSizeBytes();
+  }
+
+  uint32_t GetSizeBytes() const {
+    return GetSectorCount() * GetSectorSizeBytes();
+  }
+
+  virtual uint8_t GetAlignmentBytes() const {
+    return flash_.GetAlignmentBytes();
+  }
+
+  virtual uint32_t GetSectorCount() const { return sector_count_; }
+
+  // Convert a FlashMemory::Address to an MCU pointer, this can be used for
+  // memory mapped reads. Return NULL if the memory is not memory mapped.
+  uint8_t* PartitionAddressToMcuAddress(Address address) const {
+    return flash_.FlashAddressToMcuAddress(PartitionToFlashAddress(address));
+  }
+
+  FlashMemory::Address PartitionToFlashAddress(Address address) const {
+    return flash_.GetStartAddress() +
+           (start_sector_index_ - flash_.GetStartSector()) *
+               GetSectorSizeBytes() +
+           address;
+  }
+
+ protected:
+  Status CheckBounds(Address address, uint32_t len) const {
+    if (address + len > GetSizeBytes()) {
+      LOG(ERROR) << "Attempted out-of-bound flash memory access (address:"
+                 << address << " length:" << len << ")";
+      return Status::INVALID_ARGUMENT;
+    }
+    return Status::OK;
+  }
+
+ private:
+  FlashMemory& flash_;
+  const uint32_t start_sector_index_;
+  const uint32_t sector_count_;
+  const PartitionPermission permission_;
+};
+
+// FlashSubPartition defines a new partition which maps itself as a smaller
+// piece of another partition. This can used when a partition has special
+// behaviours (for example encrypted flash).
+// For example, this will be the first sector of test_partition:
+//    FlashSubPartition test_partition_sector1(&test_partition, 0, 1);
+class FlashSubPartition : public FlashPartition {
+ public:
+  constexpr FlashSubPartition(FlashPartition* parent_partition,
+                              uint32_t start_sector_index,
+                              uint32_t sector_count)
+      : FlashPartition(*parent_partition),
+        partition_(parent_partition),
+        start_sector_index_(start_sector_index),
+        sector_count_(sector_count) {}
+
+  Status Erase(Address address, uint32_t num_sectors) override {
+    RETURN_IF_ERROR(CheckBounds(address, num_sectors * GetSectorSizeBytes()));
+    return partition_->Erase(ParentAddress(address), num_sectors);
+  }
+
+  Status Read(uint8_t* destination_ram_address,
+              Address source_flash_address,
+              uint32_t len) override {
+    RETURN_IF_ERROR(CheckBounds(source_flash_address, len));
+    return partition_->Read(
+        destination_ram_address, ParentAddress(source_flash_address), len);
+  }
+
+  Status Write(Address destination_flash_address,
+               const uint8_t* source_ram_address,
+               uint32_t len) override {
+    RETURN_IF_ERROR(CheckBounds(destination_flash_address, len));
+    return partition_->Write(
+        ParentAddress(destination_flash_address), source_ram_address, len);
+  }
+
+  Status IsChunkErased(Address source_flash_address,
+                       uint32_t len,
+                       bool* is_erased) override {
+    RETURN_IF_ERROR(CheckBounds(source_flash_address, len));
+    return partition_->IsChunkErased(
+        ParentAddress(source_flash_address), len, is_erased);
+  }
+
+  uint8_t GetAlignmentBytes() const override {
+    return partition_->GetAlignmentBytes();
+  }
+
+  uint32_t GetSectorCount() const override { return sector_count_; }
+
+ private:
+  Address ParentAddress(Address address) const {
+    return address + start_sector_index_ * partition_->GetSectorSizeBytes();
+  }
+  FlashPartition* partition_;
+  const uint32_t start_sector_index_;
+  const uint32_t sector_count_;
+};
+
+}  // namespace pw
diff --git a/pw_kvs/public/pw_kvs/in_memory_fake_flash.h b/pw_kvs/public/pw_kvs/in_memory_fake_flash.h
new file mode 100644
index 0000000..a67c770
--- /dev/null
+++ b/pw_kvs/public/pw_kvs/in_memory_fake_flash.h
@@ -0,0 +1,92 @@
+// Copyright 2020 The Pigweed Authors
+//
+// 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
+//
+//     https://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.
+#pragma once
+
+#include <array>
+
+#include "pw_kvs/devices/flash_memory.h"
+#include "pw_kvs/status.h"
+#include "pw_kvs/status_macros.h"
+
+namespace pw {
+
+// This creates a buffer which mimics the behaviour of flash (requires erase,
+// before write, checks alignments, and is addressed in sectors).
+template <uint32_t kSectorSize, uint16_t kSectorCount>
+class InMemoryFakeFlash : public FlashMemory {
+ public:
+  InMemoryFakeFlash(uint8_t alignment = 1)  // default 8 bit alignment
+      : FlashMemory(kSectorSize, kSectorCount, alignment) {}
+
+  // Always enabled
+  Status Enable() override { return Status::OK; }
+  Status Disable() override { return Status::OK; }
+  bool IsEnabled() const override { return true; }
+
+  // Erase num_sectors starting at a given address. Blocking call.
+  // Address should be on a sector boundary.
+  // Returns: OK, on success.
+  //          INVALID_ARGUMENT, if address or sector count is invalid.
+  //          UNKNOWN, on HAL error
+  Status Erase(Address addr, uint32_t num_sectors) override {
+    RETURN_STATUS_IF(addr % GetSectorSizeBytes() != 0,
+                     Status::INVALID_ARGUMENT);
+    RETURN_STATUS_IF(
+        addr / GetSectorSizeBytes() + num_sectors > GetSectorCount(),
+        Status::UNKNOWN);
+    RETURN_STATUS_IF(addr % GetAlignmentBytes() != 0, Status::INVALID_ARGUMENT);
+    memset(&buffer_[addr], 0xFF, GetSectorSizeBytes() * num_sectors);
+    return Status::OK;
+  }
+
+  // Reads bytes from flash into buffer. Blocking call.
+  // Returns: OK, on success.
+  //          INVALID_ARGUMENT, if address or length is invalid.
+  //          UNKNOWN, on HAL error
+  Status Read(uint8_t* dest_ram_addr,
+              Address source_flash_addr,
+              uint32_t len) override {
+    RETURN_STATUS_IF(
+        (source_flash_addr + len) >= GetSectorCount() * GetSizeBytes(),
+        Status::INVALID_ARGUMENT);
+    memcpy(dest_ram_addr, &buffer_[source_flash_addr], len);
+    return Status::OK;
+  }
+
+  // Writes bytes to flash. Blocking call.
+  // Returns: OK, on success.
+  //          INVALID_ARGUMENT, if address or length is invalid.
+  //          UNKNOWN, on HAL error
+  Status Write(Address dest_flash_addr,
+               const uint8_t* source_ram_addr,
+               uint32_t len) override {
+    RETURN_STATUS_IF(
+        (dest_flash_addr + len) >= GetSectorCount() * GetSizeBytes(),
+        Status::INVALID_ARGUMENT);
+    RETURN_STATUS_IF(dest_flash_addr % GetAlignmentBytes() != 0,
+                     Status::INVALID_ARGUMENT);
+    RETURN_STATUS_IF(len % GetAlignmentBytes() != 0, Status::INVALID_ARGUMENT);
+    // Check in erased state
+    for (unsigned i = 0; i < len; i++) {
+      RETURN_STATUS_IF(buffer_[dest_flash_addr + i] != 0xFF, Status::UNKNOWN);
+    }
+    memcpy(&buffer_[dest_flash_addr], source_ram_addr, len);
+    return Status::OK;
+  }
+
+ private:
+  std::array<uint8_t, kSectorCount * kSectorSize> buffer_;
+};
+
+}  // namespace pw
diff --git a/pw_kvs/public/pw_kvs/key_value_store.h b/pw_kvs/public/pw_kvs/key_value_store.h
new file mode 100644
index 0000000..dca6507
--- /dev/null
+++ b/pw_kvs/public/pw_kvs/key_value_store.h
@@ -0,0 +1,366 @@
+// Copyright 2020 The Pigweed Authors
+//
+// 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
+//
+//     https://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.
+#pragma once
+
+#include <algorithm>
+#include <type_traits>
+
+#include "pw_kvs/devices/flash_memory.h"
+#include "pw_kvs/logging.h"
+#include "pw_kvs/os/mutex.h"
+#include "pw_kvs/status.h"
+
+namespace pw {
+
+// This object is very large and should not be placed on the stack.
+class KeyValueStore {
+ public:
+  KeyValueStore(FlashPartition* partition) : partition_(*partition) {}
+
+  // Enable the KVS, scans the sectors of the partition for any current KVS
+  // data. Erases and initializes any sectors which are not initialized.
+  // Checks the CRC of all data in the KVS; on failure the corrupted data is
+  // lost and Enable will return Status::DATA_LOSS, but the KVS will still load
+  // other data and will be enabled.
+  Status Enable();
+  bool IsEnabled() const { return enabled_; }
+  void Disable() {
+    if (enabled_ == false) {
+      return;
+    }
+    os::MutexLock lock(&lock_);
+    enabled_ = false;
+  }
+
+  // Erase a key value element.
+  // key is a null terminated c string.
+  // Returns OK if erased
+  //         NOT_FOUND if key was not found.
+  Status Erase(const char* key);
+
+  // Copy the first size bytes of key's value into value buffer.
+  // key is a null terminated c string. Size is the amount of bytes to read,
+  // Optional offset argument supports reading size bytes starting at the
+  // specified offset.
+  // Returns OK if successful
+  //         NOT_FOUND if key was not found
+  //         DATA_LOSS if the value failed crc check
+  Status Get(const char* key, void* value, uint16_t size, uint16_t offset = 0);
+
+  // Interpret the key's value as the given type and return it.
+  // Returns OK if successful
+  //         NOT_FOUND if key was not found
+  //         DATA_LOSS if the value failed crc check
+  //         INVALID_ARGUMENT if size of value != sizeof(T)
+  template <typename T>
+  Status Get(const char* key, T* value) {
+    static_assert(std::is_trivially_copyable<T>(), "KVS values must copyable");
+    static_assert(!std::is_pointer<T>(), "KVS values cannot be pointers");
+    uint16_t value_size = 0;
+    RETURN_IF_ERROR(GetValueSize(key, &value_size));
+    RETURN_STATUS_IF(value_size != sizeof(T), Status::INVALID_ARGUMENT);
+    return Get(key, value, sizeof(T));
+  }
+
+  // Writes the key value store to the partition. If the key already exists it
+  // will be deleted before writing the new value.
+  // key is a null terminated c string.
+  // Returns OK if successful
+  //         RESOURCE_EXHAUSTED if there is not enough available space
+  Status Put(const char* key, const void* value, uint16_t size);
+
+  // Writes the value to the partition. If the key already exists it will be
+  // deleted before writing the new value.
+  // key is a null terminated c string.
+  // Returns OK if successful
+  //         RESOURCE_EXHAUSTED if there is not enough available space
+  template <typename T>
+  Status Put(const char* key, const T& value) {
+    static_assert(std::is_trivially_copyable<T>(), "KVS values must copyable");
+    static_assert(!std::is_pointer<T>(), "KVS values cannot be pointers");
+    return Put(key, &value, sizeof(T));
+  }
+
+  // Gets the size of the value stored for provided key.
+  // Returns OK if successful
+  //         INVALID_ARGUMENT if args are invalid.
+  //         FAILED_PRECONDITION if KVS is not enabled.
+  //         NOT_FOUND if key was not found.
+  Status GetValueSize(const char* key, uint16_t* value_size);
+
+  // Tests if the proposed key value entry can be stored in the KVS.
+  bool CanFitEntry(uint16_t key_len, uint16_t value_len) {
+    return kSectorInvalid != FindSpace(ChunkSize(key_len, value_len));
+  }
+
+  // CleanAll cleans each sector which is currently marked for cleaning.
+  // Note: if any data is invalid/corrupt it could be lost.
+  Status CleanAll() {
+    os::MutexLock lock(&lock_);
+    return CleanAllInternal();
+  }
+  size_t PendingCleanCount() {
+    os::MutexLock lock(&lock_);
+    size_t ret = 0;
+    for (size_t i = 0; i < SectorCount(); i++) {
+      ret += sector_space_remaining_[i] == 0 ? 1 : 0;
+    }
+    return ret;
+  }
+
+  // Clean a single sector and return, if all sectors are clean it will set
+  // all_sectors_have_been_cleaned to true and return.
+  Status CleanOneSector(bool* all_sectors_have_been_cleaned);
+
+  // For debugging, logging, and testing. (Don't use in regular code)
+  // Note: a key_index is not valid after an element is erased or updated.
+  uint8_t KeyCount() const;
+  const char* GetKey(uint8_t idx) const;
+  uint16_t GetValueSize(uint8_t idx) const;
+  size_t GetMaxKeys() const { return kListCapacityMax; }
+  bool HasEmptySector() const { return HaveEmptySectorImpl(); }
+
+  static constexpr size_t kHeaderSize = 8;  // Sector and KVS Header size
+  static constexpr uint16_t MaxValueLength() { return kChunkValueLengthMax; }
+  KeyValueStore(const KeyValueStore&) = delete;
+  KeyValueStore& operator=(const KeyValueStore&) = delete;
+
+ private:
+  using KeyIndex = uint8_t;
+  using SectorIndex = uint32_t;
+
+  static constexpr uint16_t kVersion = 4;
+  static constexpr KeyIndex kListCapacityMax = cfg::kKvsMaxKeyCount;
+  static constexpr SectorIndex kSectorCountMax = cfg::kKvsMaxSectorCount;
+
+  // Number of bits for fields in KVSHeader:
+  static constexpr int kChunkHeaderKeyFieldNumBits = 4;
+  static constexpr int kChunkHeaderChunkFieldNumBits = 12;
+
+  static constexpr uint16_t kSectorReadyValue = 0xABCD;
+  static constexpr uint16_t kChunkSyncValue = 0x55AA;
+
+  static constexpr uint16_t kChunkLengthMax =
+      ((1 << kChunkHeaderChunkFieldNumBits) - 1);
+  static constexpr uint16_t kChunkKeyLengthMax =
+      ((1 << kChunkHeaderKeyFieldNumBits) - 1);
+  static constexpr uint16_t kChunkValueLengthMax =
+      (kChunkLengthMax - kChunkKeyLengthMax);
+
+  static constexpr SectorIndex kSectorInvalid = 0xFFFFFFFFul;
+  static constexpr FlashPartition::Address kAddressInvalid = 0xFFFFFFFFul;
+  static constexpr uint64_t kSectorCleanNotPending = 0xFFFFFFFFFFFFFFFFull;
+
+  // TODO: Use BitPacker if/when have more flags.
+  static constexpr uint16_t kFlagsIsErasedMask = 0x0001;
+  static constexpr uint16_t kMaxAlignmentBytes = 128;
+
+  // This packs into 16 bytes.
+  struct KvsSectorHeaderMeta {
+    uint16_t synchronize_token;
+    uint16_t version;
+    uint16_t alignment_bytes;  // alignment used for each chunk in this sector.
+    uint16_t padding;          // padding to support uint64_t alignment.
+  } __attribute__((__packed__));
+  static_assert(sizeof(KvsSectorHeaderMeta) == kHeaderSize,
+                "Invalid KvsSectorHeaderMeta size");
+
+  // sector_clean_pending is broken off from KvsSectorHeaderMeta to support
+  // larger than sizeof(KvsSectorHeaderMeta) flash write alignments.
+  struct KvsSectorHeaderCleaning {
+    // When this sector is not marked for cleaning this will be in the erased
+    // state. When marked for clean this value indicates the order the sectors
+    // were marked for cleaning, and therfore which data is the newest.
+    // To remain backwards compatible with v2 and v3 KVS this is 8 bytes, if the
+    // alignment is greater than 8 we will check the entire alignment is in the
+    // default erased state.
+    uint64_t sector_clean_order;
+  };
+  static_assert(sizeof(KvsSectorHeaderCleaning) == kHeaderSize,
+                "Invalid KvsSectorHeaderCleaning size");
+
+  // This packs into 8 bytes, to support uint64_t alignment.
+  struct KvsHeader {
+    uint16_t synchronize_token;
+    uint16_t crc;  // Crc of the key + data (Ignoring any padding bytes)
+    // flags is a Bitmask: bits 15-1 reserved = 0,
+    // bit 0: is_erased [0 when not erased, 1 when erased]
+    uint16_t flags;
+    // On little endian the length fields map to memory as follows:
+    // byte array: [ 0x(c0to3 k0to3) 0x(c8to11 c4to7) ]
+    // Key length does not include trailing zero. That is not stored.
+    uint16_t key_len : kChunkHeaderKeyFieldNumBits;
+    // Chunk length is the total length of the chunk before alignment.
+    // That way we can work out the length of the value as:
+    // (chunk length - key length - size of chunk header).
+    uint16_t chunk_len : kChunkHeaderChunkFieldNumBits;
+  } __attribute__((__packed__));
+  static_assert(sizeof(KvsHeader) == kHeaderSize, "Invalid KvsHeader size");
+
+  struct KeyMap {
+    char key[kChunkKeyLengthMax + 1];  // + 1 for null terminator
+    FlashPartition::Address address;
+    uint16_t chunk_len;
+    bool is_erased;
+  };
+
+  // NOTE: All public APIs handle the locking, the internal methods assume the
+  // lock has already been acquired.
+
+  SectorIndex AddressToSectorIndex(FlashPartition::Address address) const {
+    return address / partition_.GetSectorSizeBytes();
+  }
+
+  FlashPartition::Address SectorIndexToAddress(SectorIndex index) const {
+    return index * partition_.GetSectorSizeBytes();
+  }
+
+  // Returns kAddressInvalid if no space is found, otherwise the address.
+  FlashPartition::Address FindSpace(uint16_t requested_size) const;
+
+  // Attempts to rewrite a key's value by appending the new value to the same
+  // sector. If the sector is full the value is written to another sector, and
+  // the sector is marked for cleaning.
+  // Returns RESOURCE_EXHAUSTED if no space is available, OK otherwise.
+  Status RewriteValue(KeyIndex key_index,
+                      const uint8_t* value,
+                      uint16_t size,
+                      bool is_erased = false);
+
+  bool ValueMatches(KeyIndex key_index,
+                    const uint8_t* value,
+                    uint16_t size,
+                    bool is_erased);
+
+  // ResetSector erases the sector and writes the sector header.
+  Status ResetSector(SectorIndex sector_index);
+  Status WriteKeyValue(FlashPartition::Address address,
+                       const char* key,
+                       const uint8_t* value,
+                       uint16_t size,
+                       bool is_erased = false);
+  uint32_t SectorSpaceRemaining(SectorIndex sector_index) const;
+
+  // Returns idx if key is found, otherwise kListCapacityMax.
+  KeyIndex FindKeyInMap(const char* key) const;
+  bool IsKeyInMap(const char* key) const {
+    return FindKeyInMap(key) != kListCapacityMax;
+  }
+
+  void RemoveFromMap(KeyIndex key_index);
+  Status AppendToMap(const char* key,
+                     FlashPartition::Address address,
+                     uint16_t chunk_len,
+                     bool is_erased = false);
+  void UpdateMap(KeyIndex key_index,
+                 FlashPartition::Address address,
+                 uint16_t chunk_len,
+                 bool is_erased = false);
+  uint16_t CalculateCrc(const char* key,
+                        uint16_t key_size,
+                        const uint8_t* value,
+                        uint16_t value_size) const;
+
+  // Calculates the CRC by reading the value from flash in chunks.
+  Status CalculateCrcFromValueAddress(const char* key,
+                                      uint16_t key_size,
+                                      FlashPartition::Address value_address,
+                                      uint16_t value_size,
+                                      uint16_t* crc_ret);
+
+  uint16_t RoundUpForAlignment(uint16_t size) const {
+    if (size % alignment_bytes_ != 0) {
+      return size + alignment_bytes_ - size % alignment_bytes_;
+    }
+    return size;
+  }
+
+  // The buffer is chosen to be no larger then the config value, and
+  // be a multiple of the flash alignment.
+  size_t TempBufferAlignedSize() const {
+    CHECK_GE(sizeof(temp_buffer_), partition_.GetAlignmentBytes());
+    return sizeof(temp_buffer_) -
+           (sizeof(temp_buffer_) % partition_.GetAlignmentBytes());
+  }
+
+  // Moves a key/value chunk from one address to another, all fields expected to
+  // be aligned.
+  Status MoveChunk(FlashPartition::Address dest_address,
+                   FlashPartition::Address src_address,
+                   uint16_t size);
+
+  // Size of a chunk including header, key, value, and alignment padding.
+  uint16_t ChunkSize(uint16_t key_len, uint16_t chunk_len) const {
+    return RoundUpForAlignment(sizeof(KvsHeader)) +
+           RoundUpForAlignment(key_len) + RoundUpForAlignment(chunk_len);
+  }
+
+  // Sectors should be cleaned when full, every valid (Most recent, not erased)
+  // chunk of data is moved to another sector and the sector is erased.
+  // TODO: Clean sectors with lots of invalid data, without a rewrite
+  // or erase triggering it.
+  Status MarkSectorForClean(SectorIndex sector);
+  Status CleanSector(SectorIndex sector);
+  Status CleanAllInternal();
+  Status GarbageCollectImpl(bool clean_pending_sectors,
+                            bool exit_when_have_free_sector);
+  Status FullGarbageCollect();
+  Status EnforceFreeSector();
+
+  SectorIndex SectorCount() const {
+    return std::min(partition_.GetSectorCount(), kSectorCountMax);
+  }
+
+  size_t SectorSpaceAvailableWhenEmpty() const {
+    return partition_.GetSectorSizeBytes() -
+           RoundUpForAlignment(sizeof(KvsSectorHeaderMeta)) -
+           RoundUpForAlignment(sizeof(KvsSectorHeaderCleaning));
+  }
+
+  bool HaveEmptySectorImpl(SectorIndex skip_sector = kSectorInvalid) const {
+    for (SectorIndex i = 0; i < SectorCount(); i++) {
+      if (i != skip_sector &&
+          sector_space_remaining_[i] == SectorSpaceAvailableWhenEmpty()) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  bool IsInLastFreeSector(FlashPartition::Address address) {
+    return sector_space_remaining_[AddressToSectorIndex(address)] ==
+               SectorSpaceAvailableWhenEmpty() &&
+           !HaveEmptySectorImpl(AddressToSectorIndex(address));
+  }
+
+  FlashPartition& partition_;
+  os::Mutex lock_;
+  bool enabled_ = false;
+  uint8_t alignment_bytes_ = 0;
+  uint64_t next_sector_clean_order_ = 0;
+
+  // Free space available in each sector, set to 0 when clean is pending/active
+  uint32_t sector_space_remaining_[kSectorCountMax] = {0};
+  uint64_t sector_clean_order_[kSectorCountMax] = {kSectorCleanNotPending};
+  KeyMap key_map_[kListCapacityMax] = {{{0}}};
+  KeyIndex map_size_ = 0;
+
+  // +1 for nul-terminator since keys are stored as Length + Value and no nul
+  // termination but we are using them as nul-terminated strings through
+  // loading-up and comparing the keys.
+  char temp_key_buffer_[kChunkKeyLengthMax + 1u] = {0};
+  uint8_t temp_buffer_[cfg::kKvsBufferSize] = {0};
+};
+
+}  // namespace pw
diff --git a/pw_kvs/public/pw_kvs/partition_table_entry.h b/pw_kvs/public/pw_kvs/partition_table_entry.h
new file mode 100644
index 0000000..9aa111d
--- /dev/null
+++ b/pw_kvs/public/pw_kvs/partition_table_entry.h
@@ -0,0 +1,51 @@
+// Copyright 2020 The Pigweed Authors
+//
+// 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
+//
+//     https://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.
+#pragma once
+
+#include <cstdint>
+
+namespace pw {
+
+namespace partition_table {
+
+enum DataType { kRawData, kKvs };
+
+}  // namespace partition_table
+
+enum class PartitionPermission : bool {
+  kReadOnly = true,
+  kReadAndWrite = false,
+};
+
+struct PartitionTableEntry {
+  constexpr PartitionTableEntry(
+      const uint32_t start_sector_index,
+      const uint32_t end_sector_index,
+      const uint8_t partition_identifier,
+      partition_table::DataType datatype,
+      PartitionPermission permission = PartitionPermission::kReadAndWrite)
+      : partition_start_sector_index(start_sector_index),
+        partition_end_sector_index(end_sector_index),
+        partition_id(partition_identifier),
+        data_type(datatype),
+        partition_permission(permission) {}
+
+  const uint32_t partition_start_sector_index;
+  const uint32_t partition_end_sector_index;
+  const uint8_t partition_id;
+  const partition_table::DataType data_type;
+  const PartitionPermission partition_permission;
+};
+
+}  // namespace pw
