[Python-modules-commits] [python-bcrypt] 01/01: Import python-bcrypt_3.0.0.orig.tar.xz

Daniel Stender stender at moszumanska.debian.org
Tue Jun 28 17:44:48 UTC 2016


This is an automated email from the git hooks/post-receive script.

stender pushed a commit to branch upstream
in repository python-bcrypt.

commit 0f2834d39ceca322763c9618acdbcc813b774b0c
Author: Daniel Stender <stender at debian.org>
Date:   Tue Jun 28 18:12:02 2016 +0200

    Import python-bcrypt_3.0.0.orig.tar.xz
---
 MANIFEST.in                                   |   2 +-
 PKG-INFO                                      |  81 ++-
 README.rst                                    |  73 ++-
 setup.cfg                                     |   4 +-
 setup.py                                      |  11 +-
 src/_csrc/bcrypt.c                            | 274 ++++++++
 src/_csrc/bcrypt_pbkdf.c                      | 168 +++++
 src/_csrc/blf.c                               | 657 +++++++++++++++++++
 src/_csrc/blf.h                               |  83 +++
 src/_csrc/portable_endian.h                   | 162 +++++
 src/_csrc/pycabcrypt.h                        |  28 +
 src/_csrc/sha2.c                              | 812 +++++++++++++++++++++++
 src/_csrc/sha2.h                              |  83 +++
 src/_csrc/timingsafe_bcmp.c                   |  29 +
 src/bcrypt.egg-info/PKG-INFO                  |  81 ++-
 src/bcrypt.egg-info/SOURCES.txt               |  28 +-
 src/bcrypt.egg-info/pbr.json                  |   1 -
 src/bcrypt/__about__.py                       |   8 +-
 src/bcrypt/__init__.py                        |  57 +-
 src/build_bcrypt.py                           |  30 +-
 src/crypt_blowfish-1.3/LINKS                  |  29 -
 src/crypt_blowfish-1.3/Makefile               |  77 ---
 src/crypt_blowfish-1.3/PERFORMANCE            |  30 -
 src/crypt_blowfish-1.3/README                 |  68 --
 src/crypt_blowfish-1.3/crypt.3                | 575 ----------------
 src/crypt_blowfish-1.3/crypt.h                |  24 -
 src/crypt_blowfish-1.3/crypt_blowfish.c       | 907 --------------------------
 src/crypt_blowfish-1.3/crypt_blowfish.h       |  27 -
 src/crypt_blowfish-1.3/crypt_gensalt.c        | 124 ----
 src/crypt_blowfish-1.3/crypt_gensalt.h        |  30 -
 src/crypt_blowfish-1.3/glibc-2.1.3-crypt.diff |  53 --
 src/crypt_blowfish-1.3/glibc-2.14-crypt.diff  |  55 --
 src/crypt_blowfish-1.3/glibc-2.3.6-crypt.diff |  52 --
 src/crypt_blowfish-1.3/ow-crypt.h             |  43 --
 src/crypt_blowfish-1.3/wrapper.c              | 551 ----------------
 src/crypt_blowfish-1.3/x86.S                  | 203 ------
 36 files changed, 2598 insertions(+), 2922 deletions(-)

diff --git a/MANIFEST.in b/MANIFEST.in
index ea1c0a0..622d66b 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,3 +1,3 @@
 include LICENSE README.rst
 include src/build_bcrypt.py
-recursive-include src/crypt_blowfish-1.3 *
+recursive-include src/_csrc *
diff --git a/PKG-INFO b/PKG-INFO
index ba87b01..76f3950 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,15 +1,15 @@
 Metadata-Version: 1.1
 Name: bcrypt
-Version: 2.0.0
+Version: 3.0.0
 Summary: Modern password hashing for your software and your servers
 Home-page: https://github.com/pyca/bcrypt/
-Author: Donald Stufft
-Author-email: donald at stufft.io
+Author: The Python Cryptographic Authority developers
+Author-email: cryptography-dev at python.org
 License: Apache License, Version 2.0
 Description: bcrypt
         ======
         
