Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yubikey support? #46

Open
mtottenh opened this issue Apr 17, 2018 · 3 comments
Open

Yubikey support? #46

mtottenh opened this issue Apr 17, 2018 · 3 comments

Comments

@mtottenh
Copy link
Contributor

I have a POC clevis encrypt/decrypt stub that uses gpg to interact with a stored OpenPGP key on a yubikey, it's something that I've been toying around but it might make sense to include upstream. I'm more than happy to open a PR if there is any interest.

@mtottenh
Copy link
Contributor Author

Apparently Yubikeys can be programmed with a static key that can be used in a challenge repose mode (which uses HMAC-SHA1). This might be a better option for Yubikey support as it doesn't require the user to enter their gpg card pin.

My POC looks something like

#!/bin/bash
# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
# Author: Max Tottenham <mtottenh@gmail.com>
[ $# -eq 1 -a "$1" == "--summary" ] && exit 1

if ! cfg=$(jose fmt -j "$1" -Oo- 2>/dev/null); then
    echo "Configuration is malformed!" >&2
    exit 1
fi

slot=$(jose fmt -j "$cfg" -g "slot" -u-)
if [ -z $slot ]; then
    echo "slot argument is required" >&2
    exit 1
elif [ $slot != "2" ] && [ "$slot" != "1" ]; then
    echo "Parameter 'slot' can only be '1' or '2'" >&2
    exit 1
fi

# Construct Yubikey Challenge
chal=$(dd if=/dev/urandom of=/dev/stdout bs=32 count=1 2>/dev/null | jose b64 enc -I- -o-)

if ! resp=$(ykchalresp -$slot "$chal"); then
    echo "Unable to perform challenge response with Yubikey for slot $slot" >&2
    exit 1
fi

key=$(echo -n "$resp" | jose pbkdf2 -i- | jose b64 enc -I- -o-)

jwk=$(jose jwk gen -i '{ "alg" : "A128GCM" }')

jwk=$(jose fmt -j "$jwk" -O -q "$key" -Ss k -Uo-)


jwe='{"protected":{"clevis":{"pin":"yubikey", "yubikey": {} }}}'
#Set challenege in Yubikey header
jwe=$(jose fmt -j "$jwe" -Og protected -g clevis -g yubikey -q "$chal" -Ss chal -U -q "$slot" -Ss slot -UUUUo-)

exec jose jwe enc -i- -k- -I- -c < <(echo -n "$jwe$jwk"; cat)

ykchalresp is a binary distributed with the yubikey-personalization library. jose pbkdf2 from a patch I wrote for jose to do PBKDF2 on arbitrary input.

@mtottenh mtottenh reopened this Apr 19, 2018
@anatol
Copy link
Contributor

anatol commented Oct 19, 2020

Having a pin that works with yubikey is indeed something useful for desktop machines.

@anatol
Copy link
Contributor

anatol commented May 20, 2021

I am also interested in seeing yubikey pin in clevis. challenge-response mode support would be a great first step.

Yubikeys supports SHA1 challenge-response that provides 160 bits output. @mtottenh in your example you use A128GCM that needs 128 bits key and Yubikeys output provides enough entropy for the block cipher. KDF is not really needed in this case.

But if we want to move to ciphers with bigger keys (e.g. A256GCM) then we need to "enlarge" the key material. KDF will help with it and also adds a few more bits of protection here.

If we do not want to use KDF then another alternative is to use a PRF. I locally implemented Yubikey+A256GCM and use SHA3-256 as a way to convert Yubikey's 160 bits output to 256 key. For that purpose I generate a salt and store it to protected node. It seems works great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants