Table of Contents

B.A.U.B.A.U.

Introduction

The problem with traditional password managers is that they are often cloud-based, which means you need to trust a third party with your sensitive information. The alternative is to use a local first password manager, and although there are some good options available, they can be difficult to properly set up and may not be as convenient to use, especially if you want to access your passwords on multiple devices.

One of the solutions to this problem is writing your passwords on a piece of paper and keeping it in a safe place, but we all know how that can end up.

But what if you could have a digital piece of paper? An encrypted piece of paper that only you can read? A device that lets you access your passwords with just a fingerprint, without the need for a master password or cloud storage? A device that can be easily carried around and used on multiple devices?

That's the idea behind B.A.U.B.A.U. (Biometric Authentication Unit & Bluetooth Accesss Utility), a local first password manager that uses biometric authentication to keep your passwords safe and, at the same time, easily accessible.

Description

Block Diagram

How do the components interact?

The main component of the system is the microcontroller. The Wemos D1 R32 (ESP32-based board) is responsible for orchestrating the entire system, handling user input, managing the display, and communicating with the fingerprint sensor and the microSD card module.

Here is what interfaces with the microcontroller:

Pin Selection

Board Pin Function Component Direction Description
GPIO16/U2_RXUART RX AS608 Optical Fingerprint SensorInput Receives data from the fingerprint sensor.
GPIO17/U2_TXUART TX AS608 Optical Fingerprint SensorOutput Sends data to the fingerprint sensor.
GPIO21/SDA I2C Data SSD1306 OLED Display BidirectionalUsed for data transfer between the microcontroller and the OLED display.
GPIO22/SCL I2C Clock SSD1306 OLED Display Output Provides the clock signal for the I2C communication with the OLED display.
GPIO25 Rotary Encoder Signal A Rotary Encoder with Push Button Input Receives the signal A from the rotary encoder.
GPIO26 Rotary Encoder Signal B Rotary Encoder with Push Button Input Receives the signal B from the rotary encoder.
GPIO14 Rotary Encoder Push ButtonRotary Encoder with Push Button Input Receives the signal from the push button of the rotary encoder.
GPIO5 SPI CS microSD Card Module Output Used to select the microSD card module for SPI communication.
GPIO18 SPI SCK microSD Card Module Output Provides the clock signal for the SPI communication with the microSD card module.
GPIO19 SPI MISO microSD Card Module Input Used for receiving data from the microSD card module to the microcontroller.
GPIO23 SPI MOSI microSD Card Module Output Used for sending data from the microcontroller to the microSD card module.

Hardware Design

Bill of Materials

Componenent Description Procurement QuantityDatasheet
Wemos D1 R32 A microcontroller board based on the ESP32 chip, used as the main processing unit for the password manager.Sigmanortec 1 Datasheet
AS608 Optical Fingerprint SensorA biometric sensor used for fingerprint recognition to authenticate users. Optimus Digital1 Datasheet
OLED Display A small display used to show information such as the stored passwords and user interface. Sigmanortec 1 Datasheet
Rotary Encoder with Push Button A rotary encoder used for navigation and selection in the user interface. Sigmanortec 1 -
microSD Card Module A module used for storing the encrypted passwords on a microSD card. Sigmanortec 1 -
microSDHC Card A storage device used for storing the encrypted passwords. Any 1 -
22 AWG Solid Wires Used for connecting the components together. - Too many-
Perfboard A one-sided FR4 perfboard used for connecting the components. - 1 -

Schematic

Software Design

This project is developed using the PlatformIO environment, which provides a convenient and efficient way to manage the development process, including code editing, building, and uploading to the microcontroller.

In terms of libraries, we have no libraries.

Just kidding, at this moment, the project uses the following libraries:

Code Structure

The firmware is split into small, single-responsibility modules so it stays easy to navigate. Every module is a .h/.cpp pair under src/, and all of them pull their pins and tunables from a single config.h.

Module Responsibility
main The state machine (LOCKED > MENU > ENTRY) and the main loop that glues everything together.
config Every pin assignment, timeout and feature flag, in one place.
logger Tiny LOG/LOGF macros that compile to nothing when DEBUG_ENABLED is off.
display Everything that gets drawn on the OLED.
encoder Reads the rotary encoder and its button, debounced, as a single encoderPoll() snapshot per loop.
fingerprintTalks to the AS608 sensor: authenticates a finger, and enrolls/deletes templates for the admin menu.
ble Advertises the BLE keyboard and types out a password on the host device.
store The password store. Keeps the entries in RAM and persists them, encrypted, to the microSD card.
admin The on-device management menu: enroll/delete a fingerprint, delete an entry, wipe the vault.

