DIY USB password generator

Having done half a dozen V-USB tutorials I decided it’s time to whip up something cool. As USB keyboards were an area untouched, I decided to make a small USB HID keyboard device that types a password stored in EEPROM every time it’s attached. A new password can be generated just by tabbing CAPS LOCK a few times (4 times to start password regeneration and one tab for each password character generated, 10 is the default password length). Below you can see the device in action:

The place I work at requires me to change my password every few months so this would be one way to skip remembering a new password altogether (as long as I remember to write it down before regenerating a new one so password can be changed :).

What is inside?

The device is powered with a simplified version of the hardware I used in my ATtiny85 USB tutorial – I stripped away the LCD, reset pullup and both capacitors. If you’re better in cramming components inside enclosures I suggest adding at least a 0.1 uF capacitor between VCC and GND, but it seems to work fine even without it:


The enclosure was graciously donated by an old 512 MB flash drive. I couldn’t make myself to break the USB connector from the circuit board inside, so I stripped appart a short USB cable instead (shown on left):

After some thinking and iterative soldering, I managed to cram everything on a tripad veroboard with 2×8 pads with the following initial setup:

I soldered the connector first, then the zener diodes, then resistors and jumpers, and finally VCC, GND and the ATtiny itself. I used the following tricks to make all ends meet:

  • D+ zener diode goes to the pad under ATtiny that is connected to GND pin
  • After the D- zener diode, only 1 pad is left for 2k2 pullup and 68 ohm resistor, so I used a jumper wire to the next pad
  • 2k2 pullup goes to a pad connected to ATtiny VCC
  • VCC goes to the pad under the ATtiny using a black jumper wire
  • I soldered the D+ 68 ohm resistor to a wrong tripad, so I used another jumper wire just barely visible behind the top left black jumper wire for GND

I was pretty satisfied the result and the fact that it actually worked! The board did not initially fit into the very snug space in the plastic enclosure, so I had to use a Dremel to trim its insides a bit, but after that, everything snapped right back (click for larger versions):




Update: For those who are building this project – I recommend you first build it on a breadboard, and only when you have it working, solder it to a veroboard. Here are two additional, extra-large pictures of the configuration I used to help you in the component layout:


Software

The device presents itself to the computer as a USB HID keyboard. To enable communication to the device, it is a boot-compliant keyboard that can receive LED status changes from the computer. HID descriptor is from Frank Zhao’s USB business card example and I also looked at Frank’s code to understand how LED state is sent to the device (in short, PC sends a control message with 1 byte of data, the LED state bit mask).

The code is mostly based on my USB HID mouse example except for the usbsconfig.h and HID descriptor changes required to implement a boot keyboard. I’ve documented the code but here are some highlights if you want to understand it better:

  • PASS_LENGTH defined in the beginning controls the length of generated passwords
  • SEND_ENTER can be defined to 1 if you want the device also to send ENTER after typing the keyboard
  • measuring_message and finish_message contain the messages that are displayed when generating / saving a new password
  • buildReport() is called by the program main loop to send keypresses to PC one by one – it translates characters in messageBuffer to USB key codes on the fly
  • usbFunctionWrite() is implemented to receive the 1-byte LED state from PC – it calls caps_toggle() function every time the LED state changes
  • generate_character() is used to return random keypresses – it is currently written to return alphanumerics, hyphen and underscore (64 symbols make it simple to select one so each has equal chance of being selected without additional logic)
  • caps_toggle() does the caps-lock counting and password generation/saving

I’ve packed the source files with the schematic, critical pictures and a Makefile. In addition to “make flash” you of course need to update the fuse bits to use the PLL clock source – see details from my previous tutorial for that. I also very strongly recommend testing the device using a breadboard before soldering it, because otherwise reflashing will be a major pain.

And of course, if you build it, try it at your own risk – and remember that once you reprogram the password, nothing will be able to restore it. I recommend storing passwords generated with the device to a safe place just to be sure.

Update: Getting it from SparkFun

I found out yesterday that SparkFun is carrying an almost identical piece of hardware, the AVR Stick. So if you order one and reprogram it with this firmware (pin configuration in usbconfig.h needs to be updated in that case), you can avoid some soldering (although not all, you’ll likely need to solder in the programming header).

I asked SparkFun if they’d be interested to make a “2.0” model of their AVR Stick with actual USB connector and enclosure to go with the package, and my password generation firmware preloaded. If you think that’s a good idea, now would be a great time to send them feedback. I’d also be interested in covering additional hacks and tutorials with such a device. :)

Update 2: Indiegogo project

Alvin Chang is currently (December 1st 2012) running a Indiegogo project to build a device very similar (and inspired by) my DIY version. In case you’re interested in getting a ready-made version, be sure to check Mr. Chang’s project out: Aladdin: The Key to Your Computer.

