IBM protected key support for ECDSA and EdDSA
This patch introduces support for ECDSA and EdDSA keys backed by IBM hardware. IBM private keys are passed from PEM file format while public keys will be passed by the existing file parsing mechanisms of OpenSSH. IBM protected keys are hardware protected keys that prevent the keys from being used on other systems which helps to prevent MitM attacks.
IMO this would be better supported as a PKCS#11 module that could be loaded into ssh-agent. This would eliminate the need for special code in OpenSSH, but would allow these keys to be used for user and host authentication like any others.
FYI EdDSA support for PKCS#11 keys is being worked on in https://github.com/djmdjm/openssh-wip/pull/58
Maybe I misunderstand something but the ssh-agent is for keys used during authentication by the client. What we are trying to do is using an hardware protected key which is solely useable by the machine it was generated on to authenticate the SERVER to the client. As I read the manpages ssh-agent is a convenience tool for ssh and not for sshd. Correct me if I am wrong. Our change introduces support for IBM hardware protected keys to be used as a ssh host key. This key when stolen cannot be used on any other machine therefore stealing the ssh host key (in the case it is such a key) would not make any sense at all. The servers ssh host key is unstealable in this case.
ssh-agent is usable by both the client and the server. On the server is may be used to provide access to the private host keys, see https://man.openbsd.org/sshd_config.5#HostKeyAgent for some more details.
Note that when you use a HostKeyAgent, you should list public keys in your sshd_config, e.g.
HostKeyAgent /var/run/sshd-agent.sock
Hostkey /etc/ssh/hostkey1.pub
Hostkey /etc/ssh/hostkey2.pub
In our case this will unfortunately not work because our keys are no PKCS#11 keys. An alternative to this patch would be for us to implement an openssl provider that could handle those keys but we would need OpenSSL 3.0 functions instead of the deprecated OpenSSL 1.1 functions used in OpenSSH. Is there any plan to migrate the deprecated OpenSSL functions from your side? Otherwise I would try to migrate where we need it.
Which functions are you taking about? OpenSSH moved to EVP_PKEY for public key handling a few releases ago.
Which functions are you taking about? OpenSSH moved to EVP_PKEY for public key handling a few releases ago.
EVP_PKEY API is one thing, but still many of these EVP functions are deprecated and will eventually go away.
For example if you look at function sshkey_ecdsa_fixup_group() in ssh-ecdsa.c there EVP_PKEY_get1_EC_KEY() is used to get the low level EC key. Then the low level API function EC_KEY_get0_group() is used to get the group from the low level EC key.
Low level APIs and key structures are deprecated and will go away: https://docs.openssl.org/3.0/man7/migration_guide/#deprecation-of-low-level-functions Furthermore using these functions will hinder these key to be handled in providers.
Currently, EVP_PKEY_get1_EC_KEY() will downgrade a provider based PKEY object to a so called 'legacy' PKEY, which can no longer be handled by providers. Furthermore, this downgrade is only possible if all key parts of the key can be extracted from the provider key. This is not possible for certain hardware-backed keys used by certain providers, that don't allow to extract the private or secret key parts. Even if the downgrade works, any further processing will be done without the provider, since its now a legacy key. So using these deprecated functions basically hinder one from using providers with OpenSSH.
A replacement for EVP_PKEY_get1_EC_KEY() and EC_KEY_get0_group() as used in sshkey_ecdsa_fixup_group() would be for example:
EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, curve, sizeof(curve), &curve_len);
This gets the curve name as C-string from the PKEY object. You can then use OBJ_sn2nid(curve) to get the NID of this curve.
For all other things that one might need to obtain from a PKEY there are respective EVP_PKEY_get_param()
calls available, see https://docs.openssl.org/3.0/man7/migration_guide/#deprecated-low-level-key-object-getters-and-setters
These EVP_PKEY_get_param() calls are only available since OpenSSL 3.0, so the code would need
to use #ifdefs to have separate code paths for >= OpenSSL 3.0 and before.
sshkey_ecdsa_fixup_group() is just one example out of may where deprecated APIs are used.
Currently autoconf.ac sets OPENSSL_API_COMPAT=0x10100000L to silence the deprecation warnings:
# OpenSSL 3; we use the 1.1x API
# https://openssl.org/policies/general/versioning-policy.html
CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L"
If you remove that you will see lots of deprecation warnings. Those should be taken seriously, in not too far future OpenSSL will most likely remove those deprecated functions finally.