Every function and field is documented with Doxygen comments, so the headers double as the API reference.

Software Architecture

The whole device is a small state machine with one knob and one button, so it is worth describing exactly what each gesture does.

When idle, the device sits locked and asks for a finger. Scan an enrolled fingerprint and it unlocks into the menu, where turning the encoder browses the stored entries (the name in big letters, the account and a <current>/<total> position underneath).

From the menu you can:

The admin menu is where everything that would normally need a computer happens, all on-device:

If there is no input for a while (AUTOLOCK_TIMEOUT, 30s by default), the device locks itself again.

Where the passwords live

The passwords never sit in plaintext on the card, duh. The store module keeps the entries in RAM (I know, not ideal) while the device is unlocked, and writes them out to a single encrypted file, /vault.dat, on the microSD card.

The file format is intentionally boring:

[16 bytes IV][4 bytes plaintext length][AES-256-CBC ciphertext...]

The entries are first flattened into a plain name<TAB>email<TAB>password line per entry, then encrypted as one block with AES-256-CBC using a fresh random IV on every save. On boot, storeBegin() mounts the card and decrypts the file straight back into the in-RAM vault. If the card is blank (no /vault.dat yet), it seeds a default set of entries and saves them, so a fresh card just works.

The AES key lives in the firmware (see STORE_KEY in config.h) rather than on the card, so popping the microSD into a reader gives you nothing but ciphertext. The known limitation is that the key is a build-time constant; a production build would move it into the ESP32's secure storage instead of source.

Tutorial

The whole interface is one knob you can turn (move), tap (select / send) and hold (admin menu / peek a password). In short:

First run: with no fingerprints enrolled the lock screen shows “Tap to set up”; tap, then open the admin menu and enroll your finger.

Results

Ended up with a working prototype that demonstrates the core features:

The fingerprint authentication is reasonably reliable, with a quick response time for unlocking. Confidence of the fingerprint match is printed to the serial console for debugging purposes, and in practice it seems to work well with the enrolled fingers.

To my surprise, but also obviously, the BLE typing works on all tested host devices (PC, Android and Apple). (well, it's just a standard HID keyboard, so it should).

Conclusions

Well, this was quite a wild ride.

Started off using a breadboard and jumper wires, quickly got a working proof of concept with the OLED, the encoder and the fingerprint sensor, tested each component, and as soon as I had everything working, I coded a simple state machine to glue it all together.

With everything working on the breadboard, I moved on to soldering it all together on a perfboard.

Here comes the fun part, I did the soldering immediately after getting it working on the breadboard.

I was obliviously working with the solder wire that my dad had lying around (spoiler alert: it was lead free) and with a soldering iron that was not very good. All I knew is that using more solder and lots of flux would help, so I ended up with a perfboard that looked like a crime scene, with solder blobs everywhere, but as per the multimeter, there were no shorts.

With the board looking like that, I wanted to remove the excess flux so I tried cleaning it with isopropyl alcohol.

That was a mistake and when I powered it on, the MCU would reset in a loop, and lo and behold, there was the magic smoke coming out from under the OLED.

Residue flux + isopropyl between many pins of the OLED and the MCU was causing shorts, and the OLED was fried.

That was the biggest setback, and such a lesson learned.

One OLED later, I started looking up how to properly do this and found out about leaded solder, which is much easier to work with, how to properly use a soldering iron, and about solid AWG wires for perfboard projects, so I ordered all the necessary materials and redid the whole thing with much better results.

Gotta say, this was the most fun I've had within this project, and I learned a lot about soldering and hardware assembly in general.

Last problem faced was that at the end, the OLED and the fingerprint sensor were not powering on and after hours of debugging with the multimeter, I found out that the pin header I used for the 3V3 line was not making good contact so I had to resort to some proper Romanian engineering.

Software wise, the project went pretty smoothly, I had a clear vision of how I wanted the interface to work and how the user would interact with it, so I just had to implement it.

Source Code & Resources

All sources live in this repository, organized into directories:

Demo

Demo

Bibliography/Resources

Software

Hardware

Both