Jeffrey Hawkins
2013-May-15 00:33 UTC
Support for "ssh-rsa-sha256" and "ssh-dss-sha256" ?
Functionality request for supporting Digital Signatures for RSA and DSS Public Key Algorithms in alignment with NIST SP800-131A. I assume this has been asked before, but I could not find in the archives. Support of "ssh-rsa-sha256" and "ssh-dss-sha256" public key algorithms for OpenSSH? I know Suite B Algorithms and x509 SSH Extension Algorithms are supported, but not a path some folks (us) want to take. Tectia supports similar algorithms via their own extensions in commercial SSH. Are these algorithms being worked on for OpenSSH or been previously rejected? Assuming not rejected, and no one working on it, if I were to do the work and create the patch set, would it be accepted into the mainline? Thanks, Jeff
Geoff_Lowe at McAfee.com
2013-May-23 15:19 UTC
RE: Support for "ssh-rsa-sha256" and "ssh-dss-sha256" ?
I would like to add support for this request also. Thanks, Geoff "with a G" -----Original Message----- Sent: Tuesday, May 14, 2013 7:33 PM To: openssh-unix-dev at mindrot.org Subject: Support for "ssh-rsa-sha256" and "ssh-dss-sha256" ?? Functionality request for supporting Digital Signatures for RSA and DSS Public Key Algorithms in alignment with NIST SP800-131A. I assume this has been asked before, but I could not find in the archives. Support of "ssh-rsa-sha256" and "ssh-dss-sha256" public key algorithms for OpenSSH? I know Suite B Algorithms and x509 SSH Extension Algorithms are supported, but not a path some folks (us) want to take. Tectia supports similar algorithms via their own extensions in commercial SSH. Are these algorithms being worked on for OpenSSH or been previously rejected? Assuming not rejected, and no one working on it, if I were to do the work and create the patch set, would it be accepted into the mainline? Thanks, Jeff _______________________________________________ openssh-unix-dev mailing list openssh-unix-dev at mindrot.org https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Damien Miller
2013-May-24 12:17 UTC
Re: Support for "ssh-rsa-sha256" and "ssh-dss-sha256" ?
On Tue, 14 May 2013, Jeffrey Hawkins wrote:> Functionality request for supporting Digital Signatures for RSA and DSS > Public Key Algorithms in alignment with NIST SP800-131A. > > I > assume this has been asked before, but I could not find in the > archives. Support of "ssh-rsa-sha256" and "ssh-dss-sha256" public key > algorithms for OpenSSH? I know Suite B Algorithms and x509 SSH > Extension Algorithms are supported, but not a path some folks (us) want > to take. Tectia supports similar algorithms via their own extensions > in commercial SSH.Adding the signature code is easy (see below for a hacky diff - not for use), it's going through and duplicating all the ssh-rsa code to support ssh-rsa-sha256 and dealing with the corner cases that it tricky. E.g. when we find a PEM RSA key on disk, do we load it as a ssh-rsa key, a ssh-rsa-sha256 key or both? There are more difficulties to do with certificates too when they are signed with RSA keys - should the signature be ssh-rsa or ssh-rsa-sha256? There are probably some other traps that haven't occurred to me yet :( Please file a bug at https://bugzilla.mindrot.org/ so we can thrash this out. -d Index: compat.c ==================================================================RCS file: /cvs/src/usr.bin/ssh/compat.c,v retrieving revision 1.81 diff -u -p -r1.81 compat.c --- compat.c 17 May 2013 00:13:13 -0000 1.81 +++ compat.c 24 May 2013 12:01:33 -0000 @@ -93,6 +93,7 @@ compat_datafellows(const char *version) { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, { "OpenSSH_4*", 0 }, { "OpenSSH_5*", SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT}, + { "OpenSSH_6.2xxx*", SSH_NEW_OPENSSH|SSH_NEW_RSA_SHA2}, { "OpenSSH*", SSH_NEW_OPENSSH }, { "*MindTerm*", 0 }, { "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| Index: compat.h ==================================================================RCS file: /cvs/src/usr.bin/ssh/compat.h,v retrieving revision 1.43 diff -u -p -r1.43 compat.h --- compat.h 23 Sep 2011 07:45:05 -0000 1.43 +++ compat.h 24 May 2013 12:01:33 -0000 @@ -59,6 +59,7 @@ #define SSH_BUG_RFWD_ADDR 0x02000000 #define SSH_NEW_OPENSSH 0x04000000 #define SSH_BUG_DYNAMIC_RPORT 0x08000000 +#define SSH_NEW_RSA_SHA2 0x10000000 void enable_compat13(void); void enable_compat20(void); Index: ssh-rsa.c ==================================================================RCS file: /cvs/src/usr.bin/ssh/ssh-rsa.c,v retrieving revision 1.46 diff -u -p -r1.46 ssh-rsa.c --- ssh-rsa.c 17 May 2013 00:13:14 -0000 1.46 +++ ssh-rsa.c 24 May 2013 12:01:33 -0000 @@ -32,7 +32,7 @@ static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *); -/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */ +/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 or SHA256 */ int ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, const u_char *data, u_int datalen) @@ -44,14 +44,28 @@ ssh_rsa_sign(const Key *key, u_char **si int ok, nid; Buffer b; - if (key == NULL || key->rsa == NULL || (key->type != KEY_RSA && - key->type != KEY_RSA_CERT && key->type != KEY_RSA_CERT_V00)) { - error("ssh_rsa_sign: no RSA key"); + if (key == NULL || key->rsa == NULL) { + error("%s: no RSA key", __func__); + return -1; + } + nid = NID_sha1; + if ((datafellows & SSH_BUG_RSASIGMD5) != 0) + nid = NID_md5; + else if ((datafellows & SSH_NEW_RSA_SHA2) != 0) { + nid = NID_sha256; + } + switch (key->type) { + case KEY_RSA: + case KEY_RSA_CERT: + case KEY_RSA_CERT_V00: + break; + default: + error("%s: wrong type key %s (%d)", + __func__, key_type(key), key->type); return -1; } - nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { - error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid); + error("%s: EVP_get_digestbynid %d failed", __func__, nid); return -1; } EVP_DigestInit(&md, evp_md); @@ -67,7 +81,7 @@ ssh_rsa_sign(const Key *key, u_char **si if (ok != 1) { int ecode = ERR_get_error(); - error("ssh_rsa_sign: RSA_sign failed: %s", + error("%s: RSA_sign failed: %s", __func__, ERR_error_string(ecode, NULL)); free(sig); return -1; @@ -78,7 +92,7 @@ ssh_rsa_sign(const Key *key, u_char **si memmove(sig + diff, sig, len); memset(sig, 0, diff); } else if (len > slen) { - error("ssh_rsa_sign: slen %u slen2 %u", slen, len); + error("%s: slen %u slen2 %u", __func__, slen, len); free(sig); return -1; } @@ -112,21 +126,37 @@ ssh_rsa_verify(const Key *key, const u_c u_int len, dlen, modlen; int rlen, ret, nid; - if (key == NULL || key->rsa == NULL || (key->type != KEY_RSA && - key->type != KEY_RSA_CERT && key->type != KEY_RSA_CERT_V00)) { - error("ssh_rsa_verify: no RSA key"); + if (key == NULL || key->rsa == NULL) { + error("%s: no RSA key", __func__); + return -1; + } + nid = NID_sha1; + if ((datafellows & SSH_BUG_RSASIGMD5) != 0) + nid = NID_md5; + else if ((datafellows & SSH_NEW_RSA_SHA2) != 0) { + nid = NID_sha256; + } + switch (key->type) { + case KEY_RSA: + case KEY_RSA_CERT: + case KEY_RSA_CERT_V00: + break; + default: + error("%s: wrong type key %s (%d)", + __func__, key_type(key), key->type); return -1; } if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { - error("ssh_rsa_verify: RSA modulus too small: %d < minimum %d bits", - BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE); + error("%s: RSA modulus too small: %d < minimum %d bits", + __func__, BN_num_bits(key->rsa->n), + SSH_RSA_MINIMUM_MODULUS_SIZE); return -1; } buffer_init(&b); buffer_append(&b, signature, signaturelen); ktype = buffer_get_cstring(&b, NULL); if (strcmp("ssh-rsa", ktype) != 0) { - error("ssh_rsa_verify: cannot handle type %s", ktype); + error("%s: cannot handle type %s", __func__, ktype); buffer_free(&b); free(ktype); return -1; @@ -136,28 +166,27 @@ ssh_rsa_verify(const Key *key, const u_c rlen = buffer_len(&b); buffer_free(&b); if (rlen != 0) { - error("ssh_rsa_verify: remaining bytes in signature %d", rlen); + error("%s: remaining bytes in signature %d", __func__, rlen); free(sigblob); return -1; } /* RSA_verify expects a signature of RSA_size */ modlen = RSA_size(key->rsa); if (len > modlen) { - error("ssh_rsa_verify: len %u > modlen %u", len, modlen); + error("%s: len %u > modlen %u", __func__, len, modlen); free(sigblob); return -1; } else if (len < modlen) { u_int diff = modlen - len; - debug("ssh_rsa_verify: add padding: modlen %u > len %u", - modlen, len); + debug("%s: add padding: modlen %u > len %u", + __func__, modlen, len); sigblob = xrealloc(sigblob, 1, modlen); memmove(sigblob + diff, sigblob, len); memset(sigblob, 0, diff); len = modlen; } - nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { - error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid); + error("%s: EVP_get_digestbynid %d failed", __func__, nid); free(sigblob); return -1; } @@ -169,7 +198,7 @@ ssh_rsa_verify(const Key *key, const u_c memset(digest, 'd', sizeof(digest)); memset(sigblob, 's', len); free(sigblob); - debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : ""); + debug("%s: signature %scorrect", __func__, (ret==0) ? "in" : ""); return ret; } @@ -196,12 +225,27 @@ static const u_char id_sha1[] = { */ static const u_char id_md5[] = { 0x30, 0x20, /* type Sequence, length 0x20 (32) */ - 0x30, 0x0c, /* type Sequence, length 0x09 */ - 0x06, 0x08, /* type OID, length 0x05 */ + 0x30, 0x0c, /* type Sequence, length 0x0c (12) */ + 0x06, 0x08, /* type OID, length 0x08 */ 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */ 0x05, 0x00, /* NULL */ 0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */ }; +/* + * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html + * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) + * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) + * id-sha256(1) } + */ +static const u_char id_sha256[] = { + 0x30, 0x31, /* type Sequence, length 0x31 (49) */ + 0x30, 0x0d, /* type Sequence, length 0x0d (13) */ + 0x06, 0x09, /* type OID, length 0x09 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */ + 0x05, 0x00, /* NULL */ + 0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */ +}; + static int openssh_RSA_verify(int type, u_char *hash, u_int hashlen, @@ -218,6 +262,11 @@ openssh_RSA_verify(int type, u_char *has oid = id_sha1; oidlen = sizeof(id_sha1); hlen = 20; + break; + case NID_sha256: + oid = id_sha256; + oidlen = sizeof(id_sha256); + hlen = 32; break; case NID_md5: oid = id_md5; Index: version.h ==================================================================RCS file: /cvs/src/usr.bin/ssh/version.h,v retrieving revision 1.66 diff -u -p -r1.66 version.h --- version.h 10 Feb 2013 21:19:34 -0000 1.66 +++ version.h 24 May 2013 12:01:33 -0000 @@ -1,3 +1,3 @@ /* $OpenBSD: version.h,v 1.66 2013/02/10 21:19:34 markus Exp $ */ -#define SSH_VERSION "OpenSSH_6.2" +#define SSH_VERSION "OpenSSH_6.2xxx"