Giter VIP home page Giter VIP logo

frameworks-setup's People

Contributors

hdpklm avatar

Stargazers

 avatar

Watchers

 avatar  avatar

frameworks-setup's Issues

Información complementaria a ESP32-Encrypt.md

Buenas! Encotré tu repo de casualidad, y no sabía como escribirte por github así cree un isssue. Justo estaba buscando info porque tenía una problema con un ESP32 que por error me quedó arruinado por reprogramar el bootloader y con su BLOCK2 (Security boot key) con un valor que no era el que yo había conservado.
En referencia a lo que dice el final del md ("No se para que sirve", secure-bootloader-key-256.bin), te cuento lo que encontré haciendo un poco de ingeniería inversa del código de python, viendo la info de espressif y viendo los archivos que genera el idf.

(Por razones de seguridad, dado que el certificado lo estoy usando, cuando aparece "..." es porque he recortado datos)

espsecure.py generate_signing_key --version 1 --scheme ecdsa256 secure_boot_signing_key.pem
Me devuelve:
espsecure.py v4.7.0
ECDSA NIST256p private key in PEM format written to secure_boot_signing_key.pem

El certificado generado es ECDSA (Elliptic Curve Digital Signature Algorithm), grabado en formato PEM de texto legible, de la forma:


-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIDw.....qGSM49
AwEHo......EuZohlK5
Cq....LOO61w==
-----END EC PRIVATE KEY-----


