OpenWrt support for TP-Link Deco M4R

Sysupgrade worked! Seems like the lack of firmware partition defined in dts was the issue.

Only the web-interface that is loaded by the bootloader if you press and hold the reset button during bootup is checking the RSA signature. Once you are in the command line of the bootloader (just type tpl multiple times during bootup) you could flash a jpeg of a horse to the flash memory and the bootloader wouldn't care.

So if you are soldering anyway then you don't need to worry about any RSA checks.

I have found this: U-Boot: Verified RSA Boot on ARM target (denx.de), gives some insight...

The Deco M4R V1 and V2 don't have an ARM SoC. The bootloader isn't checking what is in the flash. It only checks whatever you upload via the web interface before it flashes it.

I wonder if the private key could be extracted from the router because the router's bootloader must check the image somehow, but I could be wrong so don't quote me on that.

Yes, you are. Whatever is encoded with the private key can only be decoded with the public key and whatever is encoded with the public key can only be decoded with the private key.

So you will never find the private key on the router. That's just not how that works.

That's also how your bank does it with your online banking or how almost all websites these days do it with https. The server is the only one who knows the private key but it will gladly tell you the public key so you can encode messages with it that only the server can decode with its private key.

Sysupgrade worked! Seems like the lack of firmware partition defined in dts was the issue.

I'm betting that the label = "firmware"; is the important part here.

Did you upgrade from your second to last build to your last build or did you upgrade from my image?

I upgraded from my second to last build to my last build so it could work with 19.07 but I haven't tested that.

The second to last build still had kernel and rootfs as separate partitions in the .dts, right? Sounds good either way that it worked for you.

Are the MACs of the eth0 interface and of the first 2.4GHz SSID now the same as the one on the label on the bottom of the Deco? Is the first 5GHz MAC one less?

For instance if the MAC on the Label is E1:AA:BB:CC:DD:E0 then the first 5GHz SSID should have E1:AA:BB:CC:DD:DF (in Hex DF + 1 = E0, E0 + 1 = E1 and so on).

(OpenWrt will add 2 to the first byte of every following SSID so the second 2.4GHz SSID should have E3:AA:BB:CC:DD:E0 and the second 5GHz SSID should have E3:AA:BB:CC:DD:DF)

Actually no, my second to last build had kernel 5.4.163 and I upgraded to 5.4.168, both had firmware partitions defined, also I just tested it on my main deco which didn't have the firmware partition (I experimented on my secondary one) and it didn't work so you have to use mtd method to go to the image with the firmware partition defined.

I'll check this in a minute.
Edit: Yes, they are exactly how you said.

Hello everyone,
I've added another mirror for backup. Hope for the best !!
Link: https://www.androidfilehost.com/?fid=17825722713688258825

1 Like

This is simply incorrect. RSA is asymmetric, the private key can only decode while the public key can only encode, I guess you didn't write that correctly.

My thinking was because the firmware image is encoded with the public key and the router checks it with its private key that is inside the bootloader, whether it would be possible to somehow extract it, but I guess it's not that simple.

Plus, I think it would make more sense to check whether the Web GUI does the RSA check or not.

Let's take this a little apart:

This is simply incorrect. RSA is asymmetric, the private key can only decode while the public key can only encode, I guess you didn't write that correctly.

The function of using RSA here is to only allow firmware signed by TP-Link to be installed on the device. In this case TP-Link uses their private key (of which we are not aware) to encrypt the hash generated from the different parts of the image and supply that signature along with the binaries (in the form of the DTS). The router calculates the hashes again, and uses the public key (it is in the image in some form, therefore it's public, it's there to see for everyone) to decrypt the hashes in the DTS and compares them with the calculated one). If they match, it's ok. If not, flushes the image down the drain.

