---
name: "efikeygen"
section: "1"
platform: "linux"
package: "pesign"
version: "117-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/efikeygen"
---

# efikeygen(1)

tool for generating keys for PE image signing for UEFI Secure Boot

## NAME

**efikeygen** – tool for generating keys for PE image signing for UEFI Secure Boot

## SYNOPSIS

**efikeygen**⟨ **-C** \| **-k** \| **-m**⟩⟨ **-S** \| **-****-signer** *nickname*⟩ **-n** *nickname* **-c** *common\_name* \[**-u** *url*\] \[**-s** *serial*\] \[**-d** *directory*\] \[**-t** *token*\]

## DESCRIPTION

**efikeygen** is a command line tool for generating keys and certificates to be used with pesign.  These are standard X.509 certificates, and can potentially be generated with any certificate creation tool. **efikeygen** generates certificates with sensible options set for a key to be used for PE image signing for UEFI Secure Boot.

## OPTIONS

- **-C** \| **-****-ca**

  Create a CA certificate

- **-k** \| **-****-kernel**

  Create a kernel signing certificate

  Not to be used for CA certificates

- **-m** \| **-****-module**

  Create a module signing certificate

  Not to be used for CA certificates

- **-S** \| **-****-self-sign**

  Create a self-signed certificate

- **-****-signer** *nickname*

  Use the NSS certificate referred to by *nickname* as the issuing certificate

- **-n** *nickname* \| **-nickname** *nickname*

  Set the new certificate nickname in the NSS database to *nickname*

- **-c** *common\_name* \| **-****-common-name** *common\_name*

  The X.509 Common Name for the generated certificate.  This should be in rfc2253 syntax, i.e.: "CN=John Doe,OU=editing,O=New York Times,L=New York,ST=NY,C=US"

- **-u** *url* \| **-****-url** *url*

  URL for information regarding this certificate and objects signed with it.

- **-s** *serial* \| **-****-serial** *serial*

  Serial number for use with this key.  A certificate is identified by its signer and its serial number, so it's best not to ever re-use this value with the same signer.  By default, this value will be generated at random. It is not recommended to use this option to override that.

- **-d** *directory* \| **-****-dbdir** *directory*

  The directory for the NSS key database( default: */etc/pki/pesign*)

- **-t** *token* \| **-****-token** *token*

  The NSS token name to use( default: *pkcs11:token=NSS%20Certificate%20DB*)

## EXAMPLES

### YubiKey

Here's how you create both a CA certificate and keypair and a kernel signing certificate and keypair, and import them into yubikey PIV devices:

Generate some keys:

```
# Create a new CA key
host:~$ efikeygen -C -n my-ca -S \
        -c "CN=CA Person,OU=My Org's CA,O=My Org" \
        -u https://myorg.example.com/ca/
# Create a kernel signing key
host:~$ efikeygen -n my-signer --signer my-ca -k \
        -c "CN=Secure Boot Signer,OU=My Org's CA,O=My Org" \
        -u https://myorg.example.com/ca/
```

Save the CA to a yubikey:

```
# Save it in a PKCS-12 bundle
host:~$ pk12util -d /etc/pki/pesign -o myca.pk12 -n my-ca
Enter password for PKCS12 file: <type a password here>
Re-enter password: <type it again here>
pk12util: PKCS12 EXPORT SUCCESSFUL
# Import the key into the yubikey
host:~$ yubico-piv-tool -s 9c -a import-key -K PKCS12 \
        -c -i myca.pk12
Enter PEM pass phrase: <type the same password here>
Successfully imported a new private key.
# Import the certificate into the yubikey
host:~$ yubico-piv-tool -s 9c -a import-certificate \
        -K PKCS12 -i myca.pk12
Enter PEM pass phrase: <type the same password here>
Successfully imported a new certificate.
# Remove the CA cert from the NSS database
host:~$ certutil -d /etc/pki/pesign -D -n my-ca
```

Now switch yubikeys and import the kernel signer onto another one

