Recent blog entries for jas

Laptop indecision

I wrote last month about buying a new laptop and I still haven’t made a decision. One reason for this is because Dell doesn’t seem to be shipping the E7250. Some online shops claim to be able to deliver it, but aren’t clear on what configuration it has – and I really don’t want to end up with Dell Wifi.

Another issue has been the graphic issues with the Broadwell GPU (see the comment section of my last post). It seems unlikely that this will be fixed in time for Debian Jessie. I really want a stable OS on this machine, as it will be a work-horse and not a toy machine. I haven’t made up my mind whether the graphics issue is a deal-breaker for me.

Meanwhile, a couple of more sub-1.5kg (sub-3.3lbs) Broadwell i7’s have hit the market. Some of these models were suggested in comments to my last post. I have decided that the 5500U CPU would also be acceptable to me, because some newer laptops doesn’t come with the 5600U. The difference is that the 5500U is a bit slower (say 5-10%) and lacks vPro, which I have no need for and mostly consider a security risk. I’m not aware of any other feature differences.

Since the last round, I have tightened my weight requirement to be sub-1.4kg (sub-3lbs), which excludes some recently introduced models, and actually excludes most of the models I looked at before (X250, X1 Carbon, HP 1040/810). Since I’m leaning towards the E7250, with the X250 as a “reliable” fallback option, I wanted to cut down on the number of further models to consider. Weigth is a simple distinguisher. The 1.4-1.5kg (3-3.3lbs) models I am aware that of that is excluded are the Asus Zenbook UX303LN, the HP Spectre X360, and the Acer TravelMate P645.

The Acer Aspire S7-393 (1.3kg) and Toshiba Kira-107 (1.26kg) would have been options if they had RJ45 ports. They may be interesting to consider for others.

The new models I am aware of are below. I’m including the E7250 and X250 for comparison, since they are my preferred choices from the first round. A column for maximum RAM is added too, since this may be a deciding factor for me. Higher weigth is with touch screens.

Toshiba Z30-B 1.2-1.34kg 16GB 13.3″ 1920×1080
Fujitsu Lifebook S935 1.24-1.36kg 12GB 13.3″ 1920×1080
HP EliteBook 820 G2 1.34-1.52kg 16GB 12.5″ 1920×1080
Dell Latitude E7250 1.25kg 8/16GB? 12.5″ 1366×768
Lenovo X250 1.42kg 8GB 12.5″ 1366×768

It appears unclear whether the E7250 is memory upgradeable, some sites say max 8GB some say max 16GB. The X250 and 820 has DisplayPort, the S935 and Z30-B has HDMI, and the E7250 has both DisplayPort/HDMI. The E7250 does not have VGA which the rest has. All of them have 3 USB 3.0 ports except for X250 that only has 2 ports. The E7250 and 820 claims NFC support, but Debian support is not given. Interestingly, all of them have a smartcard reader. All support SDXC memory cards.

The S935 has an interesting modular bay which can actually fit a CD reader or an additional battery. There is a detailed QuickSpec PDF for the HP 820 G2, haven’t found similar detailed information for the other models. It mentions support for Ubuntu, which is nice.

Comparing these laptops is really just academic until I have decided what to think about the Broadwell GPU issues. It may be that I’ll go back to a fourth-gen i7 laptop, and then I’ll probably pick a cheap reliable machine such as the X240.

Syndicated 2015-03-24 22:11:30 from Simon Josefsson's blog

EdDSA and Ed25519 goes to IETF

After meeting Niels Möller at FOSDEM and learning about his Ed25519 implementation in GNU Nettle, I started working on a simple-to-implement description of Ed25519. The goal is to help implementers of various IETF (and non-IETF) protocols add support for Ed25519. As many are aware, OpenSSH and GnuPG has support for Ed25519 in recent versions, and OpenBSD since the v5.5 May 2014 release are signed with Ed25519. The paper describing EdDSA and Ed25519 is not aimed towards implementers, and does not include test vectors. I felt there were room for improvement to get wider and more accepted adoption.

Our work is published in the IETF as draft-josefsson-eddsa-ed25519 and we are soliciting feedback from implementers and others. Please help us iron out the mistakes in the document, and point out what is missing. For example, what could be done to help implementers avoid side-channel leakage? I don’t think the draft is the place for optimized and side-channel free implementations, and it is also not the place for a comprehensive tutorial on side-channel free programming. But maybe there is a middle ground where we can say something more than what we can do today. Ideas welcome!

Syndicated 2015-03-04 14:30:16 from Simon Josefsson's blog

Laptop Buying Advice?

My current Lenovo X201 laptop has been with me for over four years. I’ve been looking at new laptop models over the years thinking that I should upgrade. Every time, after checking performance numbers, I’ve always reached the conclusion that it is not worth it. The most performant Intel Broadwell processor is the the Core i7 5600U and it is only about 1.5 times the performance of my current Intel Core i7 620M. Meanwhile disk performance has increased more rapidly, but changing the disk on a laptop is usually simple. Two years ago I upgraded to the Samsung 840 Pro 256GB disk, and this year I swapped that for the Samsung 850 Pro 1TB, and both have been good investments.

Recently my laptop usage patterns have changed slightly, and instead of carrying one laptop around, I have decided to aim for multiple semi-permanent laptops at different locations, coupled with a mobile device that right now is just my phone. The X201 will remain one of my normal work machines.

What remains is to decide on a new laptop, and there begins the fun. My requirements are relatively easy to summarize. The laptop will run a GNU/Linux distribution like Debian, so it has to work well with it. I’ve decided that my preferred CPU is the Intel Core i7 5600U. The screen size, keyboard and mouse is mostly irrelevant as I never work longer periods of time directly on the laptop. Even though the laptop will be semi-permanent, I know there will be times when I take it with me. Thus it has to be as lightweight as possible. If there would be significant advantages in going with a heavier laptop, I might reconsider this, but as far as I can see the only advantage with a heavier machine is bigger/better screen, keyboard (all of which I find irrelevant) and maximum memory capacity (which I would find useful, but not enough of an argument for me). The only sub-1.5kg laptops with the 5600U CPU on the market right now appears to be:

Lenovo X250 1.42kg 12.5″ 1366×768
Lenovo X1 Carbon (3rd gen) 1.44kg 14″ 2560×1440
Dell Latitude E7250 1.34kg 12.5″ 1366×768
Dell XPS 13 1.26kg 13.3″ 3200×1800
HP EliteBook Folio 1040 G2 1.49kg 14″ 1920×1080
HP EliteBook Revolve 810 G3 1.4kg 11.6″ 1366×768

I find it interesting that Lenovo, Dell and HP each have two models that meets my 5600U/sub-1.5kg criteria. Regarding screen, possibly there exists models with other screen resolutions. The XPS 13, HP 810 and X1 models I looked had touch screens, the others did not. As screen is not important to me, I didn’t evaluate this further.

I think all of them would suffice, and there are only subtle differences. All except the XPS 13 can be connected to peripherals using one cable, which I find convenient to avoid a cable mess. All of them have DisplayPort, but HP uses DisplayPort Standard and the rest uses miniDP. The E7250 and X1 have HDMI output. The X250 boosts a 15-pin VGA connector, none of the others have it — I’m not sure if that is a advantage or disadvantage these days. All of them have 2 USB v3.0 ports except the E7250 which has 3 ports. The HP 1040, XPS 13 and X1 Carbon do not have RJ45 Ethernet connectors, which is a significant disadvantage to me. Ironically, only the smallest one of these, the HP 810, can be memory upgraded to 12GB with the others being stuck at 8GB. HP and the E7250 supports NFC, although Debian support is not certain. The E7250 and X250 have a smartcard reader, and again, Debian support is not certain. The X1, X250 and 810 have a 3G/4G card.

Right now, I’m leaning towards rejecting the XPS 13, X1 and HP 1040 because of lack of RJ45 ethernet port. That leaves me with the E7250, X250 and the 810. Of these, the E7250 seems like the winner: lightest, 1 extra USB port, HDMI, NFC, SmartCard-reader. However, it has no 3G/4G-card and no memory upgrade options. Looking for compatibility problems, it seems you have to be careful to not end up with the “Dell Wireless” card and the E7250 appears to come in a docking and non-docking variant but I’m not sure what that means.

Are there other models I should consider? Other thoughts?

Syndicated 2015-02-23 22:49:21 from Simon Josefsson's blog

Replicant 4.2 0003 on I9300

The Replicant project released version 4.2 0003 recently. I have been using Replicant on a Samsung SIII (I9300) for around 14 months now. Since I have blogged about issues with NFC and Wifi earlier, I wanted to give a status update after upgrading to 0003. I’m happy to report that my NFC issue has been resolved in 0003 (the way I suggested; reverting the patch). My issues with Wifi has been improved in 0003, with my merge request being accepted. What follows below is a standalone explanation of what works and what doesn’t, as a superset of similar things discussed in my earlier blog posts.

What works out of the box: Audio, Telephony, SMS, Data (GSM/3G), Back Camera, NFC. 2D Graphics is somewhat slow compared to stock ROM, but I’m using it daily and can live with that so it isn’t too onerus. Stability is fine, similar to other Android device I’m used to. Video playback does not work (due to non-free media decoders?), which is not a serious problem for me but still likely the biggest outstanding issue except for freedom concerns. 3D graphics apparently doesn’t work, and I believe it is what prevents Firefox from working properly (it crashes). I’m having one annoying but strange problem with telephony: when calling one person I get scrambled audio around 75% of the time. I can still hear what the other person is saying, but can barely make anything out of it. This only happens over 3G, so my workaround when calling that person is to switch to 2G before and switch back after. I talk with plenty other people, and have never had this problem with anyone else, and it has never happened when she talks with anyone else but me. If anyone has suggestion on how to debug this, I’m all ears.

