IoT Security, DRM and user freedom
IoT security is a hot topic these days, and rightly so. Matthew Garrett has spent a lot of time reverse engineering various IoT light bulbs to determine how secure they are, with depressing results. So when I saw Bruce Schneier’s recent post Security Analysis of the LIFX Smart Light Bulb which started with “it’s terrible” I thought this was more of the same. Except it’s not. The original article is Pwn the LIFX Mini white (and the author has at least a couple of other device teardowns in the same vein).
What these articles are concerned with is not the usual protocol level security which Matthew investigates. Instead they’re about physical device security. In particular the points raised are:
- Wi-Fi details are stored in the clear on the device
- The device does not have secure boot or flash encryption enabled
- The private key for the device can be retrieved easily
All of these boil down to the same root cause; without effective DRM there is no way to protect devices from physical attacks. That can be as simple as having only internal flash and being able to blow a set of EFUSEs to prevent readout/debug interfaces functioning, or it can be a full built in boot ROM with cryptographic verification of an image pulled in from external flash (potentially encrypted) and the building up of a chain of trust. I see 2 main problems with this.
Firstly, getting security like this right is hard. Games console manufacturers are constantly trying to protect their devices against unauthorised code running, and while they seem to be getting better it’s taken quite a number of mistakes to get there. They have a much bigger financial imperative to get this right, as console DRM attacks are frequently used for piracy. An IoT vendor could end up adding significant cost to their BoM if they have to buy a more advanced chip to be able to do the appropriate end-to-end flash encryption required. (The LIFX is using the ESP32, which does have some of these features that are not present in the more basic (and cheaper) ESP8266. I’ve no idea if anyone has done a full analysis of the ESP32 security.)
Secondly, locking devices down in this way has a big impact on user freedom. It should come as no surprise that this is my primary concern, as I believe it is detrimental to the end user in multiple ways.
- There’s a lot of poor security in the IoT protocol arena. If it’s not possible for anyone other than the manufacturer to update a device, or retrieve the firmware image to examine how a device operates, security will suffer.
- Updates being locked down to the manufacturer leaves the user open to the prospect of forced obsolescence when the manufacturer decides they will no longer support the device, or goes out of business (assuming a device that has some sort of cloud component).
- Part of the appeal of a lot of the current IoT devices is the fact they can be repurposed for uses beyond what the manufacturer imagined. Just look at the Sonoff-Tasmota project - this excellent 3rd party support is one of the main reasons I purchased several Sonoff devices. If I hadn’t been able to replace the firmware they wouldn’t have been of interest to me or countless other people who’ve purchased them.
There are ways to enable user freedom while still having a locked down setup by default, but they’re hard to do in the embedded IoT space (generally no hardware infrastructure that allows plugging in a USB stick with a new root certificate on it and enrolling it like EFI Secure Boot), and add significant cost and complexity to devices that are meant to be cheap and ubiquitous. I see the validity in raising concerns about discarded devices leaking Wi-Fi credentials, but it’s something any device you connect to your Wi-Fi is potentially going to do. That means your laptop, your phone and all the random other devices you allow to connect to your Wi-Fi. It’s something we need to be aware of generally, rather than singling some cheap IoT light bulbs out.
The lack of physical security for the firmware image or device credentials is not so worrying to me. A surveillance device in a light bulb is not a new concept; in fact the added complexity of an IoT bulb makes it easier to justify the complex circuitry being present. If it requires physical access to be able to subvert the device like this that’s significantly less worrying than being able to do so remotely.
Don’t get me wrong, I love a good device teardown, and I think there’s an interesting discussion that’s already underway about how to improve physical device security without restricting user freedom. I just don’t think this is the major failure that some commenters are suggesting.
Building an ESP8266 bedside clock
My first post about waiting for some ESP8266 based boards was back in 2016, and I’ve mentioned the use of an ESP8266 in various home automation posts. However I’ve never actually written up what I did with that first board. Hopefully you’ve figured it out from the title of this post.
I had an actual need/desire for a new beside clock. Previously I had a Sony Clock Radio cube, which set itself via the MSF signal. However it ended up with drift - I’m guessing it did a set on power on, but then failed to regularly sync up. I don’t need an alarm clock - my phone provides a much more flexible set of options for that - but I do like to be able to easily tell when I wake up in the night if I’ve got 5 minutes until the alarm or several hours. This seemed like a perfect (if unimaginative) first project for the ESP8266 - build something standalone that would get the time via NTP and have a night-time visible time display.
I purchased a bare ESP-03 module and an ESP-12E on a breakout board (i.e. with a bunch of pin headers soldered on, a 5V→3.3V voltage regulator, the appropriate boot resistors) to experiment with. I figured the 12E would be a good board to prototype with and I’d use the cheaper 03 in the final implementation. For the display I bought a 4 module MAX7219 based 8x8 LED matrix - I could have gone for a 7-segment LED based thing, but I wanted the option of being able to display text.
Initially I installed MicroPython on the board; the ability to interactively try things out helped me to figure out the ESP8266 hardware, and how to drive the MAX7219s using the SPI interface. I’m really impressed with it as a prototyping tool in conjunction with the ESP8266. However I decided it wasn’t what I wanted to do my final implementation in. Although I was just building a basic clock I was using the project as a basis to learn about how to do more complicated things, and I wanted features like Over-The-Air updates, and the potential for displaying custom messages. So I turned to the ESP8266 NONOS C SDK via Paul Sokolovsky’s excellent esp-open-sdk. Richard Antony Burton has some great resources as well, and Espressif have a decent amount of SDK documentation these days. With all of this info I was able to move my code from Python to C.
One of the limitations I hit was trying to fit my code into the available flash on the 03 module. The 12E came with a massive 4MB flash chip, but the 03 was a much more limited 512kB. To allow OTA upgrades that mean I had just under 256kB to work with. Even with a pure C implementation until I made sure I was using all the ROM functions available, and only including the pieces I really needed, I was regularly exceeding this. (As it happened, ultimately the cheap flash on the 03 died during my experimentation and I ended up fixing the flash using a larger 2M chip. Trimming my code down to fit within the 256kB limitation was still an interesting exercise.)
The code’s not the prettiest, but it does what I need and I’m really glad I built in the OTA functionality - it makes testing much, much easier than having to do the serial flash dance on every change. Available locally or on GitHub.
The final piece was to find a suitable case. I suck at this. Lucky we had a small glass topped wooden box in the house which was about the right side. A piece of paper in front of the glass provided a suitable filter and while I’m not going to win any awards for design the whole thing ends up looking reasonably well on my beside table.

