esptool 4.9.dev8__tar.gz → 4.10.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. {esptool-4.9.dev8/esptool.egg-info → esptool-4.10.dev1}/PKG-INFO +1 -1
  2. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/base_operations.py +161 -0
  3. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c3/fields.py +1 -0
  4. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c3/operations.py +7 -9
  5. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c5/fields.py +15 -7
  6. esptool-4.10.dev1/espefuse/efuse/esp32c5/operations.py +390 -0
  7. {esptool-4.9.dev8/espefuse/efuse/esp32c61 → esptool-4.10.dev1/espefuse/efuse/esp32c6}/fields.py +18 -10
  8. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c6/operations.py +7 -9
  9. {esptool-4.9.dev8/espefuse/efuse/esp32c6 → esptool-4.10.dev1/espefuse/efuse/esp32c61}/fields.py +5 -8
  10. esptool-4.10.dev1/espefuse/efuse/esp32c61/operations.py +391 -0
  11. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h2/fields.py +1 -0
  12. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h2/operations.py +8 -17
  13. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h21/operations.py +8 -17
  14. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h4/fields.py +5 -0
  15. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h4/operations.py +8 -17
  16. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32p4/fields.py +12 -2
  17. esptool-4.10.dev1/espefuse/efuse/esp32p4/operations.py +391 -0
  18. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s2/operations.py +7 -75
  19. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s3/fields.py +1 -0
  20. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s3/operations.py +7 -75
  21. esptool-4.10.dev1/espefuse/efuse_defs/esp32c61.yaml +105 -0
  22. {esptool-4.9.dev8 → esptool-4.10.dev1}/espsecure/__init__.py +2 -2
  23. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/__init__.py +17 -7
  24. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/bin_image.py +104 -39
  25. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/cmds.py +78 -82
  26. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/loader.py +204 -75
  27. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32.py +1 -4
  28. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32c2.py +0 -1
  29. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32c3.py +0 -1
  30. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32c5.py +0 -1
  31. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32c5beta3.py +0 -1
  32. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32c6.py +0 -1
  33. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32c61.py +0 -1
  34. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32h2.py +0 -1
  35. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32h21.py +0 -1
  36. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32h2beta1.py +0 -1
  37. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32h2beta2.py +0 -1
  38. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32h4.py +0 -1
  39. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32p4.py +0 -1
  40. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32s2.py +0 -1
  41. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32s3.py +0 -1
  42. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32s3beta2.py +0 -1
  43. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/stub_flasher/1/README.md +1 -1
  44. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32.json +8 -0
  45. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32c2.json +8 -0
  46. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32c3.json +8 -0
  47. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32c5.json +8 -0
  48. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32c5beta3.json +8 -0
  49. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32c6.json +8 -0
  50. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32c61.json +8 -0
  51. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32c6beta.json +8 -0
  52. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32h2.json +8 -0
  53. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32h2beta1.json +8 -0
  54. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32h2beta2.json +8 -0
  55. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32p4.json +8 -0
  56. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32s2.json +8 -0
  57. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32s3.json +8 -0
  58. esptool-4.10.dev1/esptool/targets/stub_flasher/1/esp32s3beta2.json +8 -0
  59. {esptool-4.9.dev8 → esptool-4.10.dev1/esptool.egg-info}/PKG-INFO +1 -1
  60. {esptool-4.9.dev8 → esptool-4.10.dev1}/pyproject.toml +1 -1
  61. esptool-4.9.dev8/espefuse/efuse/esp32c5/operations.py +0 -466
  62. esptool-4.9.dev8/espefuse/efuse/esp32c61/operations.py +0 -466
  63. esptool-4.9.dev8/espefuse/efuse/esp32p4/operations.py +0 -466
  64. esptool-4.9.dev8/espefuse/efuse_defs/esp32c61.yaml +0 -95
  65. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32.json +0 -8
  66. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32c2.json +0 -8
  67. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32c3.json +0 -8
  68. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32c5.json +0 -8
  69. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32c5beta3.json +0 -8
  70. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32c6.json +0 -8
  71. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32c61.json +0 -8
  72. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32c6beta.json +0 -8
  73. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32h2.json +0 -8
  74. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32h2beta1.json +0 -8
  75. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32h2beta2.json +0 -8
  76. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32p4.json +0 -8
  77. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32s2.json +0 -8
  78. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32s3.json +0 -8
  79. esptool-4.9.dev8/esptool/targets/stub_flasher/1/esp32s3beta2.json +0 -8
  80. {esptool-4.9.dev8 → esptool-4.10.dev1}/LICENSE +0 -0
  81. {esptool-4.9.dev8 → esptool-4.10.dev1}/MANIFEST.in +0 -0
  82. {esptool-4.9.dev8 → esptool-4.10.dev1}/README.md +0 -0
  83. {esptool-4.9.dev8 → esptool-4.10.dev1}/esp_rfc2217_server/__init__.py +0 -0
  84. {esptool-4.9.dev8 → esptool-4.10.dev1}/esp_rfc2217_server/__main__.py +0 -0
  85. {esptool-4.9.dev8 → esptool-4.10.dev1}/esp_rfc2217_server/esp_port_manager.py +0 -0
  86. {esptool-4.9.dev8 → esptool-4.10.dev1}/esp_rfc2217_server/redirector.py +0 -0
  87. {esptool-4.9.dev8 → esptool-4.10.dev1}/esp_rfc2217_server.py +0 -0
  88. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/__init__.py +0 -0
  89. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/__main__.py +0 -0
  90. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/__init__.py +0 -0
  91. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/base_fields.py +0 -0
  92. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/csv_table_parser.py +0 -0
  93. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/emulate_efuse_controller_base.py +0 -0
  94. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32/__init__.py +0 -0
  95. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32/emulate_efuse_controller.py +0 -0
  96. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32/fields.py +0 -0
  97. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32/mem_definition.py +0 -0
  98. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32/operations.py +0 -0
  99. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c2/__init__.py +0 -0
  100. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c2/emulate_efuse_controller.py +0 -0
  101. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c2/fields.py +0 -0
  102. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c2/mem_definition.py +0 -0
  103. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c2/operations.py +0 -0
  104. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c3/__init__.py +0 -0
  105. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c3/emulate_efuse_controller.py +0 -0
  106. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c3/mem_definition.py +0 -0
  107. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c5/__init__.py +0 -0
  108. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c5/emulate_efuse_controller.py +0 -0
  109. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c5/mem_definition.py +0 -0
  110. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c5beta3/__init__.py +0 -0
  111. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c5beta3/emulate_efuse_controller.py +0 -0
  112. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c5beta3/fields.py +0 -0
  113. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c5beta3/mem_definition.py +0 -0
  114. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c5beta3/operations.py +0 -0
  115. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c6/__init__.py +0 -0
  116. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c6/emulate_efuse_controller.py +0 -0
  117. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c6/mem_definition.py +0 -0
  118. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c61/__init__.py +0 -0
  119. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c61/emulate_efuse_controller.py +0 -0
  120. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32c61/mem_definition.py +0 -0
  121. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h2/__init__.py +0 -0
  122. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h2/emulate_efuse_controller.py +0 -0
  123. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h2/mem_definition.py +0 -0
  124. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h21/__init__.py +0 -0
  125. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h21/emulate_efuse_controller.py +0 -0
  126. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h21/fields.py +0 -0
  127. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h21/mem_definition.py +0 -0
  128. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h2beta1/__init__.py +0 -0
  129. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py +0 -0
  130. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h2beta1/fields.py +0 -0
  131. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h2beta1/mem_definition.py +0 -0
  132. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h2beta1/operations.py +0 -0
  133. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h4/__init__.py +0 -0
  134. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h4/emulate_efuse_controller.py +0 -0
  135. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32h4/mem_definition.py +0 -0
  136. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32p4/__init__.py +0 -0
  137. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32p4/emulate_efuse_controller.py +0 -0
  138. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32p4/mem_definition.py +0 -0
  139. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s2/__init__.py +0 -0
  140. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s2/emulate_efuse_controller.py +0 -0
  141. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s2/fields.py +0 -0
  142. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s2/mem_definition.py +0 -0
  143. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s3/__init__.py +0 -0
  144. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s3/emulate_efuse_controller.py +0 -0
  145. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s3/mem_definition.py +0 -0
  146. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s3beta2/__init__.py +0 -0
  147. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py +0 -0
  148. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s3beta2/fields.py +0 -0
  149. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s3beta2/mem_definition.py +0 -0
  150. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/esp32s3beta2/operations.py +0 -0
  151. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/mem_definition_base.py +0 -0
  152. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse/util.py +0 -0
  153. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse_defs/esp32.yaml +0 -0
  154. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse_defs/esp32c2.yaml +0 -0
  155. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse_defs/esp32c3.yaml +0 -0
  156. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse_defs/esp32c5.yaml +0 -0
  157. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse_defs/esp32c5beta3.yaml +0 -0
  158. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse_defs/esp32c6.yaml +0 -0
  159. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse_defs/esp32h2.yaml +0 -0
  160. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse_defs/esp32h21.yaml +0 -0
  161. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse_defs/esp32h2_v0.0_v1.1.yaml +0 -0
  162. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse_defs/esp32h4.yaml +0 -0
  163. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse_defs/esp32p4.yaml +0 -0
  164. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse_defs/esp32s2.yaml +0 -0
  165. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse/efuse_defs/esp32s3.yaml +0 -0
  166. {esptool-4.9.dev8 → esptool-4.10.dev1}/espefuse.py +0 -0
  167. {esptool-4.9.dev8 → esptool-4.10.dev1}/espsecure/__main__.py +0 -0
  168. {esptool-4.9.dev8 → esptool-4.10.dev1}/espsecure/esp_hsm_sign/__init__.py +0 -0
  169. {esptool-4.9.dev8 → esptool-4.10.dev1}/espsecure/esp_hsm_sign/exceptions.py +0 -0
  170. {esptool-4.9.dev8 → esptool-4.10.dev1}/espsecure.py +0 -0
  171. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/__main__.py +0 -0
  172. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/config.py +0 -0
  173. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/reset.py +0 -0
  174. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/__init__.py +0 -0
  175. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp32c6beta.py +0 -0
  176. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/esp8266.py +0 -0
  177. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/stub_flasher/1/esp8266.json +0 -0
  178. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/stub_flasher/2/LICENSE-APACHE +0 -0
  179. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/stub_flasher/2/LICENSE-MIT +0 -0
  180. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/stub_flasher/2/README.md +0 -0
  181. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/stub_flasher/2/esp32.json +0 -0
  182. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/stub_flasher/2/esp32c2.json +0 -0
  183. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/stub_flasher/2/esp32c3.json +0 -0
  184. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/stub_flasher/2/esp32c6.json +0 -0
  185. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/stub_flasher/2/esp32h2.json +0 -0
  186. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/stub_flasher/2/esp32s2.json +0 -0
  187. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/targets/stub_flasher/2/esp32s3.json +0 -0
  188. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/uf2_writer.py +0 -0
  189. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool/util.py +0 -0
  190. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool.egg-info/SOURCES.txt +0 -0
  191. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool.egg-info/dependency_links.txt +0 -0
  192. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool.egg-info/requires.txt +0 -0
  193. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool.egg-info/top_level.txt +0 -0
  194. {esptool-4.9.dev8 → esptool-4.10.dev1}/esptool.py +0 -0
  195. {esptool-4.9.dev8 → esptool-4.10.dev1}/setup.cfg +0 -0
  196. {esptool-4.9.dev8 → esptool-4.10.dev1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: esptool
3
- Version: 4.9.dev8
3
+ Version: 4.10.dev1
4
4
  Summary: A serial utility to communicate & flash code to Espressif chips.
5
5
  Author: Fredrik Ahlberg (themadinventor), Angus Gratton (projectgus), Espressif Systems
6
6
  License: GPLv2+
@@ -5,12 +5,14 @@
5
5
  # SPDX-License-Identifier: GPL-2.0-or-later
6
6
 
7
7
  import argparse
8
+ import io
8
9
  import os
9
10
  import json
10
11
  import sys
11
12
 
12
13
  from bitstring import BitStream
13
14
 
15
+ import espsecure
14
16
  import esptool
15
17
 
16
18
  from . import base_fields
@@ -802,3 +804,162 @@ def check_error(esp, efuses, args):
802
804
  if error_in_blocks:
803
805
  raise esptool.FatalError("Error(s) were detected in eFuses")
804
806
  print("No errors detected")
807
+
808
+
809
+ def _key_block_is_unused(block, key_purpose_block):
810
+ """Helper method to check if a key block is available for use"""
811
+ if not block.is_readable() or not block.is_writeable():
812
+ return False
813
+
814
+ if key_purpose_block.get() != "USER" or not key_purpose_block.is_writeable():
815
+ return False
816
+
817
+ if not block.get_bitstring().all(False):
818
+ return False
819
+
820
+ return True
821
+
822
+
823
+ def _get_next_key_block(efuses, current_key_block, block_name_list):
824
+ """Helper method to get the next available key block"""
825
+ key_blocks = [b for b in efuses.blocks if b.key_purpose_name]
826
+ start = key_blocks.index(current_key_block)
827
+
828
+ # Sort key blocks so that we pick the next free block
829
+ # (and loop around if necessary)
830
+ key_blocks = key_blocks[start:] + key_blocks[0:start]
831
+
832
+ # Exclude any other blocks that will be be burned
833
+ key_blocks = [b for b in key_blocks if b.name not in block_name_list]
834
+
835
+ for block in key_blocks:
836
+ key_purpose_block = efuses[block.key_purpose_name]
837
+ if _key_block_is_unused(block, key_purpose_block):
838
+ return block
839
+
840
+ return None
841
+
842
+
843
+ def adjust_key_data_for_blocks(efuses, block_names, datafiles, keypurposes):
844
+ """Split a key that takes more than one efuse block into two blocks.
845
+ It handles all key purposes that require splitting into two blocks.
846
+
847
+ This method checks if key purposes require splitting into two blocks,
848
+ such as "XTS_AES_256_KEY", "XTS_AES_256_PSRAM_KEY", and "ECDSA_KEY_P384".
849
+
850
+ Args:
851
+ block_names: List of block names.
852
+ datafiles: List of BinaryIO objects containing key data.
853
+ keypurposes: List of key purposes.
854
+
855
+ Returns:
856
+ A tuple containing updated block names, datafiles, and keypurposes.
857
+ """
858
+ keypurposes = list(keypurposes)
859
+ datafiles = list(datafiles)
860
+ block_names = list(block_names)
861
+
862
+ if "XTS_AES_256_KEY" in keypurposes:
863
+ # XTS_AES_256_KEY is not an actual HW key purpose, needs to be split into
864
+ # XTS_AES_256_KEY_1 and XTS_AES_256_KEY_2
865
+ block_names, datafiles, keypurposes = _split_multiblock_key(
866
+ efuses,
867
+ block_names,
868
+ datafiles, # type: ignore
869
+ keypurposes,
870
+ "XTS_AES_256_KEY",
871
+ )
872
+
873
+ if "XTS_AES_256_PSRAM_KEY" in keypurposes:
874
+ # XTS_AES_256_PSRAM_KEY -> XTS_AES_256_PSRAM_KEY_1 and ..._KEY_2
875
+ block_names, datafiles, keypurposes = _split_multiblock_key(
876
+ efuses,
877
+ block_names,
878
+ datafiles, # type: ignore
879
+ keypurposes,
880
+ "XTS_AES_256_PSRAM_KEY",
881
+ )
882
+
883
+ # ECDSA keys can be present in a command multiple times
884
+ i = 0
885
+ while i < len(keypurposes):
886
+ if "ECDSA_KEY" in keypurposes[i]:
887
+ if keypurposes[i] not in ["ECDSA_KEY_P384_L", "ECDSA_KEY_P384_H"]:
888
+ sk = espsecure.load_ecdsa_signing_key(datafiles[i]) # type: ignore
889
+ data = sk.to_string()
890
+ if "ECDSA_KEY_P384" == keypurposes[i]:
891
+ assert (
892
+ len(data) == 48
893
+ ), "NIST384p private key should be 48 bytes long"
894
+ datafiles[i] = io.BytesIO(b"\x00" * 16 + data)
895
+ # ECDSA_KEY_P384 -> ECDSA_KEY_P384_L and ECDSA_KEY_P384_H
896
+ block_names, datafiles, keypurposes = _split_multiblock_key(
897
+ efuses,
898
+ block_names,
899
+ datafiles, # type: ignore
900
+ keypurposes,
901
+ "ECDSA_KEY_P384",
902
+ )
903
+ else:
904
+ # the private key is 24 bytes long for NIST192p,
905
+ # and 8 bytes of padding
906
+ datafiles[i] = (
907
+ io.BytesIO(b"\x00" * 8 + data)
908
+ if len(data) == 24
909
+ else io.BytesIO(data)
910
+ )
911
+
912
+ i += 1
913
+
914
+ # Check that all block names are unique
915
+ util.check_duplicate_name_in_list(block_names)
916
+
917
+ # Check that the number of blocks, datafiles, and keypurposes is equal
918
+ if len(block_names) != len(datafiles) or len(block_names) != len(keypurposes):
919
+ raise esptool.FatalError(
920
+ f"The number of blocks ({len(block_names)}), "
921
+ f"datafile ({len(datafiles)}) and keypurpose ({len(keypurposes)}) "
922
+ "should be the same."
923
+ )
924
+
925
+ return block_names, datafiles, keypurposes
926
+
927
+
928
+ def _split_multiblock_key(
929
+ efuses, block_names, datafiles, keypurposes, base_keypurpose="XTS_AES_256_KEY"
930
+ ):
931
+ """Helper method to split 512-bit key into two 256-bit keys"""
932
+
933
+ keypurpose_list = list(keypurposes)
934
+ datafile_list = list(datafiles)
935
+ block_name_list = list(block_names)
936
+
937
+ i = keypurpose_list.index(base_keypurpose)
938
+ block_name = block_name_list[i]
939
+
940
+ block_num = efuses.get_index_block_by_name(block_name)
941
+ block = efuses.blocks[block_num]
942
+
943
+ data = datafile_list[i].read()
944
+ if len(data) != 64:
945
+ raise esptool.FatalError(
946
+ f"Incorrect key file size {len(data)}, {base_keypurpose} "
947
+ "should be 64 bytes"
948
+ )
949
+
950
+ key_block_2 = _get_next_key_block(efuses, block, block_name_list)
951
+ if not key_block_2:
952
+ raise esptool.FatalError(f"{base_keypurpose} requires two free keyblocks")
953
+
954
+ postfix = (
955
+ ["_1", "_2"] if base_keypurpose.startswith("XTS_AES_256") else ["_H", "_L"]
956
+ )
957
+ keypurpose_list[i] = f"{base_keypurpose}{postfix[0]}"
958
+ datafile_list[i] = io.BytesIO(data[:32])
959
+ block_name_list[i] = block_name
960
+
961
+ keypurpose_list.insert(i + 1, f"{base_keypurpose}{postfix[1]}")
962
+ datafile_list.insert(i + 1, io.BytesIO(data[32:]))
963
+ block_name_list.insert(i + 1, key_block_2.name)
964
+
965
+ return block_name_list, datafile_list, keypurpose_list
@@ -450,5 +450,6 @@ class EfuseKeyPurposeField(EfuseField):
450
450
  raw_val = int(self.check_format(str(new_value)))
451
451
  str_new_value = self.get_name(raw_val)
452
452
  if self.name == "KEY_PURPOSE_5" and str_new_value.startswith("XTS_AES"):
453
+ # see SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK in esp-idf
453
454
  raise esptool.FatalError(f"{self.name} can not have {str_new_value} key due to a hardware bug (please see TRM for more details)")
454
455
  return super(EfuseKeyPurposeField, self).save(raw_val)
@@ -26,6 +26,7 @@ from ..base_operations import (
26
26
  read_protect_efuse,
27
27
  summary,
28
28
  write_protect_efuse,
29
+ adjust_key_data_for_blocks,
29
30
  )
30
31
 
31
32
 
@@ -224,15 +225,12 @@ def burn_key(esp, efuses, args, digest=None):
224
225
  0 : len([name for name in args.keypurpose if name is not None]) :
225
226
  ]
226
227
 
227
- util.check_duplicate_name_in_list(block_name_list)
228
- if len(block_name_list) != len(datafile_list) or len(block_name_list) != len(
229
- keypurpose_list
230
- ):
231
- raise esptool.FatalError(
232
- "The number of blocks (%d), datafile (%d) and keypurpose (%d) "
233
- "should be the same."
234
- % (len(block_name_list), len(datafile_list), len(keypurpose_list))
235
- )
228
+ block_name_list, datafile_list, keypurpose_list = adjust_key_data_for_blocks(
229
+ efuses,
230
+ block_name_list,
231
+ datafile_list,
232
+ keypurpose_list,
233
+ )
236
234
 
237
235
  print("Burn keys to blocks:")
238
236
  for block_name, datafile, keypurpose in zip(
@@ -8,7 +8,7 @@ import binascii
8
8
  import struct
9
9
  import sys
10
10
  import time
11
-
11
+ from typing import List, Tuple, Optional
12
12
  from bitstring import BitArray
13
13
 
14
14
  import esptool
@@ -403,10 +403,12 @@ class EfuseMacField(EfuseField):
403
403
 
404
404
  # fmt: off
405
405
  class EfuseKeyPurposeField(EfuseField):
406
- KEY_PURPOSES = [
406
+ key_purpose_len = 5 # bits for key purpose
407
+ KeyPurposeType = Tuple[str, int, Optional[str], Optional[str], str]
408
+ KEY_PURPOSES: List[KeyPurposeType] = [
407
409
  ("USER", 0, None, None, "no_need_rd_protect"), # User purposes (software-only use)
408
- ("ECDSA_KEY", 1, None, "Reverse", "need_rd_protect"), # ECDSA key P256
409
410
  ("ECDSA_KEY_P256", 1, None, "Reverse", "need_rd_protect"), # ECDSA key P256
411
+ ("ECDSA_KEY", 1, None, "Reverse", "need_rd_protect"), # ECDSA key P256
410
412
  ("RESERVED", 1, None, None, "no_need_rd_protect"), # Reserved
411
413
  ("XTS_AES_256_KEY_1", 2, None, "Reverse", "need_rd_protect"), # XTS_AES_256_KEY_1 (flash/PSRAM encryption)
412
414
  ("XTS_AES_256_KEY_2", 3, None, "Reverse", "need_rd_protect"), # XTS_AES_256_KEY_2 (flash/PSRAM encryption)
@@ -422,12 +424,21 @@ class EfuseKeyPurposeField(EfuseField):
422
424
  ("KM_INIT_KEY", 12, None, None, "need_rd_protect"), # init key that is used for the generation of AES/ECDSA key
423
425
  ("XTS_AES_256_PSRAM_KEY_1", 13, None, "Reverse", "need_rd_protect"), # XTS_AES_256_PSRAM_KEY_1 (PSRAM encryption)
424
426
  ("XTS_AES_256_PSRAM_KEY_2", 14, None, "Reverse", "need_rd_protect"), # XTS_AES_256_PSRAM_KEY_1 (PSRAM encryption)
425
- # ("XTS_AES_256_PSRAM_KEY", -2, "VIRTUAL", None, "no_need_rd_protect"), # Virtual purpose splits to XTS_AES_256_PSRAM_KEY_1 and XTS_AES_256_PSRAM_KEY_1
427
+ ("XTS_AES_256_PSRAM_KEY", -2, "VIRTUAL", None, "no_need_rd_protect"), # Virtual purpose splits to XTS_AES_256_PSRAM_KEY_1 and XTS_AES_256_PSRAM_KEY_1
426
428
  ("XTS_AES_128_PSRAM_KEY", 15, None, "Reverse", "need_rd_protect"), # XTS_AES_128_PSRAM_KEY (PSRAM encryption)
427
429
  ("ECDSA_KEY_P192", 16, None, "Reverse", "need_rd_protect"), # ECDSA key P192
428
430
  ("ECDSA_KEY_P384_L", 17, None, "Reverse", "need_rd_protect"), # ECDSA key P384 low
429
431
  ("ECDSA_KEY_P384_H", 18, None, "Reverse", "need_rd_protect"), # ECDSA key P384 high
432
+ ("ECDSA_KEY_P384", -3, "VIRTUAL", None, "need_rd_protect"), # Virtual purpose splits to ECDSA_KEY_P384_L and ECDSA_KEY_P384_H
430
433
  ]
434
+ CUSTOM_KEY_PURPOSES: List[KeyPurposeType] = []
435
+ for id in range(0, 1 << key_purpose_len):
436
+ if id not in [p[1] for p in KEY_PURPOSES]:
437
+ CUSTOM_KEY_PURPOSES.append((f"CUSTOM_{id}", id, None, None, "no_need_rd_protect"))
438
+ CUSTOM_KEY_PURPOSES.append((f"CUSTOM_DIGEST_{id}", id, "DIGEST", None, "no_need_rd_protect"))
439
+ CUSTOM_KEY_PURPOSES.append(("CUSTOM_MAX", (1 << key_purpose_len) - 1, None, None, "no_need_rd_protect"))
440
+ CUSTOM_KEY_PURPOSES.append(("CUSTOM_DIGEST_MAX", (1 << key_purpose_len) - 1, "DIGEST", None, "no_need_rd_protect"))
441
+ KEY_PURPOSES += CUSTOM_KEY_PURPOSES
431
442
  # fmt: on
432
443
  KEY_PURPOSES_NAME = [name[0] for name in KEY_PURPOSES]
433
444
  DIGEST_KEY_PURPOSES = [name[0] for name in KEY_PURPOSES if name[2] == "DIGEST"]
@@ -470,7 +481,4 @@ class EfuseKeyPurposeField(EfuseField):
470
481
 
471
482
  def save(self, new_value):
472
483
  raw_val = int(self.check_format(str(new_value)))
473
- str_new_value = self.get_name(raw_val)
474
- if self.name == "KEY_PURPOSE_5" and str_new_value.startswith("XTS_AES"):
475
- raise esptool.FatalError(f"{self.name} can not have {str_new_value} key due to a hardware bug (please see TRM for more details)")
476
484
  return super(EfuseKeyPurposeField, self).save(raw_val)
@@ -0,0 +1,390 @@
1
+ # This file includes the operations with eFuses for ESP32-C5 chip
2
+ #
3
+ # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
4
+ #
5
+ # SPDX-License-Identifier: GPL-2.0-or-later
6
+
7
+ import argparse
8
+ import os # noqa: F401. It is used in IDF scripts
9
+ import traceback
10
+
11
+ import espsecure
12
+
13
+ import esptool
14
+
15
+ from . import fields
16
+ from .. import util
17
+ from ..base_operations import (
18
+ add_common_commands,
19
+ add_force_write_always,
20
+ add_show_sensitive_info_option,
21
+ burn_bit,
22
+ burn_block_data,
23
+ burn_efuse,
24
+ check_error,
25
+ dump,
26
+ read_protect_efuse,
27
+ summary,
28
+ write_protect_efuse,
29
+ adjust_key_data_for_blocks,
30
+ )
31
+
32
+
33
+ def protect_options(p):
34
+ p.add_argument(
35
+ "--no-write-protect",
36
+ help="Disable write-protecting of the key. The key remains writable. "
37
+ "(The keys use the RS coding scheme that does not support "
38
+ "post-write data changes. Forced write can damage RS encoding bits.) "
39
+ "The write-protecting of keypurposes does not depend on the option, "
40
+ "it will be set anyway.",
41
+ action="store_true",
42
+ )
43
+ p.add_argument(
44
+ "--no-read-protect",
45
+ help="Disable read-protecting of the key. The key remains readable software."
46
+ "The key with keypurpose[USER, RESERVED and *_DIGEST] "
47
+ "will remain readable anyway. For the rest keypurposes the read-protection "
48
+ "will be defined the option (Read-protect by default).",
49
+ action="store_true",
50
+ )
51
+
52
+
53
+ def add_commands(subparsers, efuses):
54
+ add_common_commands(subparsers, efuses)
55
+ burn_key = subparsers.add_parser(
56
+ "burn_key", help="Burn the key block with the specified name"
57
+ )
58
+ protect_options(burn_key)
59
+ add_force_write_always(burn_key)
60
+ add_show_sensitive_info_option(burn_key)
61
+ burn_key.add_argument(
62
+ "block",
63
+ help="Key block to burn",
64
+ action="append",
65
+ choices=efuses.BLOCKS_FOR_KEYS,
66
+ )
67
+ burn_key.add_argument(
68
+ "keyfile",
69
+ help="File containing 256 bits of binary key data. For the ECDSA_KEY purpose use PEM file.",
70
+ action="append",
71
+ type=argparse.FileType("rb"),
72
+ )
73
+ burn_key.add_argument(
74
+ "keypurpose",
75
+ help="Purpose to set.",
76
+ action="append",
77
+ choices=fields.EfuseKeyPurposeField.KEY_PURPOSES_NAME,
78
+ )
79
+ for _ in efuses.BLOCKS_FOR_KEYS:
80
+ burn_key.add_argument(
81
+ "block",
82
+ help="Key block to burn",
83
+ nargs="?",
84
+ action="append",
85
+ metavar="BLOCK",
86
+ choices=efuses.BLOCKS_FOR_KEYS,
87
+ )
88
+ burn_key.add_argument(
89
+ "keyfile",
90
+ help="File containing 256 bits of binary key data. For the ECDSA_KEY purpose use PEM file.",
91
+ nargs="?",
92
+ action="append",
93
+ metavar="KEYFILE",
94
+ type=argparse.FileType("rb"),
95
+ )
96
+ burn_key.add_argument(
97
+ "keypurpose",
98
+ help="Purpose to set.",
99
+ nargs="?",
100
+ action="append",
101
+ metavar="KEYPURPOSE",
102
+ choices=fields.EfuseKeyPurposeField.KEY_PURPOSES_NAME,
103
+ )
104
+
105
+ burn_key_digest = subparsers.add_parser(
106
+ "burn_key_digest",
107
+ help="Parse a RSA public key and burn the digest to key efuse block",
108
+ )
109
+ protect_options(burn_key_digest)
110
+ add_force_write_always(burn_key_digest)
111
+ add_show_sensitive_info_option(burn_key_digest)
112
+ burn_key_digest.add_argument(
113
+ "block",
114
+ help="Key block to burn",
115
+ action="append",
116
+ choices=efuses.BLOCKS_FOR_KEYS,
117
+ )
118
+ burn_key_digest.add_argument(
119
+ "keyfile",
120
+ help="Key file to digest (PEM format)",
121
+ action="append",
122
+ type=argparse.FileType("rb"),
123
+ )
124
+ burn_key_digest.add_argument(
125
+ "keypurpose",
126
+ help="Purpose to set.",
127
+ action="append",
128
+ choices=fields.EfuseKeyPurposeField.DIGEST_KEY_PURPOSES,
129
+ )
130
+ for _ in efuses.BLOCKS_FOR_KEYS:
131
+ burn_key_digest.add_argument(
132
+ "block",
133
+ help="Key block to burn",
134
+ nargs="?",
135
+ action="append",
136
+ metavar="BLOCK",
137
+ choices=efuses.BLOCKS_FOR_KEYS,
138
+ )
139
+ burn_key_digest.add_argument(
140
+ "keyfile",
141
+ help="Key file to digest (PEM format)",
142
+ nargs="?",
143
+ action="append",
144
+ metavar="KEYFILE",
145
+ type=argparse.FileType("rb"),
146
+ )
147
+ burn_key_digest.add_argument(
148
+ "keypurpose",
149
+ help="Purpose to set.",
150
+ nargs="?",
151
+ action="append",
152
+ metavar="KEYPURPOSE",
153
+ choices=fields.EfuseKeyPurposeField.DIGEST_KEY_PURPOSES,
154
+ )
155
+
156
+ p = subparsers.add_parser(
157
+ "set_flash_voltage",
158
+ help="Permanently set the internal flash voltage regulator "
159
+ "to either 1.8V, 3.3V or OFF. "
160
+ "This means GPIO45 can be high or low at reset without "
161
+ "changing the flash voltage.",
162
+ )
163
+ p.add_argument("voltage", help="Voltage selection", choices=["1.8V", "3.3V", "OFF"])
164
+
165
+ p = subparsers.add_parser(
166
+ "burn_custom_mac", help="Burn a 48-bit Custom MAC Address to EFUSE BLOCK3."
167
+ )
168
+ p.add_argument(
169
+ "mac",
170
+ help="Custom MAC Address to burn given in hexadecimal format with bytes "
171
+ "separated by colons (e.g. AA:CD:EF:01:02:03).",
172
+ type=fields.base_fields.CheckArgValue(efuses, "CUSTOM_MAC"),
173
+ )
174
+ add_force_write_always(p)
175
+
176
+ p = subparsers.add_parser("get_custom_mac", help="Prints the Custom MAC Address.")
177
+
178
+
179
+ def burn_custom_mac(esp, efuses, args):
180
+ efuses["CUSTOM_MAC"].save(args.mac)
181
+ if not efuses.burn_all(check_batch_mode=True):
182
+ return
183
+ get_custom_mac(esp, efuses, args)
184
+ print("Successful")
185
+
186
+
187
+ def get_custom_mac(esp, efuses, args):
188
+ print("Custom MAC Address: {}".format(efuses["CUSTOM_MAC"].get()))
189
+
190
+
191
+ def set_flash_voltage(esp, efuses, args):
192
+ raise esptool.FatalError("set_flash_voltage is not supported!")
193
+
194
+
195
+ def adc_info(esp, efuses, args):
196
+ print("Block version:", efuses.get_block_version())
197
+ if efuses.get_block_version() >= 1:
198
+ for efuse in efuses:
199
+ if efuse.category == "calibration":
200
+ print(f"{efuse.name:<30} = ", efuses[efuse.name].get())
201
+
202
+
203
+ def burn_key(esp, efuses, args, digest=None):
204
+ if digest is None:
205
+ datafile_list = args.keyfile[
206
+ 0 : len([name for name in args.keyfile if name is not None]) :
207
+ ]
208
+ else:
209
+ datafile_list = digest[0 : len([name for name in digest if name is not None]) :]
210
+ efuses.force_write_always = args.force_write_always
211
+ block_name_list = args.block[
212
+ 0 : len([name for name in args.block if name is not None]) :
213
+ ]
214
+ keypurpose_list = args.keypurpose[
215
+ 0 : len([name for name in args.keypurpose if name is not None]) :
216
+ ]
217
+
218
+ block_name_list, datafile_list, keypurpose_list = adjust_key_data_for_blocks(
219
+ efuses,
220
+ block_name_list,
221
+ datafile_list,
222
+ keypurpose_list,
223
+ )
224
+
225
+ print("Burn keys to blocks:")
226
+ for block_name, datafile, keypurpose in zip(
227
+ block_name_list, datafile_list, keypurpose_list
228
+ ):
229
+ efuse = None
230
+ for block in efuses.blocks:
231
+ if block_name == block.name or block_name in block.alias:
232
+ efuse = efuses[block.name]
233
+ if efuse is None:
234
+ raise esptool.FatalError("Unknown block name - %s" % (block_name))
235
+ num_bytes = efuse.bit_len // 8
236
+
237
+ block_num = efuses.get_index_block_by_name(block_name)
238
+ block = efuses.blocks[block_num]
239
+
240
+ if digest is None:
241
+ data = datafile.read()
242
+ else:
243
+ data = datafile
244
+
245
+ print(" - %s" % (efuse.name), end=" ")
246
+ revers_msg = None
247
+ if efuses[block.key_purpose_name].need_reverse(keypurpose):
248
+ revers_msg = f"\tReversing byte order for {keypurpose} hardware peripheral"
249
+ data = data[::-1]
250
+ print(
251
+ "-> [{}]".format(
252
+ util.hexify(data, " ")
253
+ if args.show_sensitive_info
254
+ else " ".join(["??"] * len(data))
255
+ )
256
+ )
257
+ if revers_msg:
258
+ print(revers_msg)
259
+ if len(data) != num_bytes:
260
+ raise esptool.FatalError(
261
+ "Incorrect key file size %d. Key file must be %d bytes (%d bits) "
262
+ "of raw binary key data." % (len(data), num_bytes, num_bytes * 8)
263
+ )
264
+
265
+ if efuses[block.key_purpose_name].need_rd_protect(keypurpose):
266
+ read_protect = False if args.no_read_protect else True
267
+ else:
268
+ read_protect = False
269
+ write_protect = not args.no_write_protect
270
+
271
+ # using efuse instead of a block gives the advantage of checking it as the whole field.
272
+ efuse.save(data)
273
+
274
+ disable_wr_protect_key_purpose = False
275
+ if efuses[block.key_purpose_name].get() != keypurpose:
276
+ if efuses[block.key_purpose_name].is_writeable():
277
+ print(
278
+ "\t'%s': '%s' -> '%s'."
279
+ % (
280
+ block.key_purpose_name,
281
+ efuses[block.key_purpose_name].get(),
282
+ keypurpose,
283
+ )
284
+ )
285
+ efuses[block.key_purpose_name].save(keypurpose)
286
+ disable_wr_protect_key_purpose = True
287
+ else:
288
+ raise esptool.FatalError(
289
+ "It is not possible to change '%s' to '%s' "
290
+ "because write protection bit is set."
291
+ % (block.key_purpose_name, keypurpose)
292
+ )
293
+ else:
294
+ print("\t'%s' is already '%s'." % (block.key_purpose_name, keypurpose))
295
+ if efuses[block.key_purpose_name].is_writeable():
296
+ disable_wr_protect_key_purpose = True
297
+
298
+ if disable_wr_protect_key_purpose:
299
+ print("\tDisabling write to '%s'." % block.key_purpose_name)
300
+ efuses[block.key_purpose_name].disable_write()
301
+
302
+ if read_protect:
303
+ print("\tDisabling read to key block")
304
+ efuse.disable_read()
305
+
306
+ if write_protect:
307
+ print("\tDisabling write to key block")
308
+ efuse.disable_write()
309
+ print("")
310
+
311
+ if not write_protect:
312
+ print("Keys will remain writeable (due to --no-write-protect)")
313
+ if args.no_read_protect:
314
+ print("Keys will remain readable (due to --no-read-protect)")
315
+
316
+ if not efuses.burn_all(check_batch_mode=True):
317
+ return
318
+ print("Successful")
319
+
320
+
321
+ def burn_key_digest(esp, efuses, args):
322
+ digest_list = []
323
+ datafile_list = args.keyfile[
324
+ 0 : len([name for name in args.keyfile if name is not None]) :
325
+ ]
326
+ block_list = args.block[
327
+ 0 : len([block for block in args.block if block is not None]) :
328
+ ]
329
+ for block_name, datafile in zip(block_list, datafile_list):
330
+ efuse = None
331
+ for block in efuses.blocks:
332
+ if block_name == block.name or block_name in block.alias:
333
+ efuse = efuses[block.name]
334
+ if efuse is None:
335
+ raise esptool.FatalError("Unknown block name - %s" % (block_name))
336
+ num_bytes = efuse.bit_len // 8
337
+ digest = espsecure._digest_sbv2_public_key(datafile)
338
+ if len(digest) != num_bytes:
339
+ raise esptool.FatalError(
340
+ "Incorrect digest size %d. Digest must be %d bytes (%d bits) "
341
+ "of raw binary key data." % (len(digest), num_bytes, num_bytes * 8)
342
+ )
343
+ digest_list.append(digest)
344
+ burn_key(esp, efuses, args, digest=digest_list)
345
+
346
+
347
+ def espefuse(esp, efuses, args, command):
348
+ parser = argparse.ArgumentParser()
349
+ subparsers = parser.add_subparsers(dest="operation")
350
+ add_commands(subparsers, efuses)
351
+ try:
352
+ cmd_line_args = parser.parse_args(command.split())
353
+ except SystemExit:
354
+ traceback.print_stack()
355
+ raise esptool.FatalError('"{}" - incorrect command'.format(command))
356
+ if cmd_line_args.operation == "execute_scripts":
357
+ configfiles = cmd_line_args.configfiles
358
+ index = cmd_line_args.index
359
+ # copy arguments from args to cmd_line_args
360
+ vars(cmd_line_args).update(vars(args))
361
+ if cmd_line_args.operation == "execute_scripts":
362
+ cmd_line_args.configfiles = configfiles
363
+ cmd_line_args.index = index
364
+ if cmd_line_args.operation is None:
365
+ parser.print_help()
366
+ parser.exit(1)
367
+ operation_func = globals()[cmd_line_args.operation]
368
+ # each 'operation' is a module-level function of the same name
369
+ operation_func(esp, efuses, cmd_line_args)
370
+
371
+
372
+ def execute_scripts(esp, efuses, args):
373
+ efuses.batch_mode_cnt += 1
374
+ del args.operation
375
+ scripts = args.scripts
376
+ del args.scripts
377
+
378
+ for file in scripts:
379
+ with open(file.name, "r") as file:
380
+ exec(compile(file.read(), file.name, "exec"))
381
+
382
+ if args.debug:
383
+ for block in efuses.blocks:
384
+ data = block.get_bitstring(from_read=False)
385
+ block.print_block(data, "regs_for_burn", args.debug)
386
+
387
+ efuses.batch_mode_cnt -= 1
388
+ if not efuses.burn_all(check_batch_mode=True):
389
+ return
390
+ print("Successful")