Door - Leaving keys behind

Having a badge scanner on every door is one of the more interesting parts of living on a college campus. Unfortunately, the door to my dorm room did not come with a badge reader when I moved in. Here is how I fixed the problem for twelve dollars.

Parts

RBE Department cleanout

WPI CollabLab

  • 12v 5a DC power supply
  • HID R40 RFID badge reader
  • 57kΩ & 100kΩ resistors
  • 22 gauge wire
  • wire nuts
  • hose clamps

roommate

roommate’s sister

  • 2200mAh usb power bank

personal collection

  • usb a cable

micro center (asked for money)

Hardware design

The system has two components, a R40 badge reader on the outside of the door to identify users, and a winch on the inside to unlatch it.

For ease of installation, R40s attach to a mounting plate such that when installed only one screw is visible. Fortunately, the gap between the R40 and its mounting plate are sufficient to fit a pico w and a pair of voltage dividers to convert the 5v data lines from the R40 to 3.3v. Both the R40 and pico can run off of five volts, so they can share a USB power supply.

Sketch of the circuitry, the resistors are 100 and 57 kΩ

On the inside of the door is a winch attached to a network addressable control system.

winch

Software design

R40 badge readers implement the wiegand interface for transmitting badge numbers.

back of an R40

Two pins are involved, data one and data zero. Both are high (5v) by default and are pulled low for a short amount of time to indicate their respective bit. Ideally you detect the end of a transmission based on the number of bits sent (same for every card of a given type), but for maximum compatibility I use a timeout.

Once the outside of the door has a badge number, it sends a TCP packet to the inside of the door, where it is then checked.

This method of verifying badges is very vulnerable to a replay attack. Instead of worrying about that, I’m relying on the security of having both devices on a private WPA2 network.

Because the system uses asynchronous rust, the winch controller can spawn a task to open the door without blocking other operations.

async fn open_door(mut pwm_c: &mut pwm::Config, mut pwm: &mut Pwm<'_>) {
    run_motor(&mut pwm_c, &mut pwm, 0x13DF); // up
    Timer::after_millis(3000).await;
    run_motor(&mut pwm_c, &mut pwm, 0x123C); // down
    Timer::after_millis(750).await;
    run_motor(&mut pwm_c, &mut pwm, 4687); // stop
}

Fate

Unfortunately, this iteration of the system was not received well by my school. A few days after installation, I was given a deadline to remove the system for “tampering with existing room locking devices”. I did not have the opportunity to do so because it was stolen the following Saturday between 1 and 2 AM.

Read about the second iteration