summaryrefslogtreecommitdiff
path: root/include/new_nvmem.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/new_nvmem.h')
-rw-r--r--include/new_nvmem.h155
1 files changed, 155 insertions, 0 deletions
diff --git a/include/new_nvmem.h b/include/new_nvmem.h
new file mode 100644
index 0000000000..110cfd1667
--- /dev/null
+++ b/include/new_nvmem.h
@@ -0,0 +1,155 @@
+/* Copyright 2019 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef __TPM2_NVMEM_TEST_NEW_NVMEM_H
+#define __TPM2_NVMEM_TEST_NEW_NVMEM_H
+
+#include "common.h"
+#include "nvmem.h"
+#include "nvmem_vars.h"
+#include "util.h"
+
+#define NVMEM_NOT_INITIALIZED ((unsigned int)-1)
+
+/*
+ * A totally arbitrary byte limit for space occupied by (key, value) pairs in
+ * the flash. This is an improvement compared to the legacy case where there
+ * were just 272 bytes dedicated to the (key, value) pairs storage.
+ */
+#define MAX_VAR_TOTAL_SPACE 1000
+
+/*
+ * Let's be reasonable: we're unlikely to have keys longer than 40 or so
+ * bytes, and leave full 255 bytes for the value. Total data space occupied by
+ * a (key, value) pair is not to exceed the value below.
+ */
+#define MAX_VAR_BODY_SPACE 300
+
+enum nn_object_type {
+ NN_OBJ_OLD_COPY = 0,
+ NN_OBJ_TUPLE = 1,
+ NN_OBJ_TPM_RESERVED = 2,
+ NN_OBJ_TPM_EVICTABLE = 3,
+ NN_OBJ_TRANSACTION_DEL = 4,
+ NN_OBJ_ESCAPE = 5,
+ NN_OBJ_ERASED = 7,
+};
+
+/*
+ * Structure placed at the base of each flash page used for NVMEM storage.
+ *
+ * page_number: allows to arrange pages in order they were added
+ *
+ * data_offset: the offset of the first element in the page (space above
+ * page header and below data_offset could be taken by the
+ * 'tail' of the object stored on the previous page).
+ *
+ * page_hash: is used to verify page header integrity
+ */
+struct nn_page_header {
+ unsigned int page_number : 21;
+ unsigned int data_offset : 11;
+ uint32_t page_hash;
+} __packed;
+
+/*
+ * Index of the 'virtual' last reserved object. RAM index space and max
+ * counter objects stored at fixed location in the NVMEM cache are considered
+ * reserved objects by this NVMEM flash layer.
+ */
+#define NV_VIRTUAL_RESERVE_LAST (NV_RESERVE_LAST + 2)
+
+/*
+ * Container header for all blobs stored in flash.
+ *
+ * container_type: type of object stored in the container. MAKE SURE THIS
+ * FIELD TYPE IS THE FIRST FIELD IN THIS STRUCTURE, it is
+ * supposed to be in the first word of the container so that
+ * the type can be erased when object is deleted.
+ *
+ * container_type_copy: immutable copy of the container_type field, used to
+ * verify contents of deleted objects.
+ *
+ * encrypted: set to 1 if contents are encrypted.
+ *
+ * size: size of the payload, 12 bits allocated, 11 bits would be enough for
+ * this use case.
+ *
+ * generation: a free running counter, used to compare ages of two containers
+ *
+ * container_hash: hash of the ENTIRE container, both header and body
+ * included. This field is set to zero before hash is calculated
+ */
+struct nn_container {
+ unsigned int container_type : 3;
+ unsigned int container_type_copy : 3;
+ unsigned int encrypted : 1;
+ unsigned int size : 11;
+ unsigned int generation : 2;
+ unsigned int container_hash : 12;
+} __packed;
+
+/*
+ * A structure to keep context of accessing to a page, page header and offset
+ * define where the next access would happen.
+ */
+struct page_tracker {
+ const struct nn_page_header *ph;
+ uint16_t data_offset;
+};
+
+/*
+ * Helper structure to keep track of accesses to the flash storage.
+ *
+ * mt: main tracker for read or write accesses.
+ *
+ * ct: keeps track of container fetches, as the location of containers has
+ * special significance: it is both part of the seed used when
+ * encrypting/decryping container contents, and also is necessary to
+ * unwind reading of the container header when the end of storage is
+ * reached and a header of all 0xff is read.
+ *
+ * dt: keeps track of delimiters which is important when assessing flash
+ * contents integrity. If during startup the last item in flash is not a
+ * delimiter, this is an indication of a failed transaction, all data
+ * after the previous delimiter needs to be discarded.
+ *
+ * list_index; index of the current page in the list of pages, useful when
+ * sequential reading and need to get to the next page in the
+ * list.
+ */
+
+struct access_tracker {
+ struct page_tracker mt; /* Main tracker. */
+ struct page_tracker ct; /* Container tracker. */
+ struct page_tracker dt; /* Delimiter tracker.*/
+ uint8_t list_index;
+};
+
+enum ec_error_list new_nvmem_init(void);
+enum ec_error_list new_nvmem_migrate(unsigned int nvmem_act_partition);
+enum ec_error_list new_nvmem_save(void);
+
+enum ec_error_list get_next_object(struct access_tracker *at,
+ struct nn_container *ch,
+ int include_deleted);
+
+#if defined(TEST_BUILD) && !defined(TEST_FUZZ)
+#define NVMEM_TEST_BUILD
+enum ec_error_list browse_flash_contents(int);
+enum ec_error_list compact_nvmem(void);
+extern struct access_tracker master_at;
+extern uint16_t total_var_space;
+int is_uninitialized(const void *p, size_t size);
+size_t init_object_offsets(uint16_t *offsets, size_t count);
+struct nn_page_header *list_element_to_ph(size_t el);
+void *evictable_offs_to_addr(uint16_t offset);
+#endif
+
+/*
+ * Clear tpm data from nvmem.
+ */
+int nvmem_erase_tpm_data(void);
+
+#endif /* ! __TPM2_NVMEM_TEST_NEW_NVMEM_H */