From 50e6f90b09ace4afe333908c8c074aedfdf2828f Mon Sep 17 00:00:00 2001 From: "radim.karnis" Date: Tue, 22 Dec 2020 11:18:11 +0100 Subject: [PATCH] espefuse: Prevent burning multicast mac address Closes https://github.com/espressif/esptool/issues/472 --- espressif/efuse/esp32/fields.py | 8 +++-- espressif/efuse/esp32/operations.py | 4 +-- espressif/efuse/esp32c3/operations.py | 2 +- espressif/efuse/esp32s2/operations.py | 2 +- espressif/efuse/esp32s3beta2/operations.py | 2 +- test/test_espefuse_host.py | 41 +++++++++++++--------- 6 files changed, 35 insertions(+), 24 deletions(-) diff --git a/espressif/efuse/esp32/fields.py b/espressif/efuse/esp32/fields.py index df500563d..6c05f52d5 100644 --- a/espressif/efuse/esp32/fields.py +++ b/espressif/efuse/esp32/fields.py @@ -209,8 +209,12 @@ def check_format(self, new_value_str): hexad = new_value_str.replace(":", "") if len(hexad) != 12: raise esptool.FatalError("MAC Address needs to be a 6-byte hexadecimal number (12 hexadecimal characters)!") - # order of bytearray = b'\xab\xcd\xef\x01\x02\x03', - return binascii.unhexlify(hexad) + # order of bytearray = b'\xaa\xcd\xef\x01\x02\x03', + bindata = binascii.unhexlify(hexad) + # unicast address check according to https://tools.ietf.org/html/rfc7042#section-2.1 + if esptool.byte(bindata, 0) & 0x01: + raise esptool.FatalError("Custom MAC must be a unicast MAC!") + return bindata @staticmethod def get_and_check(raw_mac, stored_crc): diff --git a/espressif/efuse/esp32/operations.py b/espressif/efuse/esp32/operations.py index fc68f3641..8da698687 100644 --- a/espressif/efuse/esp32/operations.py +++ b/espressif/efuse/esp32/operations.py @@ -56,7 +56,7 @@ def add_commands(subparsers, efuses): p = subparsers.add_parser('burn_custom_mac', help='Burn a 48-bit Custom MAC Address to EFUSE BLOCK3.') p.add_argument('mac', help='Custom MAC Address to burn given in hexadecimal format with bytes separated by colons' - ' (e.g. AB:CD:EF:01:02:03).', type=fields.base_fields.CheckArgValue(efuses, "CUSTOM_MAC")) + ' (e.g. AA:CD:EF:01:02:03).', type=fields.base_fields.CheckArgValue(efuses, "CUSTOM_MAC")) add_force_write_always(p) p = subparsers.add_parser('get_custom_mac', help='Prints the Custom MAC Address.') @@ -65,7 +65,7 @@ def add_commands(subparsers, efuses): def burn_custom_mac(esp, efuses, args): # Writing to BLK3: # - MAC_VERSION = 1 - # - CUSTOM_MAC = AB:CD:EF:01:02:03 + # - CUSTOM_MAC = AA:CD:EF:01:02:03 # - CUSTOM_MAC_CRC = crc8(CUSTOM_MAC) efuses["CUSTOM_MAC"].save(args.mac) efuses.burn_all() diff --git a/espressif/efuse/esp32c3/operations.py b/espressif/efuse/esp32c3/operations.py index b81682307..2c1896ed8 100644 --- a/espressif/efuse/esp32c3/operations.py +++ b/espressif/efuse/esp32c3/operations.py @@ -72,7 +72,7 @@ def add_commands(subparsers, efuses): p = subparsers.add_parser('burn_custom_mac', help='Not supported! Burn a 48-bit Custom MAC Address to EFUSE is.') p.add_argument('mac', help='Custom MAC Address to burn given in hexadecimal format with bytes separated by colons' - ' (e.g. AB:CD:EF:01:02:03).', nargs="?") + ' (e.g. AA:CD:EF:01:02:03).', nargs="?") add_force_write_always(p) p = subparsers.add_parser('get_custom_mac', help='Not supported! Prints the Custom MAC Address.') diff --git a/espressif/efuse/esp32s2/operations.py b/espressif/efuse/esp32s2/operations.py index 0edeba185..a63fd1dfc 100644 --- a/espressif/efuse/esp32s2/operations.py +++ b/espressif/efuse/esp32s2/operations.py @@ -72,7 +72,7 @@ def add_commands(subparsers, efuses): p = subparsers.add_parser('burn_custom_mac', help='Not supported! Burn a 48-bit Custom MAC Address to EFUSE is.') p.add_argument('mac', help='Custom MAC Address to burn given in hexadecimal format with bytes separated by colons' - ' (e.g. AB:CD:EF:01:02:03).', nargs="?") + ' (e.g. AA:CD:EF:01:02:03).', nargs="?") add_force_write_always(p) p = subparsers.add_parser('get_custom_mac', help='Not supported! Prints the Custom MAC Address.') diff --git a/espressif/efuse/esp32s3beta2/operations.py b/espressif/efuse/esp32s3beta2/operations.py index b07ba4efd..ad80803a9 100644 --- a/espressif/efuse/esp32s3beta2/operations.py +++ b/espressif/efuse/esp32s3beta2/operations.py @@ -72,7 +72,7 @@ def add_commands(subparsers, efuses): p = subparsers.add_parser('burn_custom_mac', help='Not supported! Burn a 48-bit Custom MAC Address to EFUSE is.') p.add_argument('mac', help='Custom MAC Address to burn given in hexadecimal format with bytes separated by colons' - ' (e.g. AB:CD:EF:01:02:03).', nargs="?") + ' (e.g. AA:CD:EF:01:02:03).', nargs="?") add_force_write_always(p) p = subparsers.add_parser('get_custom_mac', help='Not supported! Prints the Custom MAC Address.') diff --git a/test/test_espefuse_host.py b/test/test_espefuse_host.py index c872ae25b..8431505ce 100755 --- a/test/test_espefuse_host.py +++ b/test/test_espefuse_host.py @@ -231,28 +231,34 @@ def test_write_protect_efuse2(self): def test_burn_custom_mac(self): self.espefuse_py("burn_custom_mac -h") - cmd = 'burn_custom_mac AB:CD:EF:11:22:33' + cmd = 'burn_custom_mac AA:CD:EF:11:22:33' if chip_target == "esp32": - self.espefuse_py(cmd, check_msg='Custom MAC Address version 1: ab:cd:ef:11:22:33 (CRC 0x54 OK)') + self.espefuse_py(cmd, check_msg='Custom MAC Address version 1: aa:cd:ef:11:22:33 (CRC 0x63 OK)') else: self.espefuse_py(cmd, check_msg='burn_custom_mac is not supported!', ret_code=2) + @unittest.skipUnless(chip_target == "esp32", "burn_custom_mac is supported only by esp32") def test_burn_custom_mac2(self): - if chip_target == "esp32": - self.espefuse_py('burn_custom_mac AB:CD:EF:11:22:33:44', - check_msg='A fatal error occurred: MAC Address needs to be a 6-byte hexadecimal format separated by colons (:)!', - ret_code=2) + self.espefuse_py('burn_custom_mac AA:CD:EF:11:22:33:44', + check_msg='A fatal error occurred: MAC Address needs to be a 6-byte hexadecimal format separated by colons (:)!', + ret_code=2) + + @unittest.skipUnless(chip_target == "esp32", "burn_custom_mac is supported only by esp32") + def test_burn_custom_mac3(self): + self.espefuse_py('burn_custom_mac AB:CD:EF:11:22:33', + check_msg='A fatal error occurred: Custom MAC must be a unicast MAC!', + ret_code=2) + @unittest.skipUnless(chip_target == "esp32", "burn_custom_mac is supported only by esp32") def test_burn_custom_mac_with_34_coding_scheme(self): - if chip_target == "esp32": - self._set_34_coding_scheme() - self.espefuse_py("burn_custom_mac -h") - self.espefuse_py('burn_custom_mac AB:CD:EF:01:02:03', check_msg='Custom MAC Address version 1: ab:cd:ef:01:02:03 (CRC 0x61 OK)') - self.espefuse_py('get_custom_mac', check_msg='Custom MAC Address version 1: ab:cd:ef:01:02:03 (CRC 0x61 OK)') + self._set_34_coding_scheme() + self.espefuse_py("burn_custom_mac -h") + self.espefuse_py('burn_custom_mac AA:CD:EF:01:02:03', check_msg='Custom MAC Address version 1: aa:cd:ef:01:02:03 (CRC 0x56 OK)') + self.espefuse_py('get_custom_mac', check_msg='Custom MAC Address version 1: aa:cd:ef:01:02:03 (CRC 0x56 OK)') - self.espefuse_py('burn_custom_mac FF:22:33:44:55:66', - check_msg='New value contains some bits that cannot be cleared (value will be 0x675745ffefff)', - ret_code=2) + self.espefuse_py('burn_custom_mac FE:22:33:44:55:66', + check_msg='New value contains some bits that cannot be cleared (value will be 0x675745ffeffe)', + ret_code=2) @unittest.skipIf(chip_target == "esp32c3", "TODO: add support set_flash_voltage for ESP32-C3") def test_set_flash_voltage_1_8v(self): @@ -301,11 +307,12 @@ def test_burn_efuse(self): CHIP_VER_REV2 1 \ DISABLE_DL_ENCRYPT 1 \ CONSOLE_DEBUG_DISABLE 1') - self.espefuse_py('burn_efuse MAC AB:CD:EF:01:02:03', check_msg="Writing Factory MAC address is not supported", ret_code=2) + self.espefuse_py('burn_efuse MAC AA:CD:EF:01:02:03', check_msg="Writing Factory MAC address is not supported", ret_code=2) self.espefuse_py('burn_efuse MAC_VERSION 1') self.espefuse_py("burn_efuse -h") - self.espefuse_py('burn_efuse CUSTOM_MAC AB:CD:EF:01:02:03') - self.espefuse_py('get_custom_mac', check_msg='Custom MAC Address version 1: ab:cd:ef:01:02:03 (CRC 0x61 OK)') + self.espefuse_py('burn_efuse CUSTOM_MAC AB:CD:EF:01:02:03', check_msg="A fatal error occurred: Custom MAC must be a unicast MAC!", ret_code=2) + self.espefuse_py('burn_efuse CUSTOM_MAC AA:CD:EF:01:02:03') + self.espefuse_py('get_custom_mac', check_msg='Custom MAC Address version 1: aa:cd:ef:01:02:03 (CRC 0x56 OK)') blk1 = "BLOCK1" blk2 = "BLOCK2" else: