reversebias / mitosis

Firmware for nordic MCUs used in the Mitosis Keyboard
GNU General Public License v3.0
195 stars 125 forks source link

Transport encryption #12

Open andrew-ws opened 6 years ago

andrew-ws commented 6 years ago

What is the chance of having transport encryption implemented in this firmware? I looked at implementing it myself but from what I could tell it seems a bit difficult to do anything more complex than ECB the way that things are currently implemented. I'm not very experienced writing firmware, though, so maybe I'm wrong.

rossica commented 6 years ago

I have a fork with transport encryption implemented using the Gazelle encryption library, however, I'm stuck as I can't see any of my debug statements and it's not working. I'm rather new to embedded programming, so any pointers on how to debug it and I'd happily make a pull-request once I fix what's broken.

Detegr commented 6 years ago

I got encryption working based on @rossica's code. I haven't been able to actually test it as I'm still missing a couple of components from the receiver. With debugger+logic analyzer it seems to be working. You can find the code from my fork.

andrew-ws commented 6 years ago

I can give it a test later today, but just to be clear this is still just ECB at this point, correct? Definitely much more secure than before but I'd like to know if replay attacks are still viable (although an attacker would still need to be physically close to the receiver and keyboard so it's a pretty far-fetched risk).

Detegr commented 6 years ago

The library uses dynamic key exchange and session tokens to prevent replay attacks. However, the code does not update the dynamic key after paired. I think this is not a problem as long as the dynamic key is not compromised because of the session tokens making every packet different from others.

andrew-ws commented 6 years ago

That sounds great! I'm having a bit of trouble testing, though, would you mind adding a bit of extra detail about the compiling and pairing processes? Since there's no info on the compilation process I'm worried I'm making a mistake there. Also, it looks like you need to hold down the pair button on the receiver while holding a key combination on the boards to start the pairing, but I can't figure out what that key combination is.

Detegr commented 6 years ago

The compilation should have no differences now (I just updated my fork). Have you been able to compile this repo?

I'm using Chimera Ergo as the keyboard for this firmware, and the key combo is the two function keys in that keyboard. Unfortunately I'm not sure which keys it maps to for Mitosis. If you have a multimeter, you can check that with a pinout picture. The pins are defined in config/mitosis.h.

andrew-ws commented 6 years ago

I found the keys, it's the outside (left for left board, right for right board) two on the bottom row of the command cluster. From the code it seems like the pairing process is: bring the receiver and one side of the board close together, hold the pairing button, hold down the two pairing keys on that board, and from that point on it should just work. I seem to be able to flash without any problem, and the receiver at least is recognized, but that's about it. No way to tell if it's successfully paired or not, etc. Confirmed that everything I'm doing compilation-wise works for the reverse-bias version, so I don't think that's the issue. Seems like it's not possible to flash the LED in this code, but is there any other particularly good way of debugging? Started looking into connecting GDB to the OCD, but I don't want to put in the work figuring that out if there's an easier way.

Detegr commented 6 years ago

You're right, there's no way to know whether the pairing was successful or not. Unfortunately there's no way to control the led on the 51822 side. In my opinion using gdb with openocd is the best way to go.

I finished my receiver yesterday and I got it working with the transport encryption, so I'm not sure why yours did not work.

Detegr commented 6 years ago

After testing more I found out that the pairing is indeed quite unreliable. Sometimes it works, sometimes it does not. I'll need to debug this more.

Detegr commented 6 years ago

Unfortunately, according to this, there is no way to connect two dongles simultaneously when both are using the pairing library for encryption.

rossica commented 6 years ago

Aww, that's unfortunate. I've been working on designing a cryptosystem that doesn't depend on pairing. I'll have a PR for that in the next month or two.

On Tue, Jun 5, 2018, 10:11 AM Antti Keränen notifications@github.com wrote:

Unfortunately, according to this https://devzone.nordicsemi.com/f/nordic-q-a/18344/how-to-use-gzp-for-one-nrf24-dongle-to-pair-two-nrf52, there is no way to connect two dongles simultaneously when both are using the pairing library for encryption.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/reversebias/mitosis/issues/12#issuecomment-394788506, or mute the thread https://github.com/notifications/unsubscribe-auth/AIJcYmLpHws9Jfc096XEDL86M3ol52Dkks5t5rvAgaJpZM4SRvxM .

Detegr commented 5 years ago

Any updates? I am thinking about building an extra receiver and using one receiver per keyboard half to be able to use the pairing library.

rossica commented 5 years ago

I've been swamped with work and haven't had time yet to code up the new encryption. I'll have time in December to do it. I'll update then.

On Thu, Nov 15, 2018, 11:07 AM Antti Keränen <notifications@github.com wrote:

Any updates? I am thinking about building an extra receiver and using one receiver per keyboard half to be able to use the pairing library.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/reversebias/mitosis/issues/12#issuecomment-439154335, or mute the thread https://github.com/notifications/unsubscribe-auth/AIJcYmzs-CgLfddDYsylOj2FnCcKjU0_ks5uvbtUgaJpZM4SRvxM .

Detegr commented 5 years ago

I did some tests, and it seems that using two receiver dongles, one for each half, works and the GZP pairing library can be used to pair the devices and secure the communication.

