CVE-2021-20251 lib:crypto: Add des_crypt_blob_16() for encrypting data with DES
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Wed, 6 Jul 2022 03:36:26 +0000 (15:36 +1200)
committerJule Anger <janger@samba.org>
Mon, 19 Sep 2022 04:02:12 +0000 (04:02 +0000)
This lets us access single-DES from Python. This function is used in a
following commit for encrypting an NT hash to obtain the verifier for a
SAMR password change.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
(cherry picked from commit b27a67af0216811d330d8a4c52390cf4fc04b5fd)

lib/crypto/py_crypto.c
lib/crypto/wscript

index ad18d3ada0f97fdbf39b7786f970f289b734760e..6753d3d8e9cddd9b923577492b2f9fae3534ea1e 100644 (file)
@@ -25,6 +25,7 @@
 #include <gnutls/gnutls.h>
 #include <gnutls/crypto.h>
 #include "lib/crypto/gnutls_helpers.h"
+#include "libcli/auth/libcli_auth.h"
 
 static PyObject *py_crypto_arcfour_crypt_blob(PyObject *module, PyObject *args)
 {
@@ -100,13 +101,77 @@ static PyObject *py_crypto_set_strict_mode(PyObject *module)
        Py_RETURN_NONE;
 }
 
+static PyObject *py_crypto_des_crypt_blob_16(PyObject *self, PyObject *args)
+{
+       PyObject *py_data = NULL;
+       uint8_t *data = NULL;
+       Py_ssize_t data_size;
+
+       PyObject *py_key = NULL;
+       uint8_t *key = NULL;
+       Py_ssize_t key_size;
+
+       uint8_t result[16];
+
+       bool ok;
+       int ret;
+
+       ok = PyArg_ParseTuple(args, "SS",
+                             &py_data, &py_key);
+       if (!ok) {
+               return NULL;
+       }
+
+       ret = PyBytes_AsStringAndSize(py_data,
+                                     (char **)&data,
+                                     &data_size);
+       if (ret != 0) {
+               return NULL;
+       }
+
+       ret = PyBytes_AsStringAndSize(py_key,
+                                     (char **)&key,
+                                     &key_size);
+       if (ret != 0) {
+               return NULL;
+       }
+
+       if (data_size != 16) {
+               return PyErr_Format(PyExc_ValueError,
+                                   "Expected data size of 16 bytes; got %zd",
+                                   data_size);
+       }
+
+       if (key_size != 14) {
+               return PyErr_Format(PyExc_ValueError,
+                                   "Expected key size of 14 bytes; got %zd",
+                                   key_size);
+       }
+
+       ret = des_crypt112_16(result, data, key,
+                             SAMBA_GNUTLS_ENCRYPT);
+       if (ret != 0) {
+               return PyErr_Format(PyExc_RuntimeError,
+                                   "des_crypt112_16() failed: %d",
+                                   ret);
+       }
+
+       return PyBytes_FromStringAndSize((const char *)result,
+                                        sizeof(result));
+}
+
 static const char py_crypto_arcfour_crypt_blob_doc[] = "arcfour_crypt_blob(data, key)\n"
                                         "Encrypt the data with RC4 algorithm using the key";
 
+static const char py_crypto_des_crypt_blob_16_doc[] = "des_crypt_blob_16(data, key) -> bytes\n"
+                                                     "Encrypt the 16-byte data with DES using "
+                                                     "the 14-byte key";
+
 static PyMethodDef py_crypto_methods[] = {
        { "arcfour_crypt_blob", (PyCFunction)py_crypto_arcfour_crypt_blob, METH_VARARGS, py_crypto_arcfour_crypt_blob_doc },
        { "set_relax_mode", (PyCFunction)py_crypto_set_relax_mode, METH_NOARGS, "Set fips to relax mode" },
        { "set_strict_mode", (PyCFunction)py_crypto_set_strict_mode, METH_NOARGS, "Set fips to strict mode" },
+       { "des_crypt_blob_16", (PyCFunction)py_crypto_des_crypt_blob_16, METH_VARARGS, py_crypto_des_crypt_blob_16_doc },
        {0},
 };
 
index 78927437e37b0ac2287e859788b2af9c9cc4f32c..acf5cb8e7315aab031047195b8a067581c4b98db 100644 (file)
@@ -81,7 +81,7 @@ def build(bld):
 
     bld.SAMBA_PYTHON('python_crypto',
                      source='py_crypto.c',
-                     deps='gnutls talloc',
+                     deps='gnutls talloc LIBCLI_AUTH',
                      realname='samba/crypto.so')
 
     bld.SAMBA_BINARY('test_gnutls_aead_aes_256_cbc_hmac_sha512',