```
# Save it in a PKCS-12 bundle
host:~$ pk12util -d /etc/pki/pesign -o mysigner.pk12 -n my-signer
Enter password for PKCS12 file: <type a password here>
Re-enter password: <type it again here>
pk12util: PKCS12 EXPORT SUCCESSFUL
# Import the key into the yubikey
host:~$ yubico-piv-tool -s 9c -a import-key -K PKCS12 \
        -i mysigner.pk12
Enter PEM pass phrase: <type the same password here>
Successfully imported a new private key.
# Import the certificate into the yubikey
host:~$ yubico-piv-tool -s 9c -a import-certificate \
        -K PKCS12 -i mysigner.pk12
Enter PEM pass phrase: <type it again here>
Successfully imported a new certificate.
# Remove the kernel signer from the NSS database
host:~$ certutil -d /etc/pki/pesign -D -n my-signer
```

Once you have done this, you are prepared to sign binaries:

```
# On each of these prompts, you have to enter the PIN for
# the Yubikey.  This and the strange choice of names are
# because PKCS-11 is horrible.  I'm sorry.
host:~$ pesign -s -t 'Secure Boot Signer' \
        -c "Certificate for Digital Signature" \
        -i shimx64.efi -o shimx64.signed.efi
Enter Password or Pin for "Secure Boot Signer": <type the PIN here>
Enter passphrase for private key: <type it again here>
Enter passphrase for private key: <type it again here>
```

Now verify that it worked:

```
host:~$ pesign -i shimx64.signed.efi -l
---------------------------------------------
certificate address is 0x7fbbae061468
Content was not encrypted.
Content is detached; signature cannot be verified.
The signer's common name is Secure Boot Signer
No signer email address.
Signing time: Wed May 15, 2019
There were certs or crls included.
---------------------------------------------
```

Yay!

### OpenSC (smart card)

Here's how you create both a CA certificate and keypair and a kernel signing certificate and keypair, and import them into CardOS Smart Card devices supported by OpenSC:

Optionally, format the card and initialize its PKCS15 data:

```
# Format the card
host:~$ cardos-tool -f
Using reader with a card: Generic Smart Card Reader Interface [Smart Card Reader Interface] (20070818000000000) 00 00
card in administrative state, ok
# Initialize the card's PKCS15 data, set the Security Officer PIN and unlock
# code.
host:~$ pkcs15-init -CT --so-pin $SOPIN --so-puk $SOPUK
Using reader with a card: Generic Smart Card Reader Interface [Smart Card Reader Interface] (20070818000000000) 00 00
# Initialize the user PIN and unlock code, and label the token
host:~$ pkcs15-init -P -a 1 --pin $PIN --puk $PUK \
        --so-pin $SOPIN --so-puk $SOPUK \
        --label "myorg-sb-ca"
Using reader with a card: Generic Smart Card Reader Interface [Smart Card Reader Interface] (20070818000000000) 00 00
```

Generate keys and certificates:

```
# Create a new CA key and certificate
host:~$ efikeygen -C -n my-ca -S \
        -c "CN=My Org's Secure Boot CA,OU=My Org's CA,O=My Org" \
        -u https://myorg.example.com/ca/
# Create a kernel signing key and cert
host:~$ efikeygen -n my-signer --signer my-ca -k \
        -c "CN=My Org's SB Signer,OU=My Org's CA,O=My Org"\
        -u https://myorg.example.com/ca/
```

Get them onto the Smart Card

