First bumps on the road

A project log for Picoth - 2FA Auth with Pi Pico

An easy to use yet secure 2FA gadget, using a Raspberry Pi Pico and RGB Keypad, MicroPython.

AngainorAngainor 02/08/2021 at 18:460 Comments

It's only once you get the hardware in hand you realize the obstacles on the road :D

This is also what makes this interesting. Technical challenges to solve? Let tackle them!

I wanted to use Micropython because I just love Python. RP2040 port of Micropython however, is very, very young. A rocky start they say :)

- No Native USB support yet on Micropython. Hopefully this will come soon, as circuitpython already has it

- No RTC module yet. Not critical since for a precise time source I planned to use a DS3231 chip.

Then I discovered more surprises along the way:

- Official Micropython has no support for the Pimoroni C libraries (keypad and display) , and support for user c modules is broken

- Pimoroni's fork does not have sha256

I ended up handling yet another fork, based upon official micropython with user c modules re-enabled, sha256 and pimoroni libs.

On the software side, HMAC and more important, SHA1 were also missing...

Although SHA1 is deprecated, it's still used and required for TOTP...
There, I chose to use pure python implementations of SHA1, HMAC from micropython-lib, and TOTP.

Good news, the Raspberry Pi Pico has no ram or speed issue at all computing correct TOTP, even with some code as frozen python code and not C lib. Great!

Then, real fun began with the hardware itself.

Pimoroni did a really great job designing and producing all these nifty backpacks and base for the Pico. Some details don't lie, they do it with passion!
However, one thing I'm absolutely sure they did not plan, was someone willing to use a keypad base AND a Pico display with the same Pico.
When I first saw the things, I thought you could plug the pico into the base, and the display on top of the pico.
How naive I was!
The pico display is supposed to be plugged on the back on the pico, too bad!

Well, this will not stop me: just plug it on one side with longer, folded headers, and add some wires for the other side?
Nope!  The RGB Keypad uses i2c0 port, and well as SPI0 port, with GPIO17 as CS.
The display uses SPI0, with the same CS, MOSI, SCLK as the base.

Certainly not a reason to despair.
Diving into the RP2040 docs, I checked the GPIO doc.
The RP2040 has 2 I2C and 2 SPI ports, plus the GPIO gives some flexibility.

I ended up with the following setup:
- No change to the Keypad base nor lib
- No change to the display Power, reset, BL_enable
- Move Display SPI pins to SPI1, using free gpios 21, 26 and 27. This required a small change to the ST7789 c library

I then needed another I2C for the DS3231 RTC. I used GPIO 10 and 11, unused by the keypad base.

With this setup, both the extensions can be used same time, with no conflict whatsoever.
One row of curved header physically holds the display at the right angle, and only 3 wires are needed for the TFT to work (buttons and RGB led will need more).

Current state, with really rough Python code, is able to display the correct 2FA TOTP code from a key, using the DS3231 RTC as clock source. Time remaining before the code is invalid is shown as a shrinking colored bar.

Next step will be to make sure the wiring is final (it should) and assemble the thing with shorter and definitive wires.
Then it'll be on the software end:
- handling decoding of the otp keys
- clock settings
- associate physical keys and colors to otp entries