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:


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. Update: You may also want to read my USB HID keyboard post if you want to learn more. 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!

291 thoughts on “DIY USB password generator”

  1. I meant that the files could be wrong, maybe in the final firmware file main.hex. Remake it please.

  2. sir how to change the password means what is logic behind this.
    if i change the password as you told then which logic is used to change password.

    1. The device measures the amount of time between caps lock presses – human reflexes are quite random so you can get several bits of true randomness with each press. See generate_character() comments in for details.

  3. Hello,

    I made it! Thank you, it works well with Windows XP and windows 7, it did not work with one of windows 8 but i cant tried with another windows 8 machine. when it comes to Linux (ubuntu 14.10) first two digit of password gone missing. It types 8 digits. why this behavior? i checked code what may encounter this issue but couldn’t find problem.

    1. It might be that Linux has a longer delay between the “keyboard” being recognized and starting to accept keypresses, so the first two characters are ignored. A longer delay would correct it if that is the case.

      1. I tried at console and it just worked correctly. First two digits gets lost at UNITY desktop environment (X window maybe).

    2. I think the problem is with driver in windows 8 and 10

      resolve the third party inf problem then install the driver
      it will work

    1. Seems like usbconfig.h is not found. Which dev environment uses the .inc files? Arduino? I would make sure usbconfig.h is in the usbdrv directory, and if required by the dev environment, usbdrv is added to include path (and the .c and .S files to project)

  4. Please let me know if you’re looking for a article writer for your weblog.
    You have some really good posts and I believe I would be a good asset.
    If you ever want to take some of the load off, I’d absolutely love
    to write some material for your blog in exchange for a link back to
    mine. Please shoot me an e-mail if interested. Many thanks!

    1. Thanks! Also visited your blog, good work! By the way, never write short comments like this that have no context to the post you are commenting, I get 10 of these a week and all are just spam pointing to or something. Even with the sensible blog in your URL I was still only somewhat sure this might not be spam. :)

  5. I made this awesome thing for university project. But I have some problem. I test by plug it with many labtops but just a few laptop that the USB-driver can install successfully.
    How can I solve this problem ? I am stuck in this black hole for 2 weeks.

    Ps. I flash ATtiny85 by using HEX file you give in your project by setting fuse in PLL mode.

    Thank you very much !!

  6. Thank youuuuuuuu for your awesome article.
    I’ll try it but can you say which attiny85 you’ve used? because I’m new in electronic and it’s a bit hard for me to understand these things.

    1. I think they only make one model of the ATtiny85. :) For Attiny2313 Atmel has both normal and 10PU version (2313V), and the latter is limited to about 10 MHz – for those, the normal version is the one you should get.

  7. I have been trying to compile the C file that you provided in the source package. But I have been getting these errors.

    When I try to compile with the version of ‘usbdrv’ you provided, it gives me this error:

    And when I try to compile it with the newest version of ‘usbdrv’ downloaded from the V-USB website, it gives me this error:

    Please help.

  8. Hoooray!
    Finally!I get it working after three days.
    Here is the result:
    Starting generation…
    ———–THERE IS A BUT!——————
    But! when I touch the circuit(It’s on bread board).It disconnects and reconnects a few times (windiwos diling! sound) and then doesn’t work after.but when I touch it again and mess around with it, it works perfect!.
    I don’t know If you see what I’m trying to say or not.
    Anyway thank you for the great tutorial :)

  9. Hello !

    Please tell me how to adapt the code to have azerty layout please !!

    Thanks !!!!

    1. The password generator sends a random password, does it matter if instead of wHDcQ3 it is zHDcA3? And as I said in the other reply, it might be that USB keycodes are the same regardless of your keyboard layout. If not, a quick google search probably knows more about the matter than I do. (e.g. “USB HID keyboard layout” or “azerty usb keycodes” etc.)

  10. hello
    i try make it. but it doesn’t work. i used attiny45-20pu.
    and i using avr studio 4.19
    i connect usb to pc but pc can’t recognize this device
    i setup fuse bit high is 0xDD, low is 0xE1.
    main.hex is run only attiny85??
    please reply about this problem. i need your help.

    1. I’d think the firmware would work as well in 45 as in 85, as they only differ in flash memory amount. Often in similar problems there has been some hardware glitch, so double-checking that side might help. Good luck in your project!

  11. hello! i want to change this program.
    input password not automatically.
    i want using alt key.
    if i push alt key three times, now enter password.
    but i don’t know how to use this method.
    i need you help.
    please show me your solution.

    1. A USB keyboard does not receive alt-keypresses from another device, only caps lock, num lock and scroll lock, so you are limited to those three.

      You can see the code for example on how to trigger password regeneration on four caps lock presses, you should be able to adapt that to trigger password input (for example, regeneration with num lock, input with caps lock).

      1. Thank you for your answer.
        But i dont know hid device how to get information about push caps lock key. Also how to adapt num lock key?? please give me some example. I want caps lock is regenerate pw. And numlock is input. I need you help.

  12. For many obvious reasons, this is marketable. If you don’t have a patent, get one and wile we are on that subject you may want to check this site out “”. I am in no way affiliated with kickstarter but I think they would be able to get such a project started. The primary reason I am responding to this is that I would like to ask…

    May I please buy one from you?

  13. Hello,

    I want to upload the program, but I have not an Atmel programmer. So can I do it with an Arduino ISP ?

    1. Yes you can, I wrote a post about using Arduino some years ago, that or google will be your friend. :)

      1. Hey,

        thanks for reply. Now I have an problem. I have done everything, but know windows dont recognize the device. What could I do?


  14. Hi i have Digispark Attiny85 USB,

    I tried below code,

    Keyboard.print(“password “);
    Keyboard.sendKeyStroke(“KEY_ENTER “);

    but the output is keepon continuing……
    How can i stop with one time.

    1. It probably sends that in some kind of loop. If you are running the loop yourself, just make “one-time” variable:

      char pwSent = 0; // initially false


      while(1) { // the loop
      if(!pwSent) {
      pwSent = 1; // true

      If you run Arduino-like code:

      char pwSent = 0;

      void loop() {
      if(!pwSent) {
      // same code as in while-loop

  15. Hello, I have a problem! It operates at 50% of the time the other does not recognize my device. I double checked all hardware etc is all ok
    Any suggestions? It can be for the socket that I put to ATtiny?
    Thanks Carlo

  16. I am getting the errors detailed at the bottom of this post.
    Arduino: 1.6.11 (Windows 10), Board: “ATtiny25/45/85, ATtiny85, External 16 MHz”

    sketch_dec27a:24: error: variable ‘measuring_message’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’

    PROGMEM uchar measuring_message[] = “Starting generation…”;


    sketch_dec27a:25: error: variable ‘finish_message’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’

    PROGMEM uchar finish_message[] = ” New password saved.”;


    sketch_dec27a:39: error: variable ‘usbDescriptorHidReport’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’



    sketch_dec27a:39: error: conflicting declaration ‘char usbDescriptorHidReport [63]’

    In file included from C:\Users\admin\Desktop\usb_tiny85_passgen\sketch_dec27a\sketch_dec27a.ino:15:0:

    C:\Program Files (x86)\Arduino\libraries\usbdrv1/usbdrv.h:477:6: note: previous declaration as ‘const char usbDescriptorHidReport []’

    char usbDescriptorHidReport[];


    exit status 1
    variable ‘measuring_message’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’

    This report would have more information with
    “Show verbose output during compilation”
    option enabled in File -> Preferences.

    1. Hi! The examples are a bit dated, I think AVR libraries and compilers may have changed a bit since the writing of this article. Unfortunately I don’t have time to upgrade the code so you’d need to google around to solve the issues.

      However, I noticed you mentioned Arduino in your message, I’m not sure you can compile this with Arduino, avr-gcc and using ‘make’ from command-line would likely work a lot better.

  17. Hello Friend!

    Your posts are great, especially this one. I have a query regarding this project, could you explain how buildReport () works? That is, how do you send the “pressed” keys to the PC? I would be more than grateful if you help me understand.

    Many thanks!

    1. It’s essentially a state machine (you can see my tutorial on C state machines for reference), that starts from the beginning of password buffer, then every other call it sends key down message for next password character, and every other call keyup, and advances the pointer that points to the next character to be sent from the buffer. So if the buffer was “123”, it would send “1 down”, “1 up”, “2 down”, “2 up”, “3 down”, “3 up” and after that just idle. Hope this clarifies!

  18. I’ll try it but can you say which attiny85 you’ve used? because I’m new in electronics and it’s a bit hard for me to understand these things.

  19. The best protine sames are the lean ones – egg whites, lean meat, turkey, chicken, and fish.
    If sometimes into good condition is important to
    you personally then due to the fact will not likely enable you to achieve
    that. The results were dried out skin and mental fuzziness not to mention cravings for fatty

  20. Hi, i want to try to compile the source myself, to get an understanding of avr-gcc etc, i tried to use avr-gcc. but got some errors. just wondering if you could possibly help out. thanks
    also thanks for taking the time to make this

  21. Figured it out, didint add all the .o files when i c tried to create the .elf
    in the end this worked for me. incase anyone else is stuck using avr-gcc, though i used it on windows

    avr-gcc -Wall -Os -Iusbdrv -mmcu=attiny85 -DF_CPU=16500000 -c main.c

    avr-gcc -Wall -Os -Iusbdrv -mmcu=attiny85 -DF_CPU=16500000 usbdrv/usbdrv.o usbdrv/oddebug.o usbdrv/usbdrvasm.o main.o usbdrv/usbconfig.h -o main.elf

    avr-objcopy -j .text -j .data -O ihex main.elf main.hex

    Though if you want to change the device name, serial number etc.
    you have to edit. usbconfig.h and then recompile into usbdrv.c to usbdrv.o

    avr-gcc -Wall -Os -Iusbdrv -mmcu=attiny85 -DF_CPU=16500000 -c usbdrv.c

Comments are closed.