summaryrefslogtreecommitdiffstats
path: root/Documentation/process/maintainer-pgp-guide.rst
blob: 8f8f1fee92b8514394419b89730d03b4ad80ef5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
.. _pgpguide:

===========================
Kernel Maintainer PGP guide
===========================

:Author: Konstantin Ryabitsev <konstantin@linuxfoundation.org>

This document is aimed at Linux kernel developers, and especially at
subsystem maintainers. It contains a subset of information discussed in
the more general "`Protecting Code Integrity`_" guide published by the
Linux Foundation. Please read that document for more in-depth discussion
on some of the topics mentioned in this guide.

.. _`Protecting Code Integrity`: https://github.com/lfit/itpol/blob/master/protecting-code-integrity.md

The role of PGP in Linux Kernel development
===========================================

PGP helps ensure the integrity of the code that is produced by the Linux
kernel development community and, to a lesser degree, establish trusted
communication channels between developers via PGP-signed email exchange.

The Linux kernel source code is available in two main formats:

- Distributed source repositories (git)
- Periodic release snapshots (tarballs)

Both git repositories and tarballs carry PGP signatures of the kernel
developers who create official kernel releases. These signatures offer a
cryptographic guarantee that downloadable versions made available via
kernel.org or any other mirrors are identical to what these developers
have on their workstations. To this end:

- git repositories provide PGP signatures on all tags
- tarballs provide detached PGP signatures with all downloads

.. _devs_not_infra:

Trusting the developers, not infrastructure
-------------------------------------------

Ever since the 2011 compromise of core kernel.org systems, the main
operating principle of the Kernel Archives project has been to assume
that any part of the infrastructure can be compromised at any time. For
this reason, the administrators have taken deliberate steps to emphasize
that trust must always be placed with developers and never with the code
hosting infrastructure, regardless of how good the security practices
for the latter may be.

The above guiding principle is the reason why this guide is needed. We
want to make sure that by placing trust into developers we do not simply
shift the blame for potential future security incidents to someone else.
The goal is to provide a set of guidelines developers can use to create
a secure working environment and safeguard the PGP keys used to
establish the integrity of the Linux kernel itself.

.. _pgp_tools:

PGP tools
=========

Use GnuPG v2
------------

Your distro should already have GnuPG installed by default, you just
need to verify that you are using version 2.x and not the legacy 1.4
release -- many distributions still package both, with the default
``gpg`` command invoking GnuPG v.1. To check, run::

    $ gpg --version | head -n1

If you see ``gpg (GnuPG) 1.4.x``, then you are using GnuPG v.1. Try the
``gpg2`` command (if you don't have it, you may need to install the
gnupg2 package)::

    $ gpg2 --version | head -n1

If you see ``gpg (GnuPG) 2.x.x``, then you are good to go. This guide
will assume you have the version 2.2 of GnuPG (or later). If you are
using version 2.0 of GnuPG, then some of the commands in this guide will
not work, and you should consider installing the latest 2.2 version of
GnuPG. Versions of gnupg-2.1.11 and later should be compatible for the
purposes of this guide as well.

If you have both ``gpg`` and ``gpg2`` commands, you should make sure you
are always using GnuPG v2, not the legacy version. You can enforce this
by setting the appropriate alias::

    $ alias gpg=gpg2

You can put that in your ``.bashrc`` to make sure it's always the case.

Configure gpg-agent options
~~~~~~~~~~~~~~~~~~~~~~~~~~~

The GnuPG agent is a helper tool that will start automatically whenever
you use the ``gpg`` command and run in the background with the purpose
of caching the private key passphrase. There are two options you should
know in order to tweak when the passphrase should be expired from cache:

- ``default-cache-ttl`` (seconds): If you use the same key again before
  the time-to-live expires, the countdown will reset for another period.
  The default is 600 (10 minutes).
- ``max-cache-ttl`` (seconds): Regardless of how recently you've used
  the key since initial passphrase entry, if the maximum time-to-live
  countdown expires, you'll have to enter the passphrase again. The
  default is 30 minutes.

If you find either of these defaults too short (or too long), you can
edit your ``~/.gnupg/gpg-agent.conf`` file to set your own values::

    # set to 30 minutes for regular ttl, and 2 hours for max ttl
    default-cache-ttl 1800
    max-cache-ttl 7200

.. note::

    It is no longer necessary to start gpg-agent manually at the
    beginning of your shell session. You may want to check your rc files
    to remove anything you had in place for older versions of GnuPG, as
    it may not be doing the right thing any more.

Set up a refresh cronjob
~~~~~~~~~~~~~~~~~~~~~~~~

You will need to regularly refresh your keyring in order to get the
latest changes on other people's public keys, which is best done with a
daily cronjob::

    @daily /usr/bin/gpg2 --refresh >/dev/null 2>&1

Check the full path to your ``gpg`` or ``gpg2`` command and use the
``gpg2`` command if regular ``gpg`` for you is the legacy GnuPG v.1.

.. _master_key:

Protect your master PGP key
===========================

This guide assumes that you already have a PGP key that you use for Linux
kernel development purposes. If you do not yet have one, please see the
"`Protecting Code Integrity`_" document mentioned earlier for guidance
on how to create a new one.

You should also make a new key if your current one is weaker than 2048 bits
(RSA).

Master key vs. Subkeys
----------------------

Subkeys are fully independent PGP keypairs that are tied to the "master"
key using certifying key signatures (certificates). It is important to
understand the following:

1. There are no technical differences between the "master key" and "subkeys."
2. At creation time, we assign functional limitations to each key by
   giving it specific capabilities.
3. A PGP key can have 4 capabilities:

   - **[S]** key can be used for signing
   - **[E]** key can be used for encryption
   - **[A]** key can be used for authentication
   - **[C]** key can be used for certifying other keys

4. A single key may have multiple capabilities.
5. A subkey is fully independent from the master key. A message
   encrypted to a subkey cannot be decrypted with the master key. If you
   lose your private subkey, it cannot be recreated from the master key
   in any way.

The key carrying the **[C]** (certify) capability is considered the
"master" key because it is the only key that can be used to indicate
relationship with other keys. Only the **[C]** key can be used to:

- add or revoke other keys (subkeys) with S/E/A capabilities
- add, change or revoke identities (uids) associated with the key
- add or change the expiration date on itself or any subkey
- sign other people's keys for web of trust purposes

By default, GnuPG creates the following when generating new keys:

- A master key carrying both Certify and Sign capabilities (**[SC]**)
- A separate subkey with the Encryption capability (**[E]**)

If you used the default parameters when generating your key, then that
is what you will have. You can verify by running ``gpg --list-secret-keys``,
for example::

    sec   rsa2048 2018-01-23 [SC] [expires: 2020-01-23]
          000000000000000000000000AAAABBBBCCCCDDDD
    uid           [ultimate] Alice Dev <adev@kernel.org>
    ssb   rsa2048 2018-01-23 [E] [expires: 2020-01-23]

Any key carrying the **[C]** capability is your master key, regardless
of any other capabilities it may have assigned to it.

The long line under the ``sec`` entry is your key fingerprint --
whenever you see ``[fpr]`` in the examples below, that 40-character
string is what it refers to.

Ensure your passphrase is strong
--------------------------------

GnuPG uses passphrases to encrypt your private keys before storing them on
disk. This way, even if your ``.gnupg`` directory is leaked or stolen in
its entirety, the attackers cannot use your private keys without first
obtaining the passphrase to decrypt them.

It is absolutely essential that your private keys are protected by a
strong passphrase. To set it or change it, use::

    $ gpg --change-passphrase [fpr]

Create a separate Signing subkey
--------------------------------

Our goal is to protect your master key by moving it to offline media, so
if you only have a combined **[SC]** key, then you should create a separate
signing subkey::

    $ gpg --quick-addkey [fpr] ed25519 sign

Remember to tell the keyservers about this change, so others can pull down
your new subkey::

    $ gpg --send-key [fpr]

.. note:: ECC support in GnuPG

    GnuPG 2.1 and later has full support for Elliptic Curve
    Cryptography, with ability to combine ECC subkeys with traditional
    RSA master keys. The main upside of ECC cryptography is that it is
    much faster computationally and creates much smaller signatures when
    compared byte for byte with 2048+ bit RSA keys. Unless you plan on
    using a smartcard device that does not support ECC operations, we
    recommend that you create an ECC signing subkey for your kernel
    work.

    If for some reason you prefer to stay with RSA subkeys, just replace
    "ed25519" with "rsa2048" in the above command. Additionally, if you
    plan to use a hardware device that does not support ED25519 ECC
    keys, like Nitrokey Pro or a Yubikey, then you should use
    "nistp256" instead or "ed25519."


