]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix parameter types in sshkdf
authorJuergen Christ <jchrist@linux.ibm.com>
Mon, 14 Dec 2020 16:36:22 +0000 (17:36 +0100)
committerPatrick Steuer <patrick.steuer@de.ibm.com>
Thu, 28 Jan 2021 15:05:50 +0000 (16:05 +0100)
Handling of parameter OSSL_KDF_PARAM_SSHKDF_TYPE mixed integer and string
parameters.  This caused endianness problems on big-endian machines.  As a
result, it is not possible to pass FIPS tests since the parameter was stored
with an integer value but read via a cast to char pointer.  While this works
on little endian machines, big endian s390 read the most significant bits
instead of the least significant (as done by, e.g., x86).  Change the
parameter to char array and fix the usages.

Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com>
(Merged from https://github.com/openssl/openssl/pull/13781)

doc/man7/EVP_KDF-SSHKDF.pod
doc/man7/provider-kdf.pod
include/openssl/kdf.h
providers/fips/self_test_data.inc
providers/implementations/kdfs/sshkdf.c
test/evp_kdf_test.c

index 454bb6b699b0d53f587f6724bcd3413f59b88044..2b2f0cc22776ff4bc88e9fbb028e40aa52f17ff0 100644 (file)
@@ -41,9 +41,9 @@ These parameters work as described in L<EVP_KDF(3)/PARAMETERS>.
 These parameters set the respective values for the KDF.
 If a value is already set, the contents are replaced.
 
-=item "type" (B<OSSL_KDF_PARAM_SSHKDF_TYPE>) <integer>
+=item "type" (B<OSSL_KDF_PARAM_SSHKDF_TYPE>) <UTF8 string>
 
-This parameter sets the type for the SSHHKDF operation.
+This parameter sets the type for the SSHKDF operation.
 There are six supported types:
 
 =over 4
@@ -51,32 +51,32 @@ There are six supported types:
 =item EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV
 
 The Initial IV from client to server.
-A single char of value 65 (ASCII char 'A').
+Char array initializer of value {65, 0}, i.e., ASCII string "A".
 
 =item EVP_KDF_SSHKDF_TYPE_INITIAL_IV_SRV_TO_CLI
 
 The Initial IV from server to client
-A single char of value 66 (ASCII char 'B').
+Char array initializer of value {66, 0}, i.e., ASCII string "B".
 
 =item EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_CLI_TO_SRV
 
 The Encryption Key from client to server
-A single char of value 67 (ASCII char 'C').
+Char array initializer of value {67, 0}, i.e., ASCII string "C".
 
 =item EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_SRV_TO_CLI
 
 The Encryption Key from server to client
-A single char of value 68 (ASCII char 'D').
+Char array initializer of value {68, 0}, i.e., ASCII string "D".
 
 =item EVP_KDF_SSHKDF_TYPE_INTEGRITY_KEY_CLI_TO_SRV
 
 The Integrity Key from client to server
-A single char of value 69 (ASCII char 'E').
+Char array initializer of value {69, 0}, i.e., ASCII string "E".
 
 =item EVP_KDF_SSHKDF_TYPE_INTEGRITY_KEY_SRV_TO_CLI
 
 The Integrity Key from client to server
-A single char of value 70 (ASCII char 'F').
+Char array initializer of value {70, 0}, i.e., ASCII string "F".
 
 =back
 
@@ -103,6 +103,7 @@ This example derives an 8 byte IV using SHA-256 with a 1K "key" and appropriate
 
  EVP_KDF *kdf;
  EVP_KDF_CTX *kctx;
+ const char type[] = EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV;
  unsigned char key[1024] = "01234...";
  unsigned char xcghash[32] = "012345...";
  unsigned char session_id[32] = "012345...";
@@ -122,8 +123,8 @@ This example derives an 8 byte IV using SHA-256 with a 1K "key" and appropriate
                                           xcghash, (size_t)32);
  *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
                                           session_id, (size_t)32);
- *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_SSHKDF_TYPE,
-                                 EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV);
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_SSHKDF_TYPE,
+                                         type, sizeof(type));
  *p = OSSL_PARAM_construct_end();
  if (EVP_KDF_CTX_set_params(kctx, params) <= 0)
      /* Error */
index 07aaf373c6bb71f027b931beee067460b4d0dc82..be0bc7b51b52aa45fa2bc4fa2430dbe40bc4bed4 100644 (file)
@@ -246,7 +246,7 @@ Sets the xcghash in the associated KDF ctx.
 
 Sets the session ID in the associated KDF ctx.
 
-=item "type" (B<OSSL_KDF_PARAM_SSHKDF_TYPE>) <integer>
+=item "type" (B<OSSL_KDF_PARAM_SSHKDF_TYPE>) <UTF8 string>
 
 Sets the SSH KDF type parameter in the associated KDF ctx.
 There are six supported types:
