]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Refactored DES key manipulation functions
authorAdriaan de Jong <dejong@fox-it.com>
Thu, 23 Jun 2011 10:45:29 +0000 (12:45 +0200)
committerDavid Sommerseth <davids@redhat.com>
Wed, 19 Oct 2011 20:09:53 +0000 (22:09 +0200)
Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: David Sommerseth <davids@redhat.com>
Acked-by: James Yonan <james@openvpn.net>
Signed-off-by: David Sommerseth <davids@redhat.com>
crypto.c
crypto_backend.h
crypto_openssl.c
crypto_openssl.h
ntlm.c

index ff34d5fa803b34943fa09fdcaf96fbea2a8a3c1d..ea04cdd60fa04a5bbff589bb9c5b0ded73420705 100644 (file)
--- a/crypto.c
+++ b/crypto.c
@@ -601,83 +601,6 @@ free_key_ctx_bi (struct key_ctx_bi *ctx)
   free_key_ctx(&ctx->decrypt);
 }
 
-/*
- * Return number of DES cblocks for the current
- * key type or 0 if not a DES cipher.
- */
-static int
-n_DES_cblocks (const struct key_type *kt)
-{
-  int ret = 0;
-  const char *name = OBJ_nid2sn (EVP_CIPHER_nid (kt->cipher));
-  if (name)
-    {
-      if (!strncmp (name, "DES-", 4))
-       {
-         ret = EVP_CIPHER_key_length (kt->cipher) / sizeof (DES_cblock);
-       }
-      else if (!strncmp (name, "DESX-", 5))
-       {
-         ret = 1;
-       }
-    }
-  dmsg (D_CRYPTO_DEBUG, "CRYPTO INFO: n_DES_cblocks=%d", ret);
-  return ret;
-}
-
-static bool
-check_key_DES (struct key *key, const struct key_type *kt, int ndc)
-{
-  int i;
-  struct buffer b;
-
-  buf_set_read (&b, key->cipher, kt->cipher_length);
-
-  for (i = 0; i < ndc; ++i)
-    {
-      DES_cblock *dc = (DES_cblock*) buf_read_alloc (&b, sizeof (DES_cblock));
-      if (!dc)
-       {
-         msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material");
-         goto err;
-       }
-      if (DES_is_weak_key(dc))
-       {
-         msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected");
-         goto err;
-       }
-      if (!DES_check_key_parity (dc))
-       {
-         msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected");
-         goto err;
-       }
-    }
-  return true;
-
- err:
-  ERR_clear_error ();
-  return false;
-}
-
-static void
-fixup_key_DES (struct key *key, const struct key_type *kt, int ndc)
-{
-  int i;
-  struct buffer b;
-
-  buf_set_read (&b, key->cipher, kt->cipher_length);
-  for (i = 0; i < ndc; ++i)
-    {
-      DES_cblock *dc = (DES_cblock*) buf_read_alloc(&b, sizeof(DES_cblock));
-      if (!dc)
-       {
-         msg (D_CRYPT_ERRORS, "CRYPTO INFO: fixup_key_DES: insufficient key material");
-         ERR_clear_error ();
-         return;
-       }
-      DES_set_odd_parity (dc);
-    }
-}
 
 static bool
 key_is_zero (struct key *key, const struct key_type *kt)
@@ -708,9 +631,9 @@ check_key (struct key *key, const struct key_type *kt)
        * Check for weak or semi-weak DES keys.
        */
       {
-       const int ndc = n_DES_cblocks (kt);
+       const int ndc = key_des_num_cblocks (kt->cipher);
        if (ndc)
-         return check_key_DES (key, kt, ndc);
+         return key_des_check (key->cipher, kt->cipher_length, ndc);
        else
          return true;
       }
@@ -735,10 +658,10 @@ fixup_key (struct key *key, const struct key_type *kt)
 #ifdef ENABLE_DEBUG
       const struct key orig = *key;
 #endif
-      const int ndc = n_DES_cblocks (kt);
+      const int ndc = key_des_num_cblocks (kt->cipher);
 
       if (ndc)
-       fixup_key_DES (key, kt, ndc);
+       key_des_fixup (key->cipher, kt->cipher_length, ndc);
 
 #ifdef ENABLE_DEBUG
       if (check_debug_level (D_CRYPTO_DEBUG))
index 1b85decdbc9c22aa4445403f44fc330acad390af..f0e7b181d1c01479f0a86dd088c4c496498900c9 100644 (file)
@@ -89,6 +89,43 @@ void show_available_engines (void);
  */
 int rand_bytes (uint8_t *output, int len);
 
