Giter Club home page Giter Club logo

nitrokey-pro-firmware's Introduction

Nitrokey Pro firmware

The following information is about the firmware of the Nitrokey Pro. For information about the hardware please have a look at the Nitrokey Pro hardware repo.

Overview

Nitrokey Pro, Start and HSM use the same hardware but different firmwares and different smart cards. The microprocessor being used is a STM32F103R8T6. The firmware is written in C, the desktop software Nitrokey App is written in C/C++.

To develop the firmware of the Nitrokey Pro/Start/HSM you would need:

  • An original Nitrokey Pro/Start/HSM or better a development board such as the Nucleo-F103RB or the Olimex STM32-H103. Alternatively, get any other development board equipped with a STM32F103TB and 128KB flash. On request you can get a Nitrokey for development purposes from us.
  • An OpenPGP Card 3.4 available at FLOSS Shop or on request from us. (Of course, this is not necessary for Nitrokey Start which doesn't contain a smart card.) If you use it with original Nitrokey hardware, you would need to cut it to Micro-SIM size. This can be done by using a special SIM card cutter or even with scissors. If you use a development board, you may solder the OpenPGP Card to the board directly by using some wires or you get yourself a smart card jack which you solder to the dev board instead.
  • To compile the firmware we recommend ARM's official GNU tools.

Building

make [VID=0x20a0] [PID=0x4108] firmware

Parameters:

  • VID: Define Vendor ID
  • PID: Define Product ID

Flashing

Note
Any user data present on the device will be erased when flashing it. A backup is essential to prevent data loss.

The microcontroller can be flashed in one of the following ways, depending on your hardware version:

  • all hardware versions: SWD is a STM-specific protocol and similar to JTAG allowing programming and debugging. Working adapters are Versaloon or any of the ST-Link V2 (clones). Under Linux the recent OpenOCD works quite well. This approach requires soldering wires to the contact pads or to use an adapter with pogo pins and some kind of mounting (recommended).
  • purchased before 04/04/2018: DFU is a simple protocol via serial port which allows programming but no debugging. On older Nitrokey versions, the appropriate pins are exposed over the USB connector (though it is not USB, the pin is only shared between these two).

SWD

Requirements

  • Download the .hex file you want to flash e.g. look at the releases section or build it yourself (see above).
  • Any SWD compatible programmer for ST microcontrollers. They come as part of ST's line of Discovery and Nucleo boards or can be bought seperately from ST as well as as clones for around $5 on eBay, Amazon or AliExpress (search for "ST-Link v2")

The following picture shows the pin pads of the Nitrokey. The red rectangle is only available in newer versions and easier to use as the pads are much bigger. The blue rectangle is present in older and newer devices.

SWD pins of newer Nitrokey Pro device

The SWD pins are as follows:

NK Pro v2.0 Programming Connector Layout

For SWD programming, connect the SWDIO, SWDCLK and GND pads to the respective pins of your ST-Link programmer. The device should be powered externally through USB or a 5V power supply during programming.

Flashing and Development Access

See the Development Guide for the current use.

OpenOCD

Modern OpenOCD works quite well, if not better than the official tools (especially for the debugging).

GDB Server
  openocd -f interface/stlink-v2.cfg  -f target/stm32f1x.cfg
Reading MCU Flash

Make sure the MCU is not memory protected, otherwise this operation will fail.

$ cat <<END >stm32read.cfg 
source [find interface/stlink.cfg]
source [find target/stm32f1x.cfg]
init
flash read_bank 0 firmware.bin 0 0x20000
exit
END
$ openocd -f stm32read.cfg

STM32 Official Tool

Official tool is available at stm32cubeprog.

Flashing STM32
  STM32_Programmer_CLI -c port=SWD -halt  --readunprotect
  STM32_Programmer_CLI -c port=swd -e all -w firmware.hex 0x8000000 -v -rst
GDB Server
  st-util

DFU

Please note, that this approach only works for older Nitrokey Pro device, not Nitrokey Pro 2 (all devices purchased before 04/04/2018).

DFU Requirements

  • Download the .hex file you want to flash e.g. look at the releases section or build it yourself (see above).
  • You may use STM32 Flash Loader Demonstrator (Windows only) or the open source command line tool stm32flash. Note: the terminal commands below are based on the command line tool.
  • If your computer doesn't has a RS232 port (most modern laptops don't have it) you would need a USB-to-RS232/TTL adapter. Sparkfun BOB-00718 should work (untested) and you can find even cheaper adapters online. Previously we built our own adapter which hardware layout you can download.
  • You would need a simple USB adapter to bridge Nitrokey's USB plug to the USB-to-RS232 adapter.

Your adapter should consist of a USB socket which four pins are connected to your serial/TTL connector. The pinout is as follows.

Nitrokey USB Plug <-> Serial/TTL adapter

Pin 1, VCC <-> VCC
Pin 2, D-  <-> TX
Pin 3, D+  <-> RX
Pin 4, GND <-> GND

This diagram represents the pinout of the USB socket which you are going to solder:

  ###################
  #                 #
  # ############### #
  #                 #
  #                 #
  ###################
     #   #   #   #   
     #   #   #   #    

     1   2   3   4

The following picture shows the adapter/USB-to-TTL connection. USB-to-TTL adapter and USB socket

To flash the firmware you need to bridge the two contact holes and only then connect (and power) the PCB to your adapter. The bridge triggers the hardware to boot into DFU mode. You can use a jumper with 2.0 mm pitch or just prepare/solder a wire. The following picture shows a bridge for the Nitrokey.

Nitrokey bridged with a jumper

Flashing via DFU

While the jumper is plugged in, connect the Nitrokey to the USB-serial adapter on your computer. The jumper is only required during the first moment of connection and can be removed afterwards.

You can check if the Nitrokey got successfully into DFU mode by typing in the following into a terminal:

$ sudo stm32flash /dev/ttyUSB0

stm32flash 0.5

http://stm32flash.sourceforge.net/

Error probing interface "serial_posix"
Cannot handle device "/dev/ttyUSB0"
Failed to open port: /dev/ttyUSB0

Now we have to disable the read protection first by typing

sudo stm32flash -k /dev/ttyUSB0 # read unprotecting

You may need to reconnect the device, before you can proceed. Do not forget to bridge the holes again. Now we do the actual flashing:

sudo stm32flash -w nitrokey-pro-firmware.hex /dev/ttyUSB0

Enabling the read/write protection again:

sudo stm32flash -j /dev/ttyUSB0 # read protection

nitrokey-pro-firmware's People

Contributors

alex-nitrokey avatar emeryth avatar florianuekermann avatar ggkitsas avatar jadeaffenjaeger avatar jans23 avatar kylerankin avatar nkelias avatar rudbo avatar stnikolov avatar szszszsz avatar t-than avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nitrokey-pro-firmware's Issues

Feature request: SHA256 handling for OTP

Although not seen in the open market, some proprietary systems are using SHA256 for the OTP. It would be nice to support it. Expected complexity of introducing this feature is low.

We do not support OTP based on HMAC-SHA256 in our products (only the
original HMAC-SHA1, as proposed in the RFC [1]). It is allowed in the
RFC standard, but not really encouraged, and I have not seen any in the
wild, hence we have not considered it.
[1] https://tools.ietf.org/html/rfc4226#appendix-B.1

Pass explicit string lengths and avoid strcpy and use consistent types for strings

In src/ccid/CcidLocalAccess.c strings (uint8_t * or unsigned char *, char *) of "unknown" length are used as function arguments. This can easily lead to reads exceeding array bounds if calling is not done carefully. A couple of places even use strcpy with that data. In the calling code this leads to awkward patterns like this:

uint8_t card_password[26];

memset (card_password, 0, 26);
memcpy (card_password, report + 1, 25);

res = cardAuthenticate (card_password);

A better idea would be to explicitly pass the (maximum) length of the string and use memcpy everywhere. (And why replicate the complex stuff instead of doing it inside the function?)

Furthermore consistent types should be used when passing around those pointers (uint8_t * seems like a good idea, since that is actually guaranteed to point to one byte). At the moment they are more or less randomly mixed and implicitly converted between three types in multiple places (even between signed and unsigned, which gcc issues warnings for).

A last concern. strcpy copies the terminating null character as well. Therefore, if the pattern above is used to ensure termination of a 25 char string which is copied into a 25 char array, the byte behind the array will also be set to 0. A similar situation occurs when comparing strings. I didn't check if there are precautions for this in place, but it illustrates how the approach taken here can lead to subtle errors and why it is often considered to be an antipattern.

User command authorization works only once

How I think the protocol is supposed to work:

  1. The USER_AUTHENTICATE authenticate command sets a temporary password, which I assume is supposed to be used as authorization secret during a session.
  2. The USER_AUTHORIZE command informs the device about an upcoming command CRC and needs to provide the correct temporary password.
  3. Get OTP using GET_CODE
  4. Repeat from step 2.

What actually happens:

First time works fine. Second time:
The response to GET_CODE reports the status NOT_AUTHORIZED (payload 0), even though the response to USER_AUTHORIZE looks fine.

To successfully use GET_CODE repeatedly, both the USER_AUTHENTICATE and USER_AUTHORIZE command have to be used every time.

What I didn't test:
There might be a similar issue with the other temporary password (FIRST_AUTHENTICATE). Or not.

Support bootloader

Allow to update firmware without additional hardware, by using a DFU-based bootloader.

Connected #66

Initialize AES key

Currently there is no way of initializing the AES key that is needed for password safe.

Buggy OTP slot range check

I believe the OTP slot range checks are wrong (<= instead of <):
The following lines in /src/keyboard/report_protocol.c are affected:
330, 341, 368, 383, 416, 435, 474, 490, 539, 546

Validity:
I have verified this by sending a command report with READ_SLOT as command and either 0x13 or 0x2F as payload (reads the non-existent 4th HOTP or 16th TOTP slot). In both cases the command status in the response is CMD_STATUS_SLOT_NOT_PROGRAMMED, when it should be CMD_STATUS_WRONG_SLOT (checked with payloads >0x13 && <0x20).
I would have tried writing the slots, but I only have 1 key and don't want to brick it or screw up the OTP keys stored on it. I looked at the code though (see below).

Disclaimer:
I don't know much about the hardware, nor have I properly analysed the firmware. The following could be BS.

Severity:
I tried to get an idea of how bad this is. My first impression from the rest of the code is that this reads the first 32bit behind the respective (t|h)otp_slot_offsets arrays and uses whatever happens to be there to calculate the memory address for reading and writing the slot data.
It doesn't seem like there are any more checks, so I guess the impact of this really depends on what the value of those 32bit behind the array is.
The corresponding address range would not only be somewhat readable, but by the looks of it also writeable using HID reports.

Questions:
What are the values behind the two arrays, any guarantees on that?
Assuming the values are fixed: Where do they point if used to calculate the addresses for reading and writing OTP slots?

Firmware binary:
For issues like this it may be important to get the firmware binary on the device. Can you provide either the compiled binary or instructions for reproducible builds and a hash?

Comment:
The bounds checks are replicated all over the place. I guess some refactoring wouldn't hurt.

Support HMAC-SHA1 directly

In the future we could support HMAC-SHA1 directly, if there would be a request (no one registered it in Pro's firmware project yet).

Here's the formal request! :)

Looking forward to Nitrokey Pro supporting HMAC-SHA1 directly in order to work properly with KeePassXC, as discussed here: keepassxreboot/keepassxc#255

In card key generation fails - Card error

Generation of keys fails through gpg2 --card-edit, while the key is being usable to crypt and decrypt emails. Tested on Ubuntu 15, Fedora 24 and Debian 9.

Under Fedora24:

gpg/card> admin
Admin commands are allowed

gpg/card> generate
Make off-card backup of encryption key? (Y/n) Y

gpg: Note: keys are already stored on the card!

Replace existing keys? (y/N) Y
What keysize do you want for the Signature key? (4096) 
What keysize do you want for the Encryption key? (4096) 
What keysize do you want for the Authentication key? (4096) 
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 3y
Key expires at Sun 07 Jun 2020 03:13:32 AM EDT
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: Testing
Email address: 
Comment: 
You selected this USER-ID:
    "Testing"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
gpg: key generation failed: Card error
Key generation failed: Card error

gpg/card> quit

gpg2 --version:

gpg (GnuPG) 2.1.13
libgcrypt 1.6.6
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /home/user/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

scdaemon.log:

2017-06-08 02:55:02 scdaemon[7282] listening on socket '/run/user/1000/gnupg/S.scdaemon'
2017-06-08 02:55:02 scdaemon[7282] handler for fd -1 started
2017-06-08 02:55:03 scdaemon[7282] reader slot 0: using ccid driver
2017-06-08 02:55:03 scdaemon[7282] slot 0: ATR=3B DA 18 FF 81 B1 FE 75 1F 03 00 31 C5 73 C0 01 40 00 90 00 0C
2017-06-08 02:55:03 scdaemon[7282] updating reader 0 (0) status: 0x0000->0x0007 (0->1)
2017-06-08 02:55:03 scdaemon[7282] DBG: send apdu: c=00 i=A4 p1=00 p2=0C lc=2 le=-1 em=0
2017-06-08 02:55:04 scdaemon[7282] reader slot 0: using ccid driver
2017-06-08 02:55:04 scdaemon[7282] slot 0: ATR=3B DA 18 FF 81 B1 FE 75 1F 03 00 31 C5 73 C0 01 40 00 90 00 0C
2017-06-08 02:55:04 scdaemon[7282] DBG:  raw apdu: 00 A4 00 0C 02 3F 00
2017-06-08 02:55:04 scdaemon[7282] DBG:  response: sw=6B00  datalen=0
2017-06-08 02:55:04 scdaemon[7282] DBG: send apdu: c=00 i=A4 p1=04 p2=00 lc=6 le=-1 em=0
2017-06-08 02:55:04 scdaemon[7282] DBG:  raw apdu: 00 A4 04 00 06 D2 76 00 01 24 01
2017-06-08 02:55:04 scdaemon[7282] DBG:  response: sw=9000  datalen=0
2017-06-08 02:55:04 scdaemon[7282] DBG:     dump:  
2017-06-08 02:55:04 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=4F lc=-1 le=256 em=0
2017-06-08 02:55:04 scdaemon[7282] DBG:  raw apdu: 00 CA 00 4F 00
2017-06-08 02:55:04 scdaemon[7282] DBG:  response: sw=9000  datalen=16
2017-06-08 02:55:04 scdaemon[7282] DBG:       dump:  D2 76 00 01 24 01 02 01 00 05 00 00 3D 4A 00 00
2017-06-08 02:55:04 scdaemon[7282] AID: D2 76 00 01 24 01 02 01 00 05 00 00 3D 4A 00 00
2017-06-08 02:55:04 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=5F p2=52 lc=-1 le=256 em=0
2017-06-08 02:55:04 scdaemon[7282] DBG:  raw apdu: 00 CA 5F 52 00
2017-06-08 02:55:04 scdaemon[7282] DBG:  response: sw=9000  datalen=10
2017-06-08 02:55:04 scdaemon[7282] DBG:       dump:  00 31 C5 73 C0 01 40 05 90 00
2017-06-08 02:55:04 scdaemon[7282] Historical Bytes: 00 31 C5 73 C0 01 40 05 90 00
2017-06-08 02:55:04 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=C4 lc=-1 le=256 em=0
2017-06-08 02:55:04 scdaemon[7282] DBG:  raw apdu: 00 CA 00 C4 00
2017-06-08 02:55:04 scdaemon[7282] DBG:  response: sw=9000  datalen=7
2017-06-08 02:55:04 scdaemon[7282] DBG:       dump:  01 20 20 20 03 03 03
2017-06-08 02:55:04 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=6E lc=-1 le=256 em=0
2017-06-08 02:55:04 scdaemon[7282] DBG:  raw apdu: 00 CA 00 6E 00
2017-06-08 02:55:04 scdaemon[7282] DBG:  response: sw=9000  datalen=217
2017-06-08 02:55:04 scdaemon[7282] DBG:       dump:  4F 10 D2 76 00 01 24 01 02 01 00 05 00 00 3D 4A 00 00 5F 52 0A 00 31 C5 73 C0 01 40 05 90 00 73 81 B7 C0 0A 7C 00 08 00 08 00 08 00 08 00 C1 06 01 10 00 00 20 00 C2 06 01 10 00 00 20 00 C3 06 01 10 00 00 20 00 C4 07 01 20 20 20 03 03 03 C5 3C 59 24 06 2E 23 A4 BC 0B 1F 41 DA FD 94 91 70 17 80 C6 2E 11 65 C2 BD 5E 29 A0 D1 7F A1 D3 BF 94 C1 1B B3 A7 F7 D3 87 25 04 DC F1 EA 64 0A 03 4A 65 3F B7 41 0D 3E 6E 81 CA 31 36 C2 C6 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 0C 59 37 72 3E 57 0D 31 AF 59 37 72 7D
2017-06-08 02:55:04 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=7F p2=74 lc=-1 le=256 em=0
2017-06-08 02:55:04 scdaemon[7282] DBG:  raw apdu: 00 CA 7F 74 00
2017-06-08 02:55:05 scdaemon[7282] DBG:  response: sw=6A88  datalen=0
2017-06-08 02:55:05 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=5E lc=-1 le=256 em=0
2017-06-08 02:55:05 scdaemon[7282] DBG:  raw apdu: 00 CA 00 5E 00
2017-06-08 02:55:05 scdaemon[7282] DBG:  response: sw=9000  datalen=4
2017-06-08 02:55:05 scdaemon[7282] DBG:       dump:  75 73 65 72
2017-06-08 02:55:05 scdaemon[7282] Version-2 ......: yes
2017-06-08 02:55:05 scdaemon[7282] Get-Challenge ..: yes (2048 bytes max)
2017-06-08 02:55:05 scdaemon[7282] Key-Import .....: yes
2017-06-08 02:55:05 scdaemon[7282] Change-Force-PW1: yes
2017-06-08 02:55:05 scdaemon[7282] Private-DOs ....: yes
2017-06-08 02:55:05 scdaemon[7282] Algo-Attr-Change: yes
2017-06-08 02:55:05 scdaemon[7282] SM-Support .....: no
2017-06-08 02:55:05 scdaemon[7282] Max-Cert3-Len ..: 2048
2017-06-08 02:55:05 scdaemon[7282] Max-Cmd-Data ...: 2048
2017-06-08 02:55:05 scdaemon[7282] Max-Rsp-Data ...: 2048
2017-06-08 02:55:05 scdaemon[7282] Cmd-Chaining ...: no
2017-06-08 02:55:05 scdaemon[7282] Ext-Lc-Le ......: yes
2017-06-08 02:55:05 scdaemon[7282] Status Indicator: 05
2017-06-08 02:55:05 scdaemon[7282] Symmetric crypto: no
2017-06-08 02:55:05 scdaemon[7282] Button..........: no
2017-06-08 02:55:05 scdaemon[7282] GnuPG-No-Sync ..: no
2017-06-08 02:55:05 scdaemon[7282] GnuPG-Def-PW2 ..: no
2017-06-08 02:55:05 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=6E lc=-1 le=256 em=0
2017-06-08 02:55:05 scdaemon[7282] DBG:  raw apdu: 00 CA 00 6E 00
2017-06-08 02:55:05 scdaemon[7282] DBG:  response: sw=9000  datalen=217
2017-06-08 02:55:05 scdaemon[7282] DBG:       dump:  4F 10 D2 76 00 01 24 01 02 01 00 05 00 00 3D 4A 00 00 5F 52 0A 00 31 C5 73 C0 01 40 05 90 00 73 81 B7 C0 0A 7C 00 08 00 08 00 08 00 08 00 C1 06 01 10 00 00 20 00 C2 06 01 10 00 00 20 00 C3 06 01 10 00 00 20 00 C4 07 01 20 20 20 03 03 03 C5 3C 59 24 06 2E 23 A4 BC 0B 1F 41 DA FD 94 91 70 17 80 C6 2E 11 65 C2 BD 5E 29 A0 D1 7F A1 D3 BF 94 C1 1B B3 A7 F7 D3 87 25 04 DC F1 EA 64 0A 03 4A 65 3F B7 41 0D 3E 6E 81 CA 31 36 C2 C6 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 0C 59 37 72 3E 57 0D 31 AF 59 37 72 7D
2017-06-08 02:55:05 scdaemon[7282] Key-Attr-sign ..: RSA, n=4096, e=32, fmt=std
2017-06-08 02:55:05 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=6E lc=-1 le=256 em=0
2017-06-08 02:55:05 scdaemon[7282] DBG:  raw apdu: 00 CA 00 6E 00
2017-06-08 02:55:05 scdaemon[7282] DBG:  response: sw=9000  datalen=217
2017-06-08 02:55:05 scdaemon[7282] DBG:       dump:  4F 10 D2 76 00 01 24 01 02 01 00 05 00 00 3D 4A 00 00 5F 52 0A 00 31 C5 73 C0 01 40 05 90 00 73 81 B7 C0 0A 7C 00 08 00 08 00 08 00 08 00 C1 06 01 10 00 00 20 00 C2 06 01 10 00 00 20 00 C3 06 01 10 00 00 20 00 C4 07 01 20 20 20 03 03 03 C5 3C 59 24 06 2E 23 A4 BC 0B 1F 41 DA FD 94 91 70 17 80 C6 2E 11 65 C2 BD 5E 29 A0 D1 7F A1 D3 BF 94 C1 1B B3 A7 F7 D3 87 25 04 DC F1 EA 64 0A 03 4A 65 3F B7 41 0D 3E 6E 81 CA 31 36 C2 C6 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 0C 59 37 72 3E 57 0D 31 AF 59 37 72 7D
2017-06-08 02:55:05 scdaemon[7282] Key-Attr-encr ..: RSA, n=4096, e=32, fmt=std
2017-06-08 02:55:05 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=6E lc=-1 le=256 em=0
2017-06-08 02:55:05 scdaemon[7282] DBG:  raw apdu: 00 CA 00 6E 00
2017-06-08 02:55:05 scdaemon[7282] DBG:  response: sw=9000  datalen=217
2017-06-08 02:55:05 scdaemon[7282] DBG:       dump:  4F 10 D2 76 00 01 24 01 02 01 00 05 00 00 3D 4A 00 00 5F 52 0A 00 31 C5 73 C0 01 40 05 90 00 73 81 B7 C0 0A 7C 00 08 00 08 00 08 00 08 00 C1 06 01 10 00 00 20 00 C2 06 01 10 00 00 20 00 C3 06 01 10 00 00 20 00 C4 07 01 20 20 20 03 03 03 C5 3C 59 24 06 2E 23 A4 BC 0B 1F 41 DA FD 94 91 70 17 80 C6 2E 11 65 C2 BD 5E 29 A0 D1 7F A1 D3 BF 94 C1 1B B3 A7 F7 D3 87 25 04 DC F1 EA 64 0A 03 4A 65 3F B7 41 0D 3E 6E 81 CA 31 36 C2 C6 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 0C 59 37 72 3E 57 0D 31 AF 59 37 72 7D
2017-06-08 02:55:05 scdaemon[7282] Key-Attr-auth ..: RSA, n=4096, e=32, fmt=std
2017-06-08 02:55:05 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=65 lc=-1 le=256 em=0
2017-06-08 02:55:05 scdaemon[7282] DBG:  raw apdu: 00 CA 00 65 00
2017-06-08 02:55:05 scdaemon[7282] DBG:  response: sw=9000  datalen=27
2017-06-08 02:55:05 scdaemon[7282] DBG:       dump:  5B 10 54 68 69 65 72 72 79 3C 3C 4C 61 75 72 69 6F 6E 5F 2D 02 66 72 5F 35 01 31
2017-06-08 02:55:05 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=5F p2=50 lc=-1 le=256 em=0
2017-06-08 02:55:05 scdaemon[7282] DBG:  raw apdu: 00 CA 5F 50 00
2017-06-08 02:55:05 scdaemon[7282] DBG:  response: sw=9000  datalen=70
2017-06-08 02:55:05 scdaemon[7282] DBG:       dump:  68 74 74 70 73 3A 2F 2F 73 6B 73 2D 6B 65 79 73 65 72 76 65 72 73 2E 6E 65 74 2F 70 6B 73 2F 6C 6F 6F 6B 75 70 3F 6F 70 3D 67 65 74 26 73 65 61 72 63 68 3D 30 78 35 33 37 36 33 38 32 33 42 39 32 44 30 33 30 42
2017-06-08 02:55:05 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=6E lc=-1 le=256 em=0
2017-06-08 02:55:05 scdaemon[7282] DBG:  raw apdu: 00 CA 00 6E 00
2017-06-08 02:55:05 scdaemon[7282] DBG:  response: sw=9000  datalen=217
2017-06-08 02:55:05 scdaemon[7282] DBG:       dump:  4F 10 D2 76 00 01 24 01 02 01 00 05 00 00 3D 4A 00 00 5F 52 0A 00 31 C5 73 C0 01 40 05 90 00 73 81 B7 C0 0A 7C 00 08 00 08 00 08 00 08 00 C1 06 01 10 00 00 20 00 C2 06 01 10 00 00 20 00 C3 06 01 10 00 00 20 00 C4 07 01 20 20 20 03 03 03 C5 3C 59 24 06 2E 23 A4 BC 0B 1F 41 DA FD 94 91 70 17 80 C6 2E 11 65 C2 BD 5E 29 A0 D1 7F A1 D3 BF 94 C1 1B B3 A7 F7 D3 87 25 04 DC F1 EA 64 0A 03 4A 65 3F B7 41 0D 3E 6E 81 CA 31 36 C2 C6 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 0C 59 37 72 3E 57 0D 31 AF 59 37 72 7D
2017-06-08 02:55:05 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=C4 lc=-1 le=256 em=0
2017-06-08 02:55:05 scdaemon[7282] DBG:  raw apdu: 00 CA 00 C4 00
2017-06-08 02:55:05 scdaemon[7282] DBG:  response: sw=9000  datalen=7
2017-06-08 02:55:05 scdaemon[7282] DBG:       dump:  01 20 20 20 03 03 03
2017-06-08 02:55:05 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=7A lc=-1 le=256 em=0
2017-06-08 02:55:05 scdaemon[7282] DBG:  raw apdu: 00 CA 00 7A 00
2017-06-08 02:55:05 scdaemon[7282] DBG:  response: sw=9000  datalen=5
2017-06-08 02:55:05 scdaemon[7282] DBG:       dump:  93 03 00 00 00
2017-06-08 02:55:05 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=01 p2=01 lc=-1 le=256 em=0
2017-06-08 02:55:05 scdaemon[7282] DBG:  raw apdu: 00 CA 01 01 00
2017-06-08 02:55:05 scdaemon[7282] DBG:  response: sw=9000  datalen=0
2017-06-08 02:55:05 scdaemon[7282] DBG:       dump:  
2017-06-08 02:55:05 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=01 p2=02 lc=-1 le=256 em=0
2017-06-08 02:55:05 scdaemon[7282] DBG:  raw apdu: 00 CA 01 02 00
2017-06-08 02:55:05 scdaemon[7282] DBG:  response: sw=9000  datalen=0
2017-06-08 02:55:05 scdaemon[7282] DBG:       dump:  
2017-06-08 02:55:05 scdaemon[7282] DBG: send apdu: c=00 i=47 p1=81 p2=00 lc=2 le=2048 em=1
2017-06-08 02:55:05 scdaemon[7282] DBG:  raw apdu: 00 47 81 00 00 00 02 B6 00 08 00
2017-06-08 02:55:06 scdaemon[7282] DBG:  response: sw=9000  datalen=527
2017-06-08 02:55:06 scdaemon[7282] DBG:       dump:  7F 49 82 02 0A 81 82 02 00 C6 19 C0 85 C9 24 5F 0B CC CB B4 77 F3 ED CD 68 89 A1 AB E6 F3 46 B0 8A D0 CA AF 9D 26 E6 AD 64 B6 89 A1 9A B1 E4 F5 2F FF 12 8A B7 9F A3 C4 F0 C1 06 72 02 AB 35 0D C5 4D 63 4C 60 02 FF 70 E0 88 A2 81 9F 2F 47 C8 2D 9B 62 7C 2B 43 34 D5 F7 DF 13 39 0F EC D4 B1 3D 3E B4 C3 28 C7 9C CC 03 66 C2 8D 3C 7A 1E AC C5 14 82 F1 0A 8E 44 72 7F 74 6B 04 99 15 A8 A0 CF 72 48 F2 E0 A5 50 63 FB 0D 9A B5 F5 4A 0A B9 20 A5 37 EE 28 93 6C 03 BE 2A 1B B7 91 54 CD 0A B4 0D CB 4E A7 0D 34 8E 3F 39 FC B3 F0 BE 80 C7 8E 64 0B 3A 1C 86 A5 7C FA BD 4E 33 85 69 F1 A8 C6 E8 54 BF 65 61 47 76 74 9E 3A E2 57 FD 2F 9F 93 D7 57 CB 3A 40 11 5B 56 C5 5B 69 F4 D9 78 12 F8 37 7D E9 A0 72 4F 9A 51 57 70 82 64 DC FB D6 57 17 D8 7B 9F BC 4D 7C D3 E3 DD B6 BE 72 CF C9 0F CC BA 7B 30 90 CA 4A F7 ED C7 A5 BC BB A1 F4 E1 DC 21 BE 99 38 73 D4 08 20 29 7E BD AB 63 7D B9 02 4F 6D AD 2E 73 5F D1 83 69 5C 3D 2A 21 47 A9 2E 1B 62 00 D5 26 83 1F 49 05 D8 E3 A2 81 72 4D 9B 04 39 DB 93 5B DD 44 2A DB DD D3 75 CD FB 98 B2 95 3F C8 D5 E8 B6 34 FA DB 71 18 09 30 33 38 1C 39 0B C2 D4 BC 72 6E D3 21 18 45 6D 60 39 1E 5C 5A 05 9D 64 85 B0 83 7D D4 03 52 F5 D4 C0 4F BF F8 E7 1B 97 8E AA AB A2 14 06 D0 7D 3E E5 62 31 46 3B 63 9D 3C 04 2D 13 A2 CF D4 A6 5C 1D 7D AB D0 99 D3 C0 9A 22 98 44 28 FB 11 7A 0F 11 0A 48 1A 6E 9E 1A 87 35 2E AF 53 8C 89 A4 4B CC 12 24 07 EC 88 5D 15 96 E6 89 72 3C 01 E3 C2 F8 58 C8 71 C7 0C 5C 38 F8 49 C6 90 06 E2 C3 72 E5 36 6B C3 DB C0 12 88 BF 8A 26 44 50 86 44 B3 72 B0 1B 63 E6 5A 91 80 0B D3 56 27 2F 3E 15 BB 01 49 5D D3 EB 1B 44 C9 4E FF 82 04 00 01 00 01
2017-06-08 02:55:06 scdaemon[7282] DBG: send apdu: c=00 i=47 p1=81 p2=00 lc=2 le=2048 em=1
2017-06-08 02:55:06 scdaemon[7282] DBG:  raw apdu: 00 47 81 00 00 00 02 B8 00 08 00
2017-06-08 02:55:06 scdaemon[7282] DBG:  response: sw=9000  datalen=527
2017-06-08 02:55:06 scdaemon[7282] DBG:       dump:  7F 49 82 02 0A 81 82 02 00 CE 5E 33 5F 45 D4 5B 46 DB 48 18 A5 3C E7 59 7F B8 40 31 F9 B8 FE FC 79 F4 8B 40 38 8D 09 7D FC 2E AE 4C F8 C4 C3 8B E3 F6 B3 C0 A3 91 B9 9F 71 68 CE E4 03 54 BC E2 2A D6 B8 AE A6 23 A2 CC D5 B3 8E 4E DE FA 83 07 FA 19 A7 7B F6 4B E4 F3 5D 17 0A 67 A9 31 06 2D CA 04 7D 98 C8 68 72 37 BD 1D 9A 83 2F 8D 3A 60 56 64 F9 29 03 E2 6C D3 1D 81 F0 D8 21 3F 9F 5D 54 D3 0F 09 09 B6 B3 38 6A 7D 1C 1C 63 4D 7E 88 62 A0 8C A4 A8 57 D0 8A C1 39 F5 B6 C9 7A B8 56 83 90 5C BD 88 E3 F4 BF AC 83 D4 2E E9 E5 14 67 CA AA 85 2B 48 66 E1 23 CB 89 3B 78 79 0E 6B 44 02 93 B6 C8 C8 DF 24 32 23 0E 4A 6B 76 50 A6 20 88 21 E2 2D FF 48 F0 5C A3 AD D1 8D A0 2A 79 E5 ED 35 D9 69 02 90 72 C9 84 3C 1B CE F2 5C 8F 93 94 AF 51 3C D5 55 7D E7 FA 64 72 F0 FB 4A F3 A3 37 49 78 84 D4 90 79 8B BB 50 2E C1 E5 9F B1 AF C8 CB 7E AF 56 63 1F B4 8B BC CD A9 44 75 A5 A7 70 97 C0 A0 2F FE AF 68 0F 96 AB EB 65 60 86 41 68 12 8D 30 DE 89 85 74 81 49 04 4A 1A D8 6F B8 08 15 CC FF 64 F2 05 E7 E8 25 3C C7 8A B4 77 CD 1B 0C C6 8B 64 40 BA 3F 4F 48 0C 08 36 7E 1B 0A 62 0E 5F 6B E8 05 DD E3 53 E0 BE 6C 2A 80 A8 8D 55 29 B8 AF D3 73 77 9E B9 57 83 88 44 C6 28 18 BE 50 F8 9A E8 6B 6C 04 CF 96 FE 9A 3E 57 41 0E 7F 54 55 D4 FC A6 E1 E8 FF A4 C7 E0 00 7E B9 95 DC 50 9D 32 70 29 AF FC 3B 0A 7B 6F 54 14 CC DC CC 68 51 9A 64 7B 70 03 31 59 16 50 F3 44 89 B7 99 76 38 60 DB EF E5 25 B4 27 0F B2 11 0B AB E2 C6 94 26 F4 FB 28 10 E0 53 86 2E 6F 27 F7 8C 0E 13 E7 E2 75 A2 F4 12 B7 8A 26 D2 9A 23 98 AD CE 4C D6 BA 18 78 BC D9 FB 37 D0 6D F6 A7 B1 36 AD A9 40 EA A9 79 15 29 35 19 82 04 00 01 00 01
2017-06-08 02:55:06 scdaemon[7282] DBG: send apdu: c=00 i=47 p1=81 p2=00 lc=2 le=2048 em=1
2017-06-08 02:55:06 scdaemon[7282] DBG:  raw apdu: 00 47 81 00 00 00 02 A4 00 08 00
2017-06-08 02:55:07 scdaemon[7282] DBG:  response: sw=9000  datalen=527
2017-06-08 02:55:07 scdaemon[7282] DBG:       dump:  7F 49 82 02 0A 81 82 02 00 C2 7D 26 05 6A 4C B6 4D AA D7 89 DF 71 72 99 0A 31 01 15 C1 C9 C0 C8 1E B7 3A 16 28 5B 3E 63 96 08 13 28 85 BF 16 B9 33 6E D9 C4 CE D3 A4 7E D2 3D 07 F8 06 E2 81 28 BC FB C7 7E 5A 92 1C 06 90 35 7C 20 D6 E3 DA FF 62 85 72 8C CD FF 6D 02 99 3F 64 4F 4C CA 29 EB A0 B7 8B E7 C0 24 62 22 E4 DC 9E 8E 5E 93 6F AD 2D 7A F7 09 41 D5 F1 58 62 A2 8D 14 7C 17 10 1D C6 C4 78 01 76 09 81 A4 63 5D 86 AF E0 54 B4 22 E8 76 C8 BF 5F 09 05 03 7C B9 B7 0B CB A3 84 82 32 33 51 8A 07 0E 9E 8F D2 17 22 6B 79 7D 59 C6 B3 E2 D3 67 2C E5 CD 92 BB 53 C1 D2 1A 70 FA DC 3F 83 02 A7 B6 BA 39 CD 91 D3 C9 7C 11 0F 64 81 FB 9A 24 D7 5F 14 6F D0 07 50 31 A4 82 9E E2 70 63 ED 3D A8 2C 88 1B 9F B3 DD FF 32 02 50 0D C8 BE 88 62 75 35 27 40 E6 32 26 03 76 19 40 88 D5 B0 38 C5 45 77 45 88 F9 1A 3F 4E 41 A3 C2 52 E8 3F 26 52 3E D4 B6 AE 53 67 1F 83 BF 3B 84 87 6E A8 A7 E9 03 26 33 68 1A 4C 7B 03 90 4F D3 D6 6E 78 00 03 83 AD 34 3E 20 E1 89 3B BB 22 FA 22 5B 45 EE 3E E4 54 22 F1 C1 CF 1E DA 8A 97 11 D9 EF F9 41 99 2C 2A 39 68 00 02 43 D3 91 16 BD 15 60 6A F5 B9 1F C1 5F D7 06 7F BF 51 8C E5 5A 2B 4A 7D E5 78 92 64 A0 64 47 45 B0 7F CB 82 62 8B 87 03 DD 58 57 13 F6 FC F8 08 83 6C 32 F8 C8 D2 31 79 48 92 93 5E EF 80 22 CF BF D4 16 01 D9 97 10 8C 5C 85 53 87 25 06 5D FB E0 D0 58 3C 86 E2 8E B9 EC 74 03 D4 3B C4 C6 1E C7 97 29 F0 D0 D7 7A BE 45 0A 56 4A A7 D4 49 AE 22 93 F8 F6 52 36 DA 23 95 7F 81 6F 62 45 00 73 57 ED 4A DC C9 8F 6C EF 49 5D 8C 9D 0E 13 D4 BC 39 26 96 7B 77 C5 23 20 E3 9C CA 80 0A E4 23 EA C8 0B C1 B7 E7 25 B5 F2 C5 71 BD 4A 46 5A AB 5D 82 04 00 01 00 01
2017-06-08 02:55:16 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=C4 lc=-1 le=256 em=0
2017-06-08 02:55:16 scdaemon[7282] DBG:  raw apdu: 00 CA 00 C4 00
2017-06-08 02:55:16 scdaemon[7282] DBG:  response: sw=9000  datalen=7
2017-06-08 02:55:16 scdaemon[7282] DBG:       dump:  01 20 20 20 03 03 03
2017-06-08 02:55:16 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=7A lc=-1 le=256 em=0
2017-06-08 02:55:16 scdaemon[7282] DBG:  raw apdu: 00 CA 00 7A 00
2017-06-08 02:55:16 scdaemon[7282] DBG:  response: sw=9000  datalen=5
2017-06-08 02:55:16 scdaemon[7282] DBG:       dump:  93 03 00 00 00
2017-06-08 02:55:24 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=C4 lc=-1 le=256 em=0
2017-06-08 02:55:24 scdaemon[7282] DBG:  raw apdu: 00 CA 00 C4 00
2017-06-08 02:55:24 scdaemon[7282] DBG:  response: sw=9000  datalen=7
2017-06-08 02:55:24 scdaemon[7282] DBG:       dump:  01 20 20 20 03 03 03
2017-06-08 02:55:28 scdaemon[7282] DBG: asking for PIN '||Please enter the PIN'
2017-06-08 02:55:33 scdaemon[7282] DBG: send apdu: c=00 i=20 p1=00 p2=82 lc=17 le=-1 em=0
2017-06-08 02:55:33 scdaemon[7282] DBG:  raw apdu: 00 20 00 82 11 4B 6E 30 31 33 64 67 33 20 69 73 20 70 30 77 33 72
2017-06-08 02:55:33 scdaemon[7282] DBG:  response: sw=9000  datalen=0
2017-06-08 02:55:33 scdaemon[7282] DBG:     dump:  
2017-06-08 02:55:33 scdaemon[7282] DBG: send apdu: c=00 i=20 p1=00 p2=81 lc=17 le=-1 em=0
2017-06-08 02:55:33 scdaemon[7282] DBG:  raw apdu: 00 20 00 81 11 4B 6E 30 31 33 64 67 33 20 69 73 20 70 30 77 33 72
2017-06-08 02:55:33 scdaemon[7282] DBG:  response: sw=9000  datalen=0
2017-06-08 02:55:33 scdaemon[7282] DBG:     dump:  
2017-06-08 02:55:33 scdaemon[7282] operation check_pin result: Success
2017-06-08 02:55:49 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=6E lc=-1 le=256 em=0
2017-06-08 02:55:49 scdaemon[7282] DBG:  raw apdu: 00 CA 00 6E 00
2017-06-08 02:55:49 scdaemon[7282] DBG:  response: sw=9000  datalen=217
2017-06-08 02:55:49 scdaemon[7282] DBG:       dump:  4F 10 D2 76 00 01 24 01 02 01 00 05 00 00 3D 4A 00 00 5F 52 0A 00 31 C5 73 C0 01 40 05 90 00 73 81 B7 C0 0A 7C 00 08 00 08 00 08 00 08 00 C1 06 01 10 00 00 20 00 C2 06 01 10 00 00 20 00 C3 06 01 10 00 00 20 00 C4 07 01 20 20 20 03 03 03 C5 3C 59 24 06 2E 23 A4 BC 0B 1F 41 DA FD 94 91 70 17 80 C6 2E 11 65 C2 BD 5E 29 A0 D1 7F A1 D3 BF 94 C1 1B B3 A7 F7 D3 87 25 04 DC F1 EA 64 0A 03 4A 65 3F B7 41 0D 3E 6E 81 CA 31 36 C2 C6 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 0C 59 37 72 3E 57 0D 31 AF 59 37 72 7D
2017-06-08 02:55:49 scdaemon[7282] existing key will be replaced
2017-06-08 02:55:49 scdaemon[7282] DBG: send apdu: c=00 i=CA p1=00 p2=C4 lc=-1 le=256 em=0
2017-06-08 02:55:49 scdaemon[7282] DBG:  raw apdu: 00 CA 00 C4 00
2017-06-08 02:55:49 scdaemon[7282] DBG:  response: sw=9000  datalen=7
2017-06-08 02:55:49 scdaemon[7282] DBG:       dump:  01 20 20 20 03 03 03
2017-06-08 02:55:49 scdaemon[7282] 3 Admin PIN attempts remaining before card is permanently locked
2017-06-08 02:55:49 scdaemon[7282] DBG: asking for PIN '|A|Please enter the Admin PIN'
2017-06-08 02:55:59 scdaemon[7282] DBG: send apdu: c=00 i=20 p1=00 p2=83 lc=20 le=-1 em=0
2017-06-08 02:55:59 scdaemon[7282] DBG:  raw apdu: 00 20 00 83 14 55 6E 64 33 72 67 72 6F 75 6E 64 20 62 69 61 74 63 68 65 73
2017-06-08 02:55:59 scdaemon[7282] DBG:  response: sw=9000  datalen=0
2017-06-08 02:55:59 scdaemon[7282] DBG:     dump:  
2017-06-08 02:55:59 scdaemon[7282] please wait while key is being generated ...
2017-06-08 02:55:59 scdaemon[7282] DBG: send apdu: c=00 i=47 p1=80 p2=00 lc=2 le=2048 em=1
2017-06-08 02:55:59 scdaemon[7282] DBG:  raw apdu: 00 47 80 00 00 00 02 B6 00 08 00
2017-06-08 02:56:12 scdaemon[7282] ccid_transceive failed: (0x1000a)
2017-06-08 02:56:12 scdaemon[7282] apdu_send_simple(0) failed: card I/O error
2017-06-08 02:56:12 scdaemon[7282] generating key failed
2017-06-08 02:56:12 scdaemon[7282] operation genkey result: Card error
2017-06-08 02:56:40 scdaemon[7282] updating reader 0 (0) status: 0x0007->0x0007 (1->2)
2017-06-08 02:56:40 scdaemon[7282] sending signal 12 to client 7280

Support longer passphrases

The current 20 character limit on passwords is too short for secure passphrases.
Would be great to support longer passwords eg: 128+ characters (especially considering Unicode chars take up more than one "character" in the password manager).

This makes sense for situations where you want to use the password safe on desktop 90% of the time, but must occasionally type the passphrase (eg android, or login screen, etc)

password_strength

Device locks-up on doubled AES key generation

Device is locking up on two AES key generation operation called directly after each other without a delay. Reinsertion fixes the issue.

Device: Pro v0.7 and 0.8
Details and reproduction: Run test_issue_device_locks_on_second_key_generation_in_sequence (test_pro.py) in libnitrokey
Priority: low (due to not to be a user case)

Deter Use By Malware

In the event the system is compromised and an attacker has the pin by recording keystrokes,
is there any provision against the device being used maliciously?

For example, if the device were to enforce that it only perform 1 key operation, with a delay and LED feedback, after bootup, this could significantly deter automated use by a system infection.

OTP SECRETs begining with 0x00 are not stored in the slots

Any secret (hotp o totp) beginning with 0x00 are ignored because only the first byte is checked (it's really a rudimentary check!) to know if secret have to be stored (user has type a new one) or keep the old one. htop.c/write_to_slot()/line 500.

An example. This was may google TOTP secret:

base32[aaxp ip2r v6ux xivu mqmh najd zhqy bgs3]
hex[002EF43F51AFA97BA2B46418768123C9E1809A5B]

This secret never trust the condition if (secret[0] == 0). So any secret beginig with 0x00 gives the same code as:
oathtool --totp --time-step-size=30s --digits 6 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
because FLASH memories clear to 0xFF.

Workaround:
Change the secret, request a new one or disable and reenable two step authentication. Depends on the provider.

Improve iSerial number

For Nitrokey Pro:
Currently the iSerial number (of USB interface) is something like 000000000000000000005F11. The leading part are always zeros while the actual App ID in this case is D276000124010303000500005F110000. Either the leading zeros should be dropped (so that a serial number of 8 characters is remaining) or replaced with the actual App ID.

For Nitrokey HSM:
I suggest to use everything behind DENK as a serial number, e.g. 0101774, and don't append any zeros. The iSerial would be seven digits long.

New error code for a missing AES key

Currently, the PWS commands return an AES decryption failed error if the AES key could not be decrypted. It would be helpful to have a separate error code for the case when no AES key is present (i. e. a factory reset has been performed) to show a helpful error message to the user.

This also applies to the Storage – should I open a second issue for that?

Build errors / Required version of gcc-arm-none-eabi?

Hi, what version of gcc-arm-none-eabi is required to build this?
I've tried 8.2.0 on arch and it gives me this:

Linking: nitrokey-pro-firmware.elf
arm-none-eabi-gcc -mthumb -mcpu=cortex-m3  -I. -gdwarf-2 -DROM_RUN -DUSE_STDPERIPH_DRIVER -DSTM32F10X_HD -DUSE_STM3210E_EVAL -DGLOBAL_VID=0x20a0 -DGLOBAL_PID=0x4108  -O2 -Wall -Wcast-align -Wimplicit -Wpointer-arith -Wswitch -Wredundant-decls -Wreturn-type -Wshadow -Wunused -Wa,-adhlns=../../src/main.lst -I../../src/inc -I../../src/stm/Libraries/CMSIS/Core/CM3 -I../../src/stm/Libraries/STM32_USB-FS-Device_Driver/inc -I../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/inc -Wno-cast-qual -Wno-cast-align -Wcast-qual -Wno-cast-qual -MD -MP -MF .dep/nitrokey-pro-firmware.elf.d    ../../src/main.o ../../src/hw_config.o ../../src/test_code.o ../../src/utils/delays.o ../../src/utils/memory_ops.o ../../src/ccid/Ccid_usb.o ../../src/ccid/Ifd_protocol.o ../../src/ccid/Crd.o ../../src/ccid/Ifd_ccid.o ../../src/ccid/CcidLocalAccess.o ../../src/ccid/smartcard/smartcard.o ../../src/ccid/CCIDHID_USB/CCIDHID_usb_prop.o ../../src/ccid/CCIDHID_USB/CCIDHID_usb_desc.o ../../src/sd-disk/sd-usb/usb_desc.o ../../src/sd-disk/sd-usb/usb_prop.o ../../src/stm/stm32f10x_systick.o ../../src/stm/stm32f10x_it.o ../../src/stm/Libraries/CMSIS/Core/CM3/core_cm3.o ../../src/stm/Libraries/CMSIS/Core/CM3/system_stm32f10x.o ../../src/stm/Libraries/CMSIS/Core/CM3/startup/gcc/startup_stm32f10x_hd.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/misc.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_adc.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_bkp.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_can.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_crc.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_dac.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_dbgmcu.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_dma.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_exti.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_flash.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_fsmc.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_i2c.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_iwdg.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_pwr.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rtc.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_sdio.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_spi.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_tim.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.o ../../src/stm/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_wwdg.o ../../src/stm/Libraries/STM32_USB-FS-Device_Driver/src/usb_core.o ../../src/stm/Libraries/STM32_USB-FS-Device_Driver/src/usb_init.o ../../src/stm/Libraries/STM32_USB-FS-Device_Driver/src/usb_int.o ../../src/stm/Libraries/STM32_USB-FS-Device_Driver/src/usb_mem.o ../../src/stm/Libraries/STM32_USB-FS-Device_Driver/src/usb_regs.o ../../src/crypt/aes/aes.o ../../src/crypt/sha1/sha1.o ../../src/crypt/sha1/hmac-sha1.o ../../src/hotp/hotp.o ../../src/keyboard/keyboard.o ../../src/keyboard/report_protocol.o ../../src/usb/usb_endp.o ../../src/usb/usb_bot.o ../../src/usb/usb_pwr.o ../../src/usb/usb_istr.o ../../src/pwd-safe/FlashStorage.o ../../src/pwd-safe/HandleAesStorageKey.o ../../src/pwd-safe/password_safe.o     --output nitrokey-pro-firmware.elf -nostartfiles -Wl,-Map=nitrokey-pro-firmware.map,--cref -lc  -lm -lc -lgcc  -lrdimon    -Tstm32.ld
/usr/lib/gcc/arm-none-eabi/8.2.0/../../../../arm-none-eabi/bin/ld: cannot find -lc
/usr/lib/gcc/arm-none-eabi/8.2.0/../../../../arm-none-eabi/bin/ld: cannot find -lm
/usr/lib/gcc/arm-none-eabi/8.2.0/../../../../arm-none-eabi/bin/ld: cannot find -lc
/usr/lib/gcc/arm-none-eabi/8.2.0/../../../../arm-none-eabi/bin/ld: cannot find -lrdimon
/usr/lib/gcc/arm-none-eabi/8.2.0/../../../../arm-none-eabi/bin/ld: cannot find -lg
/usr/lib/gcc/arm-none-eabi/8.2.0/../../../../arm-none-eabi/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status

I'm considering buying a Nitrokey but it's a requirement for me that I can build the firmware myself.

Update security

Hi,

I am looking for some information about the security of the update mechanism for nitrokey.

Here is one of the questions that come to mind after learning about the possibility to m do firmware updates:

What measures will prevent an aversary to flash a manipulated firmware to the nitrokey. Assuming an aversary has gained access to my system, I want nitrokey to prevent them from getting my privat keys and data. If the firmware can be manipulated, I don't see how this can be effectively prevented.

Nitrokey Pro firmware linker files ambiguously licensed

Hi,

At Purism we use the Nitrokey Pro as the basis for our own key called Librem Key. We're submitting the Librem Key for Respects Your Freedom certification. In discussions with the certification folks they note that there's some ambiguity regarding the headers in the files in the nitrokey-pro-firmware/build/gcc directory.

The files STM32_COMMON.ld & STM32_SEC_FLASH.ld have a header which says;

/*
Common part of the linker scripts for STR71x devices in FLASH mode
(that is, the FLASH is seen at 0)
Copyright RAISONANCE 2005
You can use, modify and distribute thisfile freely, but without any waranty.
*/

while STM32_128K_20K_FLASH.ld and stm32.ld have header that say;

/*
Linker script for STM32F10x
Copyright RAISONANCE 2007 (modified by Lanchon 1-Feb-2008)
You can use, copy and distribute this file freely, but without any waranty.
Configure memory sizes, end of stack and boot mode for your project here.
*/

The issues are;
-- The word "warranty" is spelled "waranty".
-- Not all the files explicitly grant the right to modify.
-- Not all the files explicitly grant the right to copy.

I'd like to propose a PR which I hope might fix this and be suitable for your needs. Alternatively, those files can be fixed by whomever wrote them if they still hold the copyright and have not contributed them into the public domain.

Support longer PINs

The firmware (and NK App) support max of 20 character long PINs while the OpenPGP Card supports 32 characters. The firmware and App should be changed to support entire 32 characters.

Authorization mechanism is vulnerable to CRC32 collisions

I have some doubts whether this is an actual problem since the temporary password and pin are clear text anyway on the hid level. An attacker with access to the stuff sent via hid can authorize anything anyway once he observed either pin or password.
However, since the protocol requires explicit "authorization" of some commands, I assume that that makes sense somehow. Here is how to circumvent it:

Authorization of commands via the (USER_)AUTHORIZE command requires the CRC of the command that is to be authorized and the temporary password.

Between the authorization command and the authorized command (e.g. GET_CODE), an attacker can execute any other command with a matching CRC without knowing the temporary password or pin. As far as I know CRC32 is not considered cryptographically secure and even reversible. It should be therefore be trivial to create collisions using the unused bytes in the payload.

I verified that GET_CODE works fine with arbitrary values in "unused" payload bytes.

Solutions: Add cryptographically secure hash or password to AUTHORIZE payload.

Question: I am pretty sure I am missing the point here. What is the reason for having temporary password and authorizations? It doesn't look like it is designed to provide security.

Question: Support EC operations

Do you support EC point multiplication: IE: I pass in an EC point, your system multiplies by the private key and replies? This is needed for custom protocols, like custom multisig, etc.

Firmware for a general purpose smart card reader

Recently my nitrokey pro's shell has cracked, with the hardware inside undamaged. I noticed with the openpgp card removed, the nitrokey pro even refused to be enumerated as a usb device, and on hsm branch there is a commit to Set USB serial to HSM smartcard's one ( 3bf8a94 ), which may mean a nitrokey pro running an hsm firmware cannot work without a smartcard hsm inserted in. Is there any branch to power the hardware as a general purpose smart card reader (e.g. enable it to read other smart cards, such as GSM's SIM) ?

redundent warnings during compile

Compiling master with

$ gcc --version
gcc (Debian 6.3.0-18) 6.3.0 20170516

Debian 9 Stable
Debian 4.9.51-1 (2017-09-28) x86_64 GNU/Linux

Will compile without error but there is a superfluous amount of warnings. Most of these warnings are very easy to fix. If I can find some time and there is interest I might do a code refactoring and clean up.

Coverity

It seems like coverity scans were disabled at some point. Is there a reason for this?

Leaking pins: memcpy != memset

memcpy (card_password, 0, sizeof (card_password));

I suspect that this is supposed to zero the card_password (memset?). It doesn't. This is undefined behavior. If you are lucky the compiler doesn't generate any code for this.

A quick regex search finds 10 of these just in report_protocol.c. I didn't look further.
Also, if this is used with a nonzero second argument the compiler will actually have to generate code for this afaik, so that might be better, or even worse, depending on the situation. Since it is a bit harder to search for, I didn't. Make sure to look for that as well.

The compiler issues a warning every time this pattern is used!

Fail to generate 4096 bit keys

Despite 4096 bit keys being said as supported, any try to generate them with GPG or GPG2 failed. The same identical setup with 2048 worked first time.

Random data sent just after connection disrupts communication

According to open-keychain/open-keychain#1936 (comment) Nitrokey Pro device is sending supposedly random data sequences just after it is connected through BulkIn endpoint, before IccPowerOn is sent to initialize the connection. It could in same cases disrupt the communication process rendering the device unusable (like in Open Keychain case).
To investigate what these bytes are and why are they sent.

The bytes are slightly changing every time, but some are also constant:
a78ae8aaf717cbbfecc7cb88a6f6910c56418514b6aaa0b8750555142bae39823210a22bfa3f73f9278bb74b2c95f65b134452ad236ea23ad0d75617ac843d29
a78ae88af6074b3f6cc7cb88a6f7910c56418514b2aaa0b8750555042aa639823210a26bfa3f73f9a78bb74bac95f65b136450ad236ea23ad0d75617ac863d39
a78ae88af707cbbb6cc5cb8826f7d10c56418514b2aaa0ba750515142ba639a23210a22bfa3f73f1a783b74b2c91f65b134452ad336ea23ad0d75217ac843c29
Someone else reported getting these bytes:
fa2e651a767541df360a8b2a1314857c890d51c16ade92891f57051846876584caca8202f4d705878e8e81cc4d36c76d650a155d2eb8fb2d74f30af7e48f86ad

build_aes_key reports WrongPassword after factory reset

(this issue is somewhat similar to Nitrokey/nitrokey-storage-firmware#80 but the symptoms are different and it only occurs on Pro devices)

When running build_aes_key after factory_reset on a Nitrokey Pro, I see a WrongPassword error being emitted (you may have to reset the card using gpg first).

int main()
{
	NK_set_debug(true);
	assert(NK_login_auto() == 1);
	assert(NK_factory_reset("12345678") == 0);
	sleep(10); // issue #80
	assert(NK_build_aes_key("12345678") == 0);
	return 0;
}
[Sun Jan 20 09:30:42 2019][DEBUG_L1]    Connection success: 1 ()
[Sun Jan 20 09:30:42 2019][DEBUG_L1]    Connection success: 0 ()
[Sun Jan 20 09:30:42 2019][DEBUG_L1]    Disconnection: handle already freed: 1 ()
[Sun Jan 20 09:30:42 2019][DEBUG]       -------------------
[Sun Jan 20 09:30:42 2019][DEBUG]       Outgoing HID packet:
[Sun Jan 20 09:30:42 2019][DEBUG]       Contents:
Command ID:     FACTORY_RESET
CRC:    ccd3b413
Payload:
 admin_password:        ***********

[Sun Jan 20 09:30:42 2019][DEBUG_L1]    => FACTORY_RESET
..........
[Sun Jan 20 09:30:43 2019][DEBUG]       Status busy, decreasing receiving_retry_counter counter: 4, current delay:200
[Sun Jan 20 09:30:43 2019][DEBUG_L1]    Busy retry: status 0, 200ms, counter 4, progress: 0
...........
[Sun Jan 20 09:30:46 2019][DEBUG]       Status busy, decreasing receiving_retry_counter counter: 3, current delay:300
[Sun Jan 20 09:30:46 2019][DEBUG_L1]    Busy retry: status 0, 300ms, counter 3, progress: 0
..
[Sun Jan 20 09:30:46 2019][DEBUG_L1]    <= FACTORY_RESET 0 0
[Sun Jan 20 09:30:46 2019][DEBUG]       Incoming HID packet:
[Sun Jan 20 09:30:46 2019][DEBUG]       Device status:  0 OK
Command ID:     FACTORY_RESET hex: 13
Last command CRC:       ccd3b413
Last command status:    0 STICK10::COMMAND_STATUS::OK
CRC:    32405835
Payload:
Empty Payload.
[Sun Jan 20 09:30:46 2019][DEBUG_L1]    Packet received with receiving_retry_counter count: 2
[Sun Jan 20 09:30:49 2019][DEBUG]       -------------------
[Sun Jan 20 09:30:49 2019][DEBUG]       Outgoing HID packet:
[Sun Jan 20 09:30:49 2019][DEBUG]       Contents:
Command ID:     NEW_AES_KEY
CRC:    52a99af0
Payload:
 admin_password:        ***********

[Sun Jan 20 09:30:49 2019][DEBUG_L1]    => NEW_AES_KEY
..........
[Sun Jan 20 09:30:50 2019][DEBUG]       Status busy, decreasing receiving_retry_counter counter: 4, current delay:200
[Sun Jan 20 09:30:50 2019][DEBUG_L1]    Busy retry: status 0, 200ms, counter 4, progress: 0
.....
[Sun Jan 20 09:30:51 2019][DEBUG_L1]    <= NEW_AES_KEY 0 0
[Sun Jan 20 09:30:51 2019][DEBUG]       Incoming HID packet:
[Sun Jan 20 09:30:51 2019][DEBUG]       Device status:  0 OK
Command ID:     NEW_AES_KEY hex: 6b
Last command CRC:       52a99af0
Last command status:    4 STICK10::COMMAND_STATUS::WRONG_PASSWORD
CRC:    2b5d073e
Payload:
Empty Payload.
[Sun Jan 20 09:30:51 2019][DEBUG_L1]    Throw: CommandFailedException 4
[Sun Jan 20 09:30:51 2019][DEBUG]       CommandFailedException, status: 4
test: test.cpp:11: int main(): Assertion `NK_build_aes_key("12345678") == 0' failed.
Aborted

The problem can seemingly be mitigated by inserting certain commands before the build_aes_key step. E.g.,

int main()
{
	NK_set_debug(true);
	assert(NK_login_auto() == 1);
	assert(NK_factory_reset("12345678") == 0);
	sleep(10);
	assert(NK_get_user_retry_count() == 3);
	assert(NK_build_aes_key("12345678") == 0);
	return 0;
}

Response with busy status has wrong CRC

Responses with status BUSY have the crc field set to 00000000
Maybe there are others too. I haven't seen an ERROR or RECEIVED_REPORT status yet.
What does the RECEIVED_REPORT status mean anyway?

PWS auto-lock after specified time

Device could lock itself (close PWS access) after specified time passes.
Such function is present as well in software password managers.

Remove Landscape code quality analysis

Landscape seems like an unnecessary annoyance (it takes longer than travis sometimes). It checks ~30 lines of code in two shell scripts. There isn't even any python code to analyze, which seems to be the point of Landscape.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.