The Making of Puffy

At DEFCON 24, the so-called “Bender badges” from AND!XOR were selling like hotcakes. To get mine, I had to huddle with a group of people in the Bally's elevator lobby, refreshing their Twitter feed. When they finally posted what floor they were on, a stampede ensued.

I was familiar with village and party badges, but didn't know that standalone badges on their own could be popular. Inspired by this success, I decided to make some badges for DC25, and with some help from my SO, I've done just that.


It started with this drawing from my aforementioned SO:

With my server closet full of OpenBSD machines, she was familiar with the puffer fish mascot, and doodled this little guy some time ago. When we decided we wanted to make a badge, he was the obvious choice for artwork.


Of course, nobody would be interested in the badge if it didn't do anything cool. So, I laid out some goals for what the badge should do:

  • Some kind of wireless connectivity (preferably WiFi)
  • Extensibility/hackability
  • Runs some kind of UNIX-like OS (ie, not an embedded OS, preferably OpenBSD)
  • A serial console
  • Blinkenlights (the most important one)

I began my search by looking at the OpenBSD supported platforms page. Unfortunately, I found that it didn't seem to support a device small enough to fit on a badge. So, I lessened my search and allowed myself to settle for running Linux.

After paging through the datasheets of a few SoCs, I realized I had to go simpler. Although I have many years of programming experience, my EE experience is much lesser, and strictly hobbyist. All the Linux-capable SoCs I found were either BGA or had an incredible amount of ridiculously small pins, which would be impossible to solder by hand, as I intended to do. I reoriented my search to find the smallest single-board computer out there.

It didn't take long to find the VoCore2. Barely larger than a US quarter, it seemed the perfect device to slap onto the badge. I could also satisfy the extensibility requirement by hooking up a microSD card slot and USB port easily. I inquired about buying in bulk:


I'm interested in a bulk order of aroung 24-50 Vocore2s with the microSD 
card slot. Your site said to send an email here to inquire about the 
rate. Can you provide more information to me?


and got a quick response:

  We have 20% discount and free DHL shipping for 25~50pcs.


Nice! A 20% discount cuts the price of each board down to $17.20 or so, which fit within my budget. I quickly exchanged payment and shipping details and sent $680 of Bitcoin to some guy in China.

Thankfully, the 40 Vocores did arrive on time. I wired one up to a power supply and it gave me a “VoCore2” WiFi hotspot in about 45 seconds. Nice!

Making the PCB

With VoCores in hand, I needed to get my hands dirty with the PCB. I knew how to design circuits and draw schematics, but I had never used a PCB tool before. Some quick researched suggested KiCAD would be my best free option.

First up, the schematic. Unsurprisingly, KiCAD does not have a VoCore2 footprint builtin, but making one was not difficult, thanks to the engineering drawings provided on the VoCore's website.

Simple in concept, but those pins were pretty tedious

Simple in concept, but those pins were pretty tedious

With that done, I drew up a simple schematic and passed it to Pcbnew, the KiCAD PCB creation tool. Turns out, creating a PCB isn't so hard. I imported the art into a KiCAD layer, carefully traced it out into the Edge Cut layer, and moved the footprints around until they all fit and looked good aesthetically. After a few iterations, I had my layout. I just needed to route it.

The final schematic

The final schematic

A rendered view of the first PCB revision (with an earlier schematic). Miri took one look at that RJ45 port and asked what I was smoking.

A rendered view of the first PCB revision (with an earlier schematic). Miri took one look at that RJ45 port and asked what I was smoking.

I wish I had a valiant tale here about how I learned to route a PCB in KiCAD. But I just downloaded FreeRouting, which was able to route all the connections but one, which I routed by hand. A couple ground pours later, and we had our PCB.

The final PCB

The final PCB

The initial renders were white-on-purple, as I figured I would use OSH Park to print these for me. However, a run of 3 of these would be upwards of $100 through them, which was way outside my budget. Shopping around, I found that ITEAD Studio, a Chinese company, could make 10 for $60. Much better.

The first run of the PCB, populated and unpopulated

The first run of the PCB, populated and unpopulated

There were a couple issues with this revision. Firstly, the serial header was wired to TXD/RDX0, and the VoCore2 uses TXD/RXD2 as its default serial console. Oops. The second issue was that the 200 ohm resistors for the LEDs were not necessary, and made the LEDs too dim.

With those issues fixed, I put in a order through ITEAD for 40 pieces of the new revision, gambling that they wouldn't need any other changes. Thankfully, the 2nd run came in and worked perfectly.

The Software

How hard could it be to blink some LEDs? Well, not that hard, but it wasn't as simple as it should have been. /sys/class/gpio can be used to manipulate the GPIO on this chip, but one of the LEDs (GPIO38) was not cooperating. I emailed the VoCore support line, who said to try writing directly to the register. One datasheet download later, I was deeper in tables full of SoC intricacies than I would ever have hoped. But it was not for naught: I noticed that, despite the VoCore page suggesting that GPIO38 was a dedicated GPIO pin, the datasheet said it shared a pin with the watchdog reset timer. Following the datasheet, writing a 1 to bit 14 of the GPIO control region at 0x10000060 allowed the LED to blink with the usual /sys/class/gpio API.

There was one more issue: how to get these guys to blink on startup. I wrote a quick shell script to blink the lights in the pattern I wanted, but I would have to launch it with an init script. The script did not fork itself, and nohup was not present on the device, so my first solution was to port OpenBSD's nohup(1) and compile it with the toolchain provided by the VoCore folks. Surprisingly, this worked for launching it, but I couldn't get it to stop reliably. Upon consulting the OpenWRT documentation (which is really patchy, but perhaps I'm spoiled by OpenBSD's stellar man pages), I discovered the project created an improved init daemon called “procd” that could handle non-forking init scripts. Sweet! I converted my init script to a procd file and the lights quit blinking when /etc/init.d/blink stop was invoked.

The final problem was battery draw. I put some fresh batteries in with this config to see how long it would last. Unfortunately, it lasted only 5 hours. Checking the VoCore datasheet, it seems having the WiFi radio on draws a substantial amount of current, which I suppose is to be expected. I altered the wireless config to turn the radio off, but the presence of the serial console allows hackers to turn it back on if they so desire.

Wrapping up

Most of the boards are now built and flashed, and I'll be finishing the last of them in the next few days. There should be 40 available, but 2 or 3 seem to be defective. I haven't decided on the price, but it will be in the ballpark of $30-$60 depending on how much the BOM totals (which I haven't calculated yet). This is more about getting my name out there and getting some experience building PCBs than making money.

Ship it!

Ship it!

The KiCAD project and scripts are all available here. See you at DEF CON!