Lo que contiene está en BASE64, que sería en Hex (https://cryptii.com/pipes/base64-to-binary):


30 77 02 01 .... 0c 5f e6 4e 48 e7 75 b4 41 60 ... 00 04 43 23 b6 3c 26 31 e9 c9 74... a6 df 68 71 ec 1d 73 93 38 c6 05 12 e6.. 71 a0 33 96 43 5d c9 2c e3 ba d7


Que es un formato Standard de Keys/Certificados, etc en este caso ASN.1 que puede decodificarse acá (https://the-x.cn/en-US/encodings/Asn1.aspx)


1 0x3C28...416065 1.2.840.10045.3.1.7 0x00044323B....BAD7 *****************************************************************************************************

Donde se ve que la Clave Privada es 0x3C28.....416065
y la pública es (el 0x0004 inicial que es?): 0x4323B.....BAD7

Por lo tanto en la Private Key están ambas!!!

En Python puede verificar esto con el script:


import ecdsa
import binascii
key_filename = '../secure_boot_signing_key.pem'
KeyFile = open(key_filename, "rb")
SigKey = ecdsa.SigningKey.from_pem(KeyFile.read())
KeyFile.close()
print('Tipo de Curva: ' + str(SigKey.curve))
print("Private Key: " + str(binascii.hexlify(SigKey.to_string())))
public_key = SigKey.verifying_key
print("Public Key: " + str(binascii.hexlify(public_key.to_string())))


Donde el tipo de Objeto SigningKey contiene la Key Privada, y por lo tanto puedo extraer la de verificación (Pública), que es lo que usualmente se hace
con openssl a partir de una Private Key

Por otro lado, siguiendo con el IDF, dentro de /build/bootloader/signature_verification_key.bin.S, que tiene el código en C con el
array de datos que contiene el hexa con la Public Key de la forma


/* * Data converted from /build/bootloader/esp-idf/bootloader_support/signature_verification_key.bin
*/
.data
.section .rodata.embedded

.global signature_verification_key_bin
signature_verification_key_bin:

.global _binary_signature_verification_key_bin_start
_binary_signature_verification_key_bin_start: /* for objcopy compatibility */
.byte 0x43, 0x23, 0xb6, .....
.byte ........., 0xba, 0xd7

.global _binary_signature_verification_key_bin_end
_binary_signature_verification_key_bin_end: /* for objcopy compatibility */

.global signature_verification_key_bin_length
signature_verification_key_bin_length:
.word 64


Por otro lado, genera un archivo que en /build/bootloader/secure-bootloader-key-256.bin, se guarda el SHA256 del Private Key, que puede
verificarse desde la web (https://emn178.github.io/online-tools/sha256.html)

o con Python, a partir del script anterior le sumo


import hashlib
SHA256 = hashlib.sha256()
SHA256.update(SigKey.to_string())
print("Digest SHA256 de Private Key: " + str(SHA256.hexdigest()))


Esta Key es la que se utiliza para generar la firma en el Bootloader cuando se hace con los path correctos durante el build:

python .../esp-idf/components/esptool_py/esptool/espsecure.py digest_secure_bootloader --keyfile .../build/bootloader/secure-bootloader-key-256.bin -o .../build/bootloader/bootloader-reflash-digest.bin .../build/bootloader/bootloader.bin

esto puede verse en https://github.com/espressif/esptool/blob/v4.7.0/espsecure/__init__.py , función "digest_secure_bootloader"
Se ve en el código que genera un Vector de Inicialización (IV) de 128 bytes, para generar aleatoriedad, que se lo concatena al Bootloader, a todo eso lo encripta con AES (ECB) usando
la Key mencionada (secure-bootloader-key-256.bin) y luego a todo eso le calcula el SHA512 (64 bytes de digest), que es lo que se guarda a continuación del IV en el archivo firmado dentro de
los primeros 0x1000 bytes (lo que no se usa se rellena con 0xFF) para generar el "bootloader-reflash-digest.bin"

Por lo tanto el ESP lo que necesita para validar el bootloader, es la Key secure-bootloader-key-256.bin (SHA256 de la Private Key) y el IV que está en la posición 0x0000 y ocupa 128 bytes.
Luego toma y encrypta en memoria el Bootloader con AES (ECB), le calcula el SHA512 y lo compara con los 64 bytes están en el offset 128 de la memoria. Si todo coincide bootea.
En resumen, en el ESP32 se graba en los eFuse del "Block 2" el contenido de "secure-bootloader-key-256.bin"

Una vez que todo está listo, se quema el eFuse y se graba el bootloader la primera vez y las siguientes con los comandos:


Bootloader built and secure digest generated.
Secure boot enabled, so bootloader not flashed automatically.
Burn secure boot key to efuse using:
python /esp-idf/components/esptool_py/esptool/espefuse.py burn_key secure_boot_v1 /build/bootloader/secure-bootloader-key-256.bin
First time flash command is:
python /esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port=(PORT) --baud=(BAUD) --before=default_reset --after=no_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 /build/bootloader/bootloader.bin


To reflash the bootloader after initial flash:
python /esp/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port=(PORT) --baud=(BAUD) --before=default_reset --after=no_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 4MB 0x0 /build/bootloader/bootloader-reflash-digest.bin


Para firmar el FW con el algoritmo de firma digital de curva elíptica (ECDSA), lo que se hace es calcular un HASH del tipo HASH256 del FW completo (Proyecto-unsigned.bin), y luego eso se encrypta con la Private Key del archivo secure_boot_signing_key.pem. El resultado son 64 bytes que se agregan al final del Binario del FW, antecedidos por 4 bytes en cero (Versión utilizada de firma) y el FW se llama ahora si Proyecto.bin

Esto en Python se puede verificar agregando al código lo siguiente:


from hashlib import sha256
Data_filename = '../build/Proyecto-unsigned.bin'
DataFile = open(Data_filename, "rb")
Data = DataFile.read()
Firma = SigKey.sign_deterministic(Data, hashfunc=sha256)
print("Binary File Data: " + str(binascii.hexlify(Data[0:20])) + "..." + str(binascii.hexlify(Data[-20:])))
print("Signed HASH: " + str(binascii.hexlify(Firma)))
ret = public_key.verify(Firma, Data, sha256)
print("Verified HASH: " + str(ret))


que arroja como salida en consola


Binary File Data: b'e906022068140840ee00000000000000008f0100'...b'19678505cb4e18abc0cdd596827ff0021f1cee93'
Signed HASH: b'897036ca10c9f981......82f38b55d39edae12a4b023c883967a2d26a2bd054720ec794fe3032759c'
Verified HASH: True


Si se abre el Proyecto.bin con un editor hexadecimal, se ve que tiene la firma al final, se ve que termina en "1f1cee93" como el original, pero se agregan "00000000" y el Signed HASH


...1f 1c ee 93 00 00 00 00 89 70 36 ca 10 c9 f9 81 ....82 f3 8b 55 d3 9e da e1 2a 4b 02 3c 88 39 67 a2 d2 6a 2b d0 54 72 0e c7 94 fe 30 32 75 9c


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.