From 1aeb5e90ec2802393b0faeba3abb76ecb4aaaa8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Guimar=C3=A3es?= Date: Thu, 14 Apr 2016 18:09:25 -0300 Subject: [PATCH] adds Des3 wrappers --- setup.py | 5 +- wolfcrypt/build_ciphers.py | 52 ++++++++++++++++++ wolfcrypt/build_hashes.py | 19 +++++++ wolfcrypt/ciphers.py | 108 +++++++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+), 1 deletion(-) mode change 100644 => 100755 setup.py create mode 100644 wolfcrypt/build_ciphers.py create mode 100644 wolfcrypt/ciphers.py diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 index 111ec15..7136f0e --- a/setup.py +++ b/setup.py @@ -26,5 +26,8 @@ setup( packages=find_packages(), setup_requires=["cffi>=1.5.2"], install_requires=["cffi>=1.5.2"], - cffi_modules=["./wolfcrypt/build_hashes.py:ffi"], + cffi_modules=[ + #"./wolfcrypt/build_hashes.py:ffi", + "./wolfcrypt/build_ciphers.py:ffi" + ], ) diff --git a/wolfcrypt/build_ciphers.py b/wolfcrypt/build_ciphers.py new file mode 100644 index 0000000..271a883 --- /dev/null +++ b/wolfcrypt/build_ciphers.py @@ -0,0 +1,52 @@ +# buidl_ciphers.py +# +# Copyright (C) 2006-2016 wolfSSL Inc. +# +# This file is part of wolfSSL. (formerly known as CyaSSL) +# +# wolfSSL is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfSSL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +import os + +from cffi import FFI + +ffi = FFI() + +ffi.set_source("wolfcrypt._ciphers", + """ + #include + #include + """, + include_dirs=["/usr/local/include"], + library_dirs=["/usr/local/lib"], + libraries=["wolfssl"], +) + +ffi.cdef( +""" + + typedef unsigned char byte; + typedef unsigned int word32; + + typedef struct { ...; } Des3; + + int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv,int dir); + int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in,word32 sz); + int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in,word32 sz); + +""" +) + +if __name__ == "__main__": + ffi.compile(verbose=1) diff --git a/wolfcrypt/build_hashes.py b/wolfcrypt/build_hashes.py index 3ff9058..28c24e1 100644 --- a/wolfcrypt/build_hashes.py +++ b/wolfcrypt/build_hashes.py @@ -1,3 +1,22 @@ +# build_hashes.py +# +# Copyright (C) 2006-2016 wolfSSL Inc. +# +# This file is part of wolfSSL. (formerly known as CyaSSL) +# +# wolfSSL is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfSSL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA import os from cffi import FFI diff --git a/wolfcrypt/ciphers.py b/wolfcrypt/ciphers.py new file mode 100644 index 0000000..f27ee4f --- /dev/null +++ b/wolfcrypt/ciphers.py @@ -0,0 +1,108 @@ +# ciphers.py +# +# Copyright (C) 2006-2016 wolfSSL Inc. +# +# This file is part of wolfSSL. (formerly known as CyaSSL) +# +# wolfSSL is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfSSL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +from wolfcrypt._ciphers import ffi +from wolfcrypt._ciphers import lib + +MODE_ECB = 1 # Electronic Code Book +MODE_CBC = 2 # Cipher Block Chaining +MODE_CFB = 3 # Cipher Feedback +MODE_OFB = 5 # Output Feedback +MODE_CTR = 6 # Counter + +class Cipher(object): + # Magic object that protects against constructors. + _JAPANESE_CYBER_SWORD = object() + + + def __init__(self, token=""): + if token is not self._JAPANESE_CYBER_SWORD: + # PEP 272 -- API for Block Encryption Algorithms v1.0 + raise ValueError("don't construct directly, use new([string])") + + + @classmethod + def new(cls, key, mode, IV=None, **kwargs): + if mode != MODE_CBC: + raise ValueError("this mode is not supported by this cipher") + + obj = cls(Cipher._JAPANESE_CYBER_SWORD) + + if len(key) != obj.key_size: + raise ValueError("key must be %d in length" % obj.key_size) + + if IV is not None and len(IV) != obj.block_size: + raise ValueError("IV must be %d in length" % obj.block_size) + + obj._native_object = ffi.new(obj._native_type) + + obj._key = key + obj._IV = IV + + return obj + + + def encrypt(self, string): + if not string or len(string) % self.block_size: + raise ValueError( + "string must be a multiple of %d in length" % self.block_size) + + cipher = ffi.new(self._native_type) + ret = "\0" * len(string) + + self._set_key(cipher, self._ENCRYPTION) + self._encrypt(cipher, ret, string) + + return ret + + + def decrypt(self, string): + if not string or len(string) % self.block_size: + raise ValueError( + "string must be a multiple of %d in length" % self.block_size) + + cipher = ffi.new(self._native_type) + ret = "\0" * len(string) + + self._set_key(cipher, self._DECRYPTION) + self._decrypt(cipher, ret, string) + + return ret + + +class Des3(Cipher): + key_size = 24 + block_size = 8 + _native_type = "Des3 *" + + # key direction flags + _ENCRYPTION = 0 + _DECRYPTION = 1 + + + def _set_key(self, native_object, direction): + lib.wc_Des3_SetKey(native_object, self._key, self._IV, direction) + + + def _encrypt(self, native_object, destination, source): + lib.wc_Des3_CbcEncrypt(native_object, destination, source, len(source)) + + + def _decrypt(self, native_object, destination, source): + lib.wc_Des3_CbcDecrypt(native_object, destination, source, len(source))