Commit 44ce054f authored by Max Lv's avatar Max Lv

remove openssl dependency from shadowsocks

parent 07a065dd
......@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.shadowsocks"
android:installLocation="auto"
android:versionCode="12"
android:versionName="1.3.2">
android:versionCode="13"
android:versionName="1.3.3">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
......
No preview for this file type
No preview for this file type
......@@ -110,10 +110,10 @@ include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_MODULE := shadowsocks
LOCAL_SRC_FILES := shadowsocks/local.c shadowsocks/encrypt.c
LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -I$(LOCAL_PATH)/libev/ -I$(LOCAL_PATH)/openssl/include
LOCAL_SRC_FILES := shadowsocks/local.c shadowsocks/encrypt.c shadowsocks/rc4.c shadowsocks/md5.c
LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -I$(LOCAL_PATH)/libev/
LOCAL_STATIC_LIBRARIES := libev libcrypto
LOCAL_STATIC_LIBRARIES := libev
LOCAL_LDLIBS := -llog
......
#ifndef _ANDROID_H
#define _ANDROID_H
#include <android/log.h>
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, "shadowsocks", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "shadowsocks", __VA_ARGS__))
#define perror(a) (LOGE("%s: %s", a, strerror(errno)))
#endif // _ANDROID_H
#include "encrypt.h"
#include "android.h"
#define OFFSET_ROL(p, o) ((u_int64_t)(*(p + o)) << (8 * o))
static int random_compare(const void *_x, const void *_y) {
uint32_t i = _i;
uint64_t a = _a;
......@@ -9,9 +11,14 @@ static int random_compare(const void *_x, const void *_y) {
return (a % (x + i) - a % (y + i));
}
static void md5(const unsigned char *text, unsigned char *digest) {
md5_state_t state;
md5_init(&state);
md5_append(&state, text, strlen((char*)text));
md5_finish(&state, digest);
}
static void merge(uint8_t *left, int llength, uint8_t *right, int rlength)
{
static void merge(uint8_t *left, int llength, uint8_t *right, int rlength) {
/* Temporary memory locations for the 2 segments of the array to merge. */
uint8_t *ltmp = (uint8_t *) malloc(llength * sizeof(uint8_t));
uint8_t *rtmp = (uint8_t *) malloc(rlength * sizeof(uint8_t));
......@@ -78,8 +85,7 @@ static void merge(uint8_t *left, int llength, uint8_t *right, int rlength)
free(rtmp);
}
static void mergesort(uint8_t array[], int length)
{
static void merge_sort(uint8_t array[], int length) {
/* This is the middle index and also the length of the right array. */
uint8_t middle;
......@@ -106,73 +112,71 @@ static void mergesort(uint8_t array[], int length)
left = array;
right = array + llength;
mergesort(left, llength);
mergesort(right, middle);
merge_sort(left, llength);
merge_sort(right, middle);
merge(left, llength, right, middle);
}
void encrypt(char *buf, int len, EVP_CIPHER_CTX *ctx) {
void encrypt(char *buf, int len, struct rc4_state *ctx) {
if (ctx != NULL) {
int outlen;
unsigned char *mybuf = malloc(BUF_SIZE);
EVP_CipherUpdate(ctx, mybuf, &outlen, (unsigned char*)buf, len);
memcpy(buf, mybuf, len);
free(mybuf);
rc4_crypt(ctx, (unsigned char*) buf, (unsigned char*) buf, len);
} else {
char *end = buf + len;
while (buf < end) {
*buf = (char)encrypt_table[(uint8_t)*buf];
*buf = (char)enc_ctx.table.encrypt_table[(uint8_t)*buf];
buf++;
}
}
}
void decrypt(char *buf, int len, EVP_CIPHER_CTX *ctx) {
void decrypt(char *buf, int len, struct rc4_state *ctx) {
if (ctx != NULL) {
int outlen;
unsigned char *mybuf = malloc(BUF_SIZE);
EVP_CipherUpdate(ctx, mybuf, &outlen, (unsigned char*) buf, len);
memcpy(buf, mybuf, len);
free(mybuf);
rc4_crypt(ctx, (unsigned char*) buf, (unsigned char*) buf, len);
} else {
char *end = buf + len;
while (buf < end) {
*buf = (char)decrypt_table[(uint8_t)*buf];
*buf = (char)enc_ctx.table.decrypt_table[(uint8_t)*buf];
buf++;
}
}
}
void enc_ctx_init(EVP_CIPHER_CTX *ctx, const char *pass, int enc) {
unsigned char key[EVP_MAX_KEY_LENGTH];
unsigned char iv[EVP_MAX_IV_LENGTH];
int key_len = EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, (unsigned char*) pass,
strlen(pass), 1, key, iv);
EVP_CIPHER_CTX_init(ctx);
EVP_CipherInit_ex(ctx, EVP_rc4(), NULL, NULL, NULL, enc);
if (!EVP_CIPHER_CTX_set_key_length(ctx, key_len)) {
LOGE("Invalid key length: %d", key_len);
EVP_CIPHER_CTX_cleanup(ctx);
exit(EXIT_FAILURE);
}
EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc);
void enc_ctx_init(struct rc4_state *ctx, int enc) {
uint8_t *key = enc_ctx.rc4.key;
int key_len = enc_ctx.rc4.key_len;
rc4_init(ctx, key, key_len);
}
void enc_key_init(const char *pass) {
enc_ctx.rc4.key_len = 16;
enc_ctx.rc4.key = malloc(16);
md5((const unsigned char*)pass, enc_ctx.rc4.key);
}
void get_table(const char *pass) {
uint8_t *table = encrypt_table;
uint8_t *tmp_hash = MD5((unsigned char *) pass, strlen(pass), NULL);
_a = htole64(*(uint64_t *) tmp_hash);
uint8_t *enc_table = malloc(256);
uint8_t *dec_table = malloc(256);
uint8_t digest[16];
uint32_t i;
md5((const unsigned char*)pass, digest);
for (i = 0; i < 8; i++) {
_a += OFFSET_ROL(digest, i);
}
for(i = 0; i < 256; ++i) {
table[i] = i;
enc_table[i] = i;
}
for(i = 1; i < 1024; ++i) {
_i = i;
mergesort(table, 256);
merge_sort(enc_table, 256);
}
for(i = 0; i < 256; ++i) {
// gen decrypt table from encrypt table
decrypt_table[encrypt_table[i]] = i;
dec_table[enc_table[i]] = i;
}
enc_ctx.table.encrypt_table = enc_table;
enc_ctx.table.decrypt_table = dec_table;
}
#pragma once
#ifndef _ENCRYPT_H
#define _ENCRYPT_H
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <openssl/md5.h>
#include <openssl/evp.h>
#include <endian.h>
#include "md5.h"
#include "rc4.h"
#define BUF_SIZE 4096
#define TABLE 0
#define RC4 1
unsigned char encrypt_table[256];
unsigned char decrypt_table[256];
union {
struct {
uint8_t *encrypt_table;
uint8_t *decrypt_table;
} table;
struct {
unsigned char *key;
int key_len;
} rc4;
} enc_ctx;
void get_table(const char* key);
void encrypt(char *buf, int len, EVP_CIPHER_CTX *ctx);
void decrypt(char *buf, int len, EVP_CIPHER_CTX *ctx);
void enc_ctx_init(EVP_CIPHER_CTX *ctx, const char *pass, int enc);
void encrypt(char *buf, int len, struct rc4_state *ctx);
void decrypt(char *buf, int len, struct rc4_state *ctx);
void enc_ctx_init(struct rc4_state *ctx, int enc);
void enc_key_init(const char *pass);
unsigned int _i;
unsigned long long _a;
int _method;
#endif // _ENCRYPT_H
......@@ -462,6 +462,7 @@ void free_remote(struct remote *remote) {
free(remote);
}
}
void close_and_free_remote(EV_P_ struct remote *remote) {
if (remote != NULL) {
ev_timer_stop(EV_A_ &remote->send_ctx->watcher);
......@@ -471,6 +472,7 @@ void close_and_free_remote(EV_P_ struct remote *remote) {
free_remote(remote);
}
}
struct server* new_server(int fd) {
struct server *server;
server = malloc(sizeof(struct server));
......@@ -485,10 +487,10 @@ struct server* new_server(int fd) {
server->send_ctx->connected = 0;
server->stage = 0;
if (_method == RC4) {
server->e_ctx = malloc(sizeof(EVP_CIPHER_CTX));
server->d_ctx = malloc(sizeof(EVP_CIPHER_CTX));
enc_ctx_init(server->e_ctx, _key, 1);
enc_ctx_init(server->d_ctx, _key, 0);
server->e_ctx = malloc(sizeof(struct rc4_state));
server->d_ctx = malloc(sizeof(struct rc4_state));
enc_ctx_init(server->e_ctx, 1);
enc_ctx_init(server->d_ctx, 0);
} else {
server->e_ctx = NULL;
server->d_ctx = NULL;
......@@ -496,14 +498,13 @@ struct server* new_server(int fd) {
server->buf_len = 0;
return server;
}
void free_server(struct server *server) {
if (server != NULL) {
if (server->remote != NULL) {
server->remote->server = NULL;
}
if (_method == RC4) {
EVP_CIPHER_CTX_cleanup(server->e_ctx);
EVP_CIPHER_CTX_cleanup(server->d_ctx);
free(server->e_ctx);
free(server->d_ctx);
}
......@@ -512,6 +513,7 @@ void free_server(struct server *server) {
free(server);
}
}
void close_and_free_server(EV_P_ struct server *server) {
if (server != NULL) {
ev_io_stop(EV_A_ &server->send_ctx->io);
......@@ -520,6 +522,7 @@ void close_and_free_server(EV_P_ struct server *server) {
free_server(server);
}
}
static void accept_cb (EV_P_ ev_io *w, int revents)
{
struct listen_ctx *listener = (struct listen_ctx *)w;
......@@ -685,7 +688,9 @@ int main (int argc, char **argv)
}
LOGD("calculating ciphers %d", _method);
if (_method != RC4) {
if (_method == RC4) {
enc_key_init(key);
} else {
get_table(key);
}
......
#pragma once
#ifndef _LOCAL_H
#define _LOCAL_H
#include <ev.h>
......@@ -21,8 +22,8 @@ struct server {
char buf[BUF_SIZE]; // server send from, remote recv into
char stage;
int buf_len;
EVP_CIPHER_CTX *e_ctx;
EVP_CIPHER_CTX *d_ctx;
struct rc4_state *e_ctx;
struct rc4_state *d_ctx;
struct server_ctx *recv_ctx;
struct server_ctx *send_ctx;
struct remote *remote;
......@@ -57,3 +58,4 @@ struct server* new_server(int fd);
void free_server(struct server *server);
void close_and_free_server(EV_P_ struct server *server);
#endif // _LOCAL_H
This diff is collapsed.
/*
Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/*$Id: md5.h,v 1.1.1.1 2001/10/18 22:50:24 jlovell Exp $ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321.
It is derived directly from the text of the RFC and not from the
reference implementation.
The original and principal author of md5.h is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version.
*/
#ifndef md5_INCLUDED
# define md5_INCLUDED
/*
* This code has some adaptations for the Ghostscript environment, but it
* will compile and run correctly in any environment with 8-bit chars and
* 32-bit ints. Specifically, it assumes that if the following are
* defined, they have the same meaning as in Ghostscript: P1, P2, P3,
* ARCH_IS_BIG_ENDIAN.
*/
typedef unsigned char md5_byte_t; /* 8-bit byte */
typedef unsigned int md5_word_t; /* 32-bit word */
/* Define the state of the MD5 Algorithm. */
typedef struct md5_state_s {
md5_word_t count[2]; /* message length in bits, lsw first */
md5_word_t abcd[4]; /* digest buffer */
md5_byte_t buf[64]; /* accumulate block */
} md5_state_t;
#ifdef __cplusplus
extern "C"
{
#endif
/* Initialize the algorithm. */
#ifdef P1
void md5_init(P1(md5_state_t *pms));
#else
void md5_init(md5_state_t *pms);
#endif
/* Append a string to the message. */
#ifdef P3
void md5_append(P3(md5_state_t *pms, const md5_byte_t *data, int nbytes));
#else
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
#endif
/* Finish the message and return the digest. */
#ifdef P2
void md5_finish(P2(md5_state_t *pms, md5_byte_t digest[16]));
#else
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
#endif
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* md5_INCLUDED */
/*
* rc4.c
*
* Copyright (c) 1996-2000 Whistle Communications, Inc.
* All rights reserved.
*
* Subject to the following obligations and disclaimer of warranty, use and
* redistribution of this software, in source or object code forms, with or
* without modifications are expressly permitted by Whistle Communications;
* provided, however, that:
* 1. Any and all reproductions of the source or object code must include the
* copyright notice above and the following disclaimer of warranties; and
* 2. No rights are granted, in any manner or form, to use Whistle
* Communications, Inc. trademarks, including the mark "WHISTLE
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
* such appears in the above copyright notice or in the software.
*
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/crypto/rc4/rc4.c,v 1.2.2.1 2000/04/18 04:48:31 archie Exp $
*/
#include <stdint.h>
#include "rc4.h"
static inline void
swap_bytes(u_char *a, u_char *b)
{
u_char temp;
temp = *a;
*a = *b;
*b = temp;
}
/*
* Initialize an RC4 state buffer using the supplied key,
* which can have arbitrary length.
*/
void
rc4_init(struct rc4_state *const state, const u_char *key, int keylen)
{
u_char j;
int i;
/* Initialize state with identity permutation */
for (i = 0; i < 256; i++)
state->perm[i] = (u_char)i;
state->index1 = 0;
state->index2 = 0;
/* Randomize the permutation using key data */
for (j = i = 0; i < 256; i++) {
j += state->perm[i] + key[i % keylen];
swap_bytes(&state->perm[i], &state->perm[j]);
}
}
/*
* Encrypt some data using the supplied RC4 state buffer.
* The input and output buffers may be the same buffer.
* Since RC4 is a stream cypher, this function is used
* for both encryption and decryption.
*/
void
rc4_crypt(struct rc4_state *const state,
const u_char *inbuf, u_char *outbuf, int buflen)
{
int i;
u_char j;
for (i = 0; i < buflen; i++) {
/* Update modification indicies */
state->index1++;
state->index2 += state->perm[state->index1];
/* Modify permutation */
swap_bytes(&state->perm[state->index1],
&state->perm[state->index2]);
/* Encrypt/decrypt next byte */
j = state->perm[state->index1] + state->perm[state->index2];
outbuf[i] = inbuf[i] ^ state->perm[j];
}
}
/*
* rc4.h
*
* Copyright (c) 1996-2000 Whistle Communications, Inc.
* All rights reserved.
*
* Subject to the following obligations and disclaimer of warranty, use and
* redistribution of this software, in source or object code forms, with or
* without modifications are expressly permitted by Whistle Communications;
* provided, however, that:
* 1. Any and all reproductions of the source or object code must include the
* copyright notice above and the following disclaimer of warranties; and
* 2. No rights are granted, in any manner or form, to use Whistle
* Communications, Inc. trademarks, including the mark "WHISTLE
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
* such appears in the above copyright notice or in the software.
*
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/crypto/rc4/rc4.h,v 1.2.2.1 2000/04/18 04:48:32 archie Exp $
*/
#ifndef RC4_H_
#define RC4_H_
typedef uint8_t u_char;
struct rc4_state {
u_char perm[256];
u_char index1;
u_char index2;
};
void rc4_init(struct rc4_state *state, const u_char *key, int keylen);
void rc4_crypt(struct rc4_state *state,
const u_char *inbuf, u_char *outbuf, int buflen);
#endif
......@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.shadowsocks</groupId>
<artifactId>shadowsocks</artifactId>
<version>1.3.2</version>
<version>1.3.3</version>
<packaging>apk</packaging>
<name>Shadowsocks</name>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment