LCOV - code coverage report
Current view: top level - hal/sgx/src/trusted - nvmem.c (source / functions) Hit Total Coverage
Test: powHSM firmware Lines: 52 52 100.0 %
Date: 2025-07-10 13:49:13 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /**
       2             :  * The MIT License (MIT)
       3             :  *
       4             :  * Copyright (c) 2021 RSK Labs Ltd
       5             :  *
       6             :  * Permission is hereby granted, free of charge, to any person obtaining a copy
       7             :  * of this software and associated documentation files (the "Software"), to
       8             :  * deal in the Software without restriction, including without limitation the
       9             :  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
      10             :  * sell copies of the Software, and to permit persons to whom the Software is
      11             :  * furnished to do so, subject to the following conditions:
      12             :  *
      13             :  * The above copyright notice and this permission notice shall be included in
      14             :  * all copies or substantial portions of the Software.
      15             :  *
      16             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      17             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      18             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      19             :  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      20             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      21             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
      22             :  * IN THE SOFTWARE.
      23             :  */
      24             : 
      25             : #include <stdlib.h>
      26             : #include <stdbool.h>
      27             : #include <string.h>
      28             : 
      29             : #include "hal/nvmem.h"
      30             : #include "hal/log.h"
      31             : 
      32             : #include "secret_store.h"
      33             : 
      34             : #define MAX_NVM_BLOCKS 5
      35             : 
      36             : typedef struct {
      37             :     char* key;
      38             :     void* addr;
      39             :     size_t size;
      40             : } nvm_block_t;
      41             : 
      42             : static nvm_block_t nvm_blocks[MAX_NVM_BLOCKS];
      43             : static unsigned int nvm_blocks_count;
      44             : 
      45             : #define STORE_PREFIX "nvmem-"
      46             : 
      47          14 : static char* store_key_for(char* key) {
      48          14 :     size_t key_size = strlen(STORE_PREFIX) + strlen(key);
      49          14 :     char* store_key = malloc(key_size + 1);
      50          14 :     strcpy(store_key, "");
      51          14 :     strcat(store_key, STORE_PREFIX);
      52          14 :     strcat(store_key, key);
      53          14 :     return store_key;
      54             : }
      55             : 
      56          10 : void nvmem_init() {
      57          10 :     memset(nvm_blocks, 0, sizeof(nvm_blocks));
      58          10 :     nvm_blocks_count = 0;
      59          10 : }
      60             : 
      61          18 : bool nvmem_register_block(char* key, void* addr, size_t size) {
      62          18 :     if (nvm_blocks_count >= MAX_NVM_BLOCKS) {
      63             :         LOG("Error registering NVM block <%s>: too many blocks\n", key);
      64           1 :         return false;
      65             :     }
      66             : 
      67          17 :     nvm_blocks[nvm_blocks_count].key = key;
      68          17 :     nvm_blocks[nvm_blocks_count].addr = addr;
      69          17 :     nvm_blocks[nvm_blocks_count].size = size;
      70          17 :     nvm_blocks_count++;
      71             : 
      72          17 :     return true;
      73             : }
      74             : 
      75           1 : static void clear_blocks() {
      76           2 :     for (unsigned int i = 0; i < nvm_blocks_count; i++) {
      77           1 :         memset((uint8_t*)nvm_blocks[i].addr, 0, nvm_blocks[i].size);
      78             :     }
      79           1 : }
      80             : 
      81           7 : bool nvmem_load() {
      82             :     LOG("Loading NVM blocks...\n");
      83          12 :     for (unsigned int i = 0; i < nvm_blocks_count; i++) {
      84           6 :         char* key = store_key_for(nvm_blocks[i].key);
      85           6 :         if (sest_exists(key)) {
      86           5 :             uint8_t* tmp = malloc(nvm_blocks[i].size);
      87           5 :             if (sest_read(key, tmp, nvm_blocks[i].size) == nvm_blocks[i].size) {
      88           4 :                 memcpy((uint8_t*)nvm_blocks[i].addr, tmp, nvm_blocks[i].size);
      89             :             } else {
      90             :                 LOG("Error loading NVM block <%s>\n", nvm_blocks[i].key);
      91           1 :                 clear_blocks();
      92           1 :                 free(key);
      93           1 :                 free(tmp);
      94           1 :                 return false;
      95             :             }
      96           4 :             free(tmp);
      97             :         } else {
      98             :             LOG("No record found for NVM block <%s>\n", nvm_blocks[i].key);
      99           1 :             memset((uint8_t*)nvm_blocks[i].addr, 0, nvm_blocks[i].size);
     100             :         }
     101           5 :         free(key);
     102             :     }
     103           6 :     return true;
     104             : }
     105             : 
     106           9 : static bool nvmem_flush() {
     107             :     LOG("Flushing NVM blocks...\n");
     108          16 :     for (unsigned int i = 0; i < nvm_blocks_count; i++) {
     109           8 :         char* key = store_key_for(nvm_blocks[i].key);
     110           8 :         if (!sest_write(
     111           8 :                 key, (uint8_t*)nvm_blocks[i].addr, nvm_blocks[i].size)) {
     112             :             LOG("Error flushing NVM block <%s>\n", nvm_blocks[i].key);
     113           1 :             free(key);
     114           1 :             return false;
     115             :         }
     116           7 :         free(key);
     117             :     }
     118           8 :     return true;
     119             : }
     120             : 
     121           9 : bool nvmem_write(void* dst, void* src, unsigned int length) {
     122           9 :     if (src == NULL) {
     123             :         // Treat as memory reset
     124           1 :         memset(dst, 0, length);
     125             :     } else {
     126             :         // Treat as normal copy
     127           8 :         memmove(dst, src, length);
     128             :     }
     129             :     // Flush to disk
     130           9 :     return nvmem_flush();
     131             : }

Generated by: LCOV version 1.16