pw_kvs: Verify checksum on write

- Replace placeholder VerifyEntry function with the real verification
  function, VerifyChecksumInFlash.
- Have VerifyChecksumInFlash read everything from flash, not just the
  value.
- Fix missing bytes_to_read updates.

Change-Id: If856c60dee710bea128684fd1bb22d3e7fc62793
diff --git a/pw_kvs/format.cc b/pw_kvs/format.cc
index 739783d..819b541 100644
--- a/pw_kvs/format.cc
+++ b/pw_kvs/format.cc
@@ -49,31 +49,31 @@
   return algorithm->Verify(checksum_bytes());
 }
 
-Status EntryHeader::VerifyChecksumInFlash(
-    FlashPartition* partition,
-    FlashPartition::Address header_address,
-    ChecksumAlgorithm* algorithm,
-    string_view key) const {
+Status EntryHeader::VerifyChecksumInFlash(FlashPartition* partition,
+                                          FlashPartition::Address address,
+                                          ChecksumAlgorithm* algorithm) const {
   if (algorithm == nullptr) {
     return checksum() == kNoChecksum ? Status::OK : Status::DATA_LOSS;
   }
 
-  CalculateChecksum(algorithm, key);
+  algorithm->Reset();
 
-  // Read the value piece-by-piece into a small buffer.
+  // Read the entire entry piece-by-piece into a small buffer.
   // TODO: This read may be unaligned. The partition can handle this, but
   // consider creating a API that skips the intermediate buffering.
   byte buffer[32];
 
-  size_t bytes_to_read = value_length();
-  FlashPartition::Address address =
-      header_address + sizeof(*this) + key_length();
+  address += checked_data_offset();
+  size_t bytes_to_read = entry_size() - checked_data_offset();
 
   while (bytes_to_read > 0u) {
     const size_t read_size = std::min(sizeof(buffer), bytes_to_read);
+
     TRY(partition->Read(address, read_size, buffer));
-    address += read_size;
     algorithm->Update(buffer, read_size);
+
+    address += read_size;
+    bytes_to_read -= read_size;
   }
 
   return algorithm->Verify(checksum_bytes());
@@ -83,9 +83,8 @@
                                     const string_view key,
                                     span<const byte> value) const {
   algorithm->Reset();
-  algorithm->Update(reinterpret_cast<const byte*>(this) +
-                        offsetof(EntryHeader, key_value_length_),
-                    sizeof(*this) - offsetof(EntryHeader, key_value_length_));
+  algorithm->Update(reinterpret_cast<const byte*>(this) + checked_data_offset(),
+                    sizeof(*this) - checked_data_offset());
   algorithm->Update(as_bytes(span(key)));
   algorithm->Update(value);
 }
diff --git a/pw_kvs/key_value_store.cc b/pw_kvs/key_value_store.cc
index 39790ae..f106f9f 100644
--- a/pw_kvs/key_value_store.cc
+++ b/pw_kvs/key_value_store.cc
@@ -167,7 +167,7 @@
   const string_view key(key_buffer.data(), header.key_length());
 
   TRY(header.VerifyChecksumInFlash(
-      &partition_, key_descriptor.address, entry_header_format_.checksum, key));
+      &partition_, key_descriptor.address, entry_header_format_.checksum));
   key_descriptor.key_hash = HashKey(key);
 
   DBG("Key hash: %zx (%zu)",
@@ -579,7 +579,8 @@
           address, {as_bytes(span(&header, 1)), as_bytes(span(key)), value}));
 
   if (options_.verify_on_write) {
-    TRY(VerifyEntry(sector, key_descriptor));
+    TRY(header.VerifyChecksumInFlash(
+        &partition_, address, entry_header_format_.checksum));
   }
 
   // TODO: UPDATE last_written_sector_ appropriately
@@ -591,20 +592,6 @@
   return Status::OK;
 }
 
-Status KeyValueStore::VerifyEntry(SectorDescriptor* sector,
-                                  KeyDescriptor* key_descriptor) {
-  // TODO: Remove this once checksums are fully implemented.
-  return Status::OK;
-
-  if (entry_header_format_.checksum == nullptr) {
-    return Status::OK;
-  }
-  // TODO: Implement me!
-  (void)sector;
-  (void)key_descriptor;
-  return Status::UNIMPLEMENTED;
-}
-
 void KeyValueStore::LogDebugInfo() {
   const size_t sector_count = partition_.sector_count();
   const size_t sector_size_bytes = partition_.sector_size_bytes();
diff --git a/pw_kvs/public/pw_kvs/key_value_store.h b/pw_kvs/public/pw_kvs/key_value_store.h
index 8632c22..0c974f2 100644
--- a/pw_kvs/public/pw_kvs/key_value_store.h
+++ b/pw_kvs/public/pw_kvs/key_value_store.h
@@ -284,8 +284,6 @@
                      std::string_view key,
                      span<const std::byte> value);
 
-  Status VerifyEntry(SectorDescriptor* sector, KeyDescriptor* key_descriptor);
-
   bool AddressInSector(const SectorDescriptor& sector, Address address) const {
     const Address sector_base = SectorBaseAddress(&sector);
     const Address sector_end = sector_base + partition_.sector_size_bytes();
diff --git a/pw_kvs/pw_kvs_private/format.h b/pw_kvs/pw_kvs_private/format.h
index a1867e4..2fefd6e 100644
--- a/pw_kvs/pw_kvs_private/format.h
+++ b/pw_kvs/pw_kvs_private/format.h
@@ -43,8 +43,7 @@
 
   Status VerifyChecksumInFlash(FlashPartition* partition,
                                FlashPartition::Address header_address,
-                               ChecksumAlgorithm* algorithm,
-                               std::string_view key) const;
+                               ChecksumAlgorithm* algorithm) const;
 
   size_t entry_size() const {
     return sizeof(*this) + key_length() + value_length();
@@ -72,13 +71,17 @@
   static constexpr uint32_t kKeyLengthMask = 0b111111;
   static constexpr uint32_t kValueLengthShift = 8;
 
+  static constexpr size_t checked_data_offset() {
+    return offsetof(EntryHeader, key_value_length_);
+  }
+
   span<const std::byte> checksum_bytes() const {
     return as_bytes(span(&checksum_, 1));
   }
 
   void CalculateChecksum(ChecksumAlgorithm* algorithm,
                          std::string_view key,
-                         span<const std::byte> value = {}) const;
+                         span<const std::byte> value) const;
 
   uint32_t magic_;
   uint32_t checksum_;