Back up your master key for disaster recovery
---------------------------------------------

The more signatures you have on your PGP key from other developers, the
more reasons you have to create a backup version that lives on something
other than digital media, for disaster recovery reasons.

The best way to create a printable hardcopy of your private key is by
using the ``paperkey`` software written for this very purpose. See ``man
paperkey`` for more details on the output format and its benefits over
other solutions. Paperkey should already be packaged for most
distributions.

Run the following command to create a hardcopy backup of your private
key::

    $ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt

Print out that file (or pipe the output straight to lpr), then take a
pen and write your passphrase on the margin of the paper. **This is
strongly recommended** because the key printout is still encrypted with
that passphrase, and if you ever change it you will not remember what it
used to be when you had created the backup -- *guaranteed*.

Put the resulting printout and the hand-written passphrase into an envelope
and store in a secure and well-protected place, preferably away from your
home, such as your bank vault.

.. note::

    Your printer is probably no longer a simple dumb device connected to
    your parallel port, but since the output is still encrypted with
    your passphrase, printing out even to "cloud-integrated" modern
    printers should remain a relatively safe operation. One option is to
    change the passphrase on your master key immediately after you are
    done with paperkey.

Back up your whole GnuPG directory
----------------------------------

.. warning::

    **!!!Do not skip this step!!!**

It is important to have a readily available backup of your PGP keys
should you need to recover them. This is different from the
disaster-level preparedness we did with ``paperkey``. You will also rely
on these external copies whenever you need to use your Certify key --
such as when making changes to your own key or signing other people's
keys after conferences and summits.

Start by getting a small USB "thumb" drive (preferably two!) that you
will use for backup purposes. You will need to encrypt them using LUKS
-- refer to your distro's documentation on how to accomplish this.

For the encryption passphrase, you can use the same one as on your
master key.

Once the encryption process is over, re-insert the USB drive and make
sure it gets properly mounted. Copy your entire ``.gnupg`` directory
over to the encrypted storage::

    $ cp -a ~/.gnupg /media/disk/foo/gnupg-backup

You should now test to make sure everything still works::

    $ gpg --homedir=/media/disk/foo/gnupg-backup --list-key [fpr]

If you don't get any errors, then you should be good to go. Unmount the
USB drive, distinctly label it so you don't blow it away next time you
need to use a random USB drive, and put in a safe place -- but not too
far away, because you'll need to use it every now and again for things
like editing identities, adding or revoking subkeys, or signing other
people's keys.

Remove the master key from  your homedir
----------------------------------------

The files in our home directory are not as well protected as we like to
think.  They can be leaked or stolen via many different means:

- by accident when making quick homedir copies to set up a new workstation
- by systems administrator negligence or malice
- via poorly secured backups
- via malware in desktop apps (browsers, pdf viewers, etc)
- via coercion when crossing international borders

Protecting your key with a good passphrase greatly helps reduce the risk
of any of the above, but passphrases can be discovered via keyloggers,
shoulder-surfing, or any number of other means. For this reason, the
recommended setup is to remove your master key from your home directory
and store it on offline storage.

.. warning::

    Please see the previous section and make sure you have backed up
    your GnuPG directory in its entirety. What we are about to do will
    render your key useless if you do not have a usable backup!

First, identify the keygrip of your master key::

    $ gpg --with-keygrip --list-key [fpr]

The output will be something like this::

    pub   rsa2048 2018-01-24 [SC] [expires: 2020-01-24]
          000000000000000000000000AAAABBBBCCCCDDDD
          Keygrip = 1111000000000000000000000000000000000000
    uid           [ultimate] Alice Dev <adev@kernel.org>
    sub   rsa2048 2018-01-24 [E] [expires: 2020-01-24]
          Keygrip = 2222000000000000000000000000000000000000
    sub   ed25519 2018-01-24 [S]
          Keygrip = 3333000000000000000000000000000000000000

Find the keygrip entry that is beneath the ``pub`` line (right under the
master key fingerprint). This will correspond directly to a file in your
``~/.gnupg`` directory::

    $ cd ~/.gnupg/private-keys-v1.d
    $ ls
    1111000000000000000000000000000000000000.key
    2222000000000000000000000000000000000000.key
    3333000000000000000000000000000000000000.key

All you have to do is simply remove the .key file that corresponds to
the master keygrip::

    $ cd ~/.gnupg/private-keys-v1.d
    $ rm 1111000000000000000000000000000000000000.key

Now, if you issue the ``--list-secret-keys`` command, it will show that
the master key is missing (the ``#`` indicates it is not available)::

    $ gpg --list-secret-keys
    sec#  rsa2048 2018-01-24 [SC] [expires: 2020-01-24]
          000000000000000000000000AAAABBBBCCCCDDDD
    uid           [ultimate] Alice Dev <adev@kernel.org>
    ssb   rsa2048 2018-01-24 [E] [expires: 2020-01-24]
    ssb   ed25519 2018-01-24 [S]

You should also remove any ``secring.gpg`` files in the ``~/.gnupg``
directory, which are left over from earlier versions of GnuPG.

If you don't have the "private-keys-v1.d" directory
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you do not have a ``~/.gnupg/private-keys-v1.d`` directory, then your
secret keys are still stored in the legacy ``secring.gpg`` file used by
GnuPG v1. Making any changes to your key, such as changing the
passphrase or adding a subkey, should automatically convert the old
``secring.gpg`` format to use ``private-keys-v1.d`` instead.

Once you get that done, make sure to delete the obsolete ``secring.gpg``
file, which still contains your private keys.

.. _smartcards:

Move the subkeys to a dedicated crypto device
=============================================

Even though the master key is now safe from being leaked or stolen, the
subkeys are still in your home directory. Anyone who manages to get
their hands on those will be able to decrypt your communication or fake
your signatures (if they know the passphrase). Furthermore, each time a
GnuPG operation is performed, the keys are loaded into system memory and
can be stolen from there by sufficiently advanced malware (think
Meltdown and Spectre).

The best way to completely protect your keys is to move them to a
specialized hardware device that is capable of smartcard operations.

The benefits of smartcards
--------------------------

A smartcard contains a cryptographic chip that is capable of storing
private keys and performing crypto operations directly on the card
itself. Because the key contents never leave the smartcard, the
operating system of the computer into which you plug in the hardware
device is not able to retrieve the private keys themselves. This is very
different from the encrypted USB storage device we used earlier for
backup purposes -- while that USB device is plugged in and mounted, the
operating system is able to access the private key contents.

Using external encrypted USB media is not a substitute to having a
smartcard-capable device.

Available smartcard devices
---------------------------

Unless all your laptops and workstations have smartcard readers, the
easiest is to get a specialized USB device that implements smartcard
functionality. There are several options available:

- `Nitrokey Start`_: Open hardware and Free Software, based on FSI
  Japan's `Gnuk`_. One of the few available commercial devices that
  support ED25519 ECC keys, but offer fewest security features (such as
  resistance to tampering or some side-channel attacks).
- `Nitrokey Pro 2`_: Similar to the Nitrokey Start, but more
  tamper-resistant and offers more security features. Pro 2 supports ECC
  cryptography (NISTP).
- `Yubikey 5`_: proprietary hardware and software, but cheaper than
  Nitrokey Pro and comes available in the USB-C form that is more useful
  with newer laptops. Offers additional security features such as FIDO
  U2F, among others, and now finally supports ECC keys (NISTP).

`LWN has a good review`_ of some of the above models, as well as several
others. Your choice will depend on cost, shipping availability in your
geographical region, and open/proprietary hardware considerations.

.. note::

    If you are listed in MAINTAINERS or have an account at kernel.org,
    you `qualify for a free Nitrokey Start`_ courtesy of The Linux
    Foundation.

.. _`Nitrokey Start`: https://shop.nitrokey.com/shop/product/nitrokey-start-6
.. _`Nitrokey Pro 2`: https://shop.nitrokey.com/shop/product/nitrokey-pro-2-3
.. _`Yubikey 5`: https://www.yubico.com/products/yubikey-5-overview/
.. _Gnuk: https://www.fsij.org/doc-gnuk/
.. _`LWN has a good review`: https://lwn.net/Articles/736231/
..</