index 7f89f7527062dadeb033ea6ce45fbababa4828f5..dd485bcb0161ee695f566852febfa5be42cb72be 100644 (file)
@@ -85,12 +85,14 @@ void EVP_KDF_names_do_all(const EVP_KDF *kdf,
 # define EVP_KDF_HKDF_MODE_EXTRACT_ONLY        1
 # define EVP_KDF_HKDF_MODE_EXPAND_ONLY         2
 
-#define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV     65
-#define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_SRV_TO_CLI     66
-#define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_CLI_TO_SRV 67
-#define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_SRV_TO_CLI 68
-#define EVP_KDF_SSHKDF_TYPE_INTEGRITY_KEY_CLI_TO_SRV  69
-#define EVP_KDF_SSHKDF_TYPE_INTEGRITY_KEY_SRV_TO_CLI  70
+/* SSHKDF key exchange stages.*/
+/* See https://tools.ietf.org/html/rfc4253#section-7.2 */
+#define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV     {65, 0}
+#define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_SRV_TO_CLI     {66, 0}
+#define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_CLI_TO_SRV {67, 0}
+#define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_SRV_TO_CLI {68, 0}
+#define EVP_KDF_SSHKDF_TYPE_INTEGRITY_KEY_CLI_TO_SRV  {69, 0}
+#define EVP_KDF_SSHKDF_TYPE_INTEGRITY_KEY_SRV_TO_CLI  {70, 0}
 
 /**** The legacy PKEY-based KDF API follows. ****/
 
index 4a9bcf450ef56f60abb63c71a188b9093b29f33c..7631d682e5babee2b54a391a8678a145d2d93504 100644 (file)
@@ -351,7 +351,7 @@ static const ST_KAT_PARAM pbkdf2_params[] = {
 };
 
 static const char sshkdf_digest[] = "SHA1";
-static int sshkdf_type = EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV;
+static const char sshkdf_type[] = EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV;
 static const unsigned char sshkdf_key[] = {
     0x00, 0x00, 0x00, 0x80, 0x55, 0xba, 0xe9, 0x31,
     0xc0, 0x7f, 0xd8, 0x24, 0xbf, 0x10, 0xad, 0xd1,
@@ -386,7 +386,7 @@ static const unsigned char sshkdf_expected[] = {
 };
 static const ST_KAT_PARAM sshkdf_params[] = {
     ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, sshkdf_digest),
-    ST_KAT_PARAM_INT(OSSL_KDF_PARAM_SSHKDF_TYPE, sshkdf_type),
+    ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_SSHKDF_TYPE, sshkdf_type),
     ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, sshkdf_key),
     ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SSHKDF_XCGHASH, sshkdf_xcghash),
     ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SSHKDF_SESSION_ID, sshkdf_session_id),
index daf0dd2e87c6ab46d0f328f74ea1376154ee811c..e86c502184e139b8442fd67d7d0894a911513d76 100644 (file)
@@ -135,7 +135,6 @@ static int kdf_sshkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
     const OSSL_PARAM *p;
     KDF_SSHKDF *ctx = vctx;
     OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx);
-    int t;
 
     if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
         return 0;
@@ -156,14 +155,17 @@ static int kdf_sshkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 
     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SSHKDF_TYPE))
         != NULL) {
-        if (p->data == NULL || p->data_size == 0)
+        const char *kdftype;
+
+        if (!OSSL_PARAM_get_utf8_string_ptr(p, &kdftype))
+            return 0;
+        if (kdftype == NULL || kdftype[0] == '\0' || kdftype[1] != '\0')
             return 0;
-        t = *(unsigned char *)p->data;
-        if (t < 65 || t > 70) {
+        if (kdftype[0] < 65 || kdftype[0] > 70) {
             ERR_raise(ERR_LIB_PROV, PROV_R_VALUE_ERROR);
             return 0;
         }
-        ctx->type = (char)t;
+        ctx->type = kdftype[0];
     }
     return 1;
 }
index d56e14cdb082e34f1a84ab4ca700924e2622aae8..b0e8d2b5fbdeac7e5bb25fc71f438f42ea2b2663 100644 (file)
@@ -1207,7 +1207,7 @@ static int test_kdf_sshkdf(void)
     int ret;
     EVP_KDF_CTX *kctx;
     OSSL_PARAM params[6], *p = params;
-    char kdftype = EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV;
+    char kdftype[] = EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV;
     unsigned char out[8];
     /* Test data from NIST CAVS 14.1 test vectors */
     static unsigned char key[] = {
@@ -1247,7 +1247,7 @@ static int test_kdf_sshkdf(void)
     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SSHKDF_SESSION_ID,
                                              sessid, sizeof(sessid));
     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_SSHKDF_TYPE,
-                                            &kdftype, sizeof(kdftype));
+                                            kdftype, sizeof(kdftype));
     *p = OSSL_PARAM_construct_end();
 
     ret =