The confusion arises from the usage of RSA which can be used for encryption (but then the content should be encrypted with the recipient's public key) or proof of authenticity aka signing (this is our case).

In that sense RSA is symmetric: something encrypted with the private key can only be decrypted by the public key and something encrypted with the public key can only be decrypted with the private key.

I think it would make more sense to check whether the Web GUI does the RSA check or not.

It is possible, but I doubt it. U-Boot has everything built-in to do the vaildation and requires only to some funtion to be called. If you do this in linux you would need to duplicate/replicate these functions and that doubles the risk of messing something up.

I suggest that we need an "unlocked" U-Boot with at least RSA-checking disabled. The U-Boot source is in the GPL pack, maybe it can be built from that and flashed from the "dev" firmware, but I definitely want to get an SPI flash reader/writer and dump the entire flash contents before I start messing around with U-Boot.

I stand corrected, thank you for this info.

I think someone could flash that leaked firmware and then try to flash an OpenWrt image in Web GUI and read logs in the telnet window to potentially see why the router was refusing to flash the OpenWrt image.

I think it would be possible to make a custom U-boot image with more recovery options, but that is outside of my scope of knowledge.

On second thought it might be possible to "debug" the running U-Boot code itself. If the images themselves are not encrypted, then their hash is known to us. If we could find the compare function in U-Boot and trace it, we could find the hash U-Boot expects and apply that to the DTS of our own image.

1 Like

Sorry, but you are incorrect.

The terminology here is clear that TP-Link has the private key and the router only ever gets the public key. Because the private key is only in their possession and the public key is public knowledge and can be seen in their GPL sources for instance.

But that does not mean that you can only decode with the private key and encode with the public key.

You can encode something with a public key and then decode it with the private key. But you can also encode something with the private key and decode it with the public key. This is not a one way street like you think it is.

We just usually call encrypting with the private key "signing" and decrypting with the public key "verifying" because that is of course not a secure communication since everybody has easy access to the public key. But you can verify that only the holder of the private key was able to write the message or in this case the firmware.


That said it's absolutely not a problem to go to tp-link.com and download the GPL sources for the Deco M4R.

In those you will find a file called nm_fwup.c and "fwup" of course means "firmware upgrade". That file does the upgrading via the bootloader web interface and it uses this to check the signature of the firmware:

static unsigned char rsaPubKey = "BgIAAACkAABSU0ExAAQAAAEAAQD9lxDCQ5DFNSYJBriTmTmZlEMYVgGcZTO+AIwm"
"dVjhaeJI6wWtN7DqCaHQlOqJ2xvKNrLB+wA1NxUh7VDViymotq/+9QDf7qEtJHmesji"
"rvPN6Hfrf+FO4/hmjbVXgytHORxGta5KW4QHVIwyMSVPOvMC4A5lFIh+D1kJW5GXWtA==";

My thinking was because the firmware image is encoded with the public key and the router checks it with its private key that is inside the bootloader, whether it would be possible to somehow extract it, but I guess it's not that simple.

So just to say this again: It doesn't work like you think it works. There is no magic private key within the bootloader code.

Edit: And before this question comes up: It's also not easy to write a "hash" or signature so that the bootloader accepts that even if you have the public key. You specifically need the private key to do this. Or else every banking website in the world would be unsecure.

But for what purpose?

If you are soldering then you don't have any RSA checking because you can flash whatever you want from the bootloader's command prompt.

And if you are not soldering then you can't overwrite the bootloader anyway.

Again: As far as the bootloader is concerned: The only thing checking the RSA signature is the bootloaders web gui.

Edit: This would only benefit those who brick their device and want to reflash it with whatever firmware they fancy. Currently that can easily be done with the instructions KinteLiX posted involving that firmware that has telnet activated. And multiple people downloaded that firmware so it isn't going away any time soon.

Alright, I understood it now.

Hey there. Quick question: is a user id/pw required for accessing the router via console?

Also, I assume that if we want to go back to stock, we just upload the stock firmware using the reset button - is that correct?

Thanks in advance.

No.

Yes.

Edit: Keep in mind that for this device it's always a very good idea to flash stock firmware via the recovery webpage you get when holding the reset button during startup. That's what that recovery webpage is designed to do.
Never try to flash stock firmware via the OpenWrt interface because I've read multiple accounts of people bricking their TP-Link device by doing so.

1 Like

looking to port this to the P9 properly, seems that the PLC board's phy may be missing in the device tree for the M4R which is the firmware tplink have made available for P9 :frowning:

Not sure I've understood you correctly. With "phy" do you mean the Powerline chip on the secondary board of the P9? Because that secondary board doesn't exist for the M4R.

Yes, looking at the F/W for the M4R there is only one entry for the switch, that is probably fine, but there is nothing that confirms the connection to the PLC, and I suspect there are missing reg writes in the switch kernel code to enable the PLC. Open PLC tools do not detect the device, which suggests I'm missing something in the dts, or its not been enabled by the vanilla kernel. Trouble is the GPL code TP-link have published is for the M4R, even though it has the P9 file name.

The powerline chip is connected to the switch chip. There is nothing you will be able to do via the dts since that's for the SoC.
Add all the other ports to the config in 02_network and look at what ports are connected when you run that on your device.

The powerline chip should simply act as a network hub. At least that's my strong feeling about how it works since it's not connected to the SoC but the switch chip.

And forget the GPL source code. The trouble isn't that it's for the M4R but that you likely don't know how to read it to realize how they compiled it for the P9. There is likely a simple switch in their make environment to toggle between M4R and P9.

since the device is not responding or apearing on the switch, i am wondering if there needs to be something like this added https://fredericb.info/2016/02/powerline-plc-support-in-openwrt-for-d.html where there is a port enable being written to the switch on the SOC that allows comm's to the plc board, that can either be an intialiser value in the DTS, or it can be added to the code for the internal switch.

I am in a position to build the firmware with changes, and am familiar enough with linux kernel hacking, just not the networking stack and code in this router.