diff options
Diffstat (limited to 'include/new_nvmem.h')
-rw-r--r-- | include/new_nvmem.h | 155 |
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 */ |