-        .. image:: https://pypip.in/version/bcrypt/badge.svg?style=flat
+        .. image:: https://img.shields.io/pypi/v/bcrypt.svg
             :target: https://pypi.python.org/pypi/bcrypt/
             :alt: Latest Version
         
@@ -28,12 +28,39 @@ Description: bcrypt
         
             $ pip install bcrypt
         
+        Note that bcrypt should build very easily on Linux provided you have a C compiler, headers for Python (if you’re not using pypy), and headers for the libffi libraries available on your system.
+        
+        For Debian and Ubuntu, the following command will ensure that the required dependencies are installed:
+        
+        .. code:: bash
+        
+            $ sudo apt-get install build-essential libffi-dev python-dev
+        
+        For Fedora and RHEL-derivatives, the following command will ensure that the required dependencies are installed:
+        
+        .. code:: bash
+        
+            $ sudo yum install gcc libffi-devel python-devel
+        
+        Changelog
+        =========
+        
+        3.0.0
+        -----
+        * Switched the C backend to code obtained from the OpenBSD project rather than
+          openwall.
+        * Added support for `bcrypt_pbkdf` via the `kdf` function.
+        
+        2.0.0
+        -----
+        * Added support for an adjustible prefix when calling `gensalt`.
+        * Switched to CFFI 1.0+
         
         Usage
         -----
         
-        Basic
-        ~~~~~
+        Hashing
+        ~~~~~~~
         
         Hashing and then later checking that a password matches the previous hashed
         password is very simple:
@@ -51,6 +78,21 @@ Description: bcrypt
             ... else:
             ...     print("It Does not Match :(")
         
+        KDF
+        ~~~
+        
+        As of 3.0.0 `bcrypt` now offers a `kdf` function which does `bcrypt_pbkdf`.
+        This KDF is used in OpenSSH's newer encrypted private key format.
+        
+        .. code:: pycon
+        
+            >>> import bcrypt
+            >>> key = bcrypt.kdf(
+            ...     password=b'password',
+            ...     salt=b'salt',
+            ...     desired_key_bytes=32,
+            ...     rounds=100)
+        
         
         Adjustable Work Factor
         ~~~~~~~~~~~~~~~~~~~~~~
@@ -79,12 +121,35 @@ Description: bcrypt
         libraries you'll remain compatible with. To adjust this, pass either ``2a`` or
         ``2b`` (the default) to ``bcrypt.gensalt(prefix=b"2b")`` as a bytes object.
         
+        As of 3.0.0 the `$2y$` prefix is still supported in `hashpw` but deprecated.
+        
+        Maxmimum Password Length
+        ~~~~~~~~~~~~~~~~~~~~~~~~
+        
+        The bcrypt algorithm only handles passwords up to 72 characters, any characters
+        beyond that are ignored. To work around this, a common approach is to hash a
+        password with a cryptographic hash (such as ``sha256``) and then base64
+        encode it to prevent NULL byte problems before hashing the result with
+        ``bcrypt``:
+        
+        .. code:: pycon
+        
+            >>> password = b"an incredibly long password" * 10
+            >>> hashed = bcrypt.hashpw(
+            ...     base64.b64encode(hashlib.sha256(password).digest()),
+            ...     bcrypt.gensalt()
+            ... )
         
         Compatibility
         -------------
         
         This library should be compatible with py-bcrypt and it will run on Python
-        2.6+, 3.2+, and PyPy.
+        2.6+, 3.3+, and PyPy 2.6+.
+        
+        C Code
+        ------
+        
+        This library uses code from OpenBSD.
         
         Security
         --------
@@ -101,5 +166,5 @@ Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.2
 Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
diff --git a/README.rst b/README.rst
index 1fa3bbd..9519ff4 100644
--- a/README.rst
+++ b/README.rst
@@ -1,7 +1,7 @@
 bcrypt
 ======
 
