From 86052eec78e3377af7a007ec5fcd6ca7e8a58144 Mon Sep 17 00:00:00 2001 From: Shivani Tipnis Date: Thu, 14 Feb 2019 15:17:57 +0530 Subject: [PATCH 1/3] nvs_util: Fix to support write of multiple singlepage big blob data Closes https://github.com/espressif/esp-idf/issues/3011 (cherry picked from commit 60b5cdde2074c572e68754d9f1402c112d9ef4c9) --- .../nvs_partition_gen.py | 177 ++++++++---------- tools/ci/setup_python.sh | 6 +- 2 files changed, 86 insertions(+), 97 deletions(-) diff --git a/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py b/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py index 47242302e..99ee53ff6 100755 --- a/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py +++ b/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py @@ -39,6 +39,8 @@ VERSION2_PRINT = "v2 - Multipage Blob Support Enabled" """ Class for standard NVS page structure """ + + class Page(object): PAGE_PARAMS = { "max_size": 4096, @@ -68,8 +70,8 @@ class Page(object): CHUNK_ANY = 0xFF ACTIVE = 0xFFFFFFFE FULL = 0xFFFFFFFC - VERSION1=0xFF - VERSION2=0xFE + VERSION1 = 0xFF + VERSION2 = 0xFE def __init__(self, page_num, is_rsrv_page=False): self.entry_num = 0 @@ -77,7 +79,7 @@ class Page(object): self.encr_key = None self.bitmap_array = array.array('B') self.version = Page.VERSION2 - self.page_buf = bytearray(b'\xff')*Page.PAGE_PARAMS["max_size"] + self.page_buf = bytearray(b'\xff') * Page.PAGE_PARAMS["max_size"] if not is_rsrv_page: self.bitmap_array = self.create_bitmap_array() self.set_header(page_num) @@ -86,7 +88,7 @@ class Page(object): global page_header # set page state to active - page_header= bytearray(b'\xff') *32 + page_header = bytearray(b'\xff') * 32 page_state_active_seq = Page.ACTIVE struct.pack_into('=0, "Page overflow!!" + assert tailroom >= 0, "Page overflow!!" # Split the binary data into two and store a chunk of available size onto curr page if tailroom < remaining_size: @@ -266,7 +259,7 @@ class Page(object): # Calculate no. of entries data chunk will require datachunk_rounded_size = (chunk_size + 31) & ~31 datachunk_entry_count = datachunk_rounded_size // 32 - datachunk_total_entry_count = datachunk_entry_count + 1 # +1 for the entry header + datachunk_total_entry_count = datachunk_entry_count + 1 # +1 for the entry header # Set Span entry_struct[2] = datachunk_total_entry_count @@ -276,7 +269,7 @@ class Page(object): entry_struct[3] = chunk_index # Set data chunk - data_chunk = data[offset:offset + chunk_size] + data_chunk = data[offset:offset + chunk_size] # Compute CRC of data chunk struct.pack_into(' Page.PAGE_PARAMS["max_old_blob_size"]: + if datalen > Page.PAGE_PARAMS["max_old_blob_size"]: + if version == Page.VERSION1: raise InputError("Version %s\n%s: Size exceeds max allowed length." % (VERSION1_PRINT,key)) - - if version == Page.VERSION2: - if encoding == "string": - if datalen > Page.PAGE_PARAMS["max_new_blob_size"]: + else: + if encoding == "string": raise InputError("Version %s\n%s: Size exceeds max allowed length." % (VERSION2_PRINT,key)) # Calculate no. of entries data will require rounded_size = (datalen + 31) & ~31 data_entry_count = rounded_size // 32 - total_entry_count = data_entry_count + 1 # +1 for the entry header + total_entry_count = data_entry_count + 1 # +1 for the entry header # Check if page is already full and new page is needed to be created right away - if version == Page.VERSION1: - if encoding in ["string", "hex2bin", "binary", "base64"]: - if (self.entry_num + total_entry_count) >= Page.PAGE_PARAMS["max_entries"]: - raise PageFullError() - else: - if encoding == "string": - if (self.entry_num + total_entry_count) >= Page.PAGE_PARAMS["max_entries"]: - raise PageFullError() + if self.entry_num >= Page.PAGE_PARAMS["max_entries"]: + raise PageFullError() + elif (self.entry_num + total_entry_count) >= Page.PAGE_PARAMS["max_entries"]: + if not (version == Page.VERSION2 and encoding in ["hex2bin", "binary", "base64"]): + raise PageFullError() # Entry header - entry_struct = bytearray(b'\xff')*32 + entry_struct = bytearray(b'\xff') * 32 # Set Namespace Index entry_struct[0] = ns_index # Set Span @@ -414,27 +399,25 @@ class Page(object): entry_struct[1] = Page.BLOB if version == Page.VERSION2 and (encoding in ["hex2bin", "binary", "base64"]): - entry_struct = self.write_varlen_binary_data(entry_struct,ns_index,key,data,\ - datalen,total_entry_count, encoding, nvs_obj) + entry_struct = self.write_varlen_binary_data(entry_struct,ns_index,key,data, + datalen,total_entry_count, encoding, nvs_obj) else: self.write_single_page_entry(entry_struct, data, datalen, data_entry_count, nvs_obj) - - """ Low-level function to write data of primitive type into page buffer. """ def write_primitive_data(self, key, data, encoding, ns_index,nvs_obj): # Check if entry exceeds max number of entries allowed per page if self.entry_num >= Page.PAGE_PARAMS["max_entries"]: raise PageFullError() - entry_struct = bytearray(b'\xff')*32 - entry_struct[0] = ns_index # namespace index - entry_struct[2] = 0x01 # Span + entry_struct = bytearray(b'\xff') * 32 + entry_struct[0] = ns_index # namespace index + entry_struct[2] = 0x01 # Span chunk_index = Page.CHUNK_ANY entry_struct[3] = chunk_index # write key - key_array = b'\x00' *16 + key_array = b'\x00' * 16 entry_struct[8:24] = key_array entry_struct[8:8 + len(key)] = key.encode() @@ -469,9 +452,13 @@ class Page(object): def get_data(self): return self.page_buf + """ -NVS class encapsulates all NVS specific operations to create a binary with given key-value pairs. Binary can later be flashed onto device via a flashing utility. +NVS class encapsulates all NVS specific operations to create a binary with given key-value pairs. +Binary can later be flashed onto device via a flashing utility. """ + + class NVS(object): def __init__(self, fout, input_size): self.size = input_size @@ -485,11 +472,11 @@ class NVS(object): return self def __exit__(self, exc_type, exc_value, traceback): - if exc_type == None and exc_value == None: + if exc_type is None and exc_value is None: # Create pages for remaining available size while True: try: - new_page = self.create_new_page() + self.create_new_page() except InsufficientSizeError: self.size = None # Creating the last reserved page @@ -577,13 +564,15 @@ class NVS(object): data += page.get_data() return data + class PageFullError(RuntimeError): """ Represents error when current page doesn't have sufficient entries left to accommodate current request """ def __init__(self): - super(PageFullError, self).__init__() + super(PageFullError, self).__init__() + class InputError(RuntimeError): """ @@ -592,6 +581,7 @@ class InputError(RuntimeError): def __init__(self, e): super(InputError, self).__init__(e) + class InsufficientSizeError(RuntimeError): """ Represents error when NVS Partition size given is insufficient @@ -600,6 +590,7 @@ class InsufficientSizeError(RuntimeError): def __init__(self, e): super(InsufficientSizeError, self).__init__(e) + def nvs_open(result_obj, input_size): """ Wrapper to create and NVS class object. This object can later be used to set key-value pairs @@ -609,6 +600,7 @@ def nvs_open(result_obj, input_size): """ return NVS(result_obj, input_size) + def write_entry(nvs_instance, key, datatype, encoding, value): """ Wrapper to set key-value pair in NVS format @@ -622,7 +614,7 @@ def write_entry(nvs_instance, key, datatype, encoding, value): if datatype == "file": abs_file_path = value - if os.path.isabs(value) == False: + if os.path.isabs(value) is False: script_dir = os.path.dirname(__file__) abs_file_path = os.path.join(script_dir, value) @@ -634,6 +626,7 @@ def write_entry(nvs_instance, key, datatype, encoding, value): else: nvs_instance.write_entry(key, value, encoding) + def nvs_close(nvs_instance): """ Wrapper to finish writing to NVS and write data to file/stream object provided to nvs_open method @@ -643,8 +636,8 @@ def nvs_close(nvs_instance): nvs_instance.__exit__(None, None, None) -def check_input_args(input_filename=None, output_filename=None, input_part_size=None, is_key_gen=None,\ -encrypt_mode=None, key_file=None, version_no=None, print_arg_str=None, print_encrypt_arg_str=None): +def check_input_args(input_filename=None, output_filename=None, input_part_size=None, is_key_gen=None, + encrypt_mode=None, key_file=None, version_no=None, print_arg_str=None, print_encrypt_arg_str=None): global version, is_encrypt_data, input_size, key_gen @@ -658,7 +651,6 @@ encrypt_mode=None, key_file=None, version_no=None, print_arg_str=None, print_enc elif is_encrypt_data.lower() == 'false': is_encrypt_data = False - if version == 'v1': version = Page.VERSION1 elif version == 'v2': @@ -669,7 +661,6 @@ encrypt_mode=None, key_file=None, version_no=None, print_arg_str=None, print_enc elif key_gen.lower() == 'false': key_gen = False - if key_gen: if all(arg is not None for arg in [input_filename, output_filename, input_size]): if not is_encrypt_data: @@ -681,7 +672,6 @@ encrypt_mode=None, key_file=None, version_no=None, print_arg_str=None, print_enc if not all(arg is not None for arg in [input_filename, output_filename]): sys.exit(print_arg_str) - if is_encrypt_data and not key_gen and not key_file: sys.exit(print_encrypt_arg_str) @@ -695,7 +685,7 @@ encrypt_mode=None, key_file=None, version_no=None, print_arg_str=None, print_enc # Set size input_size = int(input_size, 0) - if input_size % 4096 !=0: + if input_size % 4096 != 0: sys.exit("Size of partition must be multiple of 4096") # Update size as a page needs to be reserved of size 4KB @@ -705,8 +695,6 @@ encrypt_mode=None, key_file=None, version_no=None, print_arg_str=None, print_enc sys.exit("Minimum NVS partition size needed is 0x3000 bytes.") - - def nvs_part_gen(input_filename=None, output_filename=None, input_part_size=None, is_key_gen=None, encrypt_mode=None, key_file=None, version_no=None): """ Wrapper to generate nvs partition binary @@ -749,9 +737,8 @@ def nvs_part_gen(input_filename=None, output_filename=None, input_part_size=None input_file.close() output_file.close() - if key_gen: - keys_page_buf = bytearray(b'\xff')*Page.PAGE_PARAMS["max_size"] + keys_page_buf = bytearray(b'\xff') * Page.PAGE_PARAMS["max_size"] key_bytes = bytearray() if len(key_input) == key_len_needed: key_bytes = key_input @@ -773,44 +760,44 @@ def main(): parser = argparse.ArgumentParser(description="ESP32 NVS partition generation utility") nvs_part_gen_group = parser.add_argument_group('To generate NVS partition') nvs_part_gen_group.add_argument( - "--input", - help="Path to CSV file to parse.", - default=None) + "--input", + help="Path to CSV file to parse.", + default=None) nvs_part_gen_group.add_argument( - "--output", - help='Path to output converted binary file.', - default=None) + "--output", + help='Path to output converted binary file.', + default=None) nvs_part_gen_group.add_argument( - "--size", - help='Size of NVS Partition in bytes (must be multiple of 4096)') + "--size", + help='Size of NVS Partition in bytes (must be multiple of 4096)') nvs_part_gen_group.add_argument( - "--version", - help='Set version. Default: v2', - choices=['v1','v2'], - default='v2', - type=str.lower) + "--version", + help='Set version. Default: v2', + choices=['v1','v2'], + default='v2', + type=str.lower) - keygen_action=nvs_part_gen_group.add_argument( - "--keygen", - help='Generate keys for encryption. Creates an `encryption_keys.bin` file. Default: false', - choices=['true','false'], - default= 'false', - type=str.lower) + keygen_action = nvs_part_gen_group.add_argument( + "--keygen", + help='Generate keys for encryption. Creates an `encryption_keys.bin` file. Default: false', + choices=['true','false'], + default='false', + type=str.lower) nvs_part_gen_group.add_argument( - "--encrypt", - help='Set encryption mode. Default: false', - choices=['true','false'], - default='false', - type=str.lower) + "--encrypt", + help='Set encryption mode. Default: false', + choices=['true','false'], + default='false', + type=str.lower) nvs_part_gen_group.add_argument( - "--keyfile", - help='File having key for encryption (Applicable only if encryption mode is true)', - default = None) + "--keyfile", + help='File having key for encryption (Applicable only if encryption mode is true)', + default=None) key_gen_group = parser.add_argument_group('To generate encryption keys') key_gen_group._group_actions.append(keygen_action) @@ -824,13 +811,13 @@ def main(): is_encrypt_data = args.encrypt key_file = args.keyfile - print_arg_str = "Invalid.\nTo generate nvs partition binary --input, --output and --size arguments are mandatory.\nTo generate encryption keys --keygen argument is mandatory." + print_arg_str = "Invalid.\nTo generate nvs partition binary --input, --output and --size arguments are mandatory.\n \ + To generate encryption keys --keygen argument is mandatory." print_encrypt_arg_str = "Missing parameter. Enter --keyfile or --keygen." check_input_args(input_filename,output_filename, part_size, is_key_gen, is_encrypt_data, key_file, version_no, print_arg_str, print_encrypt_arg_str) nvs_part_gen(input_filename, output_filename, part_size, is_key_gen, is_encrypt_data, key_file, version_no) - if __name__ == "__main__": main() diff --git a/tools/ci/setup_python.sh b/tools/ci/setup_python.sh index 296d00735..c134ba816 100644 --- a/tools/ci/setup_python.sh +++ b/tools/ci/setup_python.sh @@ -2,8 +2,10 @@ # Regexp for matching job names which are incompatible with Python 3 # - assign_test, nvs_compatible_test, IT - auto_test_script causes the incompatibility -# - UT_009_ - RS485 multi-device test is not started properly -py3_incomp='assign_test|nvs_compatible_test|IT|UT_009_' +# - UT_009_ - multi-device tests are not compatible +# - UT_014_ - multi-device tests are not compatible +# - UT_017_ - multi-device tests are not compatible +py3_incomp='assign_test|nvs_compatible_test|IT|UT_009_|UT_013_|UT_014_|UT_017_' if [ -z ${PYTHON_VER+x} ] || [[ $CI_JOB_NAME =~ $py3_incomp ]]; then # Use this version of the Python interpreter if it was not defined before or From 8480e79ae2645ebc73d8acef435b4daec124bed4 Mon Sep 17 00:00:00 2001 From: Shivani Tipnis Date: Wed, 28 Nov 2018 10:56:06 +0530 Subject: [PATCH 2/3] nvs_util: Add support for creation of unique encryption keys (cherry picked from commit 8b88b3303d83f5f03249e7b3410f6ecabaa00396) --- .../nvs_partition_generator/README.rst | 40 +++-- .../nvs_partition_gen.py | 168 ++++++++++++------ components/nvs_flash/test_nvs_host/Makefile | 5 + .../nvs_flash/test_nvs_host/test_nvs.cpp | 100 +++++++++-- 4 files changed, 224 insertions(+), 89 deletions(-) diff --git a/components/nvs_flash/nvs_partition_generator/README.rst b/components/nvs_flash/nvs_partition_generator/README.rst index 97a83b730..cf3126136 100644 --- a/components/nvs_flash/nvs_partition_generator/README.rst +++ b/components/nvs_flash/nvs_partition_generator/README.rst @@ -12,7 +12,7 @@ Prerequisites To use this utility in encryption mode, the following packages need to be installed: - cryptography package -This dependency is already captured by including these packages in `requirement.txt` in top level IDF directory. +These dependencies is already captured by including these packages in `requirement.txt` in top level IDF directory. CSV file format --------------- @@ -28,7 +28,7 @@ Type Encoding Supported values are: ``u8``, ``i8``, ``u16``, ``u32``, ``i32``, ``string``, ``hex2bin``, ``base64`` and ``binary``. This specifies how actual data values are encoded in the resultant binary file. Difference between ``string`` and ``binary`` encoding is that ``string`` data is terminated with a NULL character, whereas ``binary`` data is not. - .. note:: For ``file`` type, only ``hex2bin``, ``base64``, ``string`` and ``binary`` is supported as of now. +.. note:: For ``file`` type, only ``hex2bin``, ``base64``, ``string`` and ``binary`` is supported as of now. Value Data value. @@ -44,7 +44,7 @@ Below is an example dump of such CSV file:: key1,data,u8,1 key2,file,string,/path/to/file -.. note:: Make sure there are no spaces before and after ',' in CSV file. +.. note:: Make sure there are no spaces before and after ',' or at the end of each line in CSV file. NVS Entry and Namespace association ----------------------------------- @@ -71,7 +71,7 @@ Running the utility python nvs_partition_gen.py [-h] [--input INPUT] [--output OUTPUT] [--size SIZE] [--version {v1,v2}] [--keygen {true,false}] [--encrypt {true,false}] - [--keyfile KEYFILE] + [--keyfile KEYFILE] [--outdir OUTDIR] +------------------------+----------------------------------------------------------------------------------------------+ @@ -85,15 +85,14 @@ Running the utility +------------------------+----------------------------------------------------------------------------------------------+ | --version {v1,v2} | Set version. Default: v2 | +------------------------+----------------------------------------------------------------------------------------------+ -| --keygen {true,false} | Generate keys for encryption. Creates an `encryption_keys.bin` file (in current directory). | -| | Default: false | +| --keygen {true,false} | Generate keys for encryption. | +------------------------+----------------------------------------------------------------------------------------------+ | --encrypt {true,false} | Set encryption mode. Default: false | +------------------------+----------------------------------------------------------------------------------------------+ | --keyfile KEYFILE | File having key for encryption (Applicable only if encryption mode is true) | +------------------------+----------------------------------------------------------------------------------------------+ - - +| --outdir OUTDIR | The output directory to store the files created (Default: current directory) | ++------------------------+----------------------------------------------------------------------------------------------+ You can run this utility in two modes: - Default mode - Binary generated in this mode is an unencrypted binary file. @@ -108,7 +107,7 @@ You can run this utility in two modes: python nvs_partition_gen.py [-h] --input INPUT --output OUTPUT --size SIZE [--version {v1,v2}] [--keygen {true,false}] [--encrypt {true,false}] - [--keyfile KEYFILE] + [--keyfile KEYFILE] [--outdir OUTDIR] You can run the utility using below command:: @@ -123,28 +122,34 @@ You can run the utility using below command:: python nvs_partition_gen.py [-h] --input INPUT --output OUTPUT --size SIZE --encrypt {true,false} - --keygen {true,false} | --keyfile KEYFILE - [--version {v1,v2}] + --keygen {true,false} --keyfile KEYFILE + [--version {v1,v2}] [--outdir OUTDIR] You can run the utility using below commands: - - By taking encryption keys as an input file. A sample encryption keys binary file is provided with the utility:: - - python nvs_partition_gen.py --input sample.csv --output sample_encrypted.bin --size 0x3000 --encrypt true --keyfile testdata/sample_encryption_keys.bin - - By enabling generation of encryption keys:: python nvs_partition_gen.py --input sample.csv --output sample_encrypted.bin --size 0x3000 --encrypt true --keygen true + - By taking encryption keys as an input file. A sample encryption keys binary file is provided with the utility:: + + python nvs_partition_gen.py --input sample.csv --output sample_encrypted.bin --size 0x3000 --encrypt true --keyfile testdata/sample_encryption_keys.bin + + - By enabling generation of encryption keys and storing the keys in custom filename:: + + python nvs_partition_gen.py --input sample.csv --output sample_encrypted.bin --size 0x3000 --encrypt true --keygen true --keyfile encryption_keys_generated.bin + +.. note:: If `--keygen` is given with `--keyfile` argument, generated keys will be stored in `--keyfile` file. If `--keygen` argument is absent, `--keyfile` is taken as input file having key for encryption. -*To generate* **only** *encryption keys with this utility* ( Creates an `encryption_keys.bin` file in current directory ): :: +*To generate* **only** *encryption keys with this utility*:: python nvs_partition_gen.py --keygen true -.. note:: This `encryption_keys.bin` file is compatible with NVS key-partition structure. Refer to :ref:`nvs_key_partition` for more details. +This creates an `encryption_keys_.bin` file. +.. note:: This newly created file having encryption keys in `keys/` directory is compatible with NVS key-partition structure. Refer to :ref:`nvs_key_partition` for more details. You can also provide the format version number (in any of the two modes): @@ -179,3 +184,4 @@ Caveats - Utility doesn't check for duplicate keys and will write data pertaining to both keys. User needs to make sure keys are distinct. - Once a new page is created, no data will be written in the space left in previous page. Fields in the CSV file need to be ordered in such a way so as to optimize memory. - 64-bit datatype is not yet supported. + diff --git a/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py b/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py index 99ee53ff6..bf423334b 100755 --- a/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py +++ b/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py @@ -31,8 +31,14 @@ import array import csv import zlib import codecs -from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes -from cryptography.hazmat.backends import default_backend +import datetime +import distutils.dir_util +try: + from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes + from cryptography.hazmat.backends import default_backend +except ImportError: + print("cryptography package needs to be installed.\nRun: pip install cryptography>=2.1.4") + sys.exit(0) VERSION1_PRINT = "v1 - Multipage Blob Support Disabled" VERSION2_PRINT = "v2 - Multipage Blob Support Enabled" @@ -637,7 +643,8 @@ def nvs_close(nvs_instance): def check_input_args(input_filename=None, output_filename=None, input_part_size=None, is_key_gen=None, - encrypt_mode=None, key_file=None, version_no=None, print_arg_str=None, print_encrypt_arg_str=None): + encrypt_mode=None, key_file=None, version_no=None, print_arg_str=None, print_encrypt_arg_str=None, + output_dir=None): global version, is_encrypt_data, input_size, key_gen @@ -646,6 +653,12 @@ def check_input_args(input_filename=None, output_filename=None, input_part_size= key_gen = is_key_gen input_size = input_part_size + if not output_dir == os.getcwd() and (key_file and os.path.isabs(key_file)): + sys.exit("Error. Cannot provide --outdir argument as --keyfile is absolute path.") + + if not os.path.isdir(output_dir): + distutils.dir_util.mkpath(output_dir) + if is_encrypt_data.lower() == 'true': is_encrypt_data = True elif is_encrypt_data.lower() == 'false': @@ -668,18 +681,25 @@ def check_input_args(input_filename=None, output_filename=None, input_part_size= elif any(arg is not None for arg in [input_filename, output_filename, input_size]): sys.exit(print_arg_str) else: - if not input_size: - if not all(arg is not None for arg in [input_filename, output_filename]): - sys.exit(print_arg_str) + if not (input_filename and output_filename and input_size): + sys.exit(print_arg_str) - if is_encrypt_data and not key_gen and not key_file: - sys.exit(print_encrypt_arg_str) + if is_encrypt_data and not key_gen and not key_file: + sys.exit(print_encrypt_arg_str) - if is_encrypt_data and key_gen and key_file: - sys.exit(print_encrypt_arg_str) + if not is_encrypt_data and key_file: + sys.exit("Invalid. Cannot give --keyfile as --encrypt is set to false.") - if not is_encrypt_data and key_file: - sys.exit("Invalid. Cannot give --keyfile as --encrypt is set to false.") + if key_file: + key_file_name, key_file_ext = os.path.splitext(key_file) + if key_file_ext: + if not key_file_ext == '.bin': + sys.exit("--keyfile argument can be a filename with no extension or .bin extension only") + + # If only one of the arguments - input_filename, output_filename, input_size is given + if ((any(arg is None for arg in [input_filename, output_filename, input_size])) is True) and \ + ((all(arg is None for arg in [input_filename, output_filename, input_size])) is False): + sys.exit(print_arg_str) if input_size: # Set size @@ -695,7 +715,8 @@ def check_input_args(input_filename=None, output_filename=None, input_part_size= sys.exit("Minimum NVS partition size needed is 0x3000 bytes.") -def nvs_part_gen(input_filename=None, output_filename=None, input_part_size=None, is_key_gen=None, encrypt_mode=None, key_file=None, version_no=None): +def nvs_part_gen(input_filename=None, output_filename=None, input_part_size=None, is_key_gen=None, encrypt_mode=None, + key_file=None, encr_key_prefix=None, version_no=None, output_dir=None): """ Wrapper to generate nvs partition binary :param input_filename: Name of input file containing data @@ -709,6 +730,9 @@ def nvs_part_gen(input_filename=None, output_filename=None, input_part_size=None """ global key_input, key_len_needed + encr_key_bin_file = None + encr_keys_dir = None + backslash = ['/','\\'] key_len_needed = 64 key_input = bytearray() @@ -720,6 +744,8 @@ def nvs_part_gen(input_filename=None, output_filename=None, input_part_size=None key_input = key_f.read(64) if all(arg is not None for arg in [input_filename, output_filename, input_size]): + if not os.path.isabs(output_filename) and not any(ch in output_filename for ch in backslash): + output_filename = os.path.join(output_dir, '') + output_filename input_file = open(input_filename, 'rt', encoding='utf8') output_file = open(output_filename, 'wb') @@ -737,6 +763,8 @@ def nvs_part_gen(input_filename=None, output_filename=None, input_part_size=None input_file.close() output_file.close() + print("NVS binary created: " + output_filename) + if key_gen: keys_page_buf = bytearray(b'\xff') * Page.PAGE_PARAMS["max_size"] key_bytes = bytearray() @@ -750,57 +778,87 @@ def nvs_part_gen(input_filename=None, output_filename=None, input_part_size=None crc_data = bytes(crc_data) crc = zlib.crc32(crc_data, 0xFFFFFFFF) struct.pack_into(' #include #include +#include #include #include +#include #define TEST_ESP_ERR(rc, res) CHECK((rc) == (res)) #define TEST_ESP_OK(rc) CHECK((rc) == ESP_OK) @@ -2358,32 +2360,68 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena { int childpid = fork(); int status; - if (childpid == 0) { - exit(execlp("python", "python", - "../nvs_partition_generator/nvs_partition_gen.py", - "--input", - "../nvs_partition_generator/sample_multipage_blob.csv", - "--output", - "../nvs_partition_generator/partition_encrypted_using_keygen.bin", - "--size", - "0x4000", - "--encrypt", - "True", - "--keygen", - "true",NULL)); + if (childpid == 0) { + exit(execlp("rm", " rm", + "-rf", + "keys",NULL)); } else { CHECK(childpid > 0); waitpid(childpid, &status, 0); CHECK(WEXITSTATUS(status) != -1); + + childpid = fork(); + if (childpid == 0) { + exit(execlp("python", "python", + "../nvs_partition_generator/nvs_partition_gen.py", + "--input", + "../nvs_partition_generator/sample_multipage_blob.csv", + "--output", + "../nvs_partition_generator/partition_encrypted_using_keygen.bin", + "--size", + "0x4000", + "--encrypt", + "True", + "--keygen", + "true",NULL)); + + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) != -1); + + } } + + DIR *dir; + struct dirent *file; + char *filename; + char *files; + char *file_ext; + + dir = opendir("keys"); + while ((file = readdir(dir)) != NULL) + { + filename = file->d_name; + files = strrchr(filename, '.'); + if (files != NULL) + { + file_ext = files+1; + if (strncmp(file_ext,"bin",3) == 0) + { + break; + } + } + } + + std::string encr_file = std::string("keys/") + std::string(filename); SpiFlashEmulator emu("../nvs_partition_generator/partition_encrypted_using_keygen.bin"); char buffer[64]; FILE *fp; - fp = fopen("encryption_keys.bin","rb"); + fp = fopen(encr_file.c_str(),"rb"); fread(buffer,sizeof(buffer),1,fp); fclose(fp); @@ -2398,14 +2436,37 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena check_nvs_part_gen_args(NVS_DEFAULT_PART_NAME, 4, "../nvs_partition_generator/testdata/sample_multipage_blob.bin", true, &cfg); - } TEST_CASE("test nvs apis for nvs partition generator utility with encryption enabled using keyfile", "[nvs_part_gen]") { int childpid = fork(); int status; - if (childpid == 0) { + + DIR *dir; + struct dirent *file; + char *filename; + char *files; + char *file_ext; + + dir = opendir("keys"); + while ((file = readdir(dir)) != NULL) + { + filename = file->d_name; + files = strrchr(filename, '.'); + if (files != NULL) + { + file_ext = files+1; + if (strncmp(file_ext,"bin",3) == 0) + { + break; + } + } + } + + std::string encr_file = std::string("keys/") + std::string(filename); + + if (childpid == 0) { exit(execlp("python", "python", "../nvs_partition_generator/nvs_partition_gen.py", "--input", @@ -2417,7 +2478,7 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena "--encrypt", "True", "--keyfile", - "encryption_keys.bin",NULL)); + encr_file.c_str(),NULL)); } else { CHECK(childpid > 0); @@ -2430,7 +2491,7 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena char buffer[64]; FILE *fp; - fp = fopen("encryption_keys.bin","rb"); + fp = fopen(encr_file.c_str(),"rb"); fread(buffer,sizeof(buffer),1,fp); fclose(fp); @@ -2448,7 +2509,8 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena childpid = fork(); if (childpid == 0) { exit(execlp("rm", " rm", - "encryption_keys.bin",NULL)); + "-rf", + "keys",NULL)); } else { CHECK(childpid > 0); waitpid(childpid, &status, 0); From 5d2c23c8abc51261d38cdac759abf375c4d5823a Mon Sep 17 00:00:00 2001 From: Shivani Tipnis Date: Wed, 28 Nov 2018 10:56:06 +0530 Subject: [PATCH 3/3] nvs_util: Add support for creation of unique encryption keys (cherry picked from commit e1f466e708c2c1b825e955ec28b70dc3058f9262) --- .../nvs_partition_gen.py | 8 +- .../nvs_flash/test_nvs_host/test_nvs.cpp | 266 ++++++++++++------ 2 files changed, 180 insertions(+), 94 deletions(-) diff --git a/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py b/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py index bf423334b..be50d4608 100755 --- a/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py +++ b/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py @@ -37,8 +37,10 @@ try: from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend except ImportError: - print("cryptography package needs to be installed.\nRun: pip install cryptography>=2.1.4") - sys.exit(0) + print('The cryptography package is not installed.' + 'Please refer to the Get Started section of the ESP-IDF Programming Guide for ' + 'setting up the required packages.') + raise VERSION1_PRINT = "v1 - Multipage Blob Support Disabled" VERSION2_PRINT = "v2 - Multipage Blob Support Enabled" @@ -621,7 +623,7 @@ def write_entry(nvs_instance, key, datatype, encoding, value): if datatype == "file": abs_file_path = value if os.path.isabs(value) is False: - script_dir = os.path.dirname(__file__) + script_dir = os.getcwd() abs_file_path = os.path.join(script_dir, value) with open(abs_file_path, 'rb') as f: diff --git a/components/nvs_flash/test_nvs_host/test_nvs.cpp b/components/nvs_flash/test_nvs_host/test_nvs.cpp index 2f2447f71..2d02c9134 100644 --- a/components/nvs_flash/test_nvs_host/test_nvs.cpp +++ b/components/nvs_flash/test_nvs_host/test_nvs.cpp @@ -827,7 +827,7 @@ TEST_CASE("nvs api tests, starting with random data in flash", "[nvs][long]") extern "C" void nvs_dump(const char *partName); class RandomTest { - + static const size_t nKeys = 11; int32_t v1 = 0, v2 = 0; uint64_t v3 = 0, v4 = 0; @@ -846,12 +846,12 @@ public: template esp_err_t doRandomThings(nvs_handle handle, TGen gen, size_t& count) { - + const char* keys[] = {"foo", "bar", "longkey_0123456", "another key", "param1", "param2", "param3", "param4", "param5", "singlepage", "multipage"}; const ItemType types[] = {ItemType::I32, ItemType::I32, ItemType::U64, ItemType::U64, ItemType::SZ, ItemType::SZ, ItemType::SZ, ItemType::SZ, ItemType::SZ, ItemType::BLOB, ItemType::BLOB}; - + void* values[] = {&v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9, &v10, &v11}; - + const size_t nKeys = sizeof(keys) / sizeof(keys[0]); static_assert(nKeys == sizeof(types) / sizeof(types[0]), ""); static_assert(nKeys == sizeof(values) / sizeof(values[0]), ""); @@ -1067,7 +1067,7 @@ public: return ESP_OK; } - esp_err_t handleExternalWriteAtIndex(uint8_t index, const void* value, const size_t len ) { + esp_err_t handleExternalWriteAtIndex(uint8_t index, const void* value, const size_t len ) { if(index == 9) { /* This is only done for small-page blobs for now*/ if(len > smallBlobLen) { return ESP_FAIL; @@ -1078,7 +1078,7 @@ public: } else { return ESP_FAIL; } - } + } }; TEST_CASE("monkey test", "[nvs][monkey]") @@ -1091,7 +1091,7 @@ TEST_CASE("monkey test", "[nvs][monkey]") SpiFlashEmulator emu(10); emu.randomize(seed); emu.clearStats(); - + const uint32_t NVS_FLASH_SECTOR = 2; const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 8; emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN); @@ -1116,10 +1116,10 @@ TEST_CASE("test recovery from sudden poweroff", "[long][nvs][recovery][monkey]") const size_t iter_count = 2000; SpiFlashEmulator emu(10); - + const uint32_t NVS_FLASH_SECTOR = 2; const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 8; - + emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN); size_t totalOps = 0; @@ -1788,7 +1788,7 @@ TEST_CASE("nvs code handles errors properly when partition is near to full", "[n SpiFlashEmulator emu(5); Storage storage; char nvs_key[16] = ""; - + TEST_ESP_OK(storage.init(0, 5)); /* Four pages should fit roughly 12 blobs*/ @@ -1796,7 +1796,7 @@ TEST_CASE("nvs code handles errors properly when partition is near to full", "[n sprintf(nvs_key, "key:%u", count); TEST_ESP_OK(storage.writeItem(1, ItemType::BLOB, nvs_key, blob, sizeof(blob))); } - + for(uint8_t count = 13; count <= 20; count++) { sprintf(nvs_key, "key:%u", count); TEST_ESP_ERR(storage.writeItem(1, ItemType::BLOB, nvs_key, blob, sizeof(blob)), ESP_ERR_NVS_NOT_ENOUGH_SPACE); @@ -1823,7 +1823,7 @@ TEST_CASE("Check that NVS supports old blob format without blob index", "[nvs]") TEST_ESP_OK( nvs_flash_init_custom("test", 0, 2) ); TEST_ESP_OK( nvs_open_from_partition("test", "dummyNamespace", NVS_READONLY, &handle)); - + char buf[64] = {0}; size_t buflen = 64; uint8_t hexdata[] = {0x01, 0x02, 0x03, 0xab, 0xcd, 0xef}; @@ -1855,7 +1855,7 @@ TEST_CASE("Check that NVS supports old blob format without blob index", "[nvs]") TEST_ESP_OK(p2.findItem(1, ItemType::BLOB_IDX, "dummyHex2BinKey")); /* Read the blob in new format and check the contents*/ - buflen = 64; + buflen = 64; TEST_ESP_OK( nvs_get_blob(handle, "dummyBase64Key", buf, &buflen)); CHECK(memcmp(buf, base64data, buflen) == 0); @@ -1867,29 +1867,29 @@ TEST_CASE("monkey test with old-format blob present", "[nvs][monkey]") std::mt19937 gen(rd()); uint32_t seed = 3; gen.seed(seed); - + SpiFlashEmulator emu(10); emu.randomize(seed); emu.clearStats(); - + const uint32_t NVS_FLASH_SECTOR = 2; const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 8; static const size_t smallBlobLen = Page::CHUNK_MAX_SIZE / 3; emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN); - + TEST_ESP_OK(nvs_flash_init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)); - + nvs_handle handle; TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle)); RandomTest test; - - for ( uint8_t it = 0; it < 10; it++) { + + for ( uint8_t it = 0; it < 10; it++) { size_t count = 200; - + /* Erase index and chunks for the blob with "singlepage" key */ for (uint8_t num = NVS_FLASH_SECTOR; num < NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN; num++) { - Page p; + Page p; p.load(num); p.eraseItem(1, ItemType::BLOB, "singlepage", Item::CHUNK_ANY, VerOffset::VER_ANY); p.eraseItem(1, ItemType::BLOB_IDX, "singlepage", Item::CHUNK_ANY, VerOffset::VER_ANY); @@ -1898,7 +1898,7 @@ TEST_CASE("monkey test with old-format blob present", "[nvs][monkey]") /* Now write "singlepage" blob in old format*/ for (uint8_t num = NVS_FLASH_SECTOR; num < NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN; num++) { - Page p; + Page p; p.load(num); if (p.state() == Page::PageState::ACTIVE) { uint8_t buf[smallBlobLen]; @@ -1907,7 +1907,7 @@ TEST_CASE("monkey test with old-format blob present", "[nvs][monkey]") if(blobLen > p.getVarDataTailroom()) { blobLen = p.getVarDataTailroom(); } - + std::generate_n(buf, blobLen, [&]() -> uint8_t { return static_cast(gen() % 256); }); @@ -1915,14 +1915,14 @@ TEST_CASE("monkey test with old-format blob present", "[nvs][monkey]") TEST_ESP_OK(p.writeItem(1, ItemType::BLOB, "singlepage", buf, blobLen, Item::CHUNK_ANY)); TEST_ESP_OK(p.findItem(1, ItemType::BLOB, "singlepage")); test.handleExternalWriteAtIndex(9, buf, blobLen); // This assumes "singlepage" is always at index 9 - + break; } } /* Initialize again */ TEST_ESP_OK(nvs_flash_init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)); TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle)); - + /* Perform random things */ auto res = test.doRandomThings(handle, gen, count); if (res != ESP_OK) { @@ -1935,7 +1935,7 @@ TEST_CASE("monkey test with old-format blob present", "[nvs][monkey]") bool oldVerPresent = false, newVerPresent = false; for (uint8_t num = NVS_FLASH_SECTOR; num < NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN; num++) { - Page p; + Page p; p.load(num); if(!oldVerPresent && p.findItem(1, ItemType::BLOB, "singlepage", Item::CHUNK_ANY, VerOffset::VER_ANY) == ESP_OK) { oldVerPresent = true; @@ -1947,7 +1947,7 @@ TEST_CASE("monkey test with old-format blob present", "[nvs][monkey]") } CHECK(oldVerPresent != newVerPresent); } - + s_perf << "Monkey test: nErase=" << emu.getEraseOps() << " nWrite=" << emu.getWriteOps() << std::endl; } @@ -1957,23 +1957,23 @@ TEST_CASE("Recovery from power-off during modification of blob present in old-fo std::mt19937 gen(rd()); uint32_t seed = 3; gen.seed(seed); - + SpiFlashEmulator emu(3); emu.clearStats(); - + TEST_ESP_OK(nvs_flash_init_custom(NVS_DEFAULT_PART_NAME, 0, 3)); - + nvs_handle handle; TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle)); - + uint8_t hexdata[] = {0x01, 0x02, 0x03, 0xab, 0xcd, 0xef}; uint8_t hexdata_old[] = {0x11, 0x12, 0x13, 0xbb, 0xcc, 0xee}; - size_t buflen = sizeof(hexdata); + size_t buflen = sizeof(hexdata); uint8_t buf[Page::CHUNK_MAX_SIZE]; /* Power-off when blob was being written on the same page where its old version in old format - * was present*/ - Page p; + * was present*/ + Page p; p.load(0); /* Write blob in old-format*/ TEST_ESP_OK(p.writeItem(1, ItemType::BLOB, "singlepage", hexdata_old, sizeof(hexdata_old))); @@ -1997,7 +1997,7 @@ TEST_CASE("Recovery from power-off during modification of blob present in old-fo TEST_ESP_OK( nvs_get_blob(handle, "singlepage", buf, &buflen)); CHECK(memcmp(buf, hexdata, buflen) == 0); - Page p2; + Page p2; p2.load(0); TEST_ESP_ERR(p2.findItem(1, ItemType::BLOB, "singlepage"), ESP_ERR_NVS_TYPE_MISMATCH); @@ -2009,7 +2009,7 @@ TEST_CASE("Recovery from power-off during modification of blob present in old-fo std::mt19937 gen(rd()); uint32_t seed = 3; gen.seed(seed); - + SpiFlashEmulator emu(3); emu.clearStats(); @@ -2020,13 +2020,13 @@ TEST_CASE("Recovery from power-off during modification of blob present in old-fo uint8_t hexdata[] = {0x01, 0x02, 0x03, 0xab, 0xcd, 0xef}; uint8_t hexdata_old[] = {0x11, 0x12, 0x13, 0xbb, 0xcc, 0xee}; - size_t buflen = sizeof(hexdata); + size_t buflen = sizeof(hexdata); uint8_t buf[Page::CHUNK_MAX_SIZE]; /* Power-off when blob was being written on the different page where its old version in old format - * was present*/ - Page p; + * was present*/ + Page p; p.load(0); /* Write blob in old-format*/ TEST_ESP_OK(p.writeItem(1, ItemType::BLOB, "singlepage", hexdata_old, sizeof(hexdata_old))); @@ -2039,7 +2039,7 @@ TEST_CASE("Recovery from power-off during modification of blob present in old-fo item.blobIndex.chunkCount = 1; item.blobIndex.chunkStart = VerOffset::VER_0_OFFSET; p.markFull(); - Page p2; + Page p2; p2.load(1); p2.setSeqNumber(1); @@ -2054,7 +2054,7 @@ TEST_CASE("Recovery from power-off during modification of blob present in old-fo TEST_ESP_OK( nvs_get_blob(handle, "singlepage", buf, &buflen)); CHECK(memcmp(buf, hexdata, buflen) == 0); - Page p3; + Page p3; p3.load(0); TEST_ESP_ERR(p3.findItem(1, ItemType::BLOB, "singlepage"), ESP_ERR_NVS_NOT_FOUND); } @@ -2062,12 +2062,12 @@ TEST_CASE("Recovery from power-off during modification of blob present in old-fo static void check_nvs_part_gen_args(char const *part_name, int size, char const *filename, bool is_encr, nvs_sec_cfg_t* xts_cfg) { nvs_handle handle; - + if (is_encr) TEST_ESP_OK(nvs_flash_secure_init_custom(part_name, 0, size, xts_cfg)); else TEST_ESP_OK( nvs_flash_init_custom(part_name, 0, size) ); - + TEST_ESP_OK( nvs_open_from_partition(part_name, "dummyNamespace", NVS_READONLY, &handle)); uint8_t u8v; TEST_ESP_OK( nvs_get_u8(handle, "dummyU8Key", &u8v)); @@ -2095,7 +2095,7 @@ static void check_nvs_part_gen_args(char const *part_name, int size, char const int j; TEST_ESP_OK( nvs_get_blob(handle, "dummyHex2BinKey", buf, &buflen)); CHECK(memcmp(buf, hexdata, buflen) == 0); - + uint8_t base64data[] = {'1', '2', '3', 'a', 'b', 'c'}; TEST_ESP_OK( nvs_get_blob(handle, "dummyBase64Key", buf, &buflen)); CHECK(memcmp(buf, base64data, buflen) == 0); @@ -2120,65 +2120,112 @@ static void check_nvs_part_gen_args(char const *part_name, int size, char const CHECK(memcmp(bin_data, binfiledata, bin_len) == 0); file.close(); - + nvs_close(handle); } TEST_CASE("check and read data from partition generated via partition generation utility with multipage blob support disabled", "[nvs_part_gen]") { + int status; int childpid = fork(); if (childpid == 0) { - exit(execlp("python", "python", - "../nvs_partition_generator/nvs_partition_gen.py", - "--input", - "../nvs_partition_generator/sample_singlepage_blob.csv", - "--output", - "../nvs_partition_generator/partition_single_page.bin", - "--size", - "0x3000", - "--version", - "v1",NULL)); + exit(execlp("cp", " cp", + "-rf", + "../nvs_partition_generator/testdata", + ".",NULL)); } else { CHECK(childpid > 0); - int status; waitpid(childpid, &status, 0); CHECK(WEXITSTATUS(status) != -1); + + childpid = fork(); + + if (childpid == 0) { + exit(execlp("python", "python", + "../nvs_partition_generator/nvs_partition_gen.py", + "--input", + "../nvs_partition_generator/sample_singlepage_blob.csv", + "--output", + "../nvs_partition_generator/partition_single_page.bin", + "--size", + "0x3000", + "--version", + "v1",NULL)); + } else { + CHECK(childpid > 0); + int status; + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) != -1); + } } SpiFlashEmulator emu("../nvs_partition_generator/partition_single_page.bin"); - - TEST_ESP_OK(nvs_flash_deinit()); - - check_nvs_part_gen_args("test", 3, "../nvs_partition_generator/testdata/sample_singlepage_blob.bin", false, NULL); -} + TEST_ESP_OK(nvs_flash_deinit()); + + check_nvs_part_gen_args("test", 3, "../nvs_partition_generator/testdata/sample_singlepage_blob.bin", false, NULL); + + if (childpid == 0) { + exit(execlp("rm", " rm", + "-rf", + "testdata",NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) != -1); + + } +} TEST_CASE("check and read data from partition generated via partition generation utility with multipage blob support enabled", "[nvs_part_gen]") { + int status; int childpid = fork(); if (childpid == 0) { - exit(execlp("python", "python", - "../nvs_partition_generator/nvs_partition_gen.py", - "--input", - "../nvs_partition_generator/sample_multipage_blob.csv", - "--output", - "../nvs_partition_generator/partition_multipage_blob.bin", - "--size", - "0x4000", - "--version", - "v2",NULL)); + exit(execlp("cp", " cp", + "-rf", + "../nvs_partition_generator/testdata", + ".",NULL)); } else { CHECK(childpid > 0); - int status; waitpid(childpid, &status, 0); CHECK(WEXITSTATUS(status) != -1); + + childpid = fork(); + + if (childpid == 0) { + exit(execlp("python", "python", + "../nvs_partition_generator/nvs_partition_gen.py", + "--input", + "../nvs_partition_generator/sample_multipage_blob.csv", + "--output", + "../nvs_partition_generator/partition_multipage_blob.bin", + "--size", + "0x4000", + "--version", + "v2",NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) != -1); + } } SpiFlashEmulator emu("../nvs_partition_generator/partition_multipage_blob.bin"); - + check_nvs_part_gen_args("test", 4, "../nvs_partition_generator/testdata/sample_multipage_blob.bin",false,NULL); + if (childpid == 0) { + exit(execlp("rm", " rm", + "-rf", + "testdata",NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) != -1); + + } } #if CONFIG_NVS_ENCRYPTION @@ -2322,29 +2369,42 @@ TEST_CASE("test nvs apis with encryption enabled", "[nvs]") TEST_CASE("test nvs apis for nvs partition generator utility with encryption enabled", "[nvs_part_gen]") { + int status; int childpid = fork(); if (childpid == 0) { - exit(execlp("python", "python", - "../nvs_partition_generator/nvs_partition_gen.py", - "--input", - "../nvs_partition_generator/sample_multipage_blob.csv", - "--output", - "../nvs_partition_generator/partition_encrypted.bin", - "--size", - "0x4000", - "--encrypt", - "True", - "--keyfile", - "../nvs_partition_generator/testdata/sample_encryption_keys.bin",NULL)); + exit(execlp("cp", " cp", + "-rf", + "../nvs_partition_generator/testdata", + ".",NULL)); } else { CHECK(childpid > 0); - int status; waitpid(childpid, &status, 0); CHECK(WEXITSTATUS(status) != -1); + + childpid = fork(); + + if (childpid == 0) { + exit(execlp("python", "python", + "../nvs_partition_generator/nvs_partition_gen.py", + "--input", + "../nvs_partition_generator/sample_multipage_blob.csv", + "--output", + "../nvs_partition_generator/partition_encrypted.bin", + "--size", + "0x4000", + "--encrypt", + "True", + "--keyfile", + "../nvs_partition_generator/testdata/sample_encryption_keys.bin",NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) != -1); + } } SpiFlashEmulator emu("../nvs_partition_generator/partition_encrypted.bin"); - + nvs_sec_cfg_t cfg; for(int count = 0; count < NVS_KEY_SIZE; count++) { cfg.eky[count] = 0x11; @@ -2352,7 +2412,19 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena } check_nvs_part_gen_args(NVS_DEFAULT_PART_NAME, 4, "../nvs_partition_generator/testdata/sample_multipage_blob.bin", true, &cfg); - + + childpid = fork(); + if (childpid == 0) { + exit(execlp("rm", " rm", + "-rf", + "testdata",NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) != -1); + + } + } @@ -2362,9 +2434,10 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena int status; if (childpid == 0) { - exit(execlp("rm", " rm", + exit(execlp("cp", " cp", "-rf", - "keys",NULL)); + "../nvs_partition_generator/testdata", + ".",NULL)); } else { CHECK(childpid > 0); waitpid(childpid, &status, 0); @@ -2417,7 +2490,7 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena std::string encr_file = std::string("keys/") + std::string(filename); SpiFlashEmulator emu("../nvs_partition_generator/partition_encrypted_using_keygen.bin"); - + char buffer[64]; FILE *fp; @@ -2516,6 +2589,17 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena waitpid(childpid, &status, 0); CHECK(WEXITSTATUS(status) != -1); + childpid = fork(); + + if (childpid == 0) { + exit(execlp("rm", " rm", + "-rf", + "testdata",NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) != -1); + } } }