```
# Save the CA key and certificate in a PKCS-12 bundle
host:~$ pk12util -d /etc/pki/pesign -o my-ca.p12 -n my-ca
Enter password for PKCS12 file: <enter a password here>
Re-enter password: <type it again here>
pk12util: PKCS12 EXPORT SUCCESSFUL
# Import the PKCS-12 bundle onto the card
host:~$ pkcs15-init --store-private-key my-ca.p12 \
        --format pkcs12 --auth-id 01 \
        --pin $PIN --so-pin $SOPIN --so-puk $SOPUK
Using reader with a card: Generic Smart Card Reader Interface [Smart Card Reader Interface] (20070818000000000) 00 00
Importing 1 certificates:
   0: /CN=My Org's Secure Boot CA
# List the contents:
host:~$ pkcs11-tool --module opensc-pkcs11.so -l --pin $PIN -O
Using slot 1 with a present token (0x1)
Private Key Object; RSA
  label:      Private Key
  ID:         de61fac87e0315352e7b9a487377ace2f6354d9b
  Usage:      sign
Certificate Object, type = X.509 cert
  label:      /CN=My Org's Secure Boot CA
  ID:         de61fac87e0315352e7b9a487377ace2f6354d9b
Public Key Object; RSA 2048 bits
  label:      /CN=My Org's Secure Boot CA
  ID:         de61fac87e0315352e7b9a487377ace2f6354d9b
  Usage:      encrypt, verify
# Check and make sure nss can see the card
host:~$ modutil -dbdir /etc/pki/pesign/ -list
Listing of PKCS #11 Modules
-----------------------------------------------------------
  1. NSS Internal PKCS #11 Module
     slots: 2 slots attached
    status: loaded
     slot: NSS Internal Cryptographic Services
    token: NSS Generic Crypto Services
     slot: NSS User Private Key and Certificate Services
    token: NSS Certificate DB
  2. opensc-pkcs11
    library name: /usr/lib64/pkcs11/opensc-pkcs11.so
     slots: 2 slots attached
    status: loaded
     slot: Virtual hotplug slot
    token:
     slot: Generic Smart Card Reader Interface [Smart Card Read...
    token: OpenSC Card (myorg-sb-ca)
-----------------------------------------------------------
# Check and make sure NSS can see the certificate:
host:~$ certutil -d /etc/pki/pesign -L \
        -h "OpenSC Card (myorg-sb-ca)"
Certificate Nickname                             Trust Attributes
                                                 SSL,S/MIME,JAR/XPI
Enter Password or Pin for "OpenSC Card (myorg-sb-ca)": <type the PIN here>
OpenSC Card (myorg-sb-ca):/CN=My Org's Secure Boot CA    u,u,u
# Remove the CA from the NSS database
host:~$ certutil -d /etc/pki/pesign -D -n my-ca
```

Remember to switch cards and do the same thing with the signer, just as in the YubiKey example, then sign a binary with the signing key on a Smart Card and verify that it worked:

```
# Sign the binary.  On each of these prompts, you have to enter
# the PIN for the Smart Card.  This and the strange choice of
# names are because PKCS-11 is horrible.  I'm sorry.
host:~$ pesign -s -t "OpenSC Card(myorg-sb-signer)" \
        -c "OpenSC Card (myorg-sb-signer):/CN=My Org's SB Signer"\
        -i shimx64.efi -o shimx64.signed.efi
Enter Password or Pin for "My Org's SB Signer": <type the PIN here>
Enter passphrase for private key: <type the PIN here>
Enter passphrase for private key: <type the PIN here>
# Verify that it worked:
host:~$ pesign -i shimx64.signed.efi -l
---------------------------------------------
certificate address is 0x7fbbae061468
Content was not encrypted.
Content is detached; signature cannot be verified.
The signer's common name is My Org's SB Signer
No signer email address.
Signing time: Wed Jun 2, 2020
There were certs or crls included.
---------------------------------------------
```

Yay!

## STANDARDS

B. Kaliski, *PKCS #7: Cryptographic Message Syntax v1.5*, RFC 2315, Internet Engineering Task Force, March 1998, https://tools.ietf.org/html/rfc2315 .

K. Moriarty, M. Nyström, S. Parkinson, A. Rusch, and M. Scott, *PKCS #12: Personal Information Exchange Syntax v1.1*, RFC 7292, Internet Engineering Task Force, July 2014, https://tools.ietf.org/html/rfc7292 .

PKCS11 Technical Committee, *PKCS#11: Cryptographic Token Interface Standard*, OASIS, https://www.cryptsoft.com/pkcs11doc/.

## SEE ALSO

[certutil(1)](/certutil/1.md), [modutil(1)](/modutil/1.md), [opensc-tool(1)](/opensc-tool/1.md), [pesign(1)](/pesign/1.md), [pk12util(1)](/pk12util/1.md), [pkcs15-init(1)](/pkcs15-init/1.md), [yubico-piv-tool(1)](/yubico-piv-tool/1.md),

## AUTHORS

Peter Jones