Published by

Joonas Pihlajamaa

Coding since 1990 in Basic, C/C++, Perl, Java, PHP, Ruby and Python, to name a few. Also interested in math, movies, anime, and the occasional slashdot now and then. Oh, and I also have a real life, but lets not talk about it!

247 thoughts on “DIY USB password generator”

  1. Excellent work there.
    I’m really interested in making one of these for myself with your bits and pieces, many thanks!
    Just one thought, you could also include a special operation on a keypress to make it change your password (for Windows 7) by getting it to do the Ctrl-Alt-Del shortcut, down arrow, down arrow, down arrow, then enter. It can then put in the known old password, and update the new password for you automatically!
    This method has the obvious advantage of having NEVER been displayed on the screen in Notepad, etc.
    Thanks!

  2. Great idea for the Windows 7 -specific key combo, I’ll see if I time to do that at some point!

    Meanwhile, it’s pretty easy to add on your own, especially if ctrl-alt-del can be sent in a single HID report – you could just invent special characters for that and the arrow keys (like ^ and _) and concatenate everything into the messageBuffer while regenerating password (first the old password, then the key sequences, and finally the new password two times) – of course messageBuffer needs to be at least 64 bytes then. :)

  3. Hi jokkebk (Sorry, I don’t know your name!)
    I would have a go myself, but I’ve been over your code, and some USB coding in the past, I’m still somewhat mystified as to why USB has to be so darned difficult to use, even with libraries like v-usb!
    I only write simple code for my PIC chips (PIC16F88 so far), so I’m not grounded in AVR at all, I’m reading more about it now though.
    But I’m perfectly content to shell out £2 for a USB serial to TTL chip off ebay and interface to my PIC chips directly on my PC via a USB virtual COM port. Good olde RS232 still serves me well.
    Of course making HID keyboards requires USB, so I’m prepared to put the effort in, but for now, I’ve got an AWFUL lot of reading to do. For starters I’ll be compiling your code or just trying out the provided HEX file, thanks! Its important to know as much as possible when diving into all this, even if your code does it all for me…
    You’re definitely a credit to the hardware hacking community! Thanks!

  4. Hi Stu,

    Yeah I have to admit USB is a hard nut to crack, and the only way I was able to do it was to start from ground up, first building the simplest possible circuit with V-USB, and then adding layer after layer: first a easy circuit, then lighting a LED, then reading and writing data, then simplyfying the circuit and getting rid of the oscillator, then HID devices, and finally the HID boot keyboard. Even understanding the keyboard reports takes some thinking and because one has to emulate key presses instead of just sending characters, another layer of complexity is added.

    I recommend you to check my V-USB tutorial from the beginning, by starting from something less complex the amount of learning in each new iteration stays small enough to absorb. You are absolutely right that USB to serial TTL is a good option well worth the cost, I myself tackled USB more because it seemed challenging than absolutely useful.

    Joonas a.k.a. JokkeBK (my home page is well hidden on the right hand navigation pane ;)

  5. Hi Adam & Trev,

    My soldering skills probably wouldn’t cut it for commercial production, and I’d also price myself out of business in any case. :) Those who want a ready solution might want to check out YubiKey. If there’s enough interest, a provider like SparkFun might be able to do a DIY/preassembled kit based on this project, I might just ask them about it.

    Joonas

  6. thierry69,

    The source package contains the .hex file you can use to program the chip. If I recall correctly it is a version that does not send ENTER, so you need to recompile using WinAVR or AVR Studio if you want to enable that functionality.

  7. Great job! Another question here, does the USB need any driver to work in Win7? Or the driver is already included inside the ATtiny chip? Likewise the USB can use it at any computer, plug-and-play?

  8. kenny, from computer’s perspective the device is a USB keyboard, so no driver at all is needed for PCs.

    However, OS X does things differently and it does not work for Macs (it seems Macs don’t send caps lock status accross keyboards, so communicating with stick using status LEDs do not work – also, OS X has “intelligent” keyboard recognition that does not work very well with non-interactive devices). I haven’t tried Linux yet.

    1. Hi jokkebk

      Thx for the passgen.
      Mine works like a charm with win7.

      Some remarks
      – win7 – mine did load a driver at first startup from microsoft
      – never did it again :D and is working since then

      – linux – does not work.

      – kernel 2.6.38.2 message is :

      [ 3144.219114] usb 3-3: default language 0x0409
      [ 3144.228145] usb 3-3: udev 9, busnum 3, minor = 264
      [ 3144.228154] usb 3-3: New USB device found, idVendor=4242, idProduct=e131
      [ 3144.228160] usb 3-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
      [ 3144.228166] usb 3-3: Product: Passgen
      [ 3144.228171] usb 3-3: Manufacturer: codeandlife.com
      [ 3144.228417] usb 3-3: usb_probe_device
      [ 3144.228429] usb 3-3: configuration #1 chosen from 1 choice
      [ 3144.231139] usb 3-3: adding 3-3:1.0 (config #1, interface 0)
      [ 3144.231296] usbserial_generic 3-3:1.0: usb_probe_interface
      [ 3144.231307] usbserial_generic 3-3:1.0: usb_probe_interface – got id
      [ 3144.231369] usbhid 3-3:1.0: usb_probe_interface
      [ 3144.231377] usbhid 3-3:1.0: usb_probe_interface – got id
      [ 3144.241875] input: codeandlife.com Passgen as /devices/pci0000:00/0000:00:04.0/usb3/3-3/3-3:1.0/input/input11
      [ 3144.242434] generic-usb 0003:4242:E131.000A: input,hidraw3: USB HID v1.01 Keyboard [codeandlife.com Passgen] on usb-0000:00:04.0-3/input0
      [ 3144.242513] drivers/usb/core/inode.c: creating file ‘009’
      [ 3144.242598] hub 3-0:1.0: state 7 ports 6 chg 0000 evt 0008

      -> so it is recognized ok.

      what it does on linux :

      it spits out the last 7 bytes (characters) of the password at first plugin and the last 8 chars of the password at every plugin afterwards. The first 3 (2) characters are always missing.
      I compiled your code on linux and flashed the chip with linux avrdude and an arduiono isp programmer. Works great.

      what it does not on linux : it does not recognize tabslock / led status change
      -> it does not generate new passwords

      At the current state of code it is not usable with linux.

      Any hint is welcome.

      THX again for this great idea and support with schematics, parts, code … blog …

      Jan

      1. USB HID devices seem to take a while (two seconds or so) to initialize themselves, so any characters sent before that are lost. With first attempts, I had a delay timer to wait a few seconds before sending the characters.

        But after I added the support for receiving LED state changes, I assumed that the device is initialized when the first LED state is received – obviously this is not the case in Linux. You’d need to add a initial delay – for example increment some counters and only start sending after counter reaches a given value.

        1. OK, there seems to be a timing problem with usb on linux. So far i was not able to set a reasonable waiting time in the main loop. I tried up to 3 seconds waiting time before sending the password.
          And i found another obstacle on my way. Keycodes are different for win7 and linux. What a surprise LOL Special characters are interpreted in a different way:
          win7 linux
          ” 2
          = 0
          $ 4
          ( 8
          …and so on ..

          If you set your password on win7 to use it on linux you r screwed if you rely on your notes in case of trouble. You have to translate your password to your linux keycodes (just look at your keyboard …). Or you you have to stick to your operating system …

          And there are more problems on linux as no keypress or LED-change seems to be recognized by your current code on linux.Probably linux doesnt send it in a way your soft can recognize it? There seems to be no way to generate a new password. Probably we are stuck like in OSX. I wouldnt mind to set a new password in win7 if i can use it on any OS afterwards.

          Seems to me i have to go through your usb tutorial
          … and understand it before i can contribute anything useful
          this might take a while …
          Keep in mind : N E V E R change a running system!
          Your system works perfectly for the OS you created it for!

          THX for your advice and help.
          Happy Easter :D

          Jan

  9. Nice project. Ive made something similar with my Teensy 2.0. However, from what I understand, if I stole your usb device, plugged it into my computer and opened notepad, I would get the password out in clear text, correct?

    So while the device is a cool way to not having to remember a given password, the security of it all completely relies on you having control over the device at any given time.

    If you have somehow taken measures to mitigate this that I somehow missed, please enlighten me :)

    1. Take a simple step… password combinations on windows login type “win” or something simple then plugin key. Therefore your password for login would be “win” and your keys password…

      For a or a login to a website such as Facebook… type “fb” then insert your key

  10. Untouchab1e: Yes, it’s much like a key in a keychain – if it’s stolen, there’s nothing to stop the user from taking advantage of it, as long as he/she knows where the key fits.

    Unfortunately there’s very limited space on USB stick to add any kind of keypad for pin code – the best option probably would be to implement a “secret knock” using the caps lock key – e.g. three short taps followed by three long ones would trigger the device to to output its password. However, you’d either need to hard-code it or whip up a very elaborate setup on how to program the device.

    Implementing a special software to program the device using caps lock is one option but you’d quickly lose any “simplicity benefits” against an encrypted USB memory stick.

  11. Pingback: My Tech Blog
  12. Tell please you can make and send by mail this device? And how many it will cost with delivery?

Leave a Reply

Your email address will not be published. Required fields are marked *


4 + = seven

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>