Skip to content

Instantly share code, notes, and snippets.

@joostd
Last active September 3, 2024 18:35
Show Gist options
  • Save joostd/69f02148b901cf2c5e00a4dd131400ff to your computer and use it in GitHub Desktop.
Save joostd/69f02148b901cf2c5e00a4dd131400ff to your computer and use it in GitHub Desktop.
Wrap and Unwrap keys using RSA_AES_KEY_WRAP_SHA256 with YubiHSM and OpenSSL
# generate and wrap target key on YubiHSM (firmware 2.4), unwrap using OpenSSL 3.3.1.
# Wrapping Algorithm = RSA_AES_KEY_WRAP_SHA256 (OAEP Padding - SHA256 digest + 256 bit AES-KWP)
HSM=yhusb://
TARGET_KEYID=0x1234
WRAP_KEYID=0xabcd
yubihsm="./yubihsm-shell -C $HSM -p password"
# generate target key
$yubihsm --action generate-asymmetric-key --object-id $TARGET_KEYID --domain 1 --capabilities exportable-under-wrap -A ecp256
# export target public key
$yubihsm --action get-public-key --object-id $TARGET_KEYID --object-type asymmetric-key --out target.pub
# generate wrap key
openssl genpkey -quiet -algorithm rsa -pkeyopt rsa_keygen_bits:4096 -out wrap.key
# import public wrap key, export wrapped target key
openssl pkey -in wrap.key -pubout | $yubihsm --action put-public-wrapkey --object-id $WRAP_KEYID --domain 1 --capabilities export-wrapped --delegated exportable-under-wrap
$yubihsm --action get-rsa-wrapped-key --wrap-id $WRAP_KEYID --object-type asymmetric-key --object-id $TARGET_KEYID --algorithm aes256 --oaep rsa-oaep-sha256 --mgf1 mgf1-sha256 --out target.key.wrapped
$yubihsm --action delete-object --object-id $TARGET_KEYID --object-type asymmetric-key 2>/dev/null
$yubihsm --action delete-object --object-id $WRAP_KEYID --object-type public-wrap-key 2>/dev/null
### UNWRAP
# extract RSA-encrypted ephemeral key and AES-encrypted target key
head -c512 target.key.wrapped > ephemeral_wrapped
tail -c +513 target.key.wrapped > target.key.aes
rm target.key.wrapped
# decrypt ephemeral key with RSA wrap key:
AES256KEY=$( \
openssl pkeyutl \
-decrypt \
-in ephemeral_wrapped \
-inkey wrap.key \
-pkeyopt rsa_padding_mode:oaep \
-pkeyopt rsa_oaep_md:sha256 \
-pkeyopt rsa_mgf1_md:sha256 \
| xxd -p -c32 \
)
rm ephemeral_wrapped wrap.key
# unwrap target key with ephemeral key
openssl aes256-wrap-pad -d -K $AES256KEY -iv A65959A6 -in target.key.aes -out target.key.der
openssl pkey -inform der --in target.key.der -out target.key
rm target.key.aes
echo hello world > message.txt
openssl dgst -sha256 -sign target.key -out message.sig message.txt
openssl dgst -sha256 -verify target.pub -signature message.sig message.txt
rm message.sig message.txt
rm target.key target.pub
# generate and wrap target key using OpenSSL 3.3.1, unwrap on YubiHSM (firmware 2.4)
# Wrapping Algorithm = RSA_AES_KEY_WRAP_SHA256 (OAEP Padding - SHA256 digest + 256 bit AES-KWP)
HSM=yhusb://
TARGET_KEYID=0x1234
WRAP_KEYID=0xabcd
yubihsm="./yubihsm-shell -C $HSM -p password"
# generate target key
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve | openssl pkcs8 -topk8 -outform DER -out target.key -nocrypt
# export target public key
openssl pkey -in target.key -pubout -out target.pub
# generate wrap key
$yubihsm --action generate-wrap-key --object-id $WRAP_KEYID --domain 1 --capabilities import-wrapped --delegated sign-ecdsa --algorithm rsa2048
# export public wrap key
$yubihsm --action get-public-key --object-id $WRAP_KEYID --object-type wrap-key > wrap.pub
### WRAP
# generate AES256 ephemeral key
EPHEMERAL=$(openssl rand -hex 32)
# encrypt ephemeral key with RSA wrap key:
echo $EPHEMERAL | xxd -r -p | openssl pkeyutl \
-encrypt \
-inkey wrap.pub \
-pubin \
-pkeyopt rsa_padding_mode:oaep \
-pkeyopt rsa_oaep_md:sha256 \
-pkeyopt rsa_mgf1_md:sha256 \
-out ephemeral_wrapped
rm wrap.pub
# wrap target key with ephemeral key
openssl aes256-wrap-pad -e -K $EPHEMERAL -iv A65959A6 -in target.key -out target.key.aes
rm target.key
cat ephemeral_wrapped target.key.aes > target.key.wrapped
rm ephemeral_wrapped target.key.aes
$yubihsm --action put-rsa-wrapped-key --wrap-id $WRAP_KEYID --object-type asymmetric-key --algorithm ecp256 --domain 1 --object-id $TARGET_KEYID --capabilities sign-ecdsa --oaep rsa-oaep-sha256 --mgf1 mgf1-sha256 --in target.key.wrapped
rm target.key.wrapped
$yubihsm --action delete-object --object-id $WRAP_KEYID --object-type wrap-key 2>/dev/null
echo hello world > message.txt
$yubihsm --action sign-ecdsa -A ecdsa-sha256 --object-id $TARGET_KEYID --in message.txt --outformat bin > message.sig
$yubihsm --action delete-object --object-id $TARGET_KEYID --object-type asymmetric-key 2>/dev/null
openssl dgst -sha256 -verify target.pub -signature message.sig message.txt
rm message.sig message.txt target.pub
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment