/** * \brief Saves the random seed to EEPROM. * * During system startup, noise sources typically won't have accumulated * much entropy. But startup is usually the time when the system most * needs to generate random data for session keys, IV's, and the like. * * The purpose of this function is to pass some of the accumulated entropy * from one session to the next after a loss of power. Thus, once the system * has been running for a while it will get progressively better at generating * random values and the accumulated entropy will not be completely lost. * * Normally it isn't necessary to call save() directly. The loop() function * will automatically save the seed on a periodic basis (default of 1 hour). * * The seed that is saved is generated in such a way that it cannot be used * to predict random values that were generated previously or subsequently * in the current session. So a compromise of the EEPROM contents of a * captured device should not result in compromise of random values * that have already been generated. However, if power is lost and the * system restarted, then there will be a short period of time where the * random state will be predictable from the seed. For this reason it is * very important to stir() in new noise data at startup. * * \sa loop(), stir() */ void RNGClass::save() { // Generate random data from the current state and save // that as the seed. Then force a rekey. ++(block[12]); ChaCha::hashCore(stream, block, RNG_ROUNDS); #if defined(RNG_EEPROM) // We shorten the seed from 48 bytes to 47 to leave room for // the CRC-8 value. We do this to align the data on an 8-byte // boundary in EERPOM. int address = RNG_EEPROM_ADDRESS; eeprom_write_block(stream, (void *)address, SEED_SIZE - 1); eeprom_write_byte((uint8_t *)(address + SEED_SIZE - 1), crypto_crc8('S', stream, SEED_SIZE - 1)); #elif defined(RNG_DUE_TRNG) unsigned posn; ((uint32_t *)(RNG_SEED_ADDR))[0] = crypto_crc8('S', stream, SEED_SIZE); for (posn = 0; posn < 12; ++posn) ((uint32_t *)(RNG_SEED_ADDR))[posn + 1] = stream[posn]; for (posn = 13; posn < (RNG_FLASH_PAGE_SIZE / 4); ++posn) ((uint32_t *)(RNG_SEED_ADDR))[posn + 13] = 0xFFFFFFFF; eraseAndWriteSeed(); #elif defined(RNG_ESP_NVS) // Save the seed into ESP non-volatile storage (NVS). nvs_handle handle = 0; if (nvs_open("rng", NVS_READWRITE, &handle) == 0) { nvs_erase_all(handle); nvs_set_blob(handle, "seed", stream, SEED_SIZE); nvs_commit(handle); nvs_close(handle); } #endif rekey(); timer = millis(); }
/** * Save our connection info for retrieval on a subsequent restart. */ static void saveConnectionInfo(connection_info_t *pConnectionInfo) { nvs_handle handle; ESP_ERROR_CHECK(nvs_open(BOOTWIFI_NAMESPACE, NVS_READWRITE, &handle)); ESP_ERROR_CHECK(nvs_set_blob(handle, KEY_CONNECTION_INFO, pConnectionInfo, sizeof(connection_info_t))); ESP_ERROR_CHECK(nvs_set_u32(handle, KEY_VERSION, g_version)); ESP_ERROR_CHECK(nvs_commit(handle)); nvs_close(handle); } // setConnectionInfo
static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle, const esp_phy_calibration_data_t* cal_data) { esp_err_t err; uint32_t cal_format_version = phy_get_rf_cal_version() & (~BIT(16)); ESP_LOGV(TAG, "phy_get_rf_cal_version: %d\n", cal_format_version); err = nvs_set_u32(handle, PHY_CAL_VERSION_KEY, cal_format_version); if (err != ESP_OK) { return err; } uint8_t sta_mac[6]; esp_efuse_mac_get_default(sta_mac); err = nvs_set_blob(handle, PHY_CAL_MAC_KEY, sta_mac, sizeof(sta_mac)); if (err != ESP_OK) { return err; } err = nvs_set_blob(handle, PHY_CAL_DATA_KEY, cal_data, sizeof(*cal_data)); return err; }
bool config_save(const config_t *config, const char *filename) { assert(config != NULL); assert(filename != NULL); assert(*filename != '\0'); esp_err_t err; int err_code = 0; nvs_handle fp; char *line = osi_calloc(1024); char *keyname = osi_calloc(sizeof(CONFIG_KEY) + 1); int config_size = get_config_size(config); char *buf = osi_calloc(config_size + 100); if (!line || !buf || !keyname) { err_code |= 0x01; goto error; } err = nvs_open(filename, NVS_READWRITE, &fp); if (err != ESP_OK) { if (err == ESP_ERR_NVS_NOT_INITIALIZED) { LOG_ERROR("%s: NVS not initialized. " "Call nvs_flash_init before initializing bluetooth.", __func__); } err_code |= 0x02; goto error; } int w_cnt, w_cnt_total = 0; for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { const section_t *section = (const section_t *)list_node(node); w_cnt = snprintf(line, 1024, "[%s]\n", section->name); LOG_DEBUG("section name: %s, w_cnt + w_cnt_total = %d\n", section->name, w_cnt + w_cnt_total); memcpy(buf + w_cnt_total, line, w_cnt); w_cnt_total += w_cnt; for (const list_node_t *enode = list_begin(section->entries); enode != list_end(section->entries); enode = list_next(enode)) { const entry_t *entry = (const entry_t *)list_node(enode); LOG_DEBUG("(key, val): (%s, %s)\n", entry->key, entry->value); w_cnt = snprintf(line, 1024, "%s = %s\n", entry->key, entry->value); LOG_DEBUG("%s, w_cnt + w_cnt_total = %d", __func__, w_cnt + w_cnt_total); memcpy(buf + w_cnt_total, line, w_cnt); w_cnt_total += w_cnt; } // Only add a separating newline if there are more sections. if (list_next(node) != list_end(config->sections)) { buf[w_cnt_total] = '\n'; w_cnt_total += 1; } else { break; } } buf[w_cnt_total] = '\0'; if (w_cnt_total < CONFIG_FILE_MAX_SIZE) { snprintf(keyname, sizeof(CONFIG_KEY)+1, "%s%d", CONFIG_KEY, 0); err = nvs_set_blob(fp, keyname, buf, w_cnt_total); if (err != ESP_OK) { nvs_close(fp); err_code |= 0x04; goto error; } }else { uint count = (w_cnt_total / CONFIG_FILE_MAX_SIZE); for (int i = 0; i <= count; i++) { snprintf(keyname, sizeof(CONFIG_KEY)+1, "%s%d", CONFIG_KEY, i); if (i == count) { err = nvs_set_blob(fp, keyname, buf + i*CONFIG_FILE_MAX_SIZE, w_cnt_total - i*CONFIG_FILE_MAX_SIZE); LOG_DEBUG("save keyname = %s, i = %d, %d\n", keyname, i, w_cnt_total - i*CONFIG_FILE_MAX_SIZE); }else { err = nvs_set_blob(fp, keyname, buf + i*CONFIG_FILE_MAX_SIZE, CONFIG_FILE_MAX_SIZE); LOG_DEBUG("save keyname = %s, i = %d, %d\n", keyname, i, CONFIG_FILE_MAX_SIZE); } if (err != ESP_OK) { nvs_close(fp); err_code |= 0x04; goto error; } } } err = nvs_commit(fp); if (err != ESP_OK) { nvs_close(fp); err_code |= 0x08; goto error; } nvs_close(fp); osi_free(line); osi_free(buf); osi_free(keyname); return true; error: if (buf) { osi_free(buf); } if (line) { osi_free(line); } if (keyname) { osi_free(keyname); } if (err_code) { LOG_ERROR("%s, err_code: 0x%x\n", __func__, err_code); } return false; }