diff options
author | Legrandin <gooksankoo@hoiptorrow.mailexpire.com> | 2011-10-18 23:20:26 +0200 |
---|---|---|
committer | Legrandin <gooksankoo@hoiptorrow.mailexpire.com> | 2011-10-18 23:20:26 +0200 |
commit | c22fa18c0dedb43a8b19dcb9b29512ba59e1764b (patch) | |
tree | e7864a848ed2c37d4a2c0d65bcae0f0cbdc6ea27 /src | |
parent | 897b75983c31a9e2630af92161e6206c2480685e (diff) | |
parent | b9658a26003ebfcfce1804a2363a29354799b47e (diff) | |
download | pycrypto-c22fa18c0dedb43a8b19dcb9b29512ba59e1764b.tar.gz |
Merged from upstream (py3k support) and modified so that all unit tests pass.
Diffstat (limited to 'src')
-rw-r--r-- | src/Blowfish.c | 9 | ||||
-rw-r--r-- | src/MD2.c | 3 | ||||
-rw-r--r-- | src/MD4.c | 5 | ||||
-rw-r--r-- | src/RIPEMD160.c | 13 | ||||
-rw-r--r-- | src/SHA256.c | 1 | ||||
-rw-r--r-- | src/_counter.c | 162 | ||||
-rw-r--r-- | src/_counter.h | 14 | ||||
-rw-r--r--[-rwxr-xr-x] | src/_fastmath.c | 323 | ||||
-rw-r--r-- | src/block_template.c | 178 | ||||
-rw-r--r-- | src/config.h.in | 141 | ||||
-rw-r--r-- | src/hash_template.c | 139 | ||||
-rw-r--r-- | src/inc-msvc/config.h | 16 | ||||
-rw-r--r-- | src/inc-msvc/stdint.h | 2 | ||||
-rw-r--r-- | src/pycrypto_compat.h | 20 | ||||
-rw-r--r-- | src/stream_template.c | 175 | ||||
-rw-r--r-- | src/strxor.c | 46 | ||||
-rw-r--r-- | src/winrand.c | 111 |
17 files changed, 1152 insertions, 206 deletions
diff --git a/src/Blowfish.c b/src/Blowfish.c index f0d8594..8a6232f 100644 --- a/src/Blowfish.c +++ b/src/Blowfish.c @@ -26,8 +26,15 @@ * http://www.schneier.com/paper-blowfish-fse.html */ +#include "config.h" +#if HAVE_STDINT_H +# include <stdint.h> +#elif defined(__sun) || defined(__sun__) +# include <sys/inttypes.h> +#else +# error "stdint.h not found" +#endif #include <assert.h> -#include <stdint.h> #include <string.h> #include "Python.h" @@ -29,6 +29,7 @@ #include <string.h> #include "Python.h" +#include "pycrypto_compat.h" #define MODULE_NAME _MD2 #define DIGEST_SIZE 16 @@ -140,7 +141,7 @@ hash_digest (const hash_state *self) for(i=0; i<padlen; i++) padding[i]=padlen; hash_update(&temp, padding, padlen); hash_update(&temp, temp.C, 16); - return PyString_FromStringAndSize((char *) temp.X, 16); + return PyBytes_FromStringAndSize((char *) temp.X, 16); } #include "hash_template.c" @@ -28,7 +28,8 @@ #include <string.h> -#include <Python.h> +#include "Python.h" +#include "pycrypto_compat.h" #define MODULE_NAME _MD4 #define DIGEST_SIZE 16 @@ -214,7 +215,7 @@ hash_digest (const hash_state *self) digest[14]=(temp.D >> 16) & 255; digest[15]=(temp.D >> 24) & 255; - return PyString_FromStringAndSize((char *) digest, 16); + return PyBytes_FromStringAndSize((char *) digest, 16); } #include "hash_template.c" diff --git a/src/RIPEMD160.c b/src/RIPEMD160.c index de3bc88..9786af8 100644 --- a/src/RIPEMD160.c +++ b/src/RIPEMD160.c @@ -43,10 +43,19 @@ * "RIPEMD-160 is big-bit-endian, little-byte-endian, and left-justified." */ +#include "config.h" +#if HAVE_STDINT_H +# include <stdint.h> +#elif defined(__sun) || defined(__sun__) +# include <sys/inttypes.h> +#else +# error "stdint.h not found" +#endif + #include <assert.h> -#include <stdint.h> #include <string.h> #include "Python.h" +#include "pycrypto_compat.h" #define RIPEMD160_DIGEST_SIZE 20 #define BLOCK_SIZE 64 @@ -403,7 +412,7 @@ static PyObject *hash_digest(hash_state *self) PyObject *retval; if (ripemd160_digest(self, (unsigned char *) buf)) { - retval = PyString_FromStringAndSize(buf, DIGEST_SIZE); + retval = PyBytes_FromStringAndSize(buf, DIGEST_SIZE); } else { PyErr_SetString(PyExc_RuntimeError, "Internal error occurred while executing ripemd160_digest"); retval = NULL; diff --git a/src/SHA256.c b/src/SHA256.c index 578e81c..61a2d74 100644 --- a/src/SHA256.c +++ b/src/SHA256.c @@ -70,5 +70,4 @@ static const sha2_word_t K[SCHEDULE_SIZE] = { #define Gamma1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) #include "hash_SHA2_template.c" - diff --git a/src/_counter.c b/src/_counter.c index 8a5522a..9b396e4 100644 --- a/src/_counter.c +++ b/src/_counter.c @@ -25,16 +25,23 @@ #include <assert.h> #include <stddef.h> #include <string.h> - +#include "Python.h" +#include "pycrypto_compat.h" #include "_counter.h" -#include "pycrypto_compat.h" +#ifndef IS_PY3K +#define PyLong_FromLong PyInt_FromLong +#endif /* NB: This can be called multiple times for a given object, via the __init__ method. Be careful. */ static int CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) { - PyStringObject *prefix=NULL, *suffix=NULL, *initval=NULL; +#ifdef IS_PY3K + PyBytesObject *prefix=NULL, *suffix=NULL, *initval=NULL; +#else + PyStringObject *prefix=NULL, *suffix=NULL, *initval=NULL; +#endif int allow_wraparound = 0; int disable_shortcut = 0; Py_ssize_t size; @@ -44,7 +51,7 @@ CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) return -1; /* Check string size and set nbytes */ - size = PyString_GET_SIZE(initval); + size = PyBytes_GET_SIZE(initval); if (size < 1) { PyErr_SetString(PyExc_ValueError, "initval length too small (must be >= 1 byte)"); return -1; @@ -55,7 +62,7 @@ CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) self->nbytes = (uint16_t) size; /* Check prefix length */ - size = PyString_GET_SIZE(prefix); + size = PyBytes_GET_SIZE(prefix); assert(size >= 0); if (size > 0xffff) { PyErr_SetString(PyExc_ValueError, "prefix length too large (must be <= 65535 bytes)"); @@ -63,7 +70,7 @@ CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) } /* Check suffix length */ - size = PyString_GET_SIZE(suffix); + size = PyBytes_GET_SIZE(suffix); assert(size >= 0); if (size > 0xffff) { PyErr_SetString(PyExc_ValueError, "suffix length too large (must be <= 65535 bytes)"); @@ -89,24 +96,24 @@ CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) /* Allocate new buffer */ /* buf_size won't overflow because the length of each string will always be <= 0xffff */ - self->buf_size = PyString_GET_SIZE(prefix) + PyString_GET_SIZE(suffix) + self->nbytes; + self->buf_size = PyBytes_GET_SIZE(prefix) + PyBytes_GET_SIZE(suffix) + self->nbytes; self->val = self->p = PyMem_Malloc(self->buf_size); if (self->val == NULL) { self->buf_size = 0; return -1; } - self->p = self->val + PyString_GET_SIZE(prefix); + self->p = self->val + PyBytes_GET_SIZE(prefix); /* Sanity-check pointers */ assert(self->val <= self->p); assert(self->p + self->nbytes <= self->val + self->buf_size); - assert(self->val + PyString_GET_SIZE(self->prefix) == self->p); - assert(PyString_GET_SIZE(self->prefix) + self->nbytes + PyString_GET_SIZE(self->suffix) == self->buf_size); + assert(self->val + PyBytes_GET_SIZE(self->prefix) == self->p); + assert(PyBytes_GET_SIZE(self->prefix) + self->nbytes + PyBytes_GET_SIZE(self->suffix) == self->buf_size); /* Copy the prefix, suffix, and initial value into the buffer. */ - memcpy(self->val, PyString_AS_STRING(prefix), PyString_GET_SIZE(prefix)); - memcpy(self->p, PyString_AS_STRING(initval), self->nbytes); - memcpy(self->p + self->nbytes, PyString_AS_STRING(suffix), PyString_GET_SIZE(suffix)); + memcpy(self->val, PyBytes_AS_STRING(prefix), PyBytes_GET_SIZE(prefix)); + memcpy(self->p, PyBytes_AS_STRING(initval), self->nbytes); + memcpy(self->p + self->nbytes, PyBytes_AS_STRING(suffix), PyBytes_GET_SIZE(suffix)); /* Set shortcut_disabled and allow_wraparound */ self->shortcut_disabled = disable_shortcut; @@ -154,7 +161,7 @@ _CounterObject_next_value(PCT_CounterObject *self, int little_endian) goto err_out; } - eight = PyInt_FromLong(8); + eight = PyLong_FromLong(8); if (!eight) goto err_out; @@ -179,7 +186,7 @@ _CounterObject_next_value(PCT_CounterObject *self, int little_endian) /* ch = ord(p) */ Py_CLEAR(ch); /* delete old ch */ - ch = PyInt_FromLong((long) *p); + ch = PyLong_FromLong((long) *p); if (!ch) goto err_out; @@ -274,7 +281,7 @@ CounterObject_call(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) return NULL; } - retval = (PyObject *)PyString_FromStringAndSize((const char *)self->val, self->buf_size); + retval = (PyObject *)PyBytes_FromStringAndSize((const char *)self->val, self->buf_size); self->inc_func(self); @@ -297,45 +304,94 @@ static PyMethodDef CounterBEObject_methods[] = { /* Python 2.1 doesn't allow us to assign methods or attributes to an object, * so we hack it here. */ + static PyObject * +#ifdef IS_PY3K +CounterLEObject_getattro(PyObject *s, PyObject *attr) +#else CounterLEObject_getattr(PyObject *s, char *name) +#endif { PCT_CounterObject *self = (PCT_CounterObject *)s; +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + + if (PyUnicode_CompareWithASCIIString(attr, "carry") == 0) { +#else if (strcmp(name, "carry") == 0) { - return PyInt_FromLong((long)self->carry); +#endif + return PyLong_FromLong((long)self->carry); +#ifdef IS_PY3K + } else if (!self->shortcut_disabled && PyUnicode_CompareWithASCIIString(attr, "__PCT_CTR_SHORTCUT__") == 0) { +#else } else if (!self->shortcut_disabled && strcmp(name, "__PCT_CTR_SHORTCUT__") == 0) { +#endif /* Shortcut hack - See block_template.c */ Py_INCREF(Py_True); return Py_True; } +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr(s, attr); +#else return Py_FindMethod(CounterLEObject_methods, (PyObject *)self, name); +#endif } static PyObject * +#ifdef IS_PY3K +CounterBEObject_getattro(PyObject *s, PyObject *attr) +#else CounterBEObject_getattr(PyObject *s, char *name) +#endif { PCT_CounterObject *self = (PCT_CounterObject *)s; +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + + if (PyUnicode_CompareWithASCIIString(attr, "carry") == 0) { +#else if (strcmp(name, "carry") == 0) { - return PyInt_FromLong((long)self->carry); +#endif + return PyLong_FromLong((long)self->carry); +#ifdef IS_PY3K + } else if (!self->shortcut_disabled && PyUnicode_CompareWithASCIIString(attr, "__PCT_CTR_SHORTCUT__") == 0) { +#else } else if (!self->shortcut_disabled && strcmp(name, "__PCT_CTR_SHORTCUT__") == 0) { +#endif /* Shortcut hack - See block_template.c */ Py_INCREF(Py_True); return Py_True; } - +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr(s, attr); +#else return Py_FindMethod(CounterBEObject_methods, (PyObject *)self, name); +#endif } static PyTypeObject my_CounterLEType = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else PyObject_HEAD_INIT(NULL) 0, /* ob_size */ +#endif "_counter.CounterLE", /* tp_name */ sizeof(PCT_CounterObject), /* tp_basicsize */ 0, /* tp_itemsize */ + /* methods */ (destructor)CounterObject_dealloc, /* tp_dealloc */ 0, /* tp_print */ +#ifdef IS_PY3K + 0, /* tp_getattr */ +#else CounterLEObject_getattr, /* tp_getattr */ +#endif 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -345,23 +401,44 @@ my_CounterLEType = { 0, /* tp_hash */ (ternaryfunc)CounterObject_call, /* tp_call */ 0, /* tp_str */ +#ifdef IS_PY3K + CounterLEObject_getattro, /* tp_getattro */ +#else 0, /* tp_getattro */ +#endif 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Counter (little endian)", /* tp_doc */ +#ifdef IS_PY3K + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + CounterLEObject_methods, /*tp_methods*/ +#endif }; static PyTypeObject my_CounterBEType = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else PyObject_HEAD_INIT(NULL) 0, /* ob_size */ +#endif "_counter.CounterBE", /* tp_name */ sizeof(PCT_CounterObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)CounterObject_dealloc, /* tp_dealloc */ 0, /* tp_print */ +#ifdef IS_PY3K + 0, /* tp_getattr */ +#else CounterBEObject_getattr, /* tp_getattr */ +#endif 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -371,11 +448,24 @@ my_CounterBEType = { 0, /* tp_hash */ (ternaryfunc)CounterObject_call, /* tp_call */ 0, /* tp_str */ +#ifdef IS_PY3K + CounterBEObject_getattro, /* tp_getattro */ +#else 0, /* tp_getattro */ +#endif 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Counter (big endian)", /* tp_doc */ +#ifdef IS_PY3K + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + CounterBEObject_methods, /*tp_methods*/ +#endif }; /* @@ -444,21 +534,51 @@ static PyMethodDef module_methods[] = { {NULL, NULL, 0, NULL} /* end-of-list sentinel value */ }; +#ifdef IS_PY3K +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "_counter", + NULL, + -1, + module_methods, + NULL, + NULL, + NULL, + NULL +}; +#endif PyMODINIT_FUNC +#ifdef IS_PY3K +PyInit__counter(void) +#else init_counter(void) +#endif { PyObject *m; /* TODO - Is the error handling here correct? */ +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&my_CounterLEType) < 0) + return NULL; + if (PyType_Ready(&my_CounterBEType) < 0) + return NULL; /* Initialize the module */ + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; + + return m; +#else m = Py_InitModule("_counter", module_methods); if (m == NULL) return; - - my_CounterLEType.ob_type = &PyType_Type; + + my_CounterLEType.ob_type = &PyType_Type; my_CounterBEType.ob_type = &PyType_Type; +#endif } /* vim:set ts=4 sw=4 sts=4 expandtab: */ diff --git a/src/_counter.h b/src/_counter.h index faaf63f..fc3e24e 100644 --- a/src/_counter.h +++ b/src/_counter.h @@ -24,13 +24,19 @@ #ifndef PCT__COUNTER_H #define PCT__COUNTER_H -#include <stdint.h> -#include "Python.h" +#include "config.h" +#if HAVE_STDINT_H +# include <stdint.h> +#elif defined(__sun) || defined(__sun__) +# include <sys/inttypes.h> +#else +# error "stdint.h not found" +#endif typedef struct { PyObject_HEAD - PyStringObject *prefix; /* Prefix (useful for a nonce) */ - PyStringObject *suffix; /* Suffix (useful for a nonce) */ + PyBytesObject *prefix; /* Prefix (useful for a nonce) */ + PyBytesObject *suffix; /* Suffix (useful for a nonce) */ uint8_t *val; /* Buffer for our output string */ uint32_t buf_size; /* Size of the buffer */ uint8_t *p; /* Pointer to the part of the buffer that we're allowed to update */ diff --git a/src/_fastmath.c b/src/_fastmath.c index 169cdbc..6af1f05 100755..100644 --- a/src/_fastmath.c +++ b/src/_fastmath.c @@ -1,4 +1,3 @@ - /* * _fastmath.c: Accelerator module that uses GMP for faster numerics. * @@ -29,24 +28,40 @@ #include <stdio.h> #include <string.h> -#include <Python.h> +#include "Python.h" +#include "pycrypto_compat.h" #include <longintrepr.h> /* for conversions */ -#include <gmp.h> +#include "config.h" +#if HAVE_LIBGMP +# include <gmp.h> +#elif HAVE_LIBMPIR +# include <mpir.h> +#else +# error "Neither HAVE_LIBGMP nor HAVE_LIBMPIR are set. Can't build." +#endif -#define SIEVE_BASE_SIZE (sizeof (sieve_base) / sizeof (sieve_base[0])) +/* If available, use mpz_powm_sec to avoid timing attacks. + * See the talk by Geremy Condra - + * "PyCon 2011: Through the Side Channel: Timing and Implementation Attacks in Python" + * http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2011-through-the-side-channel-timing-and-implementation-attacks-in-python-4897955 + */ +#if HAVE_DECL_MPZ_POWM_SEC +#define MPZ_POWM mpz_powm_sec +#else +#define MPZ_POWM mpz_powm +#endif -static unsigned int sieve_base[10000]; -static int rabinMillerTest (mpz_t n, int rounds, PyObject *randfunc); +#define SIEVE_BASE_SIZE (sizeof (sieve_base) / sizeof (sieve_base[0])) -/** - * Starting from version 5.0.0, libgmp sports a constant-time modular exponentiation. - */ -#if (__GNU_MP_VERSION>=5) -#define MPZ_POWM mpz_powm_sec +#ifdef _MSC_VER +#define INLINE __inline #else -#define MPZ_POWM mpz_powm +#define INLINE inline #endif +static unsigned int sieve_base[10000]; +static int rabinMillerTest (mpz_t n, int rounds, PyObject *randfunc); + static void longObjToMPZ (mpz_t m, PyLongObject * p) { @@ -54,15 +69,26 @@ longObjToMPZ (mpz_t m, PyLongObject * p) mpz_t temp, temp2; mpz_init (temp); mpz_init (temp2); +#ifdef IS_PY3K + if (p->ob_base.ob_size > 0) + size = p->ob_base.ob_size; + else + size = -p->ob_base.ob_size; +#else if (p->ob_size > 0) size = p->ob_size; else size = -p->ob_size; +#endif mpz_set_ui (m, 0); for (i = 0; i < size; i++) { mpz_set_ui (temp, p->ob_digit[i]); +#ifdef IS_PY3K + mpz_mul_2exp (temp2, temp, PyLong_SHIFT * i); +#else mpz_mul_2exp (temp2, temp, SHIFT * i); +#endif mpz_add (m, m, temp2); } mpz_clear (temp); @@ -73,7 +99,11 @@ static PyObject * mpzToLongObj (mpz_t m) { /* borrowed from gmpy */ +#ifdef IS_PY3K + int size = (mpz_sizeinbase (m, 2) + PyLong_SHIFT - 1) / PyLong_SHIFT; +#else int size = (mpz_sizeinbase (m, 2) + SHIFT - 1) / SHIFT; +#endif int i; mpz_t temp; PyLongObject *l = _PyLong_New (size); @@ -82,13 +112,22 @@ mpzToLongObj (mpz_t m) mpz_init_set (temp, m); for (i = 0; i < size; i++) { +#ifdef IS_PY3K + l->ob_digit[i] = (digit) (mpz_get_ui (temp) & PyLong_MASK); + mpz_fdiv_q_2exp (temp, temp, PyLong_SHIFT); +#else l->ob_digit[i] = (digit) (mpz_get_ui (temp) & MASK); mpz_fdiv_q_2exp (temp, temp, SHIFT); +#endif } i = size; while ((i > 0) && (l->ob_digit[i - 1] == 0)) i--; +#ifdef IS_PY3K + l->ob_base.ob_size = i; +#else l->ob_size = i; +#endif mpz_clear (temp); return (PyObject *) l; } @@ -118,14 +157,22 @@ static PyObject *rsaKey_new (PyObject *, PyObject *); static PyObject *dsaKey_new (PyObject *, PyObject *); static void dsaKey_dealloc (dsaKey *); +#ifdef IS_PY3K +static PyObject *dsaKey_getattro (dsaKey *, PyObject *); +#else static PyObject *dsaKey_getattr (dsaKey *, char *); +#endif static PyObject *dsaKey__sign (dsaKey *, PyObject *); static PyObject *dsaKey__verify (dsaKey *, PyObject *); static PyObject *dsaKey_size (dsaKey *, PyObject *); static PyObject *dsaKey_has_private (dsaKey *, PyObject *); static void rsaKey_dealloc (rsaKey *); +#ifdef IS_PY3K +static PyObject *rsaKey_getattro (rsaKey *, PyObject *); +#else static PyObject *rsaKey_getattr (rsaKey *, char *); +#endif static PyObject *rsaKey__encrypt (rsaKey *, PyObject *); static PyObject *rsaKey__decrypt (rsaKey *, PyObject *); static PyObject *rsaKey__verify (rsaKey *, PyObject *); @@ -288,25 +335,6 @@ rsaUnBlind (rsaKey * key, mpz_t v, mpz_t b) mpz_mod (v, v, key->n); return 0; } - - -static PyTypeObject dsaKeyType = { - PyObject_HEAD_INIT (NULL) 0, - "dsaKey", - sizeof (dsaKey), - 0, - (destructor) dsaKey_dealloc, /* dealloc */ - 0, /* print */ - (getattrfunc) dsaKey_getattr, /* getattr */ - 0, /* setattr */ - 0, /* compare */ - 0, /* repr */ - 0, /* as_number */ - 0, /* as_sequence */ - 0, /* as_mapping */ - 0, /* hash */ - 0, /* call */ -}; static PyMethodDef dsaKey__methods__[] = { {"_sign", (PyCFunction) dsaKey__sign, METH_VARARGS, @@ -320,26 +348,6 @@ static PyMethodDef dsaKey__methods__[] = { {NULL, NULL, 0, NULL} }; -static PyObject *fastmathError; /* raised on errors */ - -static PyTypeObject rsaKeyType = { - PyObject_HEAD_INIT (NULL) 0, - "rsaKey", - sizeof (rsaKey), - 0, - (destructor) rsaKey_dealloc, /* dealloc */ - 0, /* print */ - (getattrfunc) rsaKey_getattr, /* getattr */ - 0, /* setattr */ - 0, /* compare */ - 0, /* repr */ - 0, /* as_number */ - 0, /* as_sequence */ - 0, /* as_mapping */ - 0, /* hash */ - 0, /* call */ -}; - static PyMethodDef rsaKey__methods__[] = { {"_encrypt", (PyCFunction) rsaKey__encrypt, METH_VARARGS, "Encrypt the given long."}, @@ -360,6 +368,93 @@ static PyMethodDef rsaKey__methods__[] = { {NULL, NULL, 0, NULL} }; +static PyObject *fastmathError; /* raised on errors */ + +static PyTypeObject dsaKeyType = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT (NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else + PyObject_HEAD_INIT (NULL) + 0, /*ob_size*/ +#endif + "dsaKey", + sizeof (dsaKey), + 0, + (destructor) dsaKey_dealloc, /* dealloc */ + 0, /* print */ +#ifdef IS_PY3K + 0, /* getattr */ +#else + (getattrfunc) dsaKey_getattr, /* getattr */ +#endif + 0, /* setattr */ + 0, /* compare */ + 0, /* repr */ + 0, /* as_number */ + 0, /* as_sequence */ + 0, /* as_mapping */ + 0, /* hash */ + 0, /* call */ +#ifdef IS_PY3K + 0, /*tp_str*/ + (getattrofunc) dsaKey_getattro, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + dsaKey__methods__, /*tp_methods*/ +#endif +}; + +static PyTypeObject rsaKeyType = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT (NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else + PyObject_HEAD_INIT (NULL) + 0, /*ob_size*/ +#endif + "rsaKey", /*tp_name*/ + sizeof (rsaKey), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) rsaKey_dealloc, /* dealloc */ + 0, /* print */ +#ifdef IS_PY3K + 0, /* getattr */ +#else + (getattrfunc) rsaKey_getattr, /* getattr */ +#endif + 0, /* setattr */ + 0, /* compare */ + 0, /* repr */ + 0, /* as_number */ + 0, /* as_sequence */ + 0, /* as_mapping */ + 0, /* hash */ + 0, /* call */ +#ifdef IS_PY3K + 0, /*tp_str*/ + (getattrofunc) rsaKey_getattro, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + rsaKey__methods__, /*tp_methods*/ +#endif +}; + static PyObject * dsaKey_new (PyObject * self, PyObject * args) { @@ -399,17 +494,43 @@ dsaKey_dealloc (dsaKey * key) } static PyObject * +#ifdef IS_PY3K +dsaKey_getattro (dsaKey * key, PyObject *attr) +#else dsaKey_getattr (dsaKey * key, char *attr) +#endif { +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + if (PyUnicode_CompareWithASCIIString(attr,"y") == 0) +#else if (strcmp (attr, "y") == 0) +#endif return mpzToLongObj (key->y); +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "g") == 0) +#else else if (strcmp (attr, "g") == 0) +#endif return mpzToLongObj (key->g); +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "p") == 0) +#else else if (strcmp (attr, "p") == 0) +#endif return mpzToLongObj (key->p); +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "q") == 0) +#else else if (strcmp (attr, "q") == 0) +#endif return mpzToLongObj (key->q); +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "x") == 0) +#else else if (strcmp (attr, "x") == 0) +#endif { if (mpz_size (key->x) == 0) { @@ -420,9 +541,12 @@ dsaKey_getattr (dsaKey * key, char *attr) return mpzToLongObj (key->x); } else - { +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr((PyObject *) key, attr); +#else return Py_FindMethod (dsaKey__methods__, (PyObject *) key, attr); - } +#endif } static PyObject * @@ -625,13 +749,31 @@ rsaKey_dealloc (rsaKey * key) } static PyObject * +#ifdef IS_PY3K +rsaKey_getattro (rsaKey * key, PyObject *attr) +#else rsaKey_getattr (rsaKey * key, char *attr) +#endif { +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + if (PyUnicode_CompareWithASCIIString(attr, "n") == 0) +#else if (strcmp (attr, "n") == 0) +#endif return mpzToLongObj (key->n); +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "e") == 0) +#else else if (strcmp (attr, "e") == 0) +#endif return mpzToLongObj (key->e); +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "d") == 0) +#else else if (strcmp (attr, "d") == 0) +#endif { if (mpz_size (key->d) == 0) { @@ -641,7 +783,11 @@ rsaKey_getattr (rsaKey * key, char *attr) } return mpzToLongObj (key->d); } +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "p") == 0) +#else else if (strcmp (attr, "p") == 0) +#endif { if (mpz_size (key->p) == 0) { @@ -651,7 +797,11 @@ rsaKey_getattr (rsaKey * key, char *attr) } return mpzToLongObj (key->p); } +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "q") == 0) +#else else if (strcmp (attr, "q") == 0) +#endif { if (mpz_size (key->q) == 0) { @@ -661,7 +811,11 @@ rsaKey_getattr (rsaKey * key, char *attr) } return mpzToLongObj (key->q); } +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "u") == 0) +#else else if (strcmp (attr, "u") == 0) +#endif { if (mpz_size (key->u) == 0) { @@ -672,10 +826,13 @@ rsaKey_getattr (rsaKey * key, char *attr) return mpzToLongObj (key->u); } else - { +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr((PyObject *) key, attr); +#else return Py_FindMethod (rsaKey__methods__, (PyObject *) key, attr); - } +#endif } static PyObject * @@ -904,7 +1061,7 @@ cleanup: -inline size_t size (mpz_t n) +INLINE size_t size (mpz_t n) { return mpz_sizeinbase (n, 2); } @@ -998,7 +1155,7 @@ getRandomInteger (mpz_t n, unsigned long int bits, PyObject *randfunc_) arglist = Py_BuildValue ("(l)", (long int)bytes); rand_bytes = PyObject_CallObject (randfunc, arglist); Py_DECREF (arglist); - if (!PyString_Check (rand_bytes)) + if (!PyBytes_Check (rand_bytes)) { PyErr_SetString (PyExc_TypeError, "randfunc must return a string of random bytes"); @@ -1006,7 +1163,7 @@ getRandomInteger (mpz_t n, unsigned long int bits, PyObject *randfunc_) goto cleanup; } - bytes_to_mpz (n, (unsigned char *)PyString_AsString(rand_bytes), bytes); + bytes_to_mpz (n, (unsigned char *)PyBytes_AsString(rand_bytes), bytes); /* remove superflous bits by right-shifting */ mpz_fdiv_q_2exp (n, n, 8 - odd_bits); @@ -1238,6 +1395,7 @@ getStrongPrime (PyObject *self, PyObject *args, PyObject *kwargs) static char *kwlist[] = {"N", "e", "false_positive_prob", "randfunc", NULL}; unsigned long int base_size = SIEVE_BASE_SIZE; unsigned long int field_size = 5 * base_size; + int res; if (!PyArg_ParseTupleAndKeywords (args, kwargs, "l|ldO:getStrongPrime", kwlist, &bits, &e, &false_positive_prob, @@ -1288,7 +1446,7 @@ getStrongPrime (PyObject *self, PyObject *args, PyObject *kwargs) /* Randomly choose X, y[0] and y[1] */ Py_BLOCK_THREADS; - int res = 1; + res = 1; res &= getRandomRange (X, lower_bound, upper_bound, randfunc); res &= getRandomNBitInteger (y[0], 101, randfunc); res &= getRandomNBitInteger (y[1], 101, randfunc); @@ -1450,21 +1608,56 @@ static PyMethodDef _fastmath__methods__[] = { {NULL, NULL} }; +#ifdef IS_PY3K +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "_fastmath", + NULL, + -1, + _fastmath__methods__, + NULL, + NULL, + NULL, + NULL +}; +#endif + +#ifdef IS_PY3K +PyMODINIT_FUNC +PyInit__fastmath (void) +#else void init_fastmath (void) +#endif { - PyObject *_fastmath_module; - PyObject *_fastmath_dict; - + PyObject *_fastmath_module; + PyObject *_fastmath_dict; + +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&rsaKeyType) < 0) + return NULL; + if (PyType_Ready(&dsaKeyType) < 0) + return NULL; + + _fastmath_module = PyModule_Create(&moduledef); + if (_fastmath_module == NULL) + return NULL; +#else rsaKeyType.ob_type = &PyType_Type; dsaKeyType.ob_type = &PyType_Type; _fastmath_module = Py_InitModule ("_fastmath", _fastmath__methods__); - _fastmath_dict = PyModule_GetDict (_fastmath_module); +#endif + _fastmath_dict = PyModule_GetDict (_fastmath_module); fastmathError = PyErr_NewException ("_fastmath.error", NULL, NULL); - PyDict_SetItemString (_fastmath_dict, "error", fastmathError); -} + PyDict_SetItemString (_fastmath_dict, "error", fastmathError); + PyModule_AddIntConstant(_fastmath_module, "HAVE_DECL_MPZ_POWM_SEC", HAVE_DECL_MPZ_POWM_SEC); +#ifdef IS_PY3K + return _fastmath_module; +#endif +} /* The first 10000 primes to be used as a base for sieving */ static unsigned int sieve_base[10000] = { diff --git a/src/block_template.c b/src/block_template.c index a4be66a..559e582 100644 --- a/src/block_template.c +++ b/src/block_template.c @@ -34,6 +34,7 @@ #endif #include "Python.h" +#include "pycrypto_compat.h" #include "modsupport.h" #include "_counter.h" @@ -51,7 +52,11 @@ #define _XSTR(x) _STR(x) #define _PASTE(x,y) x##y #define _PASTE2(x,y) _PASTE(x,y) +#ifdef IS_PY3K +#define _MODULE_NAME _PASTE2(PyInit_,MODULE_NAME) +#else #define _MODULE_NAME _PASTE2(init,MODULE_NAME) +#endif #define _MODULE_STRING _XSTR(MODULE_NAME) typedef struct @@ -64,9 +69,17 @@ typedef struct block_state st; } ALGobject; +/* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C. + * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize + */ +#ifdef IS_PY3K +static PyTypeObject ALGtype; +#define is_ALGobject(v) (Py_TYPE(v) == &ALGtype) +#else staticforward PyTypeObject ALGtype; - #define is_ALGobject(v) ((v)->ob_type == &ALGtype) +#define PyLong_FromLong PyInt_FromLong /* For Python 2.x */ +#endif static ALGobject * newALGobject(void) @@ -95,6 +108,7 @@ ALGdealloc(PyObject *ptr) } + static char ALGnew__doc__[] = "new(key, [mode], [IV]): Return a new " _MODULE_STRING " encryption object."; @@ -168,13 +182,16 @@ ALGnew(PyObject *self, PyObject *args, PyObject *kwdict) return NULL; } } - if (mode == MODE_CTR) { if (counter == NULL) { PyErr_SetString(PyExc_TypeError, "'counter' keyword parameter is required with CTR mode"); return NULL; +#ifdef IS_PY3K + } else if (PyObject_HasAttr(counter, PyUnicode_FromString("__PCT_CTR_SHORTCUT__"))) { +#else } else if (PyObject_HasAttrString(counter, "__PCT_CTR_SHORTCUT__")) { +#endif counter_shortcut = 1; } else if (!PyCallable_Check(counter)) { PyErr_SetString(PyExc_ValueError, @@ -245,7 +262,7 @@ ALG_Encrypt(ALGobject *self, PyObject *args) return NULL; if (len==0) /* Handle empty string */ { - return PyString_FromStringAndSize(NULL, 0); + return PyBytes_FromStringAndSize(NULL, 0); } if ( (len % BLOCK_SIZE) !=0 && (self->mode!=MODE_CFB) && (self->mode!=MODE_PGP) && @@ -437,25 +454,33 @@ ALG_Encrypt(ALGobject *self, PyObject *args) free(buffer); return NULL; } - if (!PyString_Check(ctr)) + if (!PyBytes_Check(ctr)) { PyErr_SetString(PyExc_TypeError, +#ifdef IS_PY3K + "CTR counter function didn't return bytes"); +#else "CTR counter function didn't return a string"); +#endif Py_DECREF(ctr); free(buffer); return NULL; } - if (PyString_Size(ctr) != BLOCK_SIZE) { + if (PyBytes_Size(ctr) != BLOCK_SIZE) { PyErr_Format(PyExc_TypeError, "CTR counter function returned " +#ifdef IS_PY3K + "bytes not of length %i", +#else "string not of length %i", +#endif BLOCK_SIZE); Py_DECREF(ctr); free(buffer); return NULL; } Py_UNBLOCK_THREADS; - block_encrypt(&(self->st), (unsigned char *)PyString_AsString(ctr), + block_encrypt(&(self->st), (unsigned char *)PyBytes_AsString(ctr), self->IV); Py_BLOCK_THREADS; Py_DECREF(ctr); @@ -477,7 +502,7 @@ ALG_Encrypt(ALGobject *self, PyObject *args) return NULL; } Py_END_ALLOW_THREADS; - result=PyString_FromStringAndSize((char *) buffer, len); + result=PyBytes_FromStringAndSize((char *) buffer, len); free(buffer); return(result); } @@ -486,6 +511,8 @@ static char ALG_Decrypt__doc__[] = "decrypt(string): Decrypt the provided string of binary data."; + + static PyObject * ALG_Decrypt(ALGobject *self, PyObject *args) { @@ -502,7 +529,7 @@ ALG_Decrypt(ALGobject *self, PyObject *args) return NULL; if (len==0) /* Handle empty string */ { - return PyString_FromStringAndSize(NULL, 0); + return PyBytes_FromStringAndSize(NULL, 0); } if ( (len % BLOCK_SIZE) !=0 && (self->mode!=MODE_CFB && self->mode!=MODE_PGP)) @@ -642,7 +669,7 @@ ALG_Decrypt(ALGobject *self, PyObject *args) return NULL; } Py_END_ALLOW_THREADS; - result=PyString_FromStringAndSize((char *) buffer, len); + result=PyBytes_FromStringAndSize((char *) buffer, len); free(buffer); return(result); } @@ -693,17 +720,25 @@ void PrintState(self, msg) #endif -/* ALG object methods */ + + + + +/* ALG object methods */ static PyMethodDef ALGmethods[] = { +#ifdef IS_PY3K + {"encrypt", (PyCFunction) ALG_Encrypt, METH_O, ALG_Encrypt__doc__}, + {"decrypt", (PyCFunction) ALG_Decrypt, METH_O, ALG_Decrypt__doc__}, +#else {"encrypt", (PyCFunction) ALG_Encrypt, 0, ALG_Encrypt__doc__}, {"decrypt", (PyCFunction) ALG_Decrypt, 0, ALG_Decrypt__doc__}, +#endif {"sync", (PyCFunction) ALG_Sync, METH_VARARGS, ALG_Sync__doc__}, {NULL, NULL} /* sentinel */ }; - static int ALGsetattr(PyObject *ptr, char *name, PyObject *v) { @@ -721,44 +756,77 @@ ALGsetattr(PyObject *ptr, char *name, PyObject *v) "Can't delete IV attribute of block cipher object"); return -1; } - if (!PyString_Check(v)) + if (!PyBytes_Check(v)) { PyErr_SetString(PyExc_TypeError, +#ifdef IS_PY3K + "IV attribute of block cipher object must be bytes"); +#else "IV attribute of block cipher object must be string"); +#endif return -1; } - if (PyString_Size(v)!=BLOCK_SIZE) + if (PyBytes_Size(v)!=BLOCK_SIZE) { PyErr_Format(PyExc_ValueError, _MODULE_STRING " IV must be %i bytes long", BLOCK_SIZE); return -1; } - memcpy(self->IV, PyString_AsString(v), BLOCK_SIZE); + memcpy(self->IV, PyBytes_AsString(v), BLOCK_SIZE); return 0; } static PyObject * +#ifdef IS_PY3K +ALGgetattro(PyObject *s, PyObject *attr) +#else ALGgetattr(PyObject *s, char *name) +#endif { ALGobject *self = (ALGobject*)s; + +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + + if (PyUnicode_CompareWithASCIIString(attr, "IV") == 0) +#else if (strcmp(name, "IV") == 0) +#endif { - return(PyString_FromStringAndSize((char *) self->IV, BLOCK_SIZE)); + return(PyBytes_FromStringAndSize((char *) self->IV, BLOCK_SIZE)); } +#ifdef IS_PY3K + if (PyUnicode_CompareWithASCIIString(attr, "mode") == 0) +#else if (strcmp(name, "mode") == 0) +#endif { - return(PyInt_FromLong((long)(self->mode))); + return(PyLong_FromLong((long)(self->mode))); } +#ifdef IS_PY3K + if (PyUnicode_CompareWithASCIIString(attr, "block_size") == 0) +#else if (strcmp(name, "block_size") == 0) +#endif { - return PyInt_FromLong(BLOCK_SIZE); + return PyLong_FromLong(BLOCK_SIZE); } +#ifdef IS_PY3K + if (PyUnicode_CompareWithASCIIString(attr, "key_size") == 0) +#else if (strcmp(name, "key_size") == 0) +#endif { - return PyInt_FromLong(KEY_SIZE); + return PyLong_FromLong(KEY_SIZE); } - return Py_FindMethod(ALGmethods, (PyObject *) self, name); +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr(s, attr); +#else + return Py_FindMethod(ALGmethods, (PyObject *) self, name); +#endif } /* List of functions defined in the module */ @@ -771,38 +839,95 @@ static struct PyMethodDef modulemethods[] = static PyTypeObject ALGtype = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ +#endif _MODULE_STRING, /*tp_name*/ sizeof(ALGobject), /*tp_size*/ 0, /*tp_itemsize*/ /* methods */ - ALGdealloc, /*tp_dealloc*/ + (destructor) ALGdealloc, /*tp_dealloc*/ 0, /*tp_print*/ - ALGgetattr, /*tp_getattr*/ +#ifdef IS_PY3K + 0, /*tp_getattr*/ +#else + ALGgetattr, /*tp_getattr*/ +#endif ALGsetattr, /*tp_setattr*/ 0, /*tp_compare*/ - (reprfunc) 0, /*tp_repr*/ + (reprfunc) 0, /*tp_repr*/ 0, /*tp_as_number*/ +#ifdef IS_PY3K + 0, /*tp_as_sequence */ + 0, /*tp_as_mapping */ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + ALGgetattro, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + ALGmethods, /*tp_methods*/ +#endif +}; + +#ifdef IS_PY3K +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "Crypto.Cipher." _MODULE_STRING, + NULL, + -1, + modulemethods, + NULL, + NULL, + NULL, + NULL }; +#endif /* Initialization function for the module */ +/* Deal with old API in Python 2.1 */ #if PYTHON_API_VERSION < 1011 #define PyModule_AddIntConstant(m,n,v) {PyObject *o=PyInt_FromLong(v); \ if (o!=NULL) \ {PyDict_SetItemString(PyModule_GetDict(m),n,o); Py_DECREF(o);}} #endif + +#ifdef IS_PY3K +PyMODINIT_FUNC +#else void +#endif _MODULE_NAME (void) { PyObject *m; - ALGtype.ob_type = &PyType_Type; +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&ALGtype) < 0) + return NULL; /* Create the module and add the functions */ + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; +#else + ALGtype.ob_type = &PyType_Type; + /* Create the module and add the functions */ m = Py_InitModule("Crypto.Cipher." _MODULE_STRING, modulemethods); +#endif PyModule_AddIntConstant(m, "MODE_ECB", MODE_ECB); PyModule_AddIntConstant(m, "MODE_CBC", MODE_CBC); @@ -816,6 +941,9 @@ _MODULE_NAME (void) /* Check for errors */ if (PyErr_Occurred()) Py_FatalError("can't initialize module " _MODULE_STRING); -} -/* vim:set ts=8 sw=8 sts=0 noexpandtab: */ +#ifdef IS_PY3K + return m; +#endif +} +/* vim:set ts=4 sw=4 sts=0 noexpandtab: */ diff --git a/src/config.h.in b/src/config.h.in new file mode 100644 index 0000000..514c060 --- /dev/null +++ b/src/config.h.in @@ -0,0 +1,141 @@ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the declaration of `mpz_powm', and to 0 if you + don't. */ +#undef HAVE_DECL_MPZ_POWM + +/* Define to 1 if you have the declaration of `mpz_powm_sec', and to 0 if you + don't. */ +#undef HAVE_DECL_MPZ_POWM_SEC + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `gmp' library (-lgmp). */ +#undef HAVE_LIBGMP + +/* Define to 1 if you have the `mpir' library (-lmpir). */ +#undef HAVE_LIBMPIR + +/* Define to 1 if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have the <stddef.h> header file. */ +#undef HAVE_STDDEF_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the <wchar.h> header file. */ +#undef HAVE_WCHAR_H + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT32_T + +/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT64_T + +/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT8_T + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to the type of a signed integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#undef int16_t + +/* Define to the type of a signed integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef int32_t + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef int64_t + +/* Define to the type of a signed integer type of width exactly 8 bits if such + a type exists and the standard includes do not define it. */ +#undef int8_t + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +#undef size_t + +/* Define to the type of an unsigned integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#undef uint16_t + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef uint32_t + +/* Define to the type of an unsigned integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef uint64_t + +/* Define to the type of an unsigned integer type of width exactly 8 bits if + such a type exists and the standard includes do not define it. */ +#undef uint8_t diff --git a/src/hash_template.c b/src/hash_template.c index d0af39d..0f71c3e 100644 --- a/src/hash_template.c +++ b/src/hash_template.c @@ -30,12 +30,18 @@ #ifdef _HAVE_STDC_HEADERS #include <string.h> #endif +#include "Python.h" +#include "pycrypto_compat.h" #define _STR(x) #x #define _XSTR(x) _STR(x) #define _PASTE(x,y) x##y #define _PASTE2(x,y) _PASTE(x,y) +#ifdef IS_PY3K +#define _MODULE_NAME _PASTE2(PyInit_,MODULE_NAME) +#else #define _MODULE_NAME _PASTE2(init,MODULE_NAME) +#endif #define _MODULE_STRING _XSTR(MODULE_NAME) typedef struct { @@ -43,9 +49,17 @@ typedef struct { hash_state st; } ALGobject; +/* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C. + * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize + */ +#ifdef IS_PY3K +static PyTypeObject ALGtype; +#define is_ALGobject(v) (Py_TYPE(v) == &ALGtype) +#else staticforward PyTypeObject ALGtype; - #define is_ALGobject(v) ((v)->ob_type == &ALGtype) +#define PyLong_FromLong PyInt_FromLong /* For Python 2.x */ +#endif static ALGobject * newALGobject(void) @@ -117,22 +131,27 @@ ALG_hexdigest(ALGobject *self, PyObject *args) /* Get the raw (binary) digest value */ value = (PyObject *)hash_digest(&(self->st)); - size = PyString_Size(value); - raw_digest = (unsigned char *) PyString_AsString(value); + size = PyBytes_Size(value); + raw_digest = (unsigned char *) PyBytes_AsString(value); /* Create a new string */ - retval = PyString_FromStringAndSize(NULL, size * 2 ); - hex_digest = (unsigned char *) PyString_AsString(retval); + retval = PyBytes_FromStringAndSize(NULL, size * 2 ); + hex_digest = (unsigned char *) PyBytes_AsString(retval); /* Make hex version of the digest */ - for(i=j=0; i<size; i++) + for(i=j=0; i<size; i++) { char c; c = raw_digest[i] / 16; c = (c>9) ? c+'a'-10 : c + '0'; hex_digest[j++] = c; c = raw_digest[i] % 16; c = (c>9) ? c+'a'-10 : c + '0'; hex_digest[j++] = c; - } + } +#ifdef IS_PY3K + /* Create a text string return value */ + retval = PyUnicode_FromEncodedObject(retval,"latin-1","strict"); +#endif + Py_DECREF(value); return retval; } @@ -150,10 +169,12 @@ ALG_update(ALGobject *self, PyObject *args) return NULL; Py_BEGIN_ALLOW_THREADS; + hash_update(&(self->st), cp, len); Py_END_ALLOW_THREADS; Py_INCREF(Py_None); + return Py_None; } @@ -164,37 +185,80 @@ static PyObject *ALG_new(PyObject*, PyObject*); static PyMethodDef ALG_methods[] = { {"copy", (PyCFunction)ALG_copy, METH_VARARGS, ALG_copy__doc__}, {"digest", (PyCFunction)ALG_digest, METH_VARARGS, ALG_digest__doc__}, - {"hexdigest", (PyCFunction)ALG_hexdigest, METH_VARARGS, - ALG_hexdigest__doc__}, + {"hexdigest", (PyCFunction)ALG_hexdigest, METH_VARARGS, ALG_hexdigest__doc__}, {"update", (PyCFunction)ALG_update, METH_VARARGS, ALG_update__doc__}, {"new", (PyCFunction)ALG_new, METH_VARARGS, ALG_new__doc__}, {NULL, NULL} /* sentinel */ }; static PyObject * +#ifdef IS_PY3K +ALG_getattro(PyObject *self, PyObject *attr) +#else ALG_getattr(PyObject *self, char *name) +#endif { +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + + if (PyUnicode_CompareWithASCIIString(attr, "digest_size")==0) + return PyLong_FromLong(DIGEST_SIZE); +#else if (strcmp(name, "digest_size")==0) return PyInt_FromLong(DIGEST_SIZE); +#endif + +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr(self, attr); +#else return Py_FindMethod(ALG_methods, self, name); +#endif } static PyTypeObject ALGtype = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - _MODULE_STRING, /*tp_name*/ - sizeof(ALGobject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - ALG_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ +#endif + _MODULE_STRING, /*tp_name*/ + sizeof(ALGobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) ALG_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ +#ifdef IS_PY3K + 0, /*tp_getattr*/ +#else ALG_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ -}; - +#endif + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ +#ifdef IS_PY3K + 0, /*tp_as_sequence */ + 0, /*tp_as_mapping */ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + ALG_getattro, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + ALG_methods, /*tp_methods*/ +#endif + }; /* The single module-level function: new() */ @@ -236,7 +300,6 @@ ALG_new(PyObject *self, PyObject *args) return (PyObject *)new; } - /* List of functions exported by this module */ static struct PyMethodDef ALG_functions[] = { @@ -244,22 +307,51 @@ static struct PyMethodDef ALG_functions[] = { {NULL, NULL} /* Sentinel */ }; +#ifdef IS_PY3K +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "Crypto.Hash." _MODULE_STRING, + NULL, + -1, + ALG_functions, + NULL, + NULL, + NULL, + NULL +}; +#endif /* Initialize this module. */ +/* Deal with old API in Python 2.1 */ #if PYTHON_API_VERSION < 1011 #define PyModule_AddIntConstant(m,n,v) {PyObject *o=PyInt_FromLong(v); \ if (o!=NULL) \ {PyDict_SetItemString(PyModule_GetDict(m),n,o); Py_DECREF(o);}} #endif +#ifdef IS_PY3K +PyMODINIT_FUNC +#else void +#endif _MODULE_NAME (void) { PyObject *m; +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&ALGtype) < 0) + return NULL; + + /* Create the module and add the functions */ + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; +#else ALGtype.ob_type = &PyType_Type; m = Py_InitModule("Crypto.Hash." _MODULE_STRING, ALG_functions); +#endif /* Add some symbolic constants to the module */ PyModule_AddIntConstant(m, "digest_size", DIGEST_SIZE); @@ -269,4 +361,7 @@ _MODULE_NAME (void) if (PyErr_Occurred()) Py_FatalError("can't initialize module " _MODULE_STRING); +#ifdef IS_PY3K + return m; +#endif } diff --git a/src/inc-msvc/config.h b/src/inc-msvc/config.h new file mode 100644 index 0000000..2b7a626 --- /dev/null +++ b/src/inc-msvc/config.h @@ -0,0 +1,16 @@ +/* Define to 1 if you have the declaration of `mpz_powm', and to 0 if you + don't. */ +#undef HAVE_DECL_MPZ_POWM + +/* Define to 1 if you have the declaration of `mpz_powm_sec', and to 0 if you + don't. */ +#undef HAVE_DECL_MPZ_POWM_SEC + +/* Define to 1 if you have the `gmp' library (-lgmp). */ +#undef HAVE_LIBGMP + +/* Define to 1 if you have the `mpir' library (-lmpir). */ +#undef HAVE_LIBMPIR + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 diff --git a/src/inc-msvc/stdint.h b/src/inc-msvc/stdint.h index 8b7a52f..f4a8eb7 100644 --- a/src/inc-msvc/stdint.h +++ b/src/inc-msvc/stdint.h @@ -34,11 +34,9 @@ typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; -/* Define the "inline" keyword */ #ifndef inline # define inline __inline #endif /* inline */ - #endif /* PYCRYPTO_MSVC_STDINT_H */ /* vim:set ts=4 sw=4 sts=4 expandtab: */ diff --git a/src/pycrypto_compat.h b/src/pycrypto_compat.h index c40d4b5..eaaebdb 100644 --- a/src/pycrypto_compat.h +++ b/src/pycrypto_compat.h @@ -23,6 +23,26 @@ */ #ifndef PYCRYPTO_COMPAT_H #define PYCRYPTO_COMPAT_H +#include "Python.h" + +/* + * Python 3.x defines, for conditional compiles + */ + +#if PY_MAJOR_VERSION >= 3 +#define IS_PY3K +#else +#define PyBytes_GET_SIZE PyString_GET_SIZE +#define PyBytes_FromStringAndSize PyString_FromStringAndSize +#define PyBytes_AS_STRING PyString_AS_STRING +#define PyBytes_Check PyString_Check +#define PyBytes_Size PyString_Size +#define PyBytes_AsString PyString_AsString +#define PyBytesObject PyStringObject +#if PY_MINOR_VERSION <= 5 /* PyUnicode_FromString exists from Python 2.6 on up */ +#define PyUnicode_FromString PyString_FromString +#endif +#endif /* * Py_CLEAR for Python < 2.4 diff --git a/src/stream_template.c b/src/stream_template.c index e1db5b1..c3effa4 100644 --- a/src/stream_template.c +++ b/src/stream_template.c @@ -34,13 +34,18 @@ #endif #include "Python.h" +#include "pycrypto_compat.h" #include "modsupport.h" #define _STR(x) #x #define _XSTR(x) _STR(x) #define _PASTE(x,y) x##y #define _PASTE2(x,y) _PASTE(x,y) +#ifdef IS_PY3K +#define _MODULE_NAME _PASTE2(PyInit_,MODULE_NAME) +#else #define _MODULE_NAME _PASTE2(init,MODULE_NAME) +#endif #define _MODULE_STRING _XSTR(MODULE_NAME) /* @@ -55,9 +60,17 @@ typedef struct stream_state st; } ALGobject; +/* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C. + * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize + */ +#ifdef IS_PY3K +static PyTypeObject ALGtype; +#define is_ALGobject(v) (Py_TYPE(v) == &ALGtype) +#else staticforward PyTypeObject ALGtype; - #define is_ALGobject(v) ((v)->ob_type == &ALGtype) +#define PyLong_FromLong PyInt_FromLong /* For Python 2.x */ +#endif static ALGobject * newALGobject(void) @@ -134,7 +147,7 @@ ALG_Encrypt(ALGobject *self, PyObject *args) return NULL; if (len == 0) /* Handle empty string */ { - return PyString_FromStringAndSize(NULL, 0); + return PyBytes_FromStringAndSize(NULL, 0); } buffer = malloc(len); if (buffer == NULL) @@ -147,7 +160,7 @@ ALG_Encrypt(ALGobject *self, PyObject *args) memcpy(buffer, str, len); stream_encrypt(&(self->st), buffer, len); Py_END_ALLOW_THREADS; - result = PyString_FromStringAndSize((char *)buffer, len); + result = PyBytes_FromStringAndSize((char *)buffer, len); free(buffer); return (result); } @@ -166,7 +179,7 @@ ALG_Decrypt(ALGobject *self, PyObject *args) return NULL; if (len == 0) /* Handle empty string */ { - return PyString_FromStringAndSize(NULL, 0); + return PyBytes_FromStringAndSize(NULL, 0); } buffer = malloc(len); if (buffer == NULL) @@ -179,35 +192,58 @@ ALG_Decrypt(ALGobject *self, PyObject *args) memcpy(buffer, str, len); stream_decrypt(&(self->st), buffer, len); Py_END_ALLOW_THREADS; - result = PyString_FromStringAndSize((char *)buffer, len); + result = PyBytes_FromStringAndSize((char *)buffer, len); free(buffer); return (result); } /* ALGobject methods */ - static PyMethodDef ALGmethods[] = -{ + { +#ifdef IS_PY3K + {"encrypt", (PyCFunction) ALG_Encrypt, METH_O, ALG_Encrypt__doc__}, + {"decrypt", (PyCFunction) ALG_Decrypt, METH_O, ALG_Decrypt__doc__}, +#else {"encrypt", (PyCFunction) ALG_Encrypt, 0, ALG_Encrypt__doc__}, {"decrypt", (PyCFunction) ALG_Decrypt, 0, ALG_Decrypt__doc__}, - {NULL, NULL} /* sentinel */ -}; +#endif + {NULL, NULL} /* sentinel */ + }; static PyObject * +#ifdef IS_PY3K +ALGgetattro(PyObject *self, PyObject *attr) +#else ALGgetattr(PyObject *self, char *name) +#endif { +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + + if (PyUnicode_CompareWithASCIIString(attr, "block_size") == 0) +#else if (strcmp(name, "block_size") == 0) +#endif { - return PyInt_FromLong(BLOCK_SIZE); + return PyLong_FromLong(BLOCK_SIZE); } +#ifdef IS_PY3K + if (PyUnicode_CompareWithASCIIString(attr, "key_size") == 0) +#else if (strcmp(name, "key_size") == 0) +#endif { - return PyInt_FromLong(KEY_SIZE); + return PyLong_FromLong(KEY_SIZE); } +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr(self, attr); +#else return Py_FindMethod(ALGmethods, self, name); +#endif } - /* List of functions defined in the module */ static struct PyMethodDef modulemethods[] = @@ -218,50 +254,111 @@ static struct PyMethodDef modulemethods[] = }; static PyTypeObject ALGtype = -{ + { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - _MODULE_STRING, /*tp_name*/ - sizeof(ALGobject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - ALGdealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - ALGgetattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ +#endif + _MODULE_STRING, /*tp_name*/ + sizeof(ALGobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) ALGdealloc, /*tp_dealloc*/ + 0, /*tp_print*/ +#ifdef IS_PY3K + 0, /*tp_getattr*/ +#else + ALGgetattr, /*tp_getattr*/ +#endif + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ +#ifdef IS_PY3K + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + ALGgetattro, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + ALGmethods, /*tp_methods*/ +#endif + }; + +#ifdef IS_PY3K + static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "Crypto.Cipher." _MODULE_STRING, + NULL, + -1, + modulemethods, + NULL, + NULL, + NULL, + NULL }; +#endif /* Initialization function for the module */ +/* Deal with old API in Python 2.1 */ #if PYTHON_API_VERSION < 1011 #define PyModule_AddIntConstant(m,n,v) {PyObject *o=PyInt_FromLong(v); \ if (o!=NULL) \ {PyDict_SetItemString(PyModule_GetDict(m),n,o); Py_DECREF(o);}} #endif +#ifdef IS_PY3K +PyMODINIT_FUNC +#else void -_MODULE_NAME (void) -{ - PyObject *m, *d, *x; +#endif + _MODULE_NAME (void) + { + PyObject *m, *d, *x; + +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&ALGtype) < 0) + return NULL; + /* Create the module and add the functions */ + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; +#else ALGtype.ob_type = &PyType_Type; /* Create the module and add the functions */ m = Py_InitModule("Crypto.Cipher." _MODULE_STRING, modulemethods); - - /* Add some symbolic constants to the module */ - d = PyModule_GetDict(m); - x = PyString_FromString(_MODULE_STRING ".error"); - PyDict_SetItemString(d, "error", x); - - PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE); +#endif + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + x = PyUnicode_FromString(_MODULE_STRING ".error"); + PyDict_SetItemString(d, "error", x); + + PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE); PyModule_AddIntConstant(m, "key_size", KEY_SIZE); - /* Check for errors */ - if (PyErr_Occurred()) - Py_FatalError("can't initialize module " _MODULE_STRING); -} + /* Check for errors */ + if (PyErr_Occurred()) + Py_FatalError("can't initialize module " _MODULE_STRING); -/* vim:set ts=8 sw=8 sts=0 noexpandtab: */ +#ifdef IS_PY3K + return m; +#endif + } + +/* vim:set ts=4 sw=4 sts=0 noexpandtab: */ diff --git a/src/strxor.c b/src/strxor.c index 1b91631..7cbbc1c 100644 --- a/src/strxor.c +++ b/src/strxor.c @@ -139,8 +139,8 @@ strxor_function(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "SS", &a, &b)) return NULL; - len_a = PyString_GET_SIZE(a); - len_b = PyString_GET_SIZE(b); + len_a = PyBytes_GET_SIZE(a); + len_b = PyBytes_GET_SIZE(b); assert(len_a >= 0); assert(len_b >= 0); @@ -151,13 +151,13 @@ strxor_function(PyObject *self, PyObject *args) } /* Create return string */ - retval = PyString_FromStringAndSize(NULL, len_a); + retval = PyBytes_FromStringAndSize(NULL, len_a); if (!retval) { return NULL; } /* retval := a ^ b */ - xor_strings(PyString_AS_STRING(retval), PyString_AS_STRING(a), PyString_AS_STRING(b), len_a); + xor_strings(PyBytes_AS_STRING(retval), PyBytes_AS_STRING(a), PyBytes_AS_STRING(b), len_a); return retval; } @@ -186,17 +186,17 @@ strxor_c_function(PyObject *self, PyObject *args) return NULL; } - length = PyString_GET_SIZE(s); + length = PyBytes_GET_SIZE(s); assert(length >= 0); /* Create return string */ - retval = PyString_FromStringAndSize(NULL, length); + retval = PyBytes_FromStringAndSize(NULL, length); if (!retval) { return NULL; } /* retval := a ^ chr(c)*length */ - xor_string_with_char(PyString_AS_STRING(retval), PyString_AS_STRING(s), (char) c, length); + xor_string_with_char(PyBytes_AS_STRING(retval), PyBytes_AS_STRING(s), (char) c, length); return retval; } @@ -212,18 +212,46 @@ static PyMethodDef strxor_methods[] = { {NULL, NULL, 0, NULL} /* end-of-list sentinel value */ }; +#ifdef IS_PY3K +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "strxor", + NULL, + -1, + strxor_methods, + NULL, + NULL, + NULL, + NULL +}; +#endif + PyMODINIT_FUNC +#ifdef IS_PY3K +PyInit_strxor(void) +#else initstrxor(void) +#endif { - PyObject *m; + PyObject *m; /* Initialize the module */ +#ifdef IS_PY3K + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; +#else m = Py_InitModule("strxor", strxor_methods); if (m == NULL) return; - +#endif + /* Perform runtime tests */ runtime_test(); + +#ifdef IS_PY3K + return m; +#endif } /* vim:set ts=4 sw=4 sts=4 expandtab: */ diff --git a/src/winrand.c b/src/winrand.c index 8a2107d..d505e54 100644 --- a/src/winrand.c +++ b/src/winrand.c @@ -31,6 +31,7 @@ /* Author: Mark Moraes */ #include "Python.h" +#include "pycrypto_compat.h" #ifdef MS_WIN32 @@ -48,15 +49,24 @@ #endif /* To-Do: store provider name and type for print/repr? */ + typedef struct { PyObject_HEAD HCRYPTPROV hcp; } WRobject; +/* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C. + * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize + */ +#ifdef IS_PY3K +static PyTypeObject WRtype; +#define is_WRobject(v) (Py_TYPE(v) == &WRtype) +#else staticforward PyTypeObject WRtype; - #define is_WRobject(v) ((v)->ob_type == &WRtype) +#define PyLong_FromLong PyInt_FromLong /* for Python 2.x */ +#endif static void WRdealloc(PyObject *ptr) @@ -156,6 +166,7 @@ WR_get_bytes(WRobject *self, PyObject *args) * from an RC4 stream, they should be relatively * cheap. */ + if (! CryptGenRandom(self->hcp, (DWORD) nbytes, (BYTE *) buf)) { PyErr_Format(PyExc_SystemError, "CryptGenRandom failed, error 0x%x", @@ -163,7 +174,8 @@ WR_get_bytes(WRobject *self, PyObject *args) PyMem_Free(buf); return NULL; } - res = PyString_FromStringAndSize(buf, n); + + res = PyBytes_FromStringAndSize(buf, n); PyMem_Free(buf); return res; } @@ -185,9 +197,12 @@ static PyMethodDef WR_mod_methods[] = { {NULL, NULL} /* Sentinel */ }; - static PyObject * +#ifdef IS_PY3K +WRgetattro(PyObject *s, PyObject *attr) +#else WRgetattr(PyObject *s, char *name) +#endif { WRobject *self = (WRobject*)s; if (! is_WRobject(self)) { @@ -195,30 +210,99 @@ WRgetattr(PyObject *s, char *name) "WinRandom trying to getattr with non-WinRandom object"); return NULL; } +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + if (PyUnicode_CompareWithASCIIString(attr, "hcp") == 0) +#else if (strcmp(name, "hcp") == 0) - return PyInt_FromLong((long) self->hcp); +#endif + return PyLong_FromLong((long) self->hcp); +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr(s, attr); +#else return Py_FindMethod(WRmethods, (PyObject *) self, name); +#endif } static PyTypeObject WRtype = -{ + { + #ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - "winrandom.WinRandom", /*tp_name*/ - sizeof(WRobject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - WRdealloc, /*tp_dealloc*/ - 0, /*tp_print*/ +#endif + "winrandom.WinRandom", /*tp_name*/ + sizeof(WRobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) WRdealloc, /*tp_dealloc*/ + 0, /*tp_print*/ +#ifndef IS_PY3K WRgetattr, /*tp_getattr*/ +#else + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number */ + 0, /*tp_as_sequence */ + 0, /*tp_as_mapping */ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + WRgetattro, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + WRmethods, /*tp_methods*/ +#endif }; +#ifdef IS_PY3K +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "winrandom", + NULL, + -1, + WR_mod_methods, + NULL, + NULL, + NULL, + NULL + }; +#endif + +#ifdef IS_PY3K +PyMODINIT_FUNC +PyInit_winrandom() +#else void initwinrandom() +#endif { PyObject *m; +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&WRtype) < 0) + return NULL; + /* Initialize the module */ + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; +#else WRtype.ob_type = &PyType_Type; m = Py_InitModule("winrandom", WR_mod_methods); +#endif /* define Windows CSP Provider Types */ #ifdef PROV_RSA_FULL @@ -296,8 +380,11 @@ initwinrandom() if (PyErr_Occurred()) Py_FatalError("can't initialize module winrandom"); -} +#ifdef IS_PY3K + return m; +#endif +} /* CryptGenRandom usage is described in |