As a Staking-as-a-Service provider, StakeWith.Us does deep research into segments that will enhance the security of our validation setup. We envisage that best practices for security and good uptime will eventually be commoditized — which is why we have decided to publish some of our findings from time to time to bring forth higher standards across all staking service providers.
For today, we will be touching on the kind of policies a validator should set for their Hardware Security Module (HSM), specifically the YubiHSM2, a physical cryptographic device, which is integral to a validation setup.
Why use a HSM?
In short, HSMs are affordable, performant and portable pieces of hardware that help to securely generate, store and manage your private keys. Malware attacks and remote extraction of private keys are much more difficult when an HSM is configured properly.
You can check out Loom Network’s article for more information on why validators need to use HSMs. We are of the view that all serious validators should utilize a HSM to minimize attack vectors on their physical servers. Without an HSM, your priv_validator.json will be in plain text. Attackers that get access to your server can simply copy out your private key and:
- Sign malicious transactions, often known as double spending, which will result in stake slashing, tombstone and/or unbonded delegators;
- Even if the tokens are locked and bonded, the attacker can unbond your validator stake, which will also result in unbonding of delegators’ stakes.
Types of Keys within an HSM
The default authentication key 0x0001 (default keyId: 0x0001, default password: password) is known as the Super-User. It has all capabilities and all delegated capabilities across all domains — Think of it as the one key to rule them all (or for Marvel fans, the Infinity Gauntlet). As such, it is crucial that secure HSM policies are in place to minimize security lapses.
One important policy you will be required to set is to limit the capabilities of the keys within the HSM. We have identified the 3 type of keys you will need to interact with for any validator setup:
- Authentication key: Used to establish sessions, encrypt messages and tag messages that are sent to and from the device — like an account username + password;
- Asymmetric key: A private key + public key pair. Only the private key is used to perform cryptographic operations (i.e., signing);
- Wrap key: A (secret) key used to decrypt/encrypt data and export asymmetric keys under encryption.
Explaining Capabilities + Delegated Capabilities
Using the Super-User, you are able to give keys new properties (new superpowers!) which allows them to perform certain actions directly. For example, you can give the ed25519 type asymmetric key a capability ‘sign-eddsa’ to perform the sign-eddsa action directly.
Delegated capabilities are properties that are derived from the creation of new keys. For example, you can have an authentication key A that has capability ‘put-asymmetric-key’, which allows you to import an asymmetric key with delegated capabilities, ‘sign-eddsa’. This means that you can use key A to create an asymmetric key B that has the abilities to carry out actions that key A couldn’t do.
Hence, we have to keep in mind that the effective capabilities of a key is dependent on both its capabilities and delegated capabilities.
Authentication keys are allowed to perform the following set of actions:
- unwrap-data to decrypt data using a wrap key
- put-authentication-key to store authentication keys in the HSM
- put-asymmetric-key to import an asymmetric key into the device
Objects created from an authentication key can perform the following set of actions:
- sign-eddsa: performs an eddsa signature
- exportable-under-wrap: enabling encrypted data matching a designated wrap key to be exportable
Protection of Secrets
The most secure way to backup or transfer a private key is to export the private key under wrap for signing. The private key should minimally be wrapped 2 out of 3 (or m out of n) times.
- to generate a wrap key (aes-ccm by default) from a random seed;
- exporting the key using a wrap key A;
- wrapping the key again using another wrap key B.
To import a secret back into any HSM:
- it needs to be unwrapped twice;
- doing so ensures 2 out of 3 control (or m out of n);
- all operations will be done within the HSM itself.
Creating Roles from Capabilities
Roles should be created as you deem fit to cover specific sets of responsibilities, such as importing of secrets/keys, using the secrets/keys or reset/recovery of device, etc.
The effective capabilities and domain of each role are required to be set clearly. Once the roles are designed and created, they should be tested to ensure they perform all required range of operations.
Remember the Super-User we mentioned earlier? Just like the Infinity Gauntlet, you have to delete the default authentication key (yes, it can delete itself) to ensure there is absolutely nothing that can mess around and bypass your roles configuration (see the Setting up New Keys section on how to delete the Super-User).
These are some of the roles we suggest all validators to have. All executables are to be done while logged in using 0x0001 (Hint: YubiHSM2 has 12 domains, and you can theoretically have 1 domain reserved for 1 validation project):
- Importer — Effective capabilities: put wrap key, unwrap data for asymmetric keys that can sign eddsa and have trait exportable-under-wrap. To generate an Importer, execute:
yubihsm> put authkey <session_id> 0x0002 importer <domain> import-wrapped,put-wrap-key,unwrap-data exportable-under-wrap,sign-eddsa,import-wrapped,unwrap-data <importer_password>
- Signer — Effective capabilities: sign-eddsa for asymmetric keys under its domain. To generate a Signer, execute:
yubihsm> put authkey <session_id> 0x0003 signer <domain> sign-eddsa sign-eddsa <signer_password>
- Resetter — Effective capabilities: resets the device:
yubihsm> put authkey <session_id> 0x0004 resetter <domain> reset-device reset-device <resetter_password>
- Notice that none of the roles are able to export a private key.
- Only the Signer can sign transactions, even though the Importer creates the key the Signer uses.
Setting up New Keys
For more information on commands, visit the YubiHSM2 developer portal here.
Pre-requisites and important notes:
- Download and extract the yubicohsm 2 SDK files;
- Plug in the HSM and start the connector via ‘sudo ./yubihsm-connector’;
- Create a new session with authentication key using the default password. Remember that all commands have session number in it and are to be executed within the yubihsm-shell:
yubihsm> session open <userId> <userPassword>Example:
yubihsm> session open 1 password
- Assume that all session_id is 0.
You can check the list of keys inside your device by typing:
yubihsm> list objects <session_id> <key_id> <key_type>
yubihsm> list objects 0 // Returns all keys
A blank device will only have the original authentication key 0x0001.
Next, generate your asymmetric keys:
yubihsm> generate asymmetric <session_id> <key_id> <label> <domain> <capabilities comma separated> <delegated_capabilities comma separated>Example:
yubihsm> generate asymmetric 0 0 key-name 3 sign-eddsa,exportable-under-wrap ed25519
To obtain your pubkey:
yubihsm> get pubkey <session_id> <asymmetric_key_id>
Generate your random seed (keep it secret and secure — please don’t lose it) and wrap keys (do this 3 times if you are doing 2 out of 3 control):
yubihsm> get random <session_id> 32
yubihsm> put wrapkey <session_id> <wrap_key_id> <label> <domains comma separated> <capabilities comma separated> <delegated capabilities comma separated> <random_seed>Example:
yubihsm> put wrapkey 0 0 NameYourWrapKey 3 export-wrapped,import-wrapped,wrap-data sign-eddsa,exportable-under-wrap <seed>
You should end up with 3 wrap keys generated from 3 unique seeds.
Do 2 out of 3 wrap and export encrypted asymmetric Key (according to table below). Note that you only need to export wrapped key A twice (A + B and A + C) and wrapped key B once (B + C):
yubihsm> get wrapped <session_id> <wrap_key_id> asymmetric-key <asymmetric_key_id>
It will return <exported_asymmetric_key_under_wrap> in hex form.
- Re-encrypt with wrapped key. Note: you only need to encrypt key B once t hanks f(for A + B) and key C twice (A + C and B + C):
yubihsm> encrypt aesccm <session_id> <wrap_key_id> <exported_asymmetric_key_under_wrap>
It should return <double_encrypted_asymmetric_keys>.
Thereafter, create the suggested roles — Importer, Signer and Resetter — and test them.
Reset the HSM after you have tested to ensure that they perform all required range of operations. Test again and once satisfactory, delete the Super-User using this command (while logged in with the authentication key 0x0001):
yubihsm> delete <session> 0x0001 authentication-key
Re-importing / Importing Keys onto another HSM
Assuming that you reset your HSM everytime after use, you will have to create the Importer authkey:
yubihsm> session open 0x0001 passwordyubihsm> put authkey <session_id> 0x0002 importer <domain> import-wrapped,put-wrap-key,unwrap-data exportable-under-wrap,sign-eddsa,import-wrapped,unwrap-data <importer_password>
Log in via the Importer and put wrap key into the HSM. Remember you have a total of 3 unlock conditions dependent on which wrap keys you are using (for this case, A + B). You will always decrypt the outer layer first:
yubihsm> session open 0x0002 <importer_password>yubihsm> put wrapkey <session_id> 0x000b wrapkey_B <domain> unwrap-data,import-wrapped exportable-under-wrap,sign-eddsa <seed_B>
It should return <wrap_key_id>. Decrypt the following to obtain the <outer_wrapped_validator_key>, which will be used after you obtain the second wrap key:
yubihsm> decrypt aesccm <session_id> <wrap_key_id> <double_encrypted_asymmetric_keys A + B>
Put the second wrap key into HSM again to obtain the <inner_wrap_key_id>:
yubihsm> put wrapkey <session_id> 0x000a wrapkey_A <domain> import-wrapped,unwrap-data exportable-under-wrap,sign-eddsa <seed A>
Use this command to then import the validator key into the HSM:
yubihsm> put wrapped <session_id> <inner_wrap_key_id> <outer_wrapped_validator_key>
You should get a message stating ‘Object imported as 0x0000’ of type asymmetric-key’. There you go, your validator key.
Verifying your Signing Keys / Signing Data
To test the Signer and the asymmetric Key, log in with your signer authkey 0x0003:
yubihsm> session open 0x0003 <signer_password>
Sign by executing this command:
yubihsm> sign eddsa <session_id> <assymmetric_key_id> ed25519 <message>
Resetting the HSM
In the event the authentication keys is lost, we can reset the HSM by physically resetting it (press 10 seconds while inserting the HSM), or via the command line:
yubihsm> reset <session_id>
and then check the HSM to ensure that the HSM is fully reset:
yubihsm> list objects <session_id> <domain>
Warning: Resetting the device will clear all authentication keys, wrap keys, asymmetric keys from the device, and is irreversible. The HSM needs to be physically pulled out and rebooted in order to use it again, so please plan ahead. The reset HSM will have the default username and password (1: password) with all the Super-User privileges.
We hope that this article has been helpful in assisting validators to setup their HSM policies and for delegators to understand the importance of HSM in a validation setup. Though delegation is non-custodial, the slashing and security risks involved in securing a network means that delegators have to trust that their chosen validators have setups which are secure and highly available.
The StakeWith.Us team will continue to do deep research and share our findings with the wider community. We will also continue to bootstrap high quality blockchain networks like Loom Network and Cosmos Network — for the potential delegators out there: please come and StakeWith.Us!
To our existing delegators — thank you for your support thus far. We really appreciate having you on this journey!
Till next time!
Disclaimer: This article is made available for educational purposes only, to give you general information and understanding on how HSM works. You should always check the online documentation provided by Yubico. By using this guide you understand that you are liable for all actions and losses resulting from the setup and usage of your HSM.
StakeWith.Us is a secure Staking-as-a-Service provider for leading blockchain projects. Put Your Crypto to Work — Hassle Free.
We are currently preparing a simple dashboard for Loom Network that is free for everyone to use.
To get more updates on our validation updates, please follow StakeWith.Us on Twitter, Telegram and Medium. If you are interested to join our WeChat group, kindly approach gobigordietrying or mcry89 on WeChat.
Alternatively, reach out to Earn@StakeWith.Us if:
- you have any burning queries for us;
- if you are a project looking for a professional validator;
- you are looking into investment and partnership opportunities with StakeWith.Us.
Special thanks to Oliver Wee for the research on HSM and for drafting this article together!
Loom Network is the blockchain platform of choice for serious dapp developers — the Universal Layer 2 that provides developers the tools they need to build functional user-facing dapps today.
New to Loom? Start here.
Want to stake your LOOM tokens and help secure Loom Network? Find out how.
And if you enjoyed this article and want to stay in the loop, go ahead and sign up for our private mailing list.