diff --git a/shadowsocks/crypto/ctypes_openssl.py b/shadowsocks/crypto/openssl.py similarity index 78% rename from shadowsocks/crypto/ctypes_openssl.py rename to shadowsocks/crypto/openssl.py index 3bdd99d..bb11627 100644 --- a/shadowsocks/crypto/ctypes_openssl.py +++ b/shadowsocks/crypto/openssl.py @@ -74,7 +74,7 @@ def load_cipher(cipher_name): return None -class CtypesCrypto(object): +class OpenSSLCrypto(object): def __init__(self, cipher_name, key, iv, op): self._ctx = None if not loaded: @@ -117,38 +117,38 @@ class CtypesCrypto(object): ciphers = { - b'aes-128-cfb': (16, 16, CtypesCrypto), - b'aes-192-cfb': (24, 16, CtypesCrypto), - b'aes-256-cfb': (32, 16, CtypesCrypto), - b'aes-128-ofb': (16, 16, CtypesCrypto), - b'aes-192-ofb': (24, 16, CtypesCrypto), - b'aes-256-ofb': (32, 16, CtypesCrypto), - b'aes-128-ctr': (16, 16, CtypesCrypto), - b'aes-192-ctr': (24, 16, CtypesCrypto), - b'aes-256-ctr': (32, 16, CtypesCrypto), - b'aes-128-cfb8': (16, 16, CtypesCrypto), - b'aes-192-cfb8': (24, 16, CtypesCrypto), - b'aes-256-cfb8': (32, 16, CtypesCrypto), - b'aes-128-cfb1': (16, 16, CtypesCrypto), - b'aes-192-cfb1': (24, 16, CtypesCrypto), - b'aes-256-cfb1': (32, 16, CtypesCrypto), - b'bf-cfb': (16, 8, CtypesCrypto), - b'camellia-128-cfb': (16, 16, CtypesCrypto), - b'camellia-192-cfb': (24, 16, CtypesCrypto), - b'camellia-256-cfb': (32, 16, CtypesCrypto), - b'cast5-cfb': (16, 8, CtypesCrypto), - b'des-cfb': (8, 8, CtypesCrypto), - b'idea-cfb': (16, 8, CtypesCrypto), - b'rc2-cfb': (16, 8, CtypesCrypto), - b'rc4': (16, 0, CtypesCrypto), - b'seed-cfb': (16, 16, CtypesCrypto), + b'aes-128-cfb': (16, 16, OpenSSLCrypto), + b'aes-192-cfb': (24, 16, OpenSSLCrypto), + b'aes-256-cfb': (32, 16, OpenSSLCrypto), + b'aes-128-ofb': (16, 16, OpenSSLCrypto), + b'aes-192-ofb': (24, 16, OpenSSLCrypto), + b'aes-256-ofb': (32, 16, OpenSSLCrypto), + b'aes-128-ctr': (16, 16, OpenSSLCrypto), + b'aes-192-ctr': (24, 16, OpenSSLCrypto), + b'aes-256-ctr': (32, 16, OpenSSLCrypto), + b'aes-128-cfb8': (16, 16, OpenSSLCrypto), + b'aes-192-cfb8': (24, 16, OpenSSLCrypto), + b'aes-256-cfb8': (32, 16, OpenSSLCrypto), + b'aes-128-cfb1': (16, 16, OpenSSLCrypto), + b'aes-192-cfb1': (24, 16, OpenSSLCrypto), + b'aes-256-cfb1': (32, 16, OpenSSLCrypto), + b'bf-cfb': (16, 8, OpenSSLCrypto), + b'camellia-128-cfb': (16, 16, OpenSSLCrypto), + b'camellia-192-cfb': (24, 16, OpenSSLCrypto), + b'camellia-256-cfb': (32, 16, OpenSSLCrypto), + b'cast5-cfb': (16, 8, OpenSSLCrypto), + b'des-cfb': (8, 8, OpenSSLCrypto), + b'idea-cfb': (16, 8, OpenSSLCrypto), + b'rc2-cfb': (16, 8, OpenSSLCrypto), + b'rc4': (16, 0, OpenSSLCrypto), + b'seed-cfb': (16, 16, OpenSSLCrypto), } def run_method(method): - cipher = CtypesCrypto(method, b'k' * 32, b'i' * 16, 1) - decipher = CtypesCrypto(method, b'k' * 32, b'i' * 16, 0) + cipher = OpenSSLCrypto(method, b'k' * 32, b'i' * 16, 1) + decipher = OpenSSLCrypto(method, b'k' * 32, b'i' * 16, 0) util.run_cipher(cipher, decipher) diff --git a/shadowsocks/crypto/rc4_md5.py b/shadowsocks/crypto/rc4_md5.py index aa22b16..728412d 100644 --- a/shadowsocks/crypto/rc4_md5.py +++ b/shadowsocks/crypto/rc4_md5.py @@ -37,8 +37,8 @@ def create_cipher(alg, key, iv, op, key_as_bytes=0, d=None, salt=None, rc4_key = md5.digest() try: - from shadowsocks.crypto import ctypes_openssl - return ctypes_openssl.CtypesCrypto(b'rc4', rc4_key, b'', op) + from shadowsocks.crypto import openssl + return openssl.OpenSSLCrypto(b'rc4', rc4_key, b'', op) except Exception: import M2Crypto.EVP return M2Crypto.EVP.Cipher(b'rc4', rc4_key, b'', op, diff --git a/shadowsocks/crypto/salsa20_ctr.py b/shadowsocks/crypto/salsa20_ctr.py deleted file mode 100644 index 0ea13b8..0000000 --- a/shadowsocks/crypto/salsa20_ctr.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2014 clowwindy -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from __future__ import absolute_import, division, print_function, \ - with_statement - -import struct -import logging -import sys - -slow_xor = False -imported = False - -salsa20 = None -numpy = None - -BLOCK_SIZE = 16384 - - -def run_imports(): - global imported, slow_xor, salsa20, numpy - if not imported: - imported = True - try: - numpy = __import__('numpy') - except ImportError: - logging.error('can not import numpy, using SLOW XOR') - logging.error('please install numpy if you use salsa20') - slow_xor = True - try: - salsa20 = __import__('salsa20') - except ImportError: - logging.error('you have to install salsa20 before you use salsa20') - sys.exit(1) - - -def numpy_xor(a, b): - if slow_xor: - return py_xor_str(a, b) - dtype = numpy.byte - if len(a) % 4 == 0: - dtype = numpy.uint32 - elif len(a) % 2 == 0: - dtype = numpy.uint16 - - ab = numpy.frombuffer(a, dtype=dtype) - bb = numpy.frombuffer(b, dtype=dtype) - c = numpy.bitwise_xor(ab, bb) - r = c.tostring() - return r - - -def py_xor_str(a, b): - c = [] - if bytes == str: - for i in range(0, len(a)): - c.append(chr(ord(a[i]) ^ ord(b[i]))) - return ''.join(c) - else: - for i in range(0, len(a)): - c.append(a[i] ^ b[i]) - return bytes(c) - - -class Salsa20Cipher(object): - """a salsa20 CTR implemetation, provides m2crypto like cipher API""" - - def __init__(self, alg, key, iv, op, key_as_bytes=0, d=None, salt=None, - i=1, padding=1): - run_imports() - if alg != b'salsa20-ctr': - raise Exception('unknown algorithm') - self._key = key - self._nonce = struct.unpack('= BLOCK_SIZE: - self._next_stream() - self._pos = 0 - if not data: - break - return b''.join(results) - - -ciphers = { - b'salsa20-ctr': (32, 8, Salsa20Cipher), -} - - -def test(): - from shadowsocks.crypto import util - - cipher = Salsa20Cipher(b'salsa20-ctr', b'k' * 32, b'i' * 8, 1) - decipher = Salsa20Cipher(b'salsa20-ctr', b'k' * 32, b'i' * 8, 1) - - util.run_cipher(cipher, decipher) - - -if __name__ == '__main__': - test() diff --git a/shadowsocks/crypto/ctypes_libsodium.py b/shadowsocks/crypto/sodium.py similarity index 91% rename from shadowsocks/crypto/ctypes_libsodium.py rename to shadowsocks/crypto/sodium.py index 7e9f6a4..74fbb33 100644 --- a/shadowsocks/crypto/ctypes_libsodium.py +++ b/shadowsocks/crypto/sodium.py @@ -62,7 +62,7 @@ def load_libsodium(): loaded = True -class Salsa20Crypto(object): +class SodiumCrypto(object): def __init__(self, cipher_name, key, iv, op): if not loaded: load_libsodium() @@ -101,22 +101,22 @@ class Salsa20Crypto(object): ciphers = { - b'salsa20': (32, 8, Salsa20Crypto), - b'chacha20': (32, 8, Salsa20Crypto), + b'salsa20': (32, 8, SodiumCrypto), + b'chacha20': (32, 8, SodiumCrypto), } def test_salsa20(): - cipher = Salsa20Crypto(b'salsa20', b'k' * 32, b'i' * 16, 1) - decipher = Salsa20Crypto(b'salsa20', b'k' * 32, b'i' * 16, 0) + cipher = SodiumCrypto(b'salsa20', b'k' * 32, b'i' * 16, 1) + decipher = SodiumCrypto(b'salsa20', b'k' * 32, b'i' * 16, 0) util.run_cipher(cipher, decipher) def test_chacha20(): - cipher = Salsa20Crypto(b'chacha20', b'k' * 32, b'i' * 16, 1) - decipher = Salsa20Crypto(b'chacha20', b'k' * 32, b'i' * 16, 0) + cipher = SodiumCrypto(b'chacha20', b'k' * 32, b'i' * 16, 1) + decipher = SodiumCrypto(b'chacha20', b'k' * 32, b'i' * 16, 0) util.run_cipher(cipher, decipher) diff --git a/shadowsocks/encrypt.py b/shadowsocks/encrypt.py index ba02101..8b6b6d4 100644 --- a/shadowsocks/encrypt.py +++ b/shadowsocks/encrypt.py @@ -28,16 +28,14 @@ import sys import hashlib import logging -from shadowsocks.crypto import m2, rc4_md5, salsa20_ctr,\ - ctypes_openssl, ctypes_libsodium, table +from shadowsocks.crypto import m2, rc4_md5, openssl, sodium, table method_supported = {} method_supported.update(rc4_md5.ciphers) -method_supported.update(salsa20_ctr.ciphers) -method_supported.update(ctypes_openssl.ciphers) -method_supported.update(ctypes_libsodium.ciphers) -# let M2Crypto override ctypes_openssl +method_supported.update(openssl.ciphers) +method_supported.update(sodium.ciphers) +# let M2Crypto override openssl method_supported.update(m2.ciphers) method_supported.update(table.ciphers)