Add support for D-Link COVR-X1860

Quick update: a new parameter DEVICE_MODEL was introduced to allow selection of keys to be used.

Now the tool should support both the old COVR-C1200, COVR-P2500 and some DIR-8xx (see below), as well as the newer COVR-X1860 and DIR-X3260 devices that use a different vendor key derivation method (dimgkey).

For the sake of completeness, before squashing this for sending a patch to the mailing list, I was looking into devices from the DIR- range again, especially DIR-2660, DIR-3060 etc. Some of these do not share the same RSA keys, thus only AES decryption is possible at the moment (which can still be useful for analysis purposes, or to revert back to OEM software via recovery flashing).

I will spend some more time on downloading further GPL tarballs, maybe also different versions, to see which devices are compatible or might require additional keys to be included.

@Lucky1 @kar200 You seem way more familiar with the range of DIR-8xx / DIR-xx60 devices, could you maybe help extending my list of device models that so far seem to be compatible with the "old" key?

So far I have:

  • DIR-853
  • DIR-878
  • DIR-882
  • DIR-867
  • DIR-1935

Same vendor key (i.e. decryption is possible), but no RSA keys known:

  • DIR-2660
  • DIR-1960 (valid public key found in DIR-3060 tarball :man_shrugging: )
  • DIR-3060
  • DIR-3040

Same vendor key and (known) individual RSA key:

  • DIR-1260

Failed to decrypt (i.e. need to figure out vendor key generation) :

  • DIR-2640

// edit: moved DIR-853 to fully supported

Hi s_2
I'll look and remind myself about this over the next few days
the only basic observation I made was that the NOR flash used the generic keys
& NAND models had the added model specific keys added

1 Like

Awesome, never seen it from that perspective - so it seems they used they same toolchain until they needed to hire someone to adapt it for NAND flash, and that person realized they should maybe throw in some new keys :innocent:

I will try to look at DIR-853 and DIR-2640 and figure out vendor key, the main issue is probably that I don't own any of these device (and they don't seem to be available easily in the European market), but dumping an unencrypted firmware from a real device would be a good way to start.

// edit: @kar200 I see you had added DIR-853-A3, do you maybe have a flashdump / unencrypted image?

it looked like the same code in both just the nand ones had the extra file and if present used it
the DIR-2640 looks close enough to load it's firmware into my DIR-1960
there are a few models of the DIR-853 a mix of nor and nand & custom ISP models
can easily decrypt any of the firmware it's just the the rsa checksum will be invalid
I think the NAND versions A3 & A4 use the DIR-1360's board

I'm not sure what the openwrt way of doing things
but for thr DIR-878-A1 & DIR-1960-A1 you will need 3 files
one for the recover console "unencryped for older boot loaders"
one for the routers web interface "encrypted"
and the normal sysupgrade
so witch is factory & what to call the other ?

That was already the discussion in https://github.com/openwrt/openwrt/pull/3109, I think we called it factory-recovery and factory-webflash initially, but later changed it to just factory and recovery. Probably the topic would arise again (especially since the devices are currently supported with an image called factory, and changing this to recovery with future versions of OpenWrt might confuse people, but that's hopefully a minor issue (those who had their devices flashed already will use sysupgrade anyways).

Regarding DIR-853, I looked through imgdecrypt from the GPL release in ghidra, and it looked just like the same vendor key... turns out I had the path for that image file wrong in my test script, so that one did not decrypt successfully... :see_no_evil: However DIR-2640 need some attention, will have a look later in the evening.

Maybe for a first iteration, we could just support the legacy keys + the new COVR-X1860, if there really are more keys that suddenly show up in GPL tarballs, they could be added later.
But at least I want to test COVR-C1200 before submitting this. Turns out the "gzip-based signature" (as I called it back then) is actually nothing but crc32, but for some reason they used the gzip utility on the router and then just parse the crc32 field out of the resulting .gz file :joy:

sounds good I can test most of them by loading the unencrypted firmware & trying to install openwrt from that
I have not seen the dir-1960 key but i'll look in the 3060 stuff & try it soon

1 Like

weird, DIR-2640 uses the same vendor key, so we can decrypt, digest before and digest post are matching, but digest_vendor does not match the vendor digest field from the SHRS header (which is why my decryption returned error, although decryption itself was successful),

Also there is a public key in the 2640 tarball, which only works for DIR-2640. So even if we have a private key one day, it would not be the same as for the others (which was my hope initially, that some day that key will leak and work for all of those remaining devices :innocent: )