+/*
+ *
+ * Key functions, allow manipulation of keys.
+ *
+ */
+
+
+/**
+ * Return number of DES cblocks (1 cblock = length of a single-DES key) for the
+ * current key type or 0 if not a DES cipher.
+ *
+ * @param kt           Type of key
+ *
+ * @return             Number of DES cblocks that the key consists of, or 0.
+ */
+int key_des_num_cblocks (const cipher_kt_t *kt);
+
+/*
+ * Check the given DES key. Checks the given key's length, weakness and parity.
+ *
+ * @param key          Key to check
+ * @param key_len      Length of the key, in bytes
+ * @param ndc          Number of DES cblocks that the key is made up of.
+ *
+ * @return             \c true if the key is valid, \c false otherwise.
+ */
+bool key_des_check (uint8_t *key, int key_len, int ndc);
+
+/*
+ * Fix the given DES key, setting its parity to odd.
+ *
+ * @param key          Key to check
+ * @param key_len      Length of the key, in bytes
+ * @param ndc          Number of DES cblocks that the key is made up of.
+ */
+void key_des_fixup (uint8_t *key, int key_len, int ndc);
+
 /*
  *
  * Generic cipher key type functions
index 199a20999bd11713865a4f5795f97e7a479da10d..c0f36439f16974e83133be849bc5f238423e70a1 100644 (file)
 
 #if SSLEAY_VERSION_NUMBER < 0x00907000L
 
+#define DES_cblock                        des_cblock
+#define DES_is_weak_key                   des_is_weak_key
+#define DES_check_key_parity              des_check_key_parity
+#define DES_set_odd_parity                des_set_odd_parity
+
 #endif
 
 #if SSLEAY_VERSION_NUMBER < 0x00906000
@@ -354,3 +359,83 @@ int rand_bytes(uint8_t *output, int len)
   return RAND_bytes (output, len);
 }
 
+/*
+ *
+ * Key functions, allow manipulation of keys.
+ *
+ */
+
+
+int
+key_des_num_cblocks (const EVP_CIPHER *kt)
+{
+  int ret = 0;
+  const char *name = OBJ_nid2sn (EVP_CIPHER_nid (kt));
+  if (name)
+    {
+      if (!strncmp (name, "DES-", 4))
+       {
+         ret = EVP_CIPHER_key_length (kt) / sizeof (DES_cblock);
+       }
+      else if (!strncmp (name, "DESX-", 5))
+       {
+         ret = 1;
+       }
+    }
+  dmsg (D_CRYPTO_DEBUG, "CRYPTO INFO: n_DES_cblocks=%d", ret);
+  return ret;
+}
+
+bool
+key_des_check (uint8_t *key, int key_len, int ndc)
+{
+  int i;
+  struct buffer b;
+
+  buf_set_read (&b, key, key_len);
+
+  for (i = 0; i < ndc; ++i)
+    {
+      DES_cblock *dc = (DES_cblock*) buf_read_alloc (&b, sizeof (DES_cblock));
+      if (!dc)
+       {
+         msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material");
+         goto err;
+       }
+      if (DES_is_weak_key(dc))
+       {
+         msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected");
+         goto err;
+       }
+      if (!DES_check_key_parity (dc))
+       {
+         msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected");
+         goto err;
+       }
+    }
+  return true;
+
+ err:
+  ERR_clear_error ();
+  return false;
+}
+
+void
+key_des_fixup (uint8_t *key, int key_len, int ndc)
+{
+  int i;
+  struct buffer b;
+
+  buf_set_read (&b, key, key_len);
+  for (i = 0; i < ndc; ++i)
+    {
+      DES_cblock *dc = (DES_cblock*) buf_read_alloc(&b, sizeof(DES_cblock));
+      if (!dc)
+       {
+         msg (D_CRYPT_ERRORS, "CRYPTO INFO: fixup_key_DES: insufficient key material");
+         ERR_clear_error ();
+         return;
+       }
+      DES_set_odd_parity (dc);
+    }
+}
index ea3601e9b2256a986f70021d54d316a86048feed..9bc106abce200654227ed862bb1af6692339efef 100644 (file)
 #include <openssl/hmac.h>
 #include <openssl/md5.h>
 
+/** Generic cipher key type %context. */
+typedef EVP_CIPHER cipher_kt_t;
+
+/** Generic message digest key type %context. */
+typedef EVP_MD md_kt_t;
+
+/** Generic cipher %context. */
+typedef EVP_CIPHER_CTX cipher_ctx_t;
+
+/** Generic message digest %context. */
+typedef EVP_MD_CTX md_ctx_t;
+
+/** Generic HMAC %context. */
+typedef HMAC_CTX hmac_ctx_t;
+
 /** Maximum length of an IV */
 #define OPENVPN_MAX_IV_LENGTH  EVP_MAX_IV_LENGTH
 
diff --git a/ntlm.c b/ntlm.c
index 4dfeed38909caa656b612dd1a553eb2ad35eaf9d..3440c12506d7c9a921c3eedb06c0156738a0ba14 100644 (file)
--- a/ntlm.c
+++ b/ntlm.c
@@ -63,7 +63,7 @@ create_des_keys(const unsigned char *hash, unsigned char *key)
   key[5] = ((hash[4]&31)<<3)|(hash[5]>>5);
   key[6] = ((hash[5]&63)<<2)|(hash[6]>>6);
   key[7] = ((hash[6]&127)<<1);
-  des_set_odd_parity((des_cblock *)key);
+  key_des_fixup(key, 8, 1);
 }
 
 static void