-.. image:: https://pypip.in/version/bcrypt/badge.svg?style=flat
+.. image:: https://img.shields.io/pypi/v/bcrypt.svg
     :target: https://pypi.python.org/pypi/bcrypt/
     :alt: Latest Version
 
@@ -20,12 +20,39 @@ To install bcrypt, simply:
 
     $ pip install bcrypt
 
+Note that bcrypt should build very easily on Linux provided you have a C compiler, headers for Python (if you’re not using pypy), and headers for the libffi libraries available on your system.
+
+For Debian and Ubuntu, the following command will ensure that the required dependencies are installed:
+
+.. code:: bash
+
+    $ sudo apt-get install build-essential libffi-dev python-dev
+
+For Fedora and RHEL-derivatives, the following command will ensure that the required dependencies are installed:
+
+.. code:: bash
+
+    $ sudo yum install gcc libffi-devel python-devel
+
+Changelog
+=========
+
+3.0.0
+-----
+* Switched the C backend to code obtained from the OpenBSD project rather than
+  openwall.
+* Added support for `bcrypt_pbkdf` via the `kdf` function.
+
+2.0.0
+-----
+* Added support for an adjustible prefix when calling `gensalt`.
+* Switched to CFFI 1.0+
 
 Usage
 -----
 
-Basic
-~~~~~
+Hashing
+~~~~~~~
 
 Hashing and then later checking that a password matches the previous hashed
 password is very simple:
@@ -43,6 +70,21 @@ password is very simple:
     ... else:
     ...     print("It Does not Match :(")
 
+KDF
+~~~
+
+As of 3.0.0 `bcrypt` now offers a `kdf` function which does `bcrypt_pbkdf`.
+This KDF is used in OpenSSH's newer encrypted private key format.
+
+.. code:: pycon
+
+    >>> import bcrypt
+    >>> key = bcrypt.kdf(
+    ...     password=b'password',
+    ...     salt=b'salt',
+    ...     desired_key_bytes=32,
+    ...     rounds=100)
+
 
 Adjustable Work Factor
 ~~~~~~~~~~~~~~~~~~~~~~
@@ -71,12 +113,35 @@ Another one of bcrypt's features is an adjustable prefix to let you define what
 libraries you'll remain compatible with. To adjust this, pass either ``2a`` or
 ``2b`` (the default) to ``bcrypt.gensalt(prefix=b"2b")`` as a bytes object.
 
+As of 3.0.0 the `$2y$` prefix is still supported in `hashpw` but deprecated.
+
+Maxmimum Password Length
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+The bcrypt algorithm only handles passwords up to 72 characters, any characters
+beyond that are ignored. To work around this, a common approach is to hash a
+password with a cryptographic hash (such as ``sha256``) and then base64
+encode it to prevent NULL byte problems before hashing the result with
+``bcrypt``:
+
+.. code:: pycon
+
+    >>> password = b"an incredibly long password" * 10
+    >>> hashed = bcrypt.hashpw(
+    ...     base64.b64encode(hashlib.sha256(password).digest()),
+    ...     bcrypt.gensalt()
+    ... )
 
 Compatibility
 -------------
 
 This library should be compatible with py-bcrypt and it will run on Python
-2.6+, 3.2+, and PyPy.
+2.6+, 3.3+, and PyPy 2.6+.
+
+C Code
+------
+
+This library uses code from OpenBSD.
 
 Security
 --------
diff --git a/setup.cfg b/setup.cfg
index 72f9d44..861a9f5 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
 [egg_info]
-tag_svn_revision = 0
-tag_date = 0
 tag_build = 
+tag_date = 0
+tag_svn_revision = 0
 
diff --git a/setup.py b/setup.py
index f635d94..060e675 100644
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+import platform
 import sys
 from distutils.command.build import build
 
@@ -22,6 +23,14 @@ with open("src/bcrypt/__about__.py") as fp:
     exec(fp.read(), __about__)
 
 
+if platform.python_implementation() == "PyPy":
+    if sys.pypy_version_info < (2, 6):
+        raise RuntimeError(
+            "bcrypt is not compatible with PyPy < 2.6. Please upgrade PyPy to "
+            "use this library."
+        )
+
+
 class PyTest(test):
     def finalize_options(self):
         test.finalize_options(self)
@@ -217,8 +226,8 @@ setup(
         "Programming Language :: Python :: 2.6",
         "Programming Language :: Python :: 2.7",
         "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.2",
         "Programming Language :: Python :: 3.3",
+        "Programming Language :: Python :: 3.4",
     ],
 
     ext_package="bcrypt",
diff --git a/src/_csrc/bcrypt.c b/src/_csrc/bcrypt.c
new file mode 100644
index 0000000..a773602
--- /dev/null
+++ b/src/_csrc/bcrypt.c
@@ -0,0 +1,274 @@
+/*	$OpenBSD: bcrypt.c,v 1.55 2015/09/13 15:33:48 guenther Exp $	*/
+
+/*
+ * Copyright (c) 2014 Ted Unangst <tedu at openbsd.org>
+ * Copyright (c) 1997 Niels Provos <provos at umich.edu>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/* This password hashing algorithm was designed by David Mazieres
+ * <dm at lcs.mit.edu> and works as follows:
+ *
+ * 1. state := InitState ()
+ * 2. state := ExpandKey (state, salt, password)
+ * 3. REPEAT rounds:
+ *      state := ExpandKey (state, 0, password)
+ *	state := ExpandKey (state, 0, salt)
+ * 4. ctext := "OrpheanBeholderScryDoubt"
+ * 5. REPEAT 64:
+ * 	ctext := Encrypt_ECB (state, ctext);
+ * 6. RETURN Concatenate (salt, ctext);
+ *
+ */
+
+#include <sys/types.h>
+#include <blf.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pycabcrypt.h"
+
+/* This implementation is adaptable to current computing power.
+ * You can have up to 2^31 rounds which should be enough for some
+ * time to come.
+ */
+
+#define BCRYPT_VERSION '2'
+#define BCRYPT_MAXSALT 16	/* Precomputation is just so nice */
+#define BCRYPT_WORDS 6		/* Ciphertext words */
+#define BCRYPT_MINLOGROUNDS 4	/* we have log2(rounds) in salt */
+
+#define	BCRYPT_SALTSPACE	(7 + (BCRYPT_MAXSALT * 4 + 2) / 3 + 1)
+#define	BCRYPT_HASHSPACE	61
+
+char   *bcrypt_gensalt(u_int8_t);
+
+int encode_base64(char *, const u_int8_t *, size_t);
+static int decode_base64(u_int8_t *, size_t, const char *);
+
+/*
+ * the core bcrypt function
+ */
+int
+bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
+    size_t encryptedlen)
+{
+	blf_ctx state;
+	u_int32_t rounds, i, k;
+	u_int16_t j;
+	size_t key_len;
+	u_int8_t salt_len, logr, minor;
+	u_int8_t ciphertext[4 * BCRYPT_WORDS] = "OrpheanBeholderScryDoubt";
+	u_int8_t csalt[BCRYPT_MAXSALT];
+	u_int32_t cdata[BCRYPT_WORDS];
+
+	if (encryptedlen < BCRYPT_HASHSPACE)
+		goto inval;
+
+	/* Check and discard "$" identifier */
+	if (salt[0] != '$')
+		goto inval;
+	salt += 1;
+
+	if (salt[0] != BCRYPT_VERSION)
+		goto inval;
+
+	/* Check for minor versions */
+	switch ((minor = salt[1])) {
+	case 'a':
+		key_len = (u_int8_t)(strlen(key) + 1);
+		break;
+	case 'b':
+		/* strlen() returns a size_t, but the function calls
+		 * below result in implicit casts to a narrower integer
+		 * type, so cap key_len at the actual maximum supported
+		 * length here to avoid integer wraparound */
+		key_len = strlen(key);
+		if (key_len > 72)
+			key_len = 72;
+		key_len++; /* include the NUL */
+		break;
+	default:
+		 goto inval;
+	}
+	if (salt[2] != '$')
+		goto inval;
+	/* Discard version + "$" identifier */
+	salt += 3;
+
+	/* Check and parse num rounds */
+	if (!isdigit((unsigned char)salt[0]) ||
+	    !isdigit((unsigned char)salt[1]) || salt[2] != '$')
+		goto inval;
+	logr = (salt[1] - '0') + ((salt[0] - '0') * 10);
+	if (logr < BCRYPT_MINLOGROUNDS || logr > 31)
+		goto inval;
+	/* Computer power doesn't increase linearly, 2^x should be fine */
+	rounds = 1U << logr;
+
+	/* Discard num rounds + "$" identifier */
+	salt += 3;
+
+	if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
+		goto inval;
+
+	/* We dont want the base64 salt but the raw data */
+	if (decode_base64(csalt, BCRYPT_MAXSALT, salt))
+		goto inval;
+	salt_len = BCRYPT_MAXSALT;
+
+	/* Setting up S-Boxes and Subkeys */
+	Blowfish_initstate(&state);
+	Blowfish_expandstate(&state, csalt, salt_len,
+	    (u_int8_t *) key, key_len);
+	for (k = 0; k < rounds; k++) {
+		Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
+		Blowfish_expand0state(&state, csalt, salt_len);
+	}
+
+	/* This can be precomputed later */
+	j = 0;
+	for (i = 0; i < BCRYPT_WORDS; i++)
+		cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_WORDS, &j);
+
+	/* Now do the encryption */
+	for (k = 0; k < 64; k++)
+		blf_enc(&state, cdata, BCRYPT_WORDS / 2);
+
+	for (i = 0; i < BCRYPT_WORDS; i++) {
+		ciphertext[4 * i + 3] = cdata[i] & 0xff;
+		cdata[i] = cdata[i] >> 8;
+		ciphertext[4 * i + 2] = cdata[i] & 0xff;
+		cdata[i] = cdata[i] >> 8;
+		ciphertext[4 * i + 1] = cdata[i] & 0xff;
+		cdata[i] = cdata[i] >> 8;
+		ciphertext[4 * i + 0] = cdata[i] & 0xff;
+	}
+
+
+	snprintf(encrypted, 8, "$2%c$%2.2u$", minor, logr);
+	encode_base64(encrypted + 7, csalt, BCRYPT_MAXSALT);
+	encode_base64(encrypted + 7 + 22, ciphertext, 4 * BCRYPT_WORDS - 1);
+	explicit_bzero(&state, sizeof(state));
+	explicit_bzero(ciphertext, sizeof(ciphertext));
+	explicit_bzero(csalt, sizeof(csalt));
+	explicit_bzero(cdata, sizeof(cdata));
+	return 0;
+
+inval:
+	errno = EINVAL;
+	return -1;
+}
+
+/*
+ * internal utilities
+ */
+static const u_int8_t Base64Code[] =
+"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+static const u_int8_t index_64[128] = {
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
+	56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
+	255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
+	7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+	255, 255, 255, 255, 255, 255, 28, 29, 30,
+	31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+	41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+	51, 52, 53, 255, 255, 255, 255, 255
+};
+#define CHAR64(c)  ( (c) > 127 ? 255 : index_64[(c)])
+
+/*
+ * read buflen (after decoding) bytes of data from b64data
+ */
+static int
+decode_base64(u_int8_t *buffer, size_t len, const char *b64data)
+{
+	u_int8_t *bp = buffer;
+	const u_int8_t *p = b64data;
+	u_int8_t c1, c2, c3, c4;
+
+	while (bp < buffer + len) {
+		c1 = CHAR64(*p);
+		/* Invalid data */
+		if (c1 == 255)
+			return -1;
+
+		c2 = CHAR64(*(p + 1));
+		if (c2 == 255)
+			return -1;
+
+		*bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
+		if (bp >= buffer + len)
+			break;
+
+		c3 = CHAR64(*(p + 2));
+		if (c3 == 255)
+			return -1;
+
+		*bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
+		if (bp >= buffer + len)
+			break;
+
+		c4 = CHAR64(*(p + 3));
+		if (c4 == 255)
+			return -1;
+		*bp++ = ((c3 & 0x03) << 6) | c4;
+
+		p += 4;
+	}
+	return 0;
+}
+
+/*
+ * Turn len bytes of data into base64 encoded data.
+ * This works without = padding.
+ */
+int
+encode_base64(char *b64buffer, const u_int8_t *data, size_t len)
+{
+	u_int8_t *bp = b64buffer;
+	const u_int8_t *p = data;
+	u_int8_t c1, c2;
+
+	while (p < data + len) {
+		c1 = *p++;
+		*bp++ = Base64Code[(c1 >> 2)];
+		c1 = (c1 & 0x03) << 4;
+		if (p >= data + len) {
+			*bp++ = Base64Code[c1];
+			break;
+		}
+		c2 = *p++;
+		c1 |= (c2 >> 4) & 0x0f;
+		*bp++ = Base64Code[c1];
+		c1 = (c2 & 0x0f) << 2;
+		if (p >= data + len) {
+			*bp++ = Base64Code[c1];
+			break;
+		}
+		c2 = *p++;
+		c1 |= (c2 >> 6) & 0x03;
+		*bp++ = Base64Code[c1];
+		*bp++ = Base64Code[c2 & 0x3f];
+	}
+	*bp = '\0';
+	return 0;
+}
diff --git a/src/_csrc/bcrypt_pbkdf.c b/src/_csrc/bcrypt_pbkdf.c
new file mode 100644
index 0000000..453fdaa
--- /dev/null
+++ b/src/_csrc/bcrypt_pbkdf.c
@@ -0,0 +1,168 @@
+/* $OpenBSD: bcrypt_pbkdf.c,v 1.13 2015/01/12 03:20:04 tedu Exp $ */
+/*
+ * Copyright (c) 2013 Ted Unangst <tedu at openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include "pycabcrypt.h"
+#include <stdlib.h>
+#include "blf.h"
+#include "sha2.h"
+#include <string.h>
+
+#define	MINIMUM(a,b) (((a) < (b)) ? (a) : (b))
+
+/*
+ * pkcs #5 pbkdf2 implementation using the "bcrypt" hash
+ *
+ * The bcrypt hash function is derived from the bcrypt password hashing
+ * function with the following modifications:
+ * 1. The input password and salt are preprocessed with SHA512.
+ * 2. The output length is expanded to 256 bits.
+ * 3. Subsequently the magic string to be encrypted is lengthened and modifed
+ *    to "OxychromaticBlowfishSwatDynamite"
+ * 4. The hash function is defined to perform 64 rounds of initial state
+ *    expansion. (More rounds are performed by iterating the hash.)
+ *
+ * Note that this implementation pulls the SHA512 operations into the caller
+ * as a performance optimization.
+ *
+ * One modification from official pbkdf2. Instead of outputting key material
+ * linearly, we mix it. pbkdf2 has a known weakness where if one uses it to
+ * generate (e.g.) 512 bits of key material for use as two 256 bit keys, an
+ * attacker can merely run once through the outer loop, but the user
+ * always runs it twice. Shuffling output bytes requires computing the
+ * entirety of the key material to assemble any subkey. This is something a
+ * wise caller could do; we just do it for you.
+ */
+
+#define BCRYPT_WORDS 8
+#define BCRYPT_HASHSIZE (BCRYPT_WORDS * 4)
+
+static void
+bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out)
+{
+	blf_ctx state;
+	uint8_t ciphertext[BCRYPT_HASHSIZE] =
+	    "OxychromaticBlowfishSwatDynamite";
+	uint32_t cdata[BCRYPT_WORDS];
+	int i;
+	uint16_t j;
+	size_t shalen = SHA512_DIGEST_LENGTH;
+
+	/* key expansion */
+	Blowfish_initstate(&state);
+	Blowfish_expandstate(&state, sha2salt, shalen, sha2pass, shalen);
+	for (i = 0; i < 64; i++) {
+		Blowfish_expand0state(&state, sha2salt, shalen);
+		Blowfish_expand0state(&state, sha2pass, shalen);
+	}
+
+	/* encryption */
+	j = 0;
+	for (i = 0; i < BCRYPT_WORDS; i++)
+		cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext),
+		    &j);
+	for (i = 0; i < 64; i++)
+		blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t));
+
+	/* copy out */
+	for (i = 0; i < BCRYPT_WORDS; i++) {
+		out[4 * i + 3] = (cdata[i] >> 24) & 0xff;
+		out[4 * i + 2] = (cdata[i] >> 16) & 0xff;
+		out[4 * i + 1] = (cdata[i] >> 8) & 0xff;
+		out[4 * i + 0] = cdata[i] & 0xff;
+	}
+
+	/* zap */
+	explicit_bzero(ciphertext, sizeof(ciphertext));
+	explicit_bzero(cdata, sizeof(cdata));
+	explicit_bzero(&state, sizeof(state));
+}
+
+int
+bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen,
+    uint8_t *key, size_t keylen, unsigned int rounds)
+{
+	SHA2_CTX ctx;
+	uint8_t sha2pass[SHA512_DIGEST_LENGTH];
+	uint8_t sha2salt[SHA512_DIGEST_LENGTH];
+	uint8_t out[BCRYPT_HASHSIZE];
+	uint8_t tmpout[BCRYPT_HASHSIZE];
+	uint8_t countsalt[4];
+	size_t i, j, amt, stride;
+	uint32_t count;
+	size_t origkeylen = keylen;
+
+	/* nothing crazy */
+	if (rounds < 1)
+		return -1;
+	if (passlen == 0 || saltlen == 0 || keylen == 0 ||
+	    keylen > sizeof(out) * sizeof(out))
+		return -1;
+	stride = (keylen + sizeof(out) - 1) / sizeof(out);
+	amt = (keylen + stride - 1) / stride;
+
+	/* collapse password */
+	SHA512Init(&ctx);
+	SHA512Update(&ctx, pass, passlen);
+	SHA512Final(sha2pass, &ctx);
+
+
+	/* generate key, sizeof(out) at a time */
+	for (count = 1; keylen > 0; count++) {
+		countsalt[0] = (count >> 24) & 0xff;
+		countsalt[1] = (count >> 16) & 0xff;
+		countsalt[2] = (count >> 8) & 0xff;
+		countsalt[3] = count & 0xff;
+
+		/* first round, salt is salt */
+		SHA512Init(&ctx);
+		SHA512Update(&ctx, salt, saltlen);
+		SHA512Update(&ctx, countsalt, sizeof(countsalt));
+		SHA512Final(sha2salt, &ctx);
+		bcrypt_hash(sha2pass, sha2salt, tmpout);
+		memcpy(out, tmpout, sizeof(out));
+
+		for (i = 1; i < rounds; i++) {
+			/* subsequent rounds, salt is previous output */
+			SHA512Init(&ctx);
+			SHA512Update(&ctx, tmpout, sizeof(tmpout));
+			SHA512Final(sha2salt, &ctx);
+			bcrypt_hash(sha2pass, sha2salt, tmpout);
+			for (j = 0; j < sizeof(out); j++)
+				out[j] ^= tmpout[j];
+		}
+
+		/*
+		 * pbkdf2 deviation: output the key material non-linearly.
+		 */
+		amt = MINIMUM(amt, keylen);
+		for (i = 0; i < amt; i++) {
+			size_t dest = i * stride + (count - 1);
+			if (dest >= origkeylen)
+				break;
+			key[dest] = out[i];
+		}
+		keylen -= i;
+	}
+
+	/* zap */
+	explicit_bzero(&ctx, sizeof(ctx));
+	explicit_bzero(out, sizeof(out));
+
+	return 0;
+}
diff --git a/src/_csrc/blf.c b/src/_csrc/blf.c
new file mode 100644
index 0000000..2e1a68f
--- /dev/null
+++ b/src/_csrc/blf.c
@@ -0,0 +1,657 @@
+/*	$OpenBSD: blf.c,v 1.7 2007/11/26 09:28:34 martynas Exp $	*/
+
+/*
+ * Blowfish block cipher for OpenBSD
+ * Copyright 1997 Niels Provos <provos at physnet.uni-hamburg.de>
+ * All rights reserved.
+ *
+ * Implementation advice by David Mazieres <dm at lcs.mit.edu>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Niels Provos.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This code is derived from section 14.3 and the given source
+ * in section V of Applied Cryptography, second edition.
+ * Blowfish is an unpatented fast block cipher designed by
+ * Bruce Schneier.
+ */
+
+#include <sys/types.h>
+
+#include "blf.h"
+
+#undef inline
+#ifdef __GNUC__
+#define inline __inline
+#else				/* !__GNUC__ */
+#define inline
+#endif				/* !__GNUC__ */
+
+/* Function for Feistel Networks */
+
+#define F(s, x) ((((s)[        (((x)>>24)&0xFF)]  \
+		 + (s)[0x100 + (((x)>>16)&0xFF)]) \
+		 ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
+		 + (s)[0x300 + ( (x)     &0xFF)])
+
+#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
+
+void
+Blowfish_encipher(blf_ctx *c, u_int32_t *x)
+{
+	u_int32_t Xl;
+	u_int32_t Xr;
+	u_int32_t *s = c->S[0];
+	u_int32_t *p = c->P;
+
+	Xl = x[0];
+	Xr = x[1];
+
+	Xl ^= p[0];
+	BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
+	BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
+	BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
+	BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
+	BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
+	BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
+	BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
+	BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
+
+	x[0] = Xr ^ p[17];
+	x[1] = Xl;
+}
+
+void
+Blowfish_decipher(blf_ctx *c, u_int32_t *x)
+{
+	u_int32_t Xl;
+	u_int32_t Xr;
+	u_int32_t *s = c->S[0];
+	u_int32_t *p = c->P;
+
+	Xl = x[0];
+	Xr = x[1];
+
+	Xl ^= p[17];
+	BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
+	BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
+	BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
+	BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
+	BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
+	BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
+	BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
+	BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
+
+	x[0] = Xr ^ p[0];
+	x[1] = Xl;
+}
+
+void
+Blowfish_initstate(blf_ctx *c)
+{
+	/* P-box and S-box tables initialized with digits of Pi */
+
+	static const blf_ctx initstate =
+
+	{ {
+		{
+			0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
+			0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+			0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+			0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+			0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
+			0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+			0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
+			0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+			0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+			0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+			0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
+			0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+			0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
+			0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+			0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+			0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+			0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
+			0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+			0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
+			0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+			0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+			0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+			0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
+			0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+			0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
+			0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+			0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+			0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+			0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
+			0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+			0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
+			0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+			0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+			0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+			0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
+			0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+			0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
+			0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+			0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+			0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+			0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
+			0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+			0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
+			0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+			0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+			0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+			0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
+			0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+			0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
+			0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+			0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+			0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+			0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
+			0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+			0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
+			0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+			0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+			0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+			0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
+			0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+			0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
+			0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+			0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+		0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
+		{
+			0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
+			0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+			0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+			0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+			0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+			0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+			0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
+			0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
... 4991 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-bcrypt.git



More information about the Python-modules-commits mailing list