(As an aside, if you’re interested in seeing a toolchain for the ESP8266 hit Debian then I’ve already uploaded binutils-xtensa-lx106 + gcc-xtensa-lx106 and am just waiting on binutils to exit NEW - there’s been some discussion about the correct naming in #917546 that I think is making ftp-master a bit more cautious.)
MP130 Maple Leaf and Debian
Like any conference one of the nice things about DebConf is the random interesting people you meet. At the DebConf18 conference dinner I had the pleasure of talking to Jia-Bin Huang, from Centrum Embedded Systems. He told me about how he was using Debian as the basis for his MapleBoard (mostly in Chinese, unfortunately) project, which is based on the Allwinner H3 and has thousands of shipped units. The next day I went to take a look at the website (Google Translate proved helpful), which has details of the board including full schematics of the board. I reached out to Jia-Bin to see if he was still at the conference and if he had any boards with him, but he’d already returned to Taipei. He generously offered to send me one and a few weeks later (mostly due to UK customs delays) I had an “Economy Edition” board in my hands.

Getting up and running was simple; the board came with a pl2303 based USB serial cable, but I found it a little unreliable so ended up using my own cable. The supplied documentation was in Chinese, but the login details were clearly visible - username mpl1, password 1234. After logging in I found it was running a lightly customized Debian Stretch variant, with the following packages not from the main Debian repository:
base-files 9.9+mp4 Maple base system miscellaneous files
debian-archive-keyring 2017.7+mp1 GnuPG archive keys of the Debian archive
distro-info-data 0.36+mp1 information about the distributions' releases (data files)
linux-image-4.15.2a… 4.15.2a… Linux kernel, version 4.15.2a-02769-g6d0ce60c8d56
maplewebde 0.1~rc4-2 Web interface to communicate with mapleboard
maplewebde seems to be a web interface for interacting with the board, but it’s in Chinese so I wasn’t able to make much sense of it. I was more interested in the kernel - how much customisation had been done, and how much was already mainlined. Happily the Linux sunxi folk have done a lot of great work in getting things upstream, so although the supplied kernel was using its own drivers (largely branded Mapleboard rather than Allwinner) all the necessary pieces were in mainline. I did a little bit of cleanup of the supplied device tree configuration file, and am pleased to say that as of 5.0-rc1 a multi_v7_defconfig will build a kernel and a sun8i-h3-mapleboard-mp130.dtb file which Just Work™ on the device.
What about the board itself? I haven’t thrown a lot at it, but it feels reasonably responsive compared to some other ARM boards I’ve played with. Quad 1GHz cores and 1GB RAM is a nice enough base spec, though it is ARMv7 so 32-bit only. Unfortunately the “Economy Edition” doesn’t have HDMI on board or I’d have seen about trying to use it as a media player - the video decoding engine apparently has Free drivers based on a vdpau backend, which is pretty cool. There’s no SATA, so it can’t be pressed into service as a build machine easily. I suspect in the long run I’ll press it into service as part of my home automation setup, somewhere I need more oompf than an ESP8266 but still want low power consumption - there are a number of GPIOs conveniently brought out to a 40 pin header.
In general terms of the target market my understanding is the board is largely pitched as a development board, with Centrum being prepared to do customisations for sufficiently sized runs. The open nature of the board, and availability of good support upstream (even if it’s come from the community rather than Allwinner) certainly makes it an attractive option if you’re looking for a 32-bit ARM platform, and although I’m not aware of any option other than ordering from Taiwan at present I’ve found Jia-Bin to be helpful with any queries I’ve had. Also I quite like supporting companies that are using Debian. :) Worth a look if you’re in the market for such a thing.
Maxcio W-UK007S Power Monitoring Smart Plug notes
The house server I built in 2013 is getting on a bit, so I’d like to replace it. That’s currently held up on availability of Ryzen 7 2700E CPUs, which look to be the best power consumption/performance trade-off available at present. While I wait for stock I figured I should see how the current i3-3220T is doing.
To do so I decided to buy a Smart Plug that advertised energy monitoring, planning to integrate it into my current setup for the monitoring and then being able to use it for general power control once the upgrade comparison is complete. I ended up with a pair of Maxcio Smart Plugs - pricing and availability worked out and I’d found confirmation that the W-US002S was ESP8266 based.
The model I ended up with is externally marked as a W-UK007S. It’s a fairly neat form factor (slightly smaller than the SonOff S26 I already have, which doesn’t do power monitoring). It also turned out to be easy to take apart; there is a circular cover in the middle which can be carefully popped out, revealing the single screw holding the device together.

The back plate has 4 clips holding it together at the corners and can be gently pried off. Inside there’s a main circuit board labelled “W-US0007S-V0.3” which has the relay on it and a perpendicular board with the ESP8266 module and power monitoring chip on it.

Sadly the layout didn’t match anything I was familiar with, or could find any details of. That meant I had to do some detective work to figure out how to talk to the ESP8266. It was easy enough to work out GND + VCC by following PCB tracks. Likewise the relay, the button and the LED (underneath the button, and separately controlled from the relay, unlike the S26). Next move was to hook up power (just a low voltage supply to GND/VCC, I did not engage in any experimentation involving mains voltages!) and monitor each unknown pin in turn in the hope I’d find TX (even if the supplied firmware didn’t print anything out the ESP8266 prints a message on boot, so I’d definitely see something if it was there).
Thankfully TX was brought out to the module connection to the main PCB, so I had something I could monitor.
Maxcio boot log
ets Jan 8 2013,rst cause:1, boot mode:(3,7)
load 0x40100000, len 1396, room 16
tail 4
chksum 0x89
load 0x3ffe8000, len 776, room 4
tail 4
chksum 0xe8
load 0x3ffe8308, len 540, room 4
tail 8
chksum 0xc0
csum 0xc0
2nd boot version : 1.4(b1)
SPI Speed : 40MHz
SPI Mode : QIO
SPI Flash Size & Map: 8Mbit(512KB+512KB)
jump to run user1 @ 1000
OS SDK ver: 1.4.2(23fbe10) compiled @ Sep 22 2016 13:09:03
phy v[notice]user_main.c:268 SDK version:1.4.2(23fbe10)
[notice]user_main.c:270 tuya sdk version:1.0.6
[notice]user_main.c:275 tuya sdk compiled at Jul 26 2017 15:27:36
[notice]user_main.c:277 BV:5.20 PV:2.1 LPV:3.1
reset reason: 0
epc1=0x00000000, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000,depc=0x00000000
mode : softAP(de:4f:22:2c:76:93)
dhcp server start:(ip:192.168.4.1,mask:255.255.255.0,gw:192.168.4.1)
add if1
bcn 100
bcn 0
del if1
usl
mode : sta(dc:4f:22:2c:76:93)
add if0
scandone
[notice]device.c:1694 fireware info name:esp_hys_qx_single_light_jlplug version:1.0.0
[notice]device.c:1695 PID=gDYvLrWhRoqpgHMj
[notice]device.c:1696 FW Compiled date:Feb 5 2018
[notice]gw_intf.c:240 Authorization success
[notice]device.c:1722 ## AUTH DONE ##
[err]bl0937.c:1013 ### get_coefficient get err: 28
[err]device.c:1767 get ele data err...
[err]device.c:1772 get tem ele data err...
del if0
usl
mode : null
force slp enable,type: 2
fpm open,type:2 0
[notice]device.c:2041 # STAT_STA_UNCONN STAT_LOW_POWER#
[notice]device.c:2042 # STAT_STA_CONN #
[notice]device.c:648 #####I_VAL:0#####
[notice]device.c:654 ***************************Check Start 1**********************************
[notice]device.c:655 ### cur:0 mA power:0 W vol:0 V
[notice]device.c:656 ****************************Check Stop**********************************
Next I took the remaining unknown pins and tried grounding them on boot, in an attempt to find GPIO0 (which needs to be grounded to access the ROM serial bootloader). I ended up finding GPIO2 first, and then eventually figuring out the LED was using GPIO0 - learning the lesson not to assume pins don’t have multiple uses. Now I had TX + GPIO0 I could hold GPIO0 on boot and look for RX by probing the remaining pins and seeing if esptool could talk to the bootloader. Again, I was successful.
At that point I was able to download the firmware from flash, and poke it in the hope of working out the GPIO assignments (I’m a software guy, I’m happier with an assembly dump than probing randomly around a board in the hope of enlightenment). I generated a crude .elf from the flash dump using esp-bin2elf, hacking it up to cope better with an OTA ROM image and skip the boot loader. I initially used objdump to examine the result, which wasn’t that helpful, and then found ScratchABit, which made things much easier. What would have been ideal is some way to load in the .a static libraries from the SDK and automatically map those to the code; as well as providing some useful symbols it would have avoided work looking at functions that were irrelevant. The ESP8266 seems to want various levels of indirection to access functions and memory locations so it’s not just a simple matter of looking for an I/O request to a specific location, but I was able to figure out that the button was on GPIO13 and the relay on GPIO15.
All that left was the bit I was actually interested in - the power monitoring. The appropriate chip (clearly attached to a low resistance bridge from one of the AC power pins, and also attached to the other pin) on the PCB was marked “HJL-01 / J1749CYH / D797480E”. Whatever you find on the web this is not the same as the HLW8012. It’s very similar in operation but is actually a BL0937. Electrodragon’s Energy Meter page was the best resource I found - it has a link to the Chinese datasheet for the BL0937, which in combination with Google Translate allows the basic principles to be understood. Both devices work by having a pin (CF) which outputs pulses based on monitored power consumption, and a pin (CF1) which can be switched between monitoring current and voltage via a third pin (SEL). For the BL0937 you can just count pulses; the pulse width is fixed at 38µS and it’s just the frequency which varies. I’d found the GPIO interupt handler in my flash disassembly which indicated that GPIO5 was connected to CF and GPIO14 to CF1. Additionally the handler around GPIO14 needs to check which mode the chip is currently in, which let me discover GPIO12 was connected to this pin.
That resulted in the following pin mapping of the daughter PCB; the remaining 4 pins weren’t of interest once I had the ones I needed, so I didn’t do further investigation:
PCB EDGE
+----+
LED / GPIO0 |1 12| 3.3V
|2 11|
BUTTON / GPIO13 |3 10| GPIO2
TX |4 9| RX
RELAY / GPIO15 |5 8|
GND |6 7|
+----+
PCB CENTER
Of course the frequency values that come out of the BL0937 are not directly usable; there’s a certain amount of conversion/calibration that needs to be done. Thankfully although the datasheet has an equation that includes an odd constant value as well as the internal reference voltage this all boils down to a simple scaling value. I ended up using a multimeter to calibrate the voltage and then a standalone power meter + table lamp to calibrate power/current. Better results could be obtained with a constant voltage source and a known resistance load but this worked out close enough for my needs.
I wrote my own driver to fit within the ESP8266 MQTT framework I use, but if you’re looking for something more off the shelf ESPurna is probably a good start. Ticket #737 talks about adding support for the BL0937 (it’s close enough to the HLW8012 that you can get away with just changing the scaling factors), and the Homecube SP1 seems to use the same GPIOs for the various pieces of hardware.
I’ve put all the images from my teardown into a W-UK007S Teardown Album on Google Photos, in case it’s useful to anyone.
⬛⬛⬛⬛⬛⬛⬛⬛⬛⬛
We obsess over free speech. It is a club with which we beat anyone who we believe is trying to silence us, or otherwise make our opinion unheard. I live in Northern Ireland, so my legal right flows from the European Convention on Human Rights (ECHR) via a combination of the Human Rights Act 1998 (HRA) and the Northern Ireland Act 1998 s6(2) (NIA). Additionally the Charter of Fundamental Rights of the European Union applies in certain circumstances.
If you look at the ECHR the phrases “Free Speech” and “Freedom of Speech” do not actually appear. The relevant article is article 10, “Freedom of Expression”, which says:
Everyone has the right to freedom of expression. This right shall include freedom to hold opinions and to receive and impart information and ideas without interference by public authority and regardless of frontiers. This Article shall not prevent States from requiring the licensing of broadcasting, television or cinema enterprises.
The exercise of these freedoms, since it carries with it duties and responsibilities, may be subject to such formalities, conditions, restrictions or penalties as are prescribed by law and are necessary in a democratic society, in the interests of national security, territorial integrity or public safety, for the prevention of disorder or crime, for the protection of health or morals, for the protection of the reputation or rights of others, for preventing the disclosure of information received in confidence, or for maintaining the authority and impartiality of the judiciary.
Paragraph 1 is the one we trot out. Paragraph 2 doesn’t get so much airtime. The right to freedom of expression is not unqualified (compare Article 3 which prohibits torture and is short and succinct). There are recognised needs to curtail the freedom of expression. Even if you ignore state decisions such as “national security” or “protection of morals” it is still necessary to respect the right of others. The common tension is between the right to Freedom of Expression and the Right to respect for private and family life (Article 8), but prevention of disclosure of information received in confidence is also explicitly called out.
These qualifications on the right to freedom of expression shouldn’t seem surprising. Society is all about balancing the needs of everyone to try and achieve some sort of harmony. We can be generally in favour of a free press while also accepting that there need to be some limits on how much they can intrude into people’s personal lives. Equally just because one finds doxxing despicable doesn’t mean one is against freedom of expression. We need to stop the black and white view that any attempt to curtail freedom of expression, no matter what the context, is a violation of an unqualified fundamental right. Too much simplification of the details takes place.
The other thing that needs to be remembered is that this right relates to governments - “without interference by public authority”. It doesn’t say anything about what you as a private individual have to do to enable my right to freedom of expression. I can’t force you to read this blog, or provide me with aggregation on your site to help me reach a wider audience. Equally I don’t have to host comments that are spam, or that I find offensive. No one’s right to freedom of expression is impinged here; I can blog what I like if I’m the one hosting it, people can conduct their marketing in other forum without me being able to prevent them doing so.
We also don’t see any statement about what organisations have to do. The HRA talks explicitly about being able to review the actions of public authorities, but it is rightly silent on anything to do with private organisations. If you can’t be seen as acting as an arm of the government, the HRA doesn’t apply. Organisations don’t have to support the views of those they disagree with - just look at the split in newspapers over whether Brexit is a good thing or not - or things unrelated to the organisation (there’s no reason I would be syndicated on Planet GNOME). That might be disappointing to individuals, but trotting out Freedom of Expression as a defence or a justification for why an organisation should help promote our views just fails to understand the nature of the right.
I don’t make any points above that haven’t been made more eloquently by others countless times, but sometimes I feel we need to be reminded of them.
subscribe via RSS