Important apps to get through daily life for me includes K9Mail (email), DAVDroid (for ownCloud CalDav/CardDAV), CalDav Sync Adapter (for Google Calendars), Conversations (XMPP/Jabber chat), FDroid (for apps), ownCloud (auto-uploading my photos), SMS Backup+, Xabber (different XMPP/Jabber accounts), Yubico Authenticator, MuPDF and oandbackup. A couple of other apps I find useful are AdAway (remove web ads), AndStatus, Calendar Widget, NewsBlur and ownCloud News Reader (RSS readers), Tinfoil for Facebook, Twidere (I find its UI somewhat nicer than AndStatus’s), and c:geo.

A number of things requires non-free components. As I discussed in my initial writeup from when I started using Replicant I don’t like this, but I’m accepting it temporarily. The list of issues that can be fixed by adding non-free components include the front camera, Bluetooth, GPS, and Wifi. After flashing the Replicant ROM image that I built (using the fine build instructions), I’m using the following script to add the missing non-free files from Cyanogenmod.

# Download Cyanogenmod 10.1.3 (Android 4.2-based) binaries:
# wget http://download.cyanogenmod.org/get/jenkins/42508/cm-10.1.3-i9300.zip
# echo "073a464a9f5129c490502c77374495c38a25ba790c10e27f51b43845baeba6bf  cm-10.1.3-i9300.zip" | sha256sum -c 
# unzip cm-10.1.3-i9300.zip

adb root
adb remount
adb shell mkdir /system/vendor/firmware
adb shell chmod 755 /system/vendor/firmware

# Front Camera
adb push cm-10.1.3-i9300/system/vendor/firmware/fimc_is_fw.bin /system/vendor/firmware/fimc_is_fw.bin
adb push cm-10.1.3-i9300/system/vendor/firmware/setfile.bin /system/vendor/firmware/setfile.bin
adb shell chmod 644 /system/vendor/firmware/fimc_is_fw.bin /system/vendor/firmware/setfile.bin

# Bluetooth
adb push cm-10.1.3-i9300/system/bin/bcm4334.hcd /system/vendor/firmware/
adb shell chmod 644 /system/vendor/firmware/bcm4334*.hcd

# GPS
adb push cm-10.1.3-i9300/system/bin/gpsd /system/bin/gpsd
adb shell chmod 755 /system/bin/gpsd
adb push cm-10.1.3-i9300/system/lib/hw/gps.exynos4.so /system/lib/hw/gps.exynos4.so
adb push cm-10.1.3-i9300/system/lib/libsecril-client.so /system/lib/libsecril-client.so
adb shell chmod 644 /system/lib/hw/gps.exynos4.so /system/lib/libsecril-client.so

# Wifi
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_apsta.bin_b1 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_apsta.bin_b2 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_mfg.bin_b0 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_mfg.bin_b1 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_mfg.bin_b2 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_p2p.bin_b0 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_p2p.bin_b1 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_p2p.bin_b2 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_sta.bin_b0 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_sta.bin_b1 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_sta.bin_b2 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_mfg.txt /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_mfg.txt_murata /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_mfg.txt_murata_b2 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_mfg.txt_semcosh /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_net.txt /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_net.txt_murata /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_net.txt_murata_b2 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_net.txt_semcosh /system/vendor/firmware/

I hope this helps others switch to a better phone environment!

Syndicated 2015-01-13 23:17:28 from Simon Josefsson's blog

OpenPGP Smartcards and GNOME

The combination of GnuPG and a OpenPGP smartcard (such as the YubiKey NEO) has been implemented and working well for a around a decade. I recall starting to use it when I received a FSFE Fellowship card long time ago. Sadly there has been some regressions when using them under GNOME recently. I reinstalled my laptop with Debian Jessie (beta2) recently, and now took the time to work through the issue and write down a workaround.

To work with GnuPG and smartcards you install GnuPG agent, scdaemon, pscsd and pcsc-tools. On Debian you can do it like this:

apt-get install gnupg-agent scdaemon pcscd pcsc-tools

Use the pcsc_scan command line tool to make sure pcscd recognize the smartcard before continuing, if that doesn’t recognize the smartcard nothing beyond this point will work. The next step is to make sure you have the following line in ~/.gnupg/gpg.conf:

use-agent

Logging out and into GNOME should start gpg-agent for you, through the /etc/X11/Xsession.d/90gpg-agent script. In theory, this should be all that is required. However, when you start a terminal and attempt to use the smartcard through GnuPG you would get an error like this:

jas@latte:~$ gpg --card-status
gpg: selecting openpgp failed: unknown command
gpg: OpenPGP card not available: general error
jas@latte:~$

The reason is that the GNOME Keyring hijacks the GnuPG agent’s environment variables and effectively replaces gpg-agent with gnome-keyring-daemon which does not support smartcard commands (Debian bug #773304). GnuPG uses the environment variable GPG_AGENT_INFO to find the location of the agent socket, and when the GNOME Keyring is active it will typically look like this:

jas@latte:~$ echo $GPG_AGENT_INFO 
/run/user/1000/keyring/gpg:0:1
jas@latte:~$ 

If you use GnuPG with a smartcard, I recommend to disable GNOME Keyring’s GnuPG and SSH agent emulation code. This used to be easy to achieve in older GNOME releases (e.g., the one included in Debian Wheezy), through the gnome-session-properties GUI. Sadly there is no longer any GUI for disabling this functionality (Debian bug #760102). The GNOME Keyring GnuPG/SSH agent replacement functionality is invoked through the XDG autostart mechanism, and the documented way to disable system-wide services for a normal user account is to invoke the following commands.

jas@latte:~$ mkdir ~/.config/autostart
jas@latte:~$ cp /etc/xdg/autostart/gnome-keyring-gpg.desktop ~/.config/autostart/
jas@latte:~$ echo 'Hidden=true' >> ~/.config/autostart/gnome-keyring-gpg.desktop 
jas@latte:~$ cp /etc/xdg/autostart/gnome-keyring-ssh.desktop ~/.config/autostart/
jas@latte:~$ echo 'Hidden=true' >> ~/.config/autostart/gnome-keyring-ssh.desktop 
jas@latte:~$ 

You now need to logout and login again. When you start a terminal, you can look at the GPG_AGENT_INFO environment variable again and everything should be working again.

jas@latte:~$ echo $GPG_AGENT_INFO 
/tmp/gpg-dqR4L7/S.gpg-agent:1890:1
jas@latte:~$ echo $SSH_AUTH_SOCK 
/tmp/gpg-54VfLs/S.gpg-agent.ssh
jas@latte:~$ gpg --card-status
Application ID ...: D2760001240102000060000000420000
...
jas@latte:~$ ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFP+UOTZJ+OXydpmbKmdGOVoJJz8se7lMs139T+TNLryk3EEWF+GqbB4VgzxzrGjwAMSjeQkAMb7Sbn+VpbJf1JDPFBHoYJQmg6CX4kFRaGZT6DHbYjgia59WkdkEYTtB7KPkbFWleo/RZT2u3f8eTedrP7dhSX0azN0lDuu/wBrwedzSV+AiPr10rQaCTp1V8sKbhz5ryOXHQW0Gcps6JraRzMW+ooKFX3lPq0pZa7qL9F6sE4sDFvtOdbRJoZS1b88aZrENGx8KSrcMzARq9UBn1plsEG4/3BRv/BgHHaF+d97by52R0VVyIXpLlkdp1Uk4D9cQptgaH4UAyI1vr cardno:006000000042
jas@latte:~$ 

That’s it. Resolving this properly involves 1) adding smartcard code to the GNOME Keyring, 2) disabling the GnuPG/SSH replacement code in GNOME Keyring completely, 3) reorder the startup so that gpg-agent supersedes gnome-keyring-daemon instead of vice versa, so that people who installed the gpg-agent really gets it instead of the GNOME default, or 4) something else. I don’t have a strong opinion on how to solve this, but 3) sounds like a simple way forward.

Syndicated 2015-01-02 20:46:40 from Simon Josefsson's blog

Dice Random Numbers

Generating data with entropy, or random number generation (RNG), is a well-known difficult problem. Many crypto algorithms and protocols assumes random data is available. There are many implementations out there, including /dev/random in the BSD and Linux kernels and API calls in crypto libraries such as GnuTLS or OpenSSL. How they work can be understood by reading the source code. The quality of the data depends on actual hardware and what entropy sources were available — the RNG implementation itself is deterministic, it merely convert data with supposed entropy from a set of data sources and then generate an output stream.

In some situations, like on virtualized environments or on small embedded systems, it is hard to find sources of sufficient quantity. Rarely are there any lower-bound estimates on how much entropy there is in the data you get. You can improve the RNG issue by using a separate hardware RNG, but there is deployment complexity in that, and from a theoretical point of view, the problem of trusting that you get good random data merely moved from one system to another. (There is more to say about hardware RNGs, I’ll save that for another day.)

For some purposes, the available solutions does not inspire enough confidence in me because of the high complexity. Complexity is often the enemy of security. In crypto discussions I have said, only half-jokingly, that about the only RNG process that I would trust is one that I can explain in simple words and implement myself with the help of pen and paper. Normally I use the example of rolling a normal six-sided dice (a D6) several times. I have been thinking about this process in more detail lately, and felt it was time to write it down, regardless of how silly it may seem.

A dice with six sides produces a random number between 1 and 6. It is relatively straight forward to intuitively convinced yourself that it is not clearly biased: inspect that it looks symmetric and do some trial rolls. By repeatedly rolling the dice, you can generate how much data you need, time permitting.

I do not understand enough thermodynamics physics to know how to estimate the amount of entropy of a physical process, so I need to resort to intuitive arguments. It would be easy to just assume that a dice produces 3 bits of entropy, because 2^3=6 which matches the number of possible outcomes. At least I find it easy to convince myself that 3 bits is the upper bound. I suspect that most dice have some form of defect, though, which leads to a very small bias that could be found with a large number of rolls. Thus I would propose that the amount of entropy of most D6’s are slightly below 3 bits on average. Further, to establish a lower bound, and intuitively, it seems easy to believe that if the entropy of particular D6 would be closer to 2 bits than to 3 bits, this would be noticeable fairly quickly by trial rolls. That assumes the dice does not have complex logic and machinery in it that would hide the patterns. With the tinfoil hat on, consider a dice with a power source and mechanics in it that allowed it to decide which number it would land on: it could generate seamingly-looking random pattern that still contained 0 bits of entropy. For example, suppose a D6 is built to produce the pattern 4, 1, 4, 2, 1, 3, 5, 6, 2, 3, 1, 3, 6, 3, 5, 6, 4, … this would mean it produces 0 bits of entropy (compare the numbers with the decimals of sqrt(2)). Other factors may also influence the amount of entropy in the output, consider if you roll the dice by just dropping straight down from 1cm/1inch above the table. With this discussion as background, and for simplicity, going forward, I will assume that my D6 produces 3 bits of entropy on every roll.

We need to figure out how many times we need to roll it. I usually find myself needing a 128-bit random number (16 bytes). Crypto algorithms and protocols typically use power-of-2 data sizes. 64 bits of entropy results in brute-force attacks requiring about 2^64 tests, and for many operations, this is feasible with today’s computing power. Performing 2^128 operations does not seem possible with today’s technology. To produce 128 bits of entropy using a D6 that produces 3 bits of entropy per roll, you need to perform ceil(128/3)=43 rolls.

We also need to design an algorithm to convert the D6 output into the resulting 128-bit random number. While it would be nice from a theoretical point of view to let each and every bit of the D6 output influence each and every bit of the 128-bit random number, this becomes difficult to do with pen and paper. For simplicity, my process will be to write the binary representation of the D6 output on paper in 3-bit chunks and then read it up as 8-bit chunks. After 8 rolls, there are 24 bits available, which can be read up as 3 distinct 8-bit numbers. So let’s do this for the D6 outputs of 3, 6, 1, 1, 2, 5, 4, 1:

3   6   1   1   2   5   4   1
011 111 001 001 010 101 010 001
01111100 10010101 01010001
124 0x7C 149 0x95 81 0x51

After 8 rolls, we have generated the 3 byte hex string “7C9551″. I repeat the process 5 more times, concatenating the strings, resulting in a hex string with 15 bytes of data. To get the last byte, I only need to roll the D6 three more times, where the two high bits of the last roll is used and the lowest bit is discarded. Let’s say the last D6 outputs were 4, 2, 3, this would result in:

4   2   3
100 010 011
10001001
137 0x89

So the 16 bytes of random data is “7C9551..89″ with “..” replaced by the 5 pieces of 3-byte chunks of data.

So what’s the next step? Depends on what you want to use the random data for. For some purposes, such as generating a high-quality 128-bit AES key, I would be done. The key is right there. To generate a high-quality ECC private key, you need to generate somewhat more randomness (matching the ECC curve size) and do a couple of EC operations. To generate a high-quality RSA private key, unfortunately you will need much more randomness, at the point where it makes more sense to implement a PRNG seeded with a strong 128-bit seed generated using this process. The latter approach is the general solution: generate 128 bits of data using the dice approach, and then seed a CSPRNG of your choice to get large number of data quickly. These steps are somewhat technical, and you lose the pen-and-paper properties, but code to implement these parts are easier to verify compared to verifying that you get good quality entropy out of your RNG implementation.

flattr this!

Syndicated 2014-11-11 23:36:02 from Simon Josefsson's blog

The Case for Short OpenPGP Key Validity Periods

After I moved to a new OpenPGP key (see key transition statement) I have received comments about the short life length of my new key. When I created the key (see my GnuPG setup) I set it to expire after 100 days. Some people assumed that I would have to create a new key then, and therefore wondered what value there is to sign a key that will expire in two months. It doesn’t work like that, and below I will explain how OpenPGP key expiration works; how to extend the expiration time of your key; and argue why having a relatively short validity period can be a good thing.

The OpenPGP message format has a sub-packet called the Key Expiration Time, quoting the RFC:

5.2.3.6. Key Expiration Time

   (4-octet time field)

   The validity period of the key.  This is the number of seconds after
   the key creation time that the key expires.  If this is not present
   or has a value of zero, the key never expires.  This is found only on
   a self-signature.

You can print the sub-packets in your OpenPGP key with gpg --list-packets. See below an output for my key, and notice the “created 1403464490″ (which is Unix time for 2014-06-22 21:14:50) and the “subpkt 9 len 4 (key expires after 100d0h0m)” which adds up to an expiration on 2014-09-26. Don’t confuse the creation time of the key (“created 1403464321″) with when the signature was created (“created 1403464490″).

jas@latte:~$ gpg --export 54265e8c | gpg --list-packets |head -20
:public key packet:
	version 4, algo 1, created 1403464321, expires 0
	pkey[0]: [3744 bits]
	pkey[1]: [17 bits]
:user ID packet: "Simon Josefsson "
:signature packet: algo 1, keyid 0664A76954265E8C
	version 4, created 1403464490, md5len 0, sigclass 0x13
	digest algo 10, begin of digest be 8e
	hashed subpkt 27 len 1 (key flags: 03)
	hashed subpkt 9 len 4 (key expires after 100d0h0m)
	hashed subpkt 11 len 7 (pref-sym-algos: 9 8 7 13 12 11 10)
	hashed subpkt 21 len 4 (pref-hash-algos: 10 9 8 11)
	hashed subpkt 30 len 1 (features: 01)
	hashed subpkt 23 len 1 (key server preferences: 80)
	hashed subpkt 2 len 4 (sig created 2014-06-22)
	hashed subpkt 25 len 1 (primary user ID)
	subpkt 16 len 8 (issuer key ID 0664A76954265E8C)
	data: [3743 bits]
:signature packet: algo 1, keyid EDA21E94B565716F
	version 4, created 1403466403, md5len 0, sigclass 0x10
jas@latte:~$ 

So the key will simply stop being valid after that time? No. It is possible to update the key expiration time value, re-sign the key, and distribute the key to people you communicate with directly or indirectly to OpenPGP keyservers. Since that date is a couple of weeks away, now felt like the perfect opportunity to go through the exercise of taking out my offline master key and boot from a Debian LiveCD and extend its expiry time. See my earlier writeup for LiveCD and USB stick conventions.

user@debian:~$ export GNUPGHOME=/media/FA21-AE97/gnupghome
user@debian:~$ gpg --edit-key 54265e8c
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  3744R/54265E8C  created: 2014-06-22  expires: 2014-09-30  usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/32F8119D  created: 2014-06-22  expires: 2014-09-30  usage: S   
sub  2048R/78ECD86B  created: 2014-06-22  expires: 2014-09-30  usage: E   
sub  2048R/36BA8F9B  created: 2014-06-22  expires: 2014-09-30  usage: A   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  Simon Josefsson 

gpg> expire
Changing expiration time for the primary key.
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 150
Key expires at Fri 23 Jan 2015 02:47:48 PM UTC
Is this correct? (y/N) y

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 54265E8C, created 2014-06-22


pub  3744R/54265E8C  created: 2014-06-22  expires: 2015-01-23  usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/32F8119D  created: 2014-06-22  expires: 2014-09-30  usage: S   
sub  2048R/78ECD86B  created: 2014-06-22  expires: 2014-09-30  usage: E   
sub  2048R/36BA8F9B  created: 2014-06-22  expires: 2014-09-30  usage: A   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  Simon Josefsson 

gpg> key 1

pub  3744R/54265E8C  created: 2014-06-22  expires: 2015-01-23  usage: SC  
                     trust: ultimate      validity: ultimate
sub* 2048R/32F8119D  created: 2014-06-22  expires: 2014-09-30  usage: S   
sub  2048R/78ECD86B  created: 2014-06-22  expires: 2014-09-30  usage: E   
sub  2048R/36BA8F9B  created: 2014-06-22  expires: 2014-09-30  usage: A   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  Simon Josefsson 

gpg> expire
Changing expiration time for a subkey.
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 150
Key expires at Fri 23 Jan 2015 02:48:05 PM UTC
Is this correct? (y/N) y

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 54265E8C, created 2014-06-22


pub  3744R/54265E8C  created: 2014-06-22  expires: 2015-01-23  usage: SC  
                     trust: ultimate      validity: ultimate
sub* 2048R/32F8119D  created: 2014-06-22  expires: 2015-01-23  usage: S   
sub  2048R/78ECD86B  created: 2014-06-22  expires: 2014-09-30  usage: E   
sub  2048R/36BA8F9B  created: 2014-06-22  expires: 2014-09-30  usage: A   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  Simon Josefsson 

gpg> key 2

pub  3744R/54265E8C  created: 2014-06-22  expires: 2015-01-23  usage: SC  
                     trust: ultimate      validity: ultimate
sub* 2048R/32F8119D  created: 2014-06-22  expires: 2015-01-23  usage: S   
sub* 2048R/78ECD86B  created: 2014-06-22  expires: 2014-09-30  usage: E   
sub  2048R/36BA8F9B  created: 2014-06-22  expires: 2014-09-30  usage: A   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  Simon Josefsson 

gpg> key 1

pub  3744R/54265E8C  created: 2014-06-22  expires: 2015-01-23  usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/32F8119D  created: 2014-06-22  expires: 2015-01-23  usage: S   
sub* 2048R/78ECD86B  created: 2014-06-22  expires: 2014-09-30  usage: E   
sub  2048R/36BA8F9B  created: 2014-06-22  expires: 2014-09-30  usage: A   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  Simon Josefsson 

gpg> expire
Changing expiration time for a subkey.
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 150
Key expires at Fri 23 Jan 2015 02:48:14 PM UTC
Is this correct? (y/N) y

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 54265E8C, created 2014-06-22


pub  3744R/54265E8C  created: 2014-06-22  expires: 2015-01-23  usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/32F8119D  created: 2014-06-22  expires: 2015-01-23  usage: S   
sub* 2048R/78ECD86B  created: 2014-06-22  expires: 2015-01-23  usage: E   
sub  2048R/36BA8F9B  created: 2014-06-22  expires: 2014-09-30  usage: A   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  Simon Josefsson 

gpg> key 3

pub  3744R/54265E8C  created: 2014-06-22  expires: 2015-01-23  usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/32F8119D  created: 2014-06-22  expires: 2015-01-23  usage: S   
sub* 2048R/78ECD86B  created: 2014-06-22  expires: 2015-01-23  usage: E   
sub* 2048R/36BA8F9B  created: 2014-06-22  expires: 2014-09-30  usage: A   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  Simon Josefsson 

gpg> key 2

pub  3744R/54265E8C  created: 2014-06-22  expires: 2015-01-23  usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/32F8119D  created: 2014-06-22  expires: 2015-01-23  usage: S   
sub  2048R/78ECD86B  created: 2014-06-22  expires: 2015-01-23  usage: E   
sub* 2048R/36BA8F9B  created: 2014-06-22  expires: 2014-09-30  usage: A   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  Simon Josefsson 

gpg> expire
Changing expiration time for a subkey.
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 150
Key expires at Fri 23 Jan 2015 02:48:23 PM UTC
Is this correct? (y/N) y

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 54265E8C, created 2014-06-22


pub  3744R/54265E8C  created: 2014-06-22  expires: 2015-01-23  usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/32F8119D  created: 2014-06-22  expires: 2015-01-23  usage: S   
sub  2048R/78ECD86B  created: 2014-06-22  expires: 2015-01-23  usage: E   
sub* 2048R/36BA8F9B  created: 2014-06-22  expires: 2015-01-23  usage: A   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  Simon Josefsson 

gpg> save
user@debian:~$ gpg -a --export 54265e8c > /media/KINGSTON/updated-key.txt
user@debian:~$ 

I remove the “transport” USB stick from the “offline” computer, and back on my laptop I can inspect the new updated key. Let’s use the same command as before. The key creation time is the same (“created 1403464321″), of course, but the signature packet has a new time (“created 1409064478″) since it was signed now. Notice “created 1409064478″ and “subpkt 9 len 4 (key expires after 214d19h35m)”. The expiration time is computed based on when the key was generated, not when the signature packet was generated. You may want to double-check the pref-sym-algos, pref-hash-algos and other sub-packets so that you don’t accidentally change anything else. (Btw, re-signing your key is also how you would modify those preferences over time.)

jas@latte:~$ cat /media/KINGSTON/updated-key.txt |gpg --list-packets | head -20
:public key packet:
	version 4, algo 1, created 1403464321, expires 0
	pkey[0]: [3744 bits]
	pkey[1]: [17 bits]
:user ID packet: "Simon Josefsson "
:signature packet: algo 1, keyid 0664A76954265E8C
	version 4, created 1409064478, md5len 0, sigclass 0x13
	digest algo 10, begin of digest 5c b2
	hashed subpkt 27 len 1 (key flags: 03)
	hashed subpkt 11 len 7 (pref-sym-algos: 9 8 7 13 12 11 10)
	hashed subpkt 21 len 4 (pref-hash-algos: 10 9 8 11)
	hashed subpkt 30 len 1 (features: 01)
	hashed subpkt 23 len 1 (key server preferences: 80)
	hashed subpkt 25 len 1 (primary user ID)
	hashed subpkt 2 len 4 (sig created 2014-08-26)
	hashed subpkt 9 len 4 (key expires after 214d19h35m)
	subpkt 16 len 8 (issuer key ID 0664A76954265E8C)
	data: [3744 bits]
:user ID packet: "Simon Josefsson "
:signature packet: algo 1, keyid 0664A76954265E8C
jas@latte:~$ 

Being happy with the new key, I import it and send it to key servers out there.

jas@latte:~$ gpg --import /media/KINGSTON/updated-key.txt 
gpg: key 54265E8C: "Simon Josefsson " 5 new signatures
gpg: Total number processed: 1
gpg:         new signatures: 5
jas@latte:~$ gpg --send-keys 54265e8c
gpg: sending key 54265E8C to hkp server keys.gnupg.net
jas@latte:~$ gpg --keyserver keyring.debian.org  --send-keys 54265e8c
gpg: sending key 54265E8C to hkp server keyring.debian.org
jas@latte:~$ 

Finally: why go through this hassle, rather than set the key to expire in 50 years? Some reasons for this are:

  1. I don’t trust myselt to keep track of a private key (or revocation cert) for 50 years.
  2. I want people to notice my revocation certificate as quickly as possible.
  3. I want people to notice other changes to my key (e.g., cipher preferences) as quickly as possible.

Let’s look into the first reason a bit more. What would happen if I lose both the master key and the revocation cert, for a key that’s valid 50 years? I would start from scratch and create a new key that I upload to keyservers. Then there would be two keys out there that are valid and identify me, and both will have a set of signatures on it. None of them will be revoked. If I happen to lose the new key again, there will be three valid keys out there with signatures on it. You may argue that this shouldn’t be a problem, and that nobody should use any other key than the latest one I want to be used, but that’s a technical argument — and at this point we have moved into usability, and that’s a trickier area. Having users select which out of a couple of apparently all valid keys that exist for me is simply not going to work well.

The second is more subtle, but considerably more important. If people retrieve my key from keyservers today, and it expires in 50 years, there will be no need to refresh it from key servers. If for some reason I have to publish my revocation certificate, there will be people that won’t see it. If instead I set a short validity period, people will have to refresh my key once in a while, and will then either get an updated expiration time, or will get the revocation certificate. This amounts to a CRL/OCSP-like model.

The third is similar to the second, but deserves to be mentioned on its own. Because the cipher preferences are expressed (and signed) in my key, and that ciphers come and go, I would expect that I will modify those during the life-time of my long-term key. If I have a long validity period of my key, people would not refresh it from key servers, and would encrypt messages to me with ciphers I may no longer want to be used.

The downside of having a short validity period is that I have to do slightly more work to get out the offline master key once in a while (which I have to once in a while anyway because I’m signing other peoples keys) and that others need to refresh my key from the key servers. Can anyone identify other disadvantages? Also, having to explain why I’m using a short validity period used to be a downside, but with this writeup posted that won’t be the case any more. :-)

flattr this!

Syndicated 2014-08-26 18:11:27 from Simon Josefsson's blog

Wifi on S3 with Replicant

I’m using Replicant on my main phone. As I’ve written before, I didn’t get Wifi to work. The other day leth in #replicant pointed me towards a CyanogenMod discussion about a similar issue. The fix does indeed work, and allowed me to connect to wifi networks and to setup my phone for Internet sharing. Digging deeper, I found a CM Jira issue about it, and ultimately a code commit. It seems the issue is that more recent S3′s comes with a Murata Wifi chipset that uses MAC addresses not known back in the Android 4.2 (CM-10.1.3 and Replicant-4.2) days. Pulling in the latest fixes for macloader.cpp solves this problem for me, although I still need to load the non-free firmware images that I get from CM-10.1.3. I’ve created a pull request fixing macloader.cpp for Replicant 4.2 if someone else is curious about the details. You have to rebuild your OS with the patch for things to work (if you don’t want to, the workaround using /data/.cid.info works fine), and install some firmware blobs as below.

adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_apsta.bin_b1 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_apsta.bin_b2 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_mfg.bin_b0 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_mfg.bin_b1 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_mfg.bin_b2 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_p2p.bin_b0 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_p2p.bin_b1 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_p2p.bin_b2 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_sta.bin_b0 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_sta.bin_b1 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/bcmdhd_sta.bin_b2 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_mfg.txt /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_mfg.txt_murata /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_mfg.txt_murata_b2 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_mfg.txt_semcosh /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_net.txt /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_net.txt_murata /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_net.txt_murata_b2 /system/vendor/firmware/
adb push cm-10.1.3-i9300/system/etc/wifi/nvram_net.txt_semcosh /system/vendor/firmware/

flattr this!

Syndicated 2014-08-10 18:02:37 from Simon Josefsson's blog

Replicant 4.2 0002 and NFC on I9300

During my vacation the Replicant project released version 4.2-0002 as a minor update to their initial 4.2 release. I didn’t anticipate any significant differences, so I followed the installation instructions but instead of “wipe data/factory reset” I chose “wipe cache partition” and rebooted. Everything appeared to work fine, but I soon discovered that NFC was not working. Using adb logcat I could get some error messages:

E/NFC-HCI ( 7022): HCI Timeout - Exception raised - Force restart of NFC service
F/libc    ( 7022): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 7046 (message)
I/DEBUG   ( 1900): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   ( 1900): Build fingerprint: 'samsung/m0xx/m0:4.1.1/JRO03C/I9300XXDLIB:user/release-keys'
I/DEBUG   ( 1900): Revision: '12'
I/DEBUG   ( 1900): pid: 7022, tid: 7046, name: message  >>> com.android.nfc 

The phone would loop trying to start NFC and having the NFC sub-system die over and over. Talking on #replicant channel, paulk quickly realized and fixed the bug. I had to rebuild the images to get things to work, so I took the time to create a new virtual machine based on Debian 7.5 for building Replicant on. As a side note, the only thing not covered by Replicant build dependency documentation was that I needed the Debian xmllint package to avoid a build failure and the Debian xsltproc package to avoid a error message being printed in the beginning of every build. Soon I had my own fresh images and installed them and NFC was working again, after installing the non-free libpn544_fw.so file.

During this, I noticed that there are multiple libpn544_fw.so files floating around. I have the following files:

version string source
libpn544_fw_C3_1_26_SP.so internet
libpn544_fw_C3_1_34_SP.so stock ROM on S3 bought in Sweden during 2013 and 2014 (two phones)
libpn544_fw_C3_1_39_SP.so internet

(For reference the md5sum's of these files are 682e50666effa919d557688c276edc48, b9364ba59de1947d4588f588229bae20 and 18b4e634d357849edbe139b04c939593 respectively.)

If you do not have any of these files available as /vendor/firmware/libpn544_fw.so you will get the following error message:

I/NfcService( 2488): Enabling NFC
D/NFCJNI  ( 2488): Start Initialization
E/NFC-HCI ( 2488): Could not open /system/vendor/firmware/libpn544_fw.so or /system/lib/libpn544_fw.so
E/NFCJNI  ( 2488): phLibNfc_Mgt_Initialize() returned 0x00ff[NFCSTATUS_FAILED]
E/NFC-HCI ( 2488): Could not open /system/vendor/firmware/libpn544_fw.so or /system/lib/libpn544_fw.so
W/NFCJNI  ( 2488): Firmware update FAILED
E/NFC-HCI ( 2488): Could not open /system/vendor/firmware/libpn544_fw.so or /system/lib/libpn544_fw.so
W/NFCJNI  ( 2488): Firmware update FAILED
E/NFC-HCI ( 2488): Could not open /system/vendor/firmware/libpn544_fw.so or /system/lib/libpn544_fw.so
W/NFCJNI  ( 2488): Firmware update FAILED
E/NFCJNI  ( 2488): Unable to update firmware, giving up
D/NFCJNI  ( 2488): phLibNfc_Mgt_UnConfigureDriver() returned 0x0000[NFCSTATUS_SUCCESS]
D/NFCJNI  ( 2488): Terminating client thread...
W/NfcService( 2488): Error enabling NFC

Using the first (26) file or the last (39) file does not appear to be working on my phone, I get the following error messages. Note that the line starting with 'NFC capabilities' has 'Rev = 34' in it, possibly indicating that I need the version 34 file.

I/NfcService( 5735): Enabling NFC
D/NFCJNI  ( 5735): Start Initialization
D/NFCJNI  ( 5735): NFC capabilities: HAL = 8150100, FW = b10122, HW = 620003, Model = 12, HCI = 1, Full_FW = 1, Rev = 34, FW Update Info = 8
D/NFCJNI  ( 5735): Download new Firmware
W/NFCJNI  ( 5735): Firmware update FAILED
D/NFCJNI  ( 5735): Download new Firmware
W/NFCJNI  ( 5735): Firmware update FAILED
D/NFCJNI  ( 5735): Download new Firmware
W/NFCJNI  ( 5735): Firmware update FAILED
E/NFCJNI  ( 5735): Unable to update firmware, giving up
D/NFCJNI  ( 5735): phLibNfc_Mgt_UnConfigureDriver() returned 0x0000[NFCSTATUS_SUCCESS]
D/NFCJNI  ( 5735): Terminating client thread...
W/NfcService( 5735): Error enabling NFC

Loading the 34 works fine.

I/NfcService( 2501): Enabling NFC
D/NFCJNI  ( 2501): Start Initialization
D/NFCJNI  ( 2501): NFC capabilities: HAL = 8150100, FW = b10122, HW = 620003, Model = 12, HCI = 1, Full_FW = 1, Rev = 34, FW Update Info = 0
D/NFCJNI  ( 2501): phLibNfc_SE_GetSecureElementList()
D/NFCJNI  ( 2501): 
D/NFCJNI  ( 2501): > Number of Secure Element(s) : 1
D/NFCJNI  ( 2501): phLibNfc_SE_GetSecureElementList(): SMX detected, handle=0xabcdef
D/NFCJNI  ( 2501): phLibNfc_SE_SetMode() returned 0x000d[NFCSTATUS_PENDING]
I/NFCJNI  ( 2501): NFC Initialized
D/NdefPushServer( 2501): start, thread = null
D/NdefPushServer( 2501): starting new server thread
D/NdefPushServer( 2501): about create LLCP service socket
D/NdefPushServer( 2501): created LLCP service socket
D/NdefPushServer( 2501): about to accept
D/NfcService( 2501): NFC-EE OFF
D/NfcService( 2501): NFC-C ON

What is interesting is, that my other S3 running CyanogenMod does not have the libpn544_fw.so file but still NFC works. The messages are:

I/NfcService( 2619): Enabling NFC
D/NFCJNI  ( 2619): Start Initialization
E/NFC-HCI ( 2619): Could not open /system/vendor/firmware/libpn544_fw.so or /system/lib/libpn544_fw.so
W/NFC     ( 2619): Firmware image not available: this device might be running old NFC firmware!
D/NFCJNI  ( 2619): NFC capabilities: HAL = 8150100, FW = b10122, HW = 620003, Model = 12, HCI = 1, Full_FW = 1, Rev = 34, FW Update Info = 0
D/NFCJNI  ( 2619): phLibNfc_SE_GetSecureElementList()
D/NFCJNI  ( 2619): 
D/NFCJNI  ( 2619): > Number of Secure Element(s) : 1
D/NFCJNI  ( 2619): phLibNfc_SE_GetSecureElementList(): SMX detected, handle=0xabcdef
D/NFCJNI  ( 2619): phLibNfc_SE_SetMode() returned 0x000d[NFCSTATUS_PENDING]
I/NFCJNI  ( 2619): NFC Initialized
D/NdefPushServer( 2619): start, thread = null
D/NdefPushServer( 2619): starting new server thread
D/NdefPushServer( 2619): about create LLCP service socket
D/NdefPushServer( 2619): created LLCP service socket
D/NdefPushServer( 2619): about to accept
D/NfcService( 2619): NFC-EE OFF
D/NfcService( 2619): NFC-C ON

Diffing the two NFC-relevant repositories between Replicant (external_libnfc-nxp and packages_apps_nfc) and CyanogenMod (android_external_libnfc-nxp and android_packages_apps_Nfc) I found a commit in Replicant that changes a soft-fail on missing firmware to a hard-fail. I manually reverted that patch in my build tree, and rebuilt and booted a new image. Enabling NFC now prints this on my Replicant phone:

I/NfcService( 2508): Enabling NFC
D/NFCJNI  ( 2508): Start Initialization
E/NFC-HCI ( 2508): Could not open /system/vendor/firmware/libpn544_fw.so or /system/lib/libpn544_fw.so
W/NFC     ( 2508): Firmware image not available: this device might be running old NFC firmware!
D/NFCJNI  ( 2508): NFC capabilities: HAL = 8150100, FW = b10122, HW = 620003, Model = 12, HCI = 1, Full_FW = 1, Rev = 34, FW Update Info = 0
D/NFCJNI  ( 2508): phLibNfc_SE_GetSecureElementList()
D/NFCJNI  ( 2508): 
D/NFCJNI  ( 2508): > Number of Secure Element(s) : 1
D/NFCJNI  ( 2508): phLibNfc_SE_GetSecureElementList(): SMX detected, handle=0xabcdef
D/NFCJNI  ( 2508): phLibNfc_SE_SetMode() returned 0x000d[NFCSTATUS_PENDING]
I/NFCJNI  ( 2508): NFC Initialized
D/NdefPushServer( 2508): start, thread = null
D/NdefPushServer( 2508): starting new server thread
D/NdefPushServer( 2508): about create LLCP service socket
D/NdefPushServer( 2508): created LLCP service socket
D/NdefPushServer( 2508): about to accept
D/NfcService( 2508): NFC-EE OFF
D/NfcService( 2508): NFC-C ON

And NFC works! One less non-free blob on my phone.

I have double-checked that power-cycling the phone (even removing battery for a while) does not affect anything, so it seems the NFC chip has firmware loaded from the factory.

Question remains why that commit was added. Is it necessary on some other phone? I have no idea, other than if the patch is reverted, S3 owners will have NFC working with Replicant without non-free software added. Alternatively, make the patch apply only on the platform where it was needed, or even to all non-S3 builds.

flattr this!

Syndicated 2014-08-05 12:20:18 from Simon Josefsson's blog

Offline GnuPG Master Key and Subkeys on YubiKey NEO Smartcard

I have moved to a new OpenPGP key. There are many tutorials and blog posts on GnuPG key generation around, but none of them matched exactly the setup I wanted to have. So I wrote down the steps I took, to remember them if I need to in the future. Briefly my requirements were as follows:

  • The new master GnuPG key is on an USB stick.
  • The USB stick is only ever used on an offline computer.
  • There are subkeys stored on a YubiKey NEO smartcard for daily use.
  • I want to generate the subkeys using GnuPG so I have a backup.
  • Some non-default hash/cipher preferences encoded into the public key.

After writing down the notes below, I posted about how to create a small JPEG image to embed in my OpenPGP key. I was planning to go live with the first key I generated, however as was gently pointed out to me, the JPEG image I generated was not optimal (too low quality and not sufficiently compressed). I have decided to retake the photo so I have a color image as a basis for size optimization. I don’t want to postpone using the new key though, so I stepped through all of these steps again (except adding the photo) to get a new key. This is why the notes below are for a key 1C5C4717 that is now revoked. My new real key is 54265E8C. I will add the photo to my 54265E8C key once I have a JPEG file that I’m happy with.

Offline machine

The offline machine setup I use is a Live CD on a machine that is physically well protected. I’m using the Debian Live CD version 7.5.0 GNOME Desktop. The password for the auto-logged in user is “live” which you need if the screen-saver kicks in. Configure the keyboard layout if you need to. Insert an USB memory stick. I’m using a VFAT filesystem to keep things simple; and for this writeup it happened to be mounted as /media/FA21-BEC7 so you will have to replace that path with something that points to your USB stick. Open a terminal since the rest of this writeup will be done from a terminal window.

GnuPG configuration

Set your GnuPG home directory to point at the USB memory device. You will need to do this in every terminal windows you open that you want to use GnuPG in.

user@debian:~$ export GNUPGHOME=/media/FA21-BEC7/gnupghome
user@debian:~$ mkdir $GNUPGHOME
user@debian:~$ 

The GnuPG defaults (as of version 1.4.16) to rank SHA1 higher than SHA384, SHA512, and SHA224 in the default hash preference list. To be precise, the default hash preference order is SHA256, SHA1, SHA384, SHA512, SHA224. I consider SHA1 broken so I don’t advertise it all, although I believe that will not prevent some implementations of using SHA1 anyway since it is the mandatory to implement hash algorithm. Regarding symmetric ciphers, the default order is AES256, AES192, AES128, CAST5, 3DES. I don’t like ciphers with 64-bit block lengths, so I don’t advertise them but similarily, I believe this will not prevent some implementations of using CAST5 or 3DES anyway. I also advertise support for Twofish and Camellia in case someone wants to use them, they are 128-bit block length and relatively modern ciphers after all. The “default-preference-list” keyword is used to override the default settings, which will be recorded into any newly generated keys.

GnuPG self-sign keys with SHA1 by default, and I prefer to use a member of the SHA2 family, hence the “cert-digest-algo” keyword. Further down below we will use the GnuPG Agent to talk to the smartcard, so configure GnuPG to use it with the “use-agent” keyword. GnuPG prints ugly warning messages about locking (gpg: DBG: locking for `/media/FA21-BEC7/gnupghome/secring.gpg.lock' done via O_EXCL), presumably because of the VFAT filesystem, so I use “lock-never” to silence that.

user@debian:~$ cat > $GNUPGHOME/gpg.conf
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAMELLIA256 CAMELLIA192 CAMELLIA128 TWOFISH
cert-digest-algo SHA512
use-agent
lock-never
user@debian:~$ 

Generate master key

Below I will use a 3744 bit RSA key, where the key size is selected based on the assumption that people will focus efforts to crack RSA keys on the usual power-of-two key sizes. I have chosen to not generate an encryption key, since I will use subkeys on a smartcard. With my old B565716F key I noticed that sometimes people will encrypt to my main encryption key even though I have encryption subkeys. Presumably this happens due to implementation flaws or user configuration mistakes. It could happen “intentionally” if someone had a public key from me with an expired subkeys but not expired main keys. This could be a reason to use the same expiration day for all your keys. Still, I chose to not generate an encryption key at all at this point. For additional protection, I’m using a passphrase on the key.

user@debian:~$ gpg --gen-key
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

gpg: keyring `/media/FA21-BEC7/gnupghome/secring.gpg' created
gpg: keyring `/media/FA21-BEC7/gnupghome/pubring.gpg' created
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 3744
Requested keysize is 3744 bits
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 100
Key expires at Fri 26 Sep 2014 10:50:22 PM UTC
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) "

Real name: Simon Josefsson
Email address: simon@josefsson.org
Comment: 
You selected this USER-ID:
    "Simon Josefsson "

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
...
gpg: /media/FA21-BEC7/gnupghome/trustdb.gpg: trustdb created
gpg: key 1C5C4717 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2014-09-26
pub   3744R/1C5C4717 2014-06-18 [expires: 2014-09-26]
      Key fingerprint = EF0A 1996 7B3B 4BAD 9D5C  A97F 1A44 08DD 1C5C 4717
uid                  Simon Josefsson 

Note that this key cannot be used for encryption.  You may want to use
the command "--edit-key" to generate a subkey for this purpose.
user@debian:~$ 

Add photo

I’m in the process of creating a better JPEG photo, so I skipped this step for my new key. However the notes here are correct anyway.

user@debian:~$ gpg --edit-key 1C5C4717
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: ultimate      validity: ultimate
[ultimate] (1). Simon Josefsson 

gpg> addphoto

Pick an image to use for your photo ID.  The image must be a JPEG file.
Remember that the image is stored within your public key.  If you use a
very large picture, your key will become very large as well!
Keeping the image close to 240x288 is a good size to use.

Enter JPEG filename for photo ID: /media/FA21-BEC7/simon-gpg.jpg
Is this photo correct (y/N/q)? y

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 1C5C4717, created 2014-06-18


pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: ultimate      validity: ultimate
[ultimate] (1). Simon Josefsson 
[ unknown] (2)  [jpeg image of size 6048]

gpg> save
user@debian:~$ 

Add another identity

Most people have multiple email addresses, and this needs to be reflected in the GnuPG key. Use the primary command to specify your main User ID.

user@debian:~$ gpg --edit-key 1C5C4717
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: ultimate      validity: ultimate
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  [jpeg image of size 6048]

gpg> adduid
Real name: Simon Josefsson
Email address: simon@yubico.com
Comment: 
You selected this USER-ID:
    "Simon Josefsson "

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 1C5C4717, created 2014-06-18


pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: ultimate      validity: ultimate
[ultimate] (1)  Simon Josefsson 
[ultimate] (2)  [jpeg image of size 6048]
[ unknown] (3). Simon Josefsson 

gpg> uid 1

pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: ultimate      validity: ultimate
[ultimate] (1)* Simon Josefsson 
[ultimate] (2)  [jpeg image of size 6048]
[ unknown] (3). Simon Josefsson 

gpg> primary

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 1C5C4717, created 2014-06-18


pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: ultimate      validity: ultimate
[ultimate] (1)* Simon Josefsson 
[ultimate] (2)  [jpeg image of size 6048]
[ unknown] (3)  Simon Josefsson 

gpg> save
user@debian:~$ 

Create a revocation certificate

It is good practice to generate a revocation certificate in case you lose your key. Store this in a safe place, possibly printed out on paper.

user@debian:~$ gpg --output $GNUPGHOME/../revocation-certificate.txt --gen-revoke 1C5C4717

sec  3744R/1C5C4717 2014-06-18 Simon Josefsson 

Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
(Probably you want to select 1 here)
Your decision? 1
Enter an optional description; end it with an empty line:
> Created during key creation, emergency use only.
> 
Reason for revocation: Key has been compromised
Created during key creation, emergency use only.
Is this okay? (y/N) y

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 1C5C4717, created 2014-06-18

ASCII armored output forced.
Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable.  But have some caution:  The print system of
your machine might store the data and make it available to others!
user@debian:~$ 

Make a backup of the master key

To have an easy way to move back and forward in time in GnuPG, I both export the key to a stable data format and keep a backup of the actual GnuPG home directory.

user@debian:~$ gpg -a --export-secret-keys 1C5C4717 > $GNUPGHOME/../masterkey.txt
user@debian:~$ cp -a $GNUPGHOME $GNUPGHOME-backup-masterkey
user@debian:~$ 

Create subkeys

Now I will generate three keys that will go onto the smartcard. I have chosen to generate these using GnuPG and then move the keys onto the smartcards, instead of generating the keys directly on the card. The difference is that with this approach, I get a backup of the keys and can import them to another key in the future if I need to.

Each key has its own purpose: Signature, Encryption, and Authentication. Smartcards typically have limitation on key sizes, so I select 2048 as a widely supported size. Expert mode is required to generate authentication subkeys.

user@debian:~$ gpg --expert --edit-key 1C5C4717
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: ultimate      validity: ultimate
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  [jpeg image of size 6048]
[ultimate] (3)  Simon Josefsson 

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 1C5C4717, created 2014-06-18

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 100
Key expires at Fri 26 Sep 2014 11:03:16 PM UTC
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
..+++++
....+++++

pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/72D5245B  created: 2014-06-18  expires: 2014-09-26  usage: S   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  [jpeg image of size 6048]
[ultimate] (3)  Simon Josefsson 

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 1C5C4717, created 2014-06-18

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
Your selection? 6
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 100
Key expires at Fri 26 Sep 2014 11:03:31 PM UTC
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
......+++++

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 7 more bytes)
.+++++

pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/72D5245B  created: 2014-06-18  expires: 2014-09-26  usage: S   
sub  2048R/A11F46D2  created: 2014-06-18  expires: 2014-09-26  usage: E   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  [jpeg image of size 6048]
[ultimate] (3)  Simon Josefsson 

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 1C5C4717, created 2014-06-18

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
Your selection? 8

Possible actions for a RSA key: Sign Encrypt Authenticate 
Current allowed actions: Sign Encrypt 

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? s

Possible actions for a RSA key: Sign Encrypt Authenticate 
Current allowed actions: Encrypt 

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? e

Possible actions for a RSA key: Sign Encrypt Authenticate 
Current allowed actions: 

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? a

Possible actions for a RSA key: Sign Encrypt Authenticate 
Current allowed actions: Authenticate 

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 100
Key expires at Fri 26 Sep 2014 11:03:59 PM UTC
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
+++++

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 56 more bytes)
+++++

pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/72D5245B  created: 2014-06-18  expires: 2014-09-26  usage: S   
sub  2048R/A11F46D2  created: 2014-06-18  expires: 2014-09-26  usage: E   
sub  2048R/D6987A02  created: 2014-06-18  expires: 2014-09-26  usage: A   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  [jpeg image of size 6048]
[ultimate] (3)  Simon Josefsson 

gpg> save
user@debian:~$ 

Export subkeys for backup

This is a good time to save a restore point for your key. Note in the output of --list-secret-keys the keywords sec and ssb which means the main key and the subkeys are available. If the secret keyring contained only stubs, it would be sec> and sec#.

user@debian:~$ gpg --list-keys
/media/FA21-BEC7/gnupghome/pubring.gpg
--------------------------------------
pub   3744R/1C5C4717 2014-06-18 [expires: 2014-09-26]
uid                  Simon Josefsson 
uid                  [jpeg image of size 6048]
uid                  Simon Josefsson 
sub   2048R/72D5245B 2014-06-18 [expires: 2014-09-26]
sub   2048R/A11F46D2 2014-06-18 [expires: 2014-09-26]
sub   2048R/D6987A02 2014-06-18 [expires: 2014-09-26]

user@debian:~$ gpg --list-secret-keys
/media/FA21-BEC7/gnupghome/secring.gpg
--------------------------------------
sec   3744R/1C5C4717 2014-06-18 [expires: 2014-09-26]
uid                  Simon Josefsson 
uid                  [jpeg image of size 6048]
uid                  Simon Josefsson 
ssb   2048R/72D5245B 2014-06-18
ssb   2048R/A11F46D2 2014-06-18
ssb   2048R/D6987A02 2014-06-18

user@debian:~$ gpg -a --export-secret-keys 1C5C4717 > $GNUPGHOME/../mastersubkeys.txt
user@debian:~$ gpg -a --export-secret-subkeys 1C5C4717 > $GNUPGHOME/../subkeys.txt
user@debian:~$ cp -a $GNUPGHOME $GNUPGHOME-backup-mastersubkeys
user@debian:~$ 

Configure machine for smartcards

The YubiKey NEO requires that RSA keys are imported with some additional parameters, used for CRT speedups. This was fixed in GnuPG 2.0.22. Unfortunately, it is not fixed in GnuPG 1.x. However, GnuPG 1.x can use gpg-agent and scdaemon from GnuPG to communicate with the smartcard. So let’s work around the limitation in GnuPG 1.x by installing parts from GnuPG 2.x and use those.

You will need to install the following packages: gnupg-agent, libpth20, pinentry-curses, libccid, pcscd, scdaemon, libksba8. Make sure that scdaemon is version 2.0.22 or later (get it from backports). I downloaded these packages and put them on the USB stick.

Unfortunately, libccid in Debian is a bit outdated, and does not contain the USB device vendor/product ID in /etc/libccid_Info.plist. You will need to manually add this, and restart pcscd.

user@debian:~$ sudo gedit /etc/libccid_Info.plist
user@debian:~$ sudo service pcscd restart

Start gnupg-agent and setup the environment variable for this session:

user@debian:~$ gpg-agent --daemon
gpg-agent[22556]: directory `/media/FA21-BEC7/gnupghome/private-keys-v1.d' created
GPG_AGENT_INFO=/tmp/gpg-wGji5C/S.gpg-agent:22557:1; export GPG_AGENT_INFO;
gpg-agent[22557]: gpg-agent (GnuPG) 2.0.22 started
user@debian:~$ GPG_AGENT_INFO=/tmp/gpg-wGji5C/S.gpg-agent:22557:1; export GPG_AGENT_INFO;
user@debian:~$ 

Prepare YubiKey NEO

Make sure you have a recent firmware version, 3.1.8 or later; use lsusb -v to find out.

Make sure the device is in OTP/CCID or CCID mode, use ykpersonalize -m from the YubiKey Personalization project to switch.

Make sure you have the OpenPGP applet loaded properly, otherwise see the YubiKey NEO OpenPGP applet project on installing it. You may want to set a proper Application ID, see herlo’s ssh-gpg-smartcard-config github repository for some hints.

Configure OpenPGP applet

This also changes the PIN and Admin codes.

user@debian:~$ gpg --card-edit

Application ID ...: D2760001240102000060000000420000
Version ..........: 2.0
Manufacturer .....: unknown
Serial number ....: 00000042
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

gpg/card> admin
Admin commands are allowed

gpg/card> passwd
gpg: OpenPGP card no. D2760001240102000060000000420000 detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 3
PIN changed.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 1
PIN changed.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? q

gpg/card> name
Cardholder's surname: Josefsson
Cardholder's given name: Simon

gpg/card> lang
Language preferences: sv

gpg/card> url
URL to retrieve public key: https://josefsson.org/1c5c4717.txt

gpg/card> sex
Sex ((M)ale, (F)emale or space): m

gpg/card> login
Login data (account name): jas

gpg/card> 

Application ID ...: D2760001240102000060000000420000
Version ..........: 2.0
Manufacturer .....: unknown
Serial number ....: 00000042
Name of cardholder: Simon Josefsson
Language prefs ...: sv
Sex ..............: male
URL of public key : https://josefsson.org/1c5c4717.txt
Login data .......: jas
Signature PIN ....: forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

gpg/card> quit
user@debian:~$ 

Move subkeys to YubiKey NEO

Moving subkeys to a NEO is a destructive operation, so make sure you took backups of the subkeys as above. After this step, your GnuPG keyring will contain stubs for the subkeys.

user@debian:~$ gpg --edit-key 1C5C4717
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/72D5245B  created: 2014-06-18  expires: 2014-09-26  usage: S   
sub  2048R/A11F46D2  created: 2014-06-18  expires: 2014-09-26  usage: E   
sub  2048R/D6987A02  created: 2014-06-18  expires: 2014-09-26  usage: A   
[ultimate] (1). Simon Josefsson 
[ultimate] (2)  [jpeg image of size 6048]
[ultimate] (3)  Simon Josefsson 

gpg> toggle

sec  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26
ssb  2048R/72D5245B  created: 2014-06-18  expires: never     
ssb  2048R/A11F46D2  created: 2014-06-18  expires: never     
ssb  2048R/D6987A02  created: 2014-06-18  expires: never     
(1)  Simon Josefsson 
(2)  [jpeg image of size 6048]
(3)  Simon Josefsson 

gpg> key 1

sec  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26
ssb* 2048R/72D5245B  created: 2014-06-18  expires: never     
ssb  2048R/A11F46D2  created: 2014-06-18  expires: never     
ssb  2048R/D6987A02  created: 2014-06-18  expires: never     
(1)  Simon Josefsson 
(2)  [jpeg image of size 6048]
(3)  Simon Josefsson 

gpg> keytocard
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]

Please select where to store the key:
   (1) Signature key
   (3) Authentication key
Your selection? 1

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
2048-bit RSA key, ID 72D5245B, created 2014-06-18


sec  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26
ssb* 2048R/72D5245B  created: 2014-06-18  expires: never     
                     card-no: 0060 00000042
ssb  2048R/A11F46D2  created: 2014-06-18  expires: never     
ssb  2048R/D6987A02  created: 2014-06-18  expires: never     
(1)  Simon Josefsson 
(2)  [jpeg image of size 6048]
(3)  Simon Josefsson 

gpg> key 1

sec  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26
ssb  2048R/72D5245B  created: 2014-06-18  expires: never     
                     card-no: 0060 00000042
ssb  2048R/A11F46D2  created: 2014-06-18  expires: never     
ssb  2048R/D6987A02  created: 2014-06-18  expires: never     
(1)  Simon Josefsson 
(2)  [jpeg image of size 6048]
(3)  Simon Josefsson 

gpg> key 2

sec  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26
ssb  2048R/72D5245B  created: 2014-06-18  expires: never     
                     card-no: 0060 00000042
ssb* 2048R/A11F46D2  created: 2014-06-18  expires: never     
ssb  2048R/D6987A02  created: 2014-06-18  expires: never     
(1)  Simon Josefsson 
(2)  [jpeg image of size 6048]
(3)  Simon Josefsson 

gpg> keytocard
Signature key ....: EF34 D1F7 95C0 3392 E52A  54FE DFF1 6372 72D5 245B
Encryption key....: [none]
Authentication key: [none]

Please select where to store the key:
   (2) Encryption key
Your selection? 2

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
2048-bit RSA key, ID A11F46D2, created 2014-06-18


sec  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26
ssb  2048R/72D5245B  created: 2014-06-18  expires: never     
                     card-no: 0060 00000042
ssb* 2048R/A11F46D2  created: 2014-06-18  expires: never     
                     card-no: 0060 00000042
ssb  2048R/D6987A02  created: 2014-06-18  expires: never     
(1)  Simon Josefsson 
(2)  [jpeg image of size 6048]
(3)  Simon Josefsson 

gpg> key 2

sec  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26
ssb  2048R/72D5245B  created: 2014-06-18  expires: never     
                     card-no: 0060 00000042
ssb  2048R/A11F46D2  created: 2014-06-18  expires: never     
                     card-no: 0060 00000042
ssb  2048R/D6987A02  created: 2014-06-18  expires: never     
(1)  Simon Josefsson 
(2)  [jpeg image of size 6048]
(3)  Simon Josefsson 

gpg> key 3

sec  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26
ssb  2048R/72D5245B  created: 2014-06-18  expires: never     
                     card-no: 0060 00000042
ssb  2048R/A11F46D2  created: 2014-06-18  expires: never     
                     card-no: 0060 00000042
ssb* 2048R/D6987A02  created: 2014-06-18  expires: never     
(1)  Simon Josefsson 
(2)  [jpeg image of size 6048]
(3)  Simon Josefsson 

gpg> keytocard
Signature key ....: EF34 D1F7 95C0 3392 E52A  54FE DFF1 6372 72D5 245B
Encryption key....: E24D 5135 C2FC 905C 8995  ACD8 EC96 9E77 A11F 46D2
Authentication key: [none]

Please select where to store the key:
   (3) Authentication key
Your selection? 3

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
2048-bit RSA key, ID D6987A02, created 2014-06-18


sec  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26
ssb  2048R/72D5245B  created: 2014-06-18  expires: never     
                     card-no: 0060 00000042
ssb  2048R/A11F46D2  created: 2014-06-18  expires: never     
                     card-no: 0060 00000042
ssb* 2048R/D6987A02  created: 2014-06-18  expires: never     
                     card-no: 0060 00000042
(1)  Simon Josefsson 
(2)  [jpeg image of size 6048]
(3)  Simon Josefsson 

gpg> save
user@debian:~$ 

Take another backup

Can you tell yet that I like having backup options? Note that the subkeys are now marked ssb> indicating they are stubs for a smartcard key.

user@debian:~$ gpg --list-secret-keys
/media/FA21-BEC7/gnupghome/secring.gpg
--------------------------------------
sec   3744R/1C5C4717 2014-06-18 [expires: 2014-09-26]
uid                  Simon Josefsson 
uid                  [jpeg image of size 6048]
uid                  Simon Josefsson 
ssb>  2048R/72D5245B 2014-06-18
ssb>  2048R/A11F46D2 2014-06-18
ssb>  2048R/D6987A02 2014-06-18

user@debian:~$ gpg -a --export-secret-keys 1C5C4717 > $GNUPGHOME/../masterstubs.txt
user@debian:~$ gpg -a --export-secret-subkeys 1C5C4717 > $GNUPGHOME/../subkeysstubs.txt
user@debian:~$ gpg -a --export 1C5C4717 > $GNUPGHOME/../publickey.txt
user@debian:~$ cp -a $GNUPGHOME $GNUPGHOME-backup-masterstubs

Transfer to daily machine

Copy publickey.txt to your day-to-day laptop and import it.

jas@latte:~$ gpg --import " imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
jas@latte:~$ 

Insert the YubiKey NEO and generate secret key stubs:

jas@latte:~$ gpg --card-status
Application ID ...: D2760001240102000060000000420000
Version ..........: 2.0
Manufacturer .....: unknown
Serial number ....: 00000042
Name of cardholder: Simon Josefsson
Language prefs ...: sv
Sex ..............: male
URL of public key : https://josefsson.org/1c5c4717.txt
Login data .......: jas
Signature PIN ....: forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 0 0 0
PIN retry counter : 0 0 0
Signature counter : 0
Signature key ....: EF34 D1F7 95C0 3392 E52A  54FE DFF1 6372 72D5 245B
      created ....: 2014-06-18 23:03:16
Encryption key....: E24D 5135 C2FC 905C 8995  ACD8 EC96 9E77 A11F 46D2
      created ....: 2014-06-18 23:03:31
Authentication key: 2768 2EF9 415C 19FC F0CC  9CA5 DA81 BA39 D698 7A02
      created ....: 2014-06-18 23:03:59
General key info..: pub  2048R/72D5245B 2014-06-18 Simon Josefsson 
sec#  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26
ssb>  2048R/72D5245B  created: 2014-06-18  expires: 2014-09-26
                      card-no: 0060 00000042
ssb>  2048R/A11F46D2  created: 2014-06-18  expires: 2014-09-26
                      card-no: 0060 00000042
ssb>  2048R/D6987A02  created: 2014-06-18  expires: 2014-09-26
                      card-no: 0060 00000042
jas@latte:~$ 

Now you should have a offline master key with subkey stubs. Note that the master key is not available (sec#) and the subkeys are stubs for smartcard keys (ssb>).

jas@latte:~$ gpg --list-secret-keys 1c5c4717
sec#  3744R/1C5C4717 2014-06-18 [expires: 2014-09-26]
uid                  Simon Josefsson 
uid                  [jpeg image of size 6048]
uid                  Simon Josefsson 
ssb>  2048R/72D5245B 2014-06-18 [expires: 2014-09-26]
ssb>  2048R/A11F46D2 2014-06-18 [expires: 2014-09-26]
ssb>  2048R/D6987A02 2014-06-18 [expires: 2014-09-26]
jas@latte:~$ 

Mark the key as ultimately trusted.

jas@latte:~$ gpg --edit-key 1c5c4717
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: unknown       validity: unknown
sub  2048R/72D5245B  created: 2014-06-18  expires: 2014-09-26  usage: S   
sub  2048R/A11F46D2  created: 2014-06-18  expires: 2014-09-26  usage: E   
sub  2048R/D6987A02  created: 2014-06-18  expires: 2014-09-26  usage: A   
[ unknown] (1). Simon Josefsson 
[ unknown] (2)  [jpeg image of size 6048]
[ unknown] (3)  Simon Josefsson 

gpg> trust
pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: unknown       validity: unknown
sub  2048R/72D5245B  created: 2014-06-18  expires: 2014-09-26  usage: S   
sub  2048R/A11F46D2  created: 2014-06-18  expires: 2014-09-26  usage: E   
sub  2048R/D6987A02  created: 2014-06-18  expires: 2014-09-26  usage: A   
[ unknown] (1). Simon Josefsson 
[ unknown] (2)  [jpeg image of size 6048]
[ unknown] (3)  Simon Josefsson 

Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

pub  3744R/1C5C4717  created: 2014-06-18  expires: 2014-09-26  usage: SC  
                     trust: ultimate      validity: unknown
sub  2048R/72D5245B  created: 2014-06-18  expires: 2014-09-26  usage: S   
sub  2048R/A11F46D2  created: 2014-06-18  expires: 2014-09-26  usage: E   
sub  2048R/D6987A02  created: 2014-06-18  expires: 2014-09-26  usage: A   
[ unknown] (1). Simon Josefsson 
[ unknown] (2)  [jpeg image of size 6048]
[ unknown] (3)  Simon Josefsson 
Please note that the shown key validity is not necessarily correct
unless you restart the program.

gpg> quit
jas@latte:~$ 

Signing keys

This needs to be done using your master key, since it is your certification key that will be used. So boot the Live CD and make the usual GnuPG configurations. Below I’m signing my own old key (0xB565716F) so the output may look a bit confusing with me signing my own key, but there is really two different keys involved here. The same process apply if you want to sign someone else’s key too.

Before signing the key, you need to put the public key on a USB stick and move it to the “secure” machine. On your laptop:

jas@latte:~$ gpg -a --export b565716f > /media/KINGSTON/b565716f.txt
jas@latte:~$ 

On the disconnected machine:

user@debian:~$ gpg --import " imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2014-09-26
user@debian:~$ gpg --sign-key b565716f

pub  1280R/B565716F  created: 2002-05-05  expires: 2014-11-10  usage: SC  
                     trust: unknown       validity: unknown
sub  2048R/105E722E  created: 2012-03-13  expires: 2014-11-10  usage: S   
sub  2048R/728AB82C  created: 2012-03-13  expires: 2014-11-10  usage: E   
sub  2048R/9394F626  created: 2012-03-13  expires: 2014-11-10  usage: A   
sub  1280R/4D5D40AE  created: 2002-05-05  expires: 2014-11-10  usage: E   
sub  1024R/09CC4670  created: 2006-03-18  expired: 2011-05-23  usage: A   
sub  1024R/AABB1F7B  created: 2006-03-18  expired: 2011-05-23  usage: S   
sub  1024R/A14C401A  created: 2006-03-18  expired: 2011-05-23  usage: E   
[ unknown] (1). Simon Josefsson 
[ unknown] (2)  Simon Josefsson 
[ revoked] (3)  Simon Josefsson 

Really sign all user IDs? (y/N) y
User ID "Simon Josefsson " is revoked.  Unable to sign.

pub  1280R/B565716F  created: 2002-05-05  expires: 2014-11-10  usage: SC  
                     trust: unknown       validity: unknown
 Primary key fingerprint: 0424 D4EE 81A0 E3D1 19C6  F835 EDA2 1E94 B565 716F

     Simon Josefsson 
     Simon Josefsson 

This key is due to expire on 2014-11-10.
Are you sure that you want to sign this key with your
key "Simon Josefsson " (1C5C4717)

Really sign? (y/N) y

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 1C5C4717, created 2014-06-18


user@debian:~$ 

Then export the newly signed key back to your laptop for further distribution.

user@debian:~$ gpg -a --export b565716f > /media/KINGSTON/signed-b565716f.txt
user@debian:~$ 

On your laptop, either email it encrypted to the other person, or upload it to keyservers directly depending on your preference. By emailing it encrypted to the other person, they need to prove posession of the key before receiving your signature. In my case, I’m the other person, so I just import the signed key and then send the key:

jas@latte:~$ gpg --import 

Key transition

Since I'm migrating from an key to a new, I sign my new key using my old key, and publish that signature on keyservers. This allows people to trust my new key more easily.

To let the world know about your key transition, I created a key transition statement. The transition statement should be signed by both keys. I created a new temporary GnuPG home directory and imported both master keys, and clearsigned the file. Note that I used "54265e8c!" to make GnuPG use the master key for signing rather than a subkey, which it would normally do.

user@debian:~$ export GNUPGHOME=/tmp/kts
user@debian:~$ mkdir $GNUPGHOME
user@debian:~$ gpg --import b565716f.txt 
gpg: WARNING: unsafe permissions on homedir `/tmp/kts'
gpg: keyring `/tmp/kts/secring.gpg' created
gpg: keyring `/tmp/kts/pubring.gpg' created
gpg: key B565716F: secret key imported
gpg: /tmp/kts/trustdb.gpg: trustdb created
gpg: key B565716F: public key "Simon Josefsson " imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
gpg:       secret keys read: 1
gpg:   secret keys imported: 1
user@debian:~$ gpg --import /media/FA21-AE97/secret-master-subkeys.txt 
gpg: WARNING: unsafe permissions on homedir `/tmp/kts'
gpg: key 54265E8C: secret key imported
gpg: key 54265E8C: public key "Simon Josefsson " imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
gpg:       secret keys read: 1
gpg:   secret keys imported: 1
user@debian:~$ cat key-transition-2014-06-22-unsigned.txt | gpg --clearsign --personal-digest-preferences "SHA512" --local-user b565716f --local-user 54265e8c! > key-transition-2014-06-22.txt 
gpg: WARNING: unsafe permissions on homedir `/tmp/kts'

You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 54265E8C, created 2014-06-22

                  
You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
1280-bit RSA key, ID B565716F, created 2002-05-05

user@debian:~$    

My statement is available as https://josefsson.org/key-transition-2014-06-22.txt if you want to download the signed text file directly. Feel free to base your own document on it, as I based mine on earlier examples.

flattr this!

Syndicated 2014-06-23 11:18:38 from Simon Josefsson's blog

39 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!