From 032c609c4d328e990491dcc76ed39eb847880618 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Thu, 24 Sep 2015 17:46:46 +0800 Subject: [PATCH] truncate HMAC-SHA1 to 10 bytes --- src/encrypt.c | 15 +++++++++------ src/encrypt.h | 2 +- src/server.c | 6 ++++-- src/udprelay.c | 3 ++- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/encrypt.c b/src/encrypt.c index 6bb030ca..d214cafa 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -1032,22 +1032,25 @@ static int cipher_context_update(cipher_ctx_t *ctx, uint8_t *output, size_t *ole int ss_onetimeauth(char *auth, char *msg, int msg_len, uint8_t *iv) { + uint8_t hash[ONETIMEAUTH_BYTES * 2]; uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH]; memcpy(auth_key, iv, enc_iv_len); memcpy(auth_key + enc_iv_len, enc_key, enc_key_len); #if defined(USE_CRYPTO_OPENSSL) - HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)auth, NULL); + HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash, NULL); #else - ss_sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)auth); + ss_sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); #endif + memcpy(auth, hash, ONETIMEAUTH_BYTES); + return 0; } int ss_onetimeauth_verify(char *auth, char *msg, int msg_len, uint8_t *iv) { - uint8_t hash[ONETIMEAUTH_BYTES]; + uint8_t hash[ONETIMEAUTH_BYTES * 2]; uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH]; memcpy(auth_key, iv, enc_iv_len); memcpy(auth_key + enc_iv_len, enc_key, enc_key_len); @@ -1087,7 +1090,7 @@ char * ss_encrypt_all(int buf_size, char *plaintext, ssize_t *len, int method, i memcpy(ciphertext, iv, iv_len); if (auth) { - char hash[ONETIMEAUTH_BYTES]; + char hash[ONETIMEAUTH_BYTES * 2]; ss_onetimeauth(hash, plaintext, p_len, iv); if (buf_size < ONETIMEAUTH_BYTES + p_len) { plaintext = realloc(plaintext, ONETIMEAUTH_BYTES + p_len); @@ -1538,7 +1541,7 @@ int ss_check_hash(char **buf_ptr, ssize_t *buf_len, struct chunk *chunk, struct if (cidx == chunk->len + AUTH_BYTES) { // Compare hash - uint8_t hash[ONETIMEAUTH_BYTES]; + uint8_t hash[ONETIMEAUTH_BYTES * 2]; uint8_t key[MAX_IV_LENGTH + sizeof(uint32_t)]; uint32_t c = htonl(chunk->counter); @@ -1585,7 +1588,7 @@ char *ss_gen_hash(char *buf, ssize_t *buf_len, uint32_t *counter, struct enc_ctx } uint16_t chunk_len = htons((uint16_t)blen); - uint8_t hash[ONETIMEAUTH_BYTES]; + uint8_t hash[ONETIMEAUTH_BYTES * 2]; uint8_t key[MAX_IV_LENGTH + sizeof(uint32_t)]; uint32_t c = htonl(*counter); diff --git a/src/encrypt.h b/src/encrypt.h index b3f7ed30..a5251bb4 100644 --- a/src/encrypt.h +++ b/src/encrypt.h @@ -144,7 +144,7 @@ typedef struct { #define ONETIMEAUTH_FLAG 0x10 #define ADDRTYPE_MASK 0xF -#define ONETIMEAUTH_BYTES 20U +#define ONETIMEAUTH_BYTES 10U #define CLEN_BYTES 2U #define AUTH_BYTES (ONETIMEAUTH_BYTES + CLEN_BYTES) diff --git a/src/server.c b/src/server.c index deffe731..4f6a2ad1 100644 --- a/src/server.c +++ b/src/server.c @@ -531,12 +531,13 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) * +------+----------+----------+----------------+ * | ATYP | DST.ADDR | DST.PORT | HMAC-SHA1 | * +------+----------+----------+----------------+ - * | 1 | Variable | 2 | 20 | + * | 1 | Variable | 2 | 10 | * +------+----------+----------+----------------+ * * If ATYP & ONETIMEAUTH_FLAG(0x10) == 1, Authentication (HMAC-SHA1) is enabled. * * The key of HMAC-SHA1 is (IV + KEY) and the input is the whole header. + * The output of HMAC-SHA is truncated to 10 bytes (leftmost bits). */ /* @@ -545,10 +546,11 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) * +------+-----------+-------------+------+ * | LEN | HMAC-SHA1 | DATA | ... * +------+-----------+-------------+------+ - * | 2 | 20 | Variable | ... + * | 2 | 10 | Variable | ... * +------+-----------+-------------+------+ * * The key of HMAC-SHA1 is (IV + CHUNK ID) + * The output of HMAC-SHA is truncated to 10 bytes (leftmost bits). */ int offset = 0; diff --git a/src/udprelay.c b/src/udprelay.c index 53fd7739..c4b032b3 100644 --- a/src/udprelay.c +++ b/src/udprelay.c @@ -872,12 +872,13 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) * +------+----------+----------+----------+-------------+ * | ATYP | DST.ADDR | DST.PORT | DATA | HMAC-SHA1 | * +------+----------+----------+----------+-------------+ - * | 1 | Variable | 2 | Variable | 20 | + * | 1 | Variable | 2 | Variable | 10 | * +------+----------+----------+----------+-------------+ * * If ATYP & ONETIMEAUTH_FLAG(0x10) == 1, Authentication (HMAC-SHA1) is enabled. * * The key of HMAC-SHA1 is (IV + KEY) and the input is the whole packet. + * The output of HMAC-SHA is truncated to 10 bytes (leftmost bits). * * shadowsocks UDP Response (before encrypted) * +------+----------+----------+----------+