Edit: Further testing shows that using two dongles is not actually going to work. Running two QMK's at the same time leads to all kind of synchronization issues.

sigboe commented 5 years ago

Yay great to see this, I just started a new job and wanted to start ordering parts this Christmas. But we got a (soft) ban on wireless keyboards, and I spoke to the security officer and he said I could go ahead as long as it has proper encryption.

Is this close to being merged? Could someone draw up a diagram how and why this is secure?

Detegr commented 5 years ago

I'm not sure how @rossica is planning to implement his system and therefore can't provide you much information.

The gazell pairing library I tried to use is quite nicely documented here, but as I mentioned it does not fit in this use case, at least not without modifying the receiver PCB, which is something I'm not planning to do.

rossica commented 5 years ago

My design is to closely match the security model of the Gazell Pairing library, but without requiring the receive radios active on the keyboard halves. The downside to this design is that a hard-coded 'chord' pattern is required on the keyboard halves to force a re-keying operation when the receiver has been power cycled.  Otherwise, the receiver won't be able to signal to the keyboard halves that it needs the latest key information.  The user must perform this 'chord' whenever the receiver has been power cycled, or plugged in for the first time, before the keyboard halves will function, and the 'chord' must not be used for any actual key press sequence.

The alternative, is to have the keyboard halves use their receive radios and listen for a signal from the receiver unit to tell them that it needs to be informed of the latest key material.  The downside is, as documented somewhere in the issue tracker for mitosis, that having the receive radios active reduces battery life.

My question to you, @Detegr, is how much decline you've noticed in battery life while using the pairing library? This will inform which approach, described above, I use when implementing this.

I'm open to other alternatives, if they exist, without compromising on the security design.

On 12/11/2018 8:36 PM, Antti Keränen wrote:

I'm not sure how @rossica https://github.com/rossica is planning to implement his system and therefore can't provide you much information.

The gazell pairing library I tried to use is quite nicely documented here https://www.nordicsemi.com/DocLib/Content/SDK_Doc/nRF5_SDK/v15-2-0/gzp_02_user_guide, but as I mentioned it does not fit in this use case, at least not without modifying the receiver PCB, which is something I'm not planning to do.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/reversebias/mitosis/issues/12#issuecomment-446459301, or mute the thread https://github.com/notifications/unsubscribe-auth/AIJcYj4CgjRWhej37BgP66VgaClCo9y2ks5u4IfXgaJpZM4SRvxM.

Detegr commented 5 years ago

Unfortunately I did not do any measurements as the keyboard was pretty much unusable with the double dongle setup.

rossica commented 5 years ago

Oh I misunderstood, I thought you said it was workable.

Well, since I don't like the idea of a programmable keyboard that doesn't let me use every possible key combination, I'll go ahead and enable the receive radios on the keyboard halves so the dongle can signal to the halves that it needs the latest key.

On 12/13/2018 11:27 AM, Antti Keränen wrote:

Unfortunately I did not do any measurements as the keyboard was pretty much unusable with the double dongle setup.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/reversebias/mitosis/issues/12#issuecomment-447090315, or mute the thread https://github.com/notifications/unsubscribe-auth/AIJcYhfgNhY4adMEkgABBbxbGA4m6_Ytks5u4qorgaJpZM4SRvxM.

barneycg commented 5 years ago

@rossica, have you got anywhere with this ?

Something that springs to mind though is it isn't like the message being passed says the "H" key has been pressed, all people will get when sniffing the wireless traffic between the receiver and the keyboards is a string of ones and zero's representing which keys are pressed but how that matrix is turned into a specific character is done in the Pro Micro in the receiver. Given this is transport encryption that important ?

Detegr commented 5 years ago

@barneycg You are correct about nature of the traffic, but unfortunately that is just obscurity. Obviously, that is better than plaintext, but it offers no real protection should someone want to capture and analyze your keystrokes.

rossica commented 5 years ago

@barneycg, @detegr is correct, the "symbols" that mitosis uses to represent your keypresses are vulnerable to frequency analysis, and an eavesdropper would eventually be able to figure out what keys you're pressing and what they mean. I have implemented some of the basic cryptographic primitives needed this weekend. Hopefully I'll have more time soon to do the rest.

rossica commented 5 years ago

I have a crypto implementation that is ready for beta testing! Pull this branch: https://github.com/rossica/mitosis/tree/feature-crypto and build as you would normally. I STRONGLY RECOMMEND changing the crypto seed value in mitosis-crypto.h if you want to use this for more than simple testing. But for testing, you can use the new crypto versions in the precompiled/ directory. If you find issues, please open them in my repro fork. I welcome pull requests into my feature-crypto branch that fix issues found.

Known Issues

No blocking issues that I saw in my limited testing. It looks about the same speed as before. Only issue I saw was that if both keyboard halves hold a printable character at the same time, the second one pressed "wins" and keeps getting printed and the first is ignored.

Detegr commented 4 years ago

Thank you for your hard work! @rossica

I did a PoC test with your code and it seems to work fine (as in, I am able to send and receive keys). I did discover one trivial bug, and made a PR out of that. I am going to merge the code to my fork, as I need to get the keys mapped correctly (I am using Chimera Ergo, which is incompatible with Mitosis keymap). I will report back if I run into any issues.