DIR-3060 will not be flashable via OEM I guess, at least from trying to verify the image using the old RSA key pair (the private.pem files actually include the public exponent, so the public key can be derived from the private.pem, this is why I also dropped the public keys from the tool, since the OpenSSL API can use the private.pem for verification as well. So if a firmware does not verify against a known key, there is no use in testing. However, being able to verify it on the other hand does not yet guarantee the device would also accept the image, so this will need testing.

For curiosity, I will further look at DIR-2640 and see how the heck that vendor digest can be different here :joy:

I do think the keys would be different for most models and each have there own private/public key set
but it is up to the creator
we need the private key to generate the firmware
that will validate with the public key
so given we only have the public key
we can only check if it's valid for the device
and not create a file that will validate

I'm sure I used to be able to extract the file system
from the oem unencrypted firmware with 7zip
but I have forgotten how or 7zip has changed

This is something that confused me as well, since going through the GPL tarballs did not reveal so much in terms of private keys, the firmware images themselves are now the last thing to check.
It's curious there seems to be no rootfs that could be extracted with binwalk, it just finds the kernel lzma at A0. Even tools like sasquatch won't help as there is not even as hsqs magic for the squashfs.

I was wondering if access via serial console could be a way of searching through the file system, there seems to be a default password for many devices based on the user-set web password + @twsz2018, according to Adding OpenWrt support for DIR-3060 - #24 by kar200.
Also there were several security vulnerabilities foudn recently for these devices, that could allow enabling telnet access to the device:
https://www.tenable.com/security/research/tra-2022-09

I think I currently only have DIR-2660 and DIR-878 devices in my pile, I guess the 2660 (using NAND) could work for flashing a DIR-3060 image?

Just ignoring the public keys for now, only included those where we also have the private key.

Squashed everything, polished comments and usage output, rebased to firmware-utils master, pushed as separate branch. Cloned once again to /tmp folder just to make sure it all builds and works perfectly:

git clone https://github.com/s-2/firmware-utils.git
cd firmware-utils
git checkout dlink-sge-image_2k23
cmake .
make dlink-sge-image

no errors, no warnings, everything's looking fine.

Tried to edit tools/firmware-utils/Makefile to include the hash and remote repo, building openwrt, and guess what - it fails:

.../firmware-utils-2023-06-20-a6cd8ce0/src/dlink-sge-image.c:87:18: warning: implicit declaration of function 'EVP_MD_fetch'; did you mean 'EVP_MD_flags'?
.../firmware-utils-2023-06-20-a6cd8ce0/src/dlink-sge-image.c:100:9: warning: implicit declaration of function 'EVP_EncryptInit_ex2'; did you mean 'EVP_EncryptInit_ex'?
.../firmware-utils-2023-06-20-a6cd8ce0/src/dlink-sge-image.c:262:9: warning: implicit declaration of function 'EVP_DecryptInit_ex2'; did you mean 'EVP_DecryptInit_ex'?
.../firmware-utils-2023-06-20-a6cd8ce0/src/dlink-sge-image.c:455:18: warning: implicit declaration of function 'EVP_CIPHER_fetch'; did you mean 'EVP_CIPHER_flags'?

and a few more warnings regarding pointer types as a result (since the function declarations were not found at all), finally the linker failing to find the source of these functions will stop the build.

Great, so I've spent several days migrating this old thing to current OpenSSL, to get rid of all the deprecation warnings, now I shall backport it again to something in between, since what my host uses to build firmware-utils as a standalone package is apparently too new again?

I'm done working on this for today, maybe by the end of the week...

1 Like

sound like you have been having lots of fun
you have the same as me my 1960 may as well be the 2660
just sold as a ac1900 with ac3200 hardware
I'm trying to remember how this all works
& get my linux pc up to date

@s_2 openwrt support for the COVR-X1860 will be awesome - thank you for taking this on!

wait, so they waste unused RF chains just for marketing purposes? I see that the PCB of DIR-2660 allows for multiple populations though, e.g. there are 8 antenna connector footprints, but only 4 populated.
Maybe Mediatek just sell different versions of their wifi chipsets in the same package, so the footprint would remain pin-compatible regardless of the number of spatial streams / antennas supported, I haven't looked so closely at what's actually written on the chips though.

Migrating back to slightly older OpenSSL was less of an issue than expected, also fixed warnings about fread() output being unused (i.e. implemented proper error handling if input file is too short).

Updated branch dlink-sge-image_2k23, also including key for DIR-2150 as mentioned in a current PR for that device.

It is now part of my local build system, next step: rebase some old PR for COVR-C1200 to master for final testing, also COVR-X1860 of course. This should now allow us to build images that are accepted by the OEM webinterface, if all goes well, I will send a PR for this tool to the mailing list :slightly_smiling_face:

Finally, tests with COVR-C1200 and COVR-X1860 were successful, the latter was quite annoying though in terms of trying to login to the web interface... Using Chromium in Incognito mode eventually worked, even Firefox didn't do it for me anymore, kept getting the "invalid password" message.

Curiously, the whole webinterface is a static web application that uses HNAP to login and configure the router, it seems the implementation of the challenge/response login stuff might not be working correctly?
It seems kind of ironic to put so much effort in getting rid of the bootloader recovery for flashing, just to treat the user to a different set of browser-induced flashing troubles instead :joy:

Added a new branch, not yet squashed:

But first, we need the tool in firmware-utils, I will send a patch to the mailing list :slightly_smiling_face:
@Lucky1 can I add your Tested-By to the commit message for the patch?

yes the DIR-878 & the DIR-1960 are the same both ac3200 at lest the ones I have
but the 867 had some transistors removed
that's not to say that there are all like that tho
but as they all use the same PCB just with different loading had to same
both of mine do have 4 steams on 2.4 & 5G in it's factory config
I'm making the presumption that the 867 has only 3's in there not 4's
once I'm happy my Linux pc is set-up & working I'll test & note etc

I don't think it's an absolute requirement to test further if this is inconvenient to you at the moment, I just wanted to offer adding your name to the commit, since you've helped a lot in working on this series of devices. Just let me know whether I shall wait for your test, or send a patch to the list already? A few days won't make any difference here, so feel free to take you time, e.g. over the weekend.

I'm having another look at C1200 / P2500, time to replace the gzip-signature (which is actually just crc32 as it turned out) with a build recipe, and get rid of the Python script.

all good here now I'm more up to date now
I have tested the current version on the current master
on the DIR-867-878-882-A1's and all work fine from web install to openwrt :slight_smile:
can add away only tested in encode mode all works great :slight_smile:

1 Like

https://patchwork.ozlabs.org/project/openwrt/patch/20230623120600.16663-1-openwrt@sebastianschaper.net/

1 Like

For those located in Germany:
MediaMarkt / Saturn currently offer 19% off until sunday, making the total price for the pack of two devices € 33,61 with shipping included.

4 Likes