Skip to content

Commit 7400fdb

Browse files
Merge pull request #68 from Skyler84/skyler/HMAC
HMAC: Add tildagon HMAC module
2 parents efd1975 + 08e6e2f commit 7400fdb

File tree

8 files changed

+168
-9
lines changed

8 files changed

+168
-9
lines changed

burn_mac.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#!/usr/bin/python
2+
3+
import hashlib
4+
import esptool, espefuse
5+
import os, hmac, time
6+
7+
8+
def burn_hmac_key(key_to_use=1, port=None, do_not_confirm=False):
9+
# This is the master secret and should be kept secret
10+
# Initialise it from the environment variable
11+
MASTER_SECRET = os.environ["MASTER_SECRET"]
12+
13+
# Fix this in the code to the sha256sum of the master secret
14+
MASTER_HASH='59a61bdad01d1074a37bc6ee2ae4bac0a424fc2fcfcbdfd0c386d1fdac0d5c7e'
15+
16+
# PLEASE PLEASE PLEASE DO NOT REMOVE THIS CHECK
17+
# IF YOU FLASH THE WRONG SECRET TO THE DEVICE IT CAN NEVER BE UNDONE
18+
if hashlib.sha256(MASTER_SECRET.encode()).hexdigest() != MASTER_HASH:
19+
print("Master secret does not match")
20+
raise Exception("Master secret does not match")
21+
22+
esp=esptool.get_default_connected_device(esptool.get_port_list(), port=port, connect_attempts=1, initial_baud=115200)
23+
mac_address = esp.read_mac("BASE_MAC")
24+
mac_str = '-'.join([f"{b:02X}" for b in mac_address])
25+
26+
print("MAC Address:", mac_str)
27+
28+
COMBINED_SECRET = MASTER_SECRET + mac_str
29+
30+
HMAC_KEY = hashlib.sha256(COMBINED_SECRET.encode()).digest()
31+
32+
test_mac = hmac.digest(HMAC_KEY, b"test", "sha256")
33+
print(test_mac.hex())
34+
35+
efuses, operations = espefuse.get_efuses(esp, do_not_confirm=do_not_confirm)
36+
class Args:
37+
name_value_pairs = {}
38+
args = Args()
39+
args.name_value_pairs[f"KEY_PURPOSE_{key_to_use}"] = 8
40+
args.name_value_pairs[f"BLOCK_KEY{key_to_use}"] = HMAC_KEY
41+
args.name_value_pairs[f"RD_DIS"] = (1<<(key_to_use))
42+
# args.name_value_pairs[f"WR_DIS"] = (1<<(23+key_to_use))
43+
print(operations.burn_efuse)
44+
operations.burn_efuse(esp, efuses, args)
45+
46+
47+
if __name__ == "__main__":
48+
_in = input("Burn in a loop? (y/N): ")
49+
loop=False
50+
if _in.lower() == "y":
51+
loop = True
52+
print("Burning fuses on loop. Press Ctrl+C to stop")
53+
else:
54+
print("Burning single fuse, waiting for device.")
55+
while(True):
56+
ports = esptool.get_port_list()
57+
if not ports:
58+
time.sleep(1)
59+
continue
60+
burn_hmac_key(do_not_confirm=loop)
61+
while esptool.get_port_list():
62+
time.sleep(1)
63+
if not loop:
64+
break

drivers/micropython.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,9 @@ include(${CMAKE_CURRENT_LIST_DIR}/tildagon_power/tildagon_power.cmake)
1818

1919
# Add OTA helpers
2020
include(${CMAKE_CURRENT_LIST_DIR}/ota/micropython.cmake)
21+
22+
# Add Tildagon module
23+
include(${CMAKE_CURRENT_LIST_DIR}/tildagon/micropython.cmake)
24+
25+
# Add HMAC driver
26+
include(${CMAKE_CURRENT_LIST_DIR}/tildagon_hmac/micropython.cmake)

drivers/tildagon/micropython.cmake

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Create an INTERFACE library for our C module.
2+
add_library(usermod_tildagon INTERFACE)
3+
4+
# Add our source files to the lib
5+
target_sources(usermod_tildagon INTERFACE
6+
${CMAKE_CURRENT_LIST_DIR}/tildagon.c
7+
)
8+
9+
# Add the current directory as an include directory.
10+
target_include_directories(usermod_tildagon INTERFACE
11+
${CMAKE_CURRENT_LIST_DIR}
12+
)
13+
14+
# Link our INTERFACE library to the usermod target.
15+
target_link_libraries(usermod_tildagon INTERFACE usermod_tildagon_hmac)
16+
target_link_libraries(usermod INTERFACE usermod_tildagon)
Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
#include "py/builtin.h"
22
#include "py/runtime.h"
33

4-
#if MICROPY_PY_TILDAGON
4+
// #include "tildagon_hmac/tildagon_hmac.h"
5+
6+
extern const mp_obj_module_t tildagon_hmac_module;
57

