kamilsss655 / uv-k5-firmware-custom

Open re-implementation of the Quansheng UV-K5 firmware

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[BUG] Messenger security: Leaked encryption key

Lar-Sen opened this issue · comments

Describe the bug
Messenger encryption key is cleartext readable everytime.

To Reproduce

  1. Set encrytion key
  2. Dump EEPROM using any tool requesting UART 051B command, e.g. https://github.com/Lar-Sen/Quansheng_UV-K5_Kitchen/blob/main/v2.01.31_mods/utils/eeprom_tool.py
  3. Read encryption key at 0x0F30
  4. Dun goofed.

Expected behavior
Genuine firmware uses EEPROM 0x0F30 offset to store hashed config password which is used as an AES key. If config password was not given since last boot ('login'), the UART command 0x51B just fails, which is expected behaviour.
In our case, as 'config password' routines were circomvented, EEPROM offset 0x0F30 should NEVER get dumped.

Fix: UART routine must send 0xFF in place of key data if block 0x0F30-0x0F3F gets requested (or just restore original 'login' process before allowing dump).

Details:

  • Firmware version: RC20.5
  • other: UV-K5(8) HW rev. 1.6

Additional context
In case of a group scenario, users must share the same encryption key.
Original firmware didn't allow 0x0F30 eeprom block to be restored. In our case, I think it's better to allow it, provided that block couldn't get dumped in any way.

...anyway, this fork is still the best in my opinion :)

commented

Well you are wrong.

Yes, the EEPROM password is stored in plaintext, which is clearly mentioned in the Wiki:

Of course if the EEPROM password is read, it can be copied to other devices and these devices will derive it to the same encryption key, which is actually desired as it allows setting up multiple encrypted radios in bulk via CHIRP.

The solution you propose doesn't provide any additional security, considering the EEPROM itself is not encrypted, users could flash other firmware that would still allow for EEPROM dump.

What you propose (locking EEPROM read, without FW re-flashing) can already be achieved by setting the Passwd option in menu. This way serial connection is prevented until correct password is entered on boot.

commented

It is a good exercise in terms of security though. :)

Based on your issue I've enabled Private vulnerability reporting for this repository.

Let me know once you read it, so we can delete this issue.

Oh ok :)

I've read the Wiki note about that, but supposed "EEPROM read" meant "using a probe clip", not by software. Which is not secure, but it still requires device opening, a little knowledge and tools.

Being able to easily dump that block using a genuine cable is a worse practice in my opinion. It shouldn't be software dumpable. But either case, I agree it is still unsecure.

In genuine AES driver there was a sort of key hashing algorithm based on a unique UID found in NVR section of flash. I dunno how much space this should take, but it could inspire you if you decide to get it more secured

edit: I don't think this case should be kept private :) You decide.
edit2: Good to know about the PIN password locking UART access. I wasn't aware of that.

commented

edit: I don't think this case should be kept private :) You decide.

I guess you are right. Let's keep it public, to prevent duplicates.

commented

Oh and I don't like that approach with AES key hashing.

The only proper hardening solution in my opinion would be to encrypt EEPROM with Passwd derived key (plus some salt and maybe device UID). The EEPROM would have to be decrypted on each boot based on user entered key. After 3 wrong retries the EEPROM would get reset.

This would take too much space of the binary image though, so I will not be implementing that.

Full EEPROM encryption seems a bit overkill, as its data being non-critical (PIN and messenger key apart).
If I had a better knowledge of C, I would opt for PIN and key hashing using UUID before storing them, and make related blocks report 0xFF if dumped (so chirp/PsCps.exe/whatever don't even know about ciphering key)

Anyway UUID entropy at quansheng's is pretty bad. I don't know if it has sufficient randomness.

Another simpler idea: As soon as a PIN is set, user shouldn't be able to dump anything via UART. It's an answer to a 'stolen/lost device scenario' : Even powered on (and PIN entered), key wouldn't be compromised.