6-
// info()
7-
static mp_obj_t py_tildagon_info(void) {
8-
return MP_OBJ_NEW_SMALL_INT(42);
9-
}
10-
MP_DEFINE_CONST_FUN_OBJ_0(tildagon_info_obj, py_tildagon_info);
118

129
static const mp_rom_map_elem_t mp_module_tildagon_globals_table[] = {
1310
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_tildagon) },
14-
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&tildagon_info_obj) },
11+
{ MP_ROM_QSTR(MP_QSTR_HMAC), MP_ROM_PTR(&tildagon_hmac_module) },
1512
};
1613
static MP_DEFINE_CONST_DICT(mp_module_tildagon_globals, mp_module_tildagon_globals_table);
1714

@@ -21,5 +18,3 @@ const mp_obj_module_t mp_module_tildagon = {
2118
};
2219

2320
MP_REGISTER_MODULE(MP_QSTR_tildagon, mp_module_tildagon);
24-
25-
#endif
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Create an INTERFACE library for our C module.
2+
add_library(usermod_tildagon_hmac INTERFACE)
3+
4+
# Add our source files to the lib
5+
target_sources(usermod_tildagon_hmac INTERFACE
6+
${CMAKE_CURRENT_LIST_DIR}/tildagon_hmac.c
7+
)
8+
9+
# Add the current directory as an include directory.
10+
target_include_directories(usermod_tildagon_hmac INTERFACE
11+
${CMAKE_CURRENT_LIST_DIR}
12+
)
13+
14+
# Link our INTERFACE library to the usermod target.
15+
target_link_libraries(usermod INTERFACE usermod_tildagon_hmac)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include "tildagon_hmac.h"
2+
#include "esp_hmac.h"
3+
4+
#include "py/runtime.h"
5+
6+
static mp_obj_t tildagon_hmac_digest(mp_obj_t key_slot, mp_obj_t msg) {
7+
uint8_t hmac[32];
8+
hmac_key_id_t key_id = mp_obj_get_int(key_slot);
9+
10+
mp_buffer_info_t bufinfo;
11+
mp_get_buffer_raise(msg, &bufinfo, MP_BUFFER_READ);
12+
13+
esp_err_t err = esp_hmac_calculate(key_id, bufinfo.buf, bufinfo.len, hmac);
14+
15+
if (err == ESP_FAIL) {
16+
mp_raise_msg(&mp_type_Exception, "HMAC key not provisioned!");
17+
}
18+
19+
return mp_obj_new_bytes(hmac, 32);
20+
}
21+
22+
static MP_DEFINE_CONST_FUN_OBJ_2(tildagon_hmac_digest_obj, tildagon_hmac_digest);
23+
24+
static const mp_rom_map_elem_t tildagon_hmac_globals_table[] = {
25+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_HMAC)},
26+
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&tildagon_hmac_digest_obj) },
27+
{ MP_ROM_QSTR(MP_QSTR_HMAC_KEY0), MP_ROM_INT(HMAC_KEY0)},
28+
{ MP_ROM_QSTR(MP_QSTR_HMAC_KEY1), MP_ROM_INT(HMAC_KEY1)},
29+
{ MP_ROM_QSTR(MP_QSTR_HMAC_KEY2), MP_ROM_INT(HMAC_KEY2)},
30+
{ MP_ROM_QSTR(MP_QSTR_HMAC_KEY3), MP_ROM_INT(HMAC_KEY3)},
31+
{ MP_ROM_QSTR(MP_QSTR_HMAC_KEY4), MP_ROM_INT(HMAC_KEY4)},
32+
{ MP_ROM_QSTR(MP_QSTR_HMAC_KEY5), MP_ROM_INT(HMAC_KEY5)},
33+
};
34+
35+
static MP_DEFINE_CONST_DICT(tildagon_hmac_globals, tildagon_hmac_globals_table);
36+
37+
const mp_obj_module_t tildagon_hmac_module = {
38+
.base = { &mp_type_module },
39+
.globals = (mp_obj_dict_t *)&tildagon_hmac_globals,
40+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef _TILDAGON_HMAC_H_
2+
#define _TILDAGON_HMAC_H_
3+
4+
#include "py/runtime.h"
5+
6+
extern const mp_obj_module_t tildagon_hmac_module;
7+
8+
#endif // _TILDAGON_HMAC_H_

sim/fakes/tildagon/HMAC.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import hmac
2+
3+
def digest(key_slot, msg):
4+
key = bytes(32)
5+
if key_slot == HMAC_KEY0:
6+
key = b'\x96\xd6I\x0c\x8f\x81\x0f\xc1\x95a\xe2K\xef\xa5xT~\x8d\xcd\xa7~\xd9H\x0b\xdc\xf2\x9dD\xd3\xd3>Y'
7+
return hmac.digest(key, msg, "sha256")
8+
9+
10+
HMAC_KEY0 = 0
11+
HMAC_KEY1 = 1
12+
HMAC_KEY2 = 2
13+
HMAC_KEY3 = 3
14+
HMAC_KEY4 = 4
15+
HMAC_KEY5 = 5

0 commit comments

Comments
 (0)