Compare commits
10 commits
5fc0e739d0
...
8e132d8293
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e132d8293 | ||
|
|
b709c5de83 | ||
|
|
0cb753882d | ||
|
|
c6655312f7 | ||
|
|
f8c84554b5 | ||
|
|
e644f35cce | ||
|
|
ce06064fcf | ||
|
|
8a1f63b557 | ||
|
|
5fff2a6a16 | ||
|
|
d799a4a7b0 |
10 changed files with 406 additions and 2 deletions
|
|
@ -10,6 +10,9 @@
|
||||||
pname = "softether-5";
|
pname = "softether-5";
|
||||||
version = "5.02.5187";
|
version = "5.02.5187";
|
||||||
in {
|
in {
|
||||||
packages.${system}.default = pkgs.callPackage ./package.nix { inherit pname version; };
|
packages.${system} = {
|
||||||
|
default = pkgs.callPackage ./package.nix { inherit pname version; };
|
||||||
|
sha0 = pkgs.callPackage ./sha0 {};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
lib,
|
lib,
|
||||||
stdenv,
|
stdenv,
|
||||||
fetchFromGitHub,
|
fetchFromGitHub,
|
||||||
|
debug ? false,
|
||||||
pname ? "softether",
|
pname ? "softether",
|
||||||
logDir ? "/var/log/${pname}",
|
logDir ? "/var/log/${pname}",
|
||||||
pidDir ? "/run/${pname}",
|
pidDir ? "/run/${pname}",
|
||||||
|
|
@ -22,6 +23,8 @@ stdenv.mkDerivation (finalAttrs: {
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
patches = [ ./patches/ipb-profile-key.patch ./patches/tap-name-no-prefix.patch ./patches/prevent-dmesg-call.patch ./patches/simplify_l2tp_auth.patch ];
|
||||||
|
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
cmake
|
cmake
|
||||||
pkg-config
|
pkg-config
|
||||||
|
|
@ -39,7 +42,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||||
|
|
||||||
cmakeFlags = [
|
cmakeFlags = [
|
||||||
"-DSE_PIDDIR=${pidDir}" "-DSE_LOGDIR=${logDir}" "-DSE_DBDIR=${dbDir}" "-DCMAKE_INSTALL_SYSTEMD_UNITDIR="
|
"-DSE_PIDDIR=${pidDir}" "-DSE_LOGDIR=${logDir}" "-DSE_DBDIR=${dbDir}" "-DCMAKE_INSTALL_SYSTEMD_UNITDIR="
|
||||||
"-DCMAKE_BUILD_TYPE=Debug"
|
(lib.optionalString debug "-DCMAKE_BUILD_TYPE=Debug")
|
||||||
"-DCMAKE_INSTALL_PREFIX=${placeholder "out"}"
|
"-DCMAKE_INSTALL_PREFIX=${placeholder "out"}"
|
||||||
"-DCMAKE_INSTALL_LIBDIR=lib"
|
"-DCMAKE_INSTALL_LIBDIR=lib"
|
||||||
"-DCMAKE_INSTALL_INCLUDEDIR=include"
|
"-DCMAKE_INSTALL_INCLUDEDIR=include"
|
||||||
|
|
|
||||||
112
patches/ipb-profile-key.patch
Normal file
112
patches/ipb-profile-key.patch
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
diff --git a/src/Cedar/Proto_OpenVPN.c b/src/Cedar/Proto_OpenVPN.c
|
||||||
|
index 9143d46..9e2d9d8 100644
|
||||||
|
--- a/src/Cedar/Proto_OpenVPN.c
|
||||||
|
+++ b/src/Cedar/Proto_OpenVPN.c
|
||||||
|
@@ -823,7 +823,8 @@ void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN
|
||||||
|
s->Dh = DhNewFromBits(s->Cedar->DhParamBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
- c->SslPipe = NewSslPipeEx(true, s->Cedar->ServerX, s->Cedar->ServerK, s->Dh, true, &c->ClientCert);
|
||||||
|
+ // disable automatic cert auth, use profileKey based auth instead
|
||||||
|
+ c->SslPipe = NewSslPipeEx(true, s->Cedar->ServerX, s->Cedar->ServerK, s->Dh, false, NULL);
|
||||||
|
if (c->SslPipe == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
@@ -1477,6 +1478,36 @@ void OvsWriteStringToBuf(BUF *b, char *str, UINT max_size)
|
||||||
|
Free(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
+// Extract the value of profile-key as UV_TOKEN from the openvpn peer info
|
||||||
|
+char *ExtractProfileKeyAsUvTokenFromPeerInfo(char *peerInfo)
|
||||||
|
+{
|
||||||
|
+ if (peerInfo == NULL) return NULL;
|
||||||
|
+
|
||||||
|
+ TOKEN_LIST *tokens = ParseTokenWithoutNullStr(peerInfo, "\r\n");
|
||||||
|
+ if (tokens == NULL) return NULL;
|
||||||
|
+
|
||||||
|
+ char *result = NULL;
|
||||||
|
+
|
||||||
|
+ for (UINT i = 0; i < tokens->NumTokens; i++)
|
||||||
|
+ {
|
||||||
|
+ char *line = tokens->Token[i];
|
||||||
|
+ Trim(line);
|
||||||
|
+ char key[1536], value[1536]; // same length allocated to peerInfo
|
||||||
|
+
|
||||||
|
+ if (GetKeyAndValue(line, key, sizeof(key), value, sizeof(value), "="))
|
||||||
|
+ {
|
||||||
|
+ if (StrCmpi(key, "UV_TOKEN") == 0)
|
||||||
|
+ {
|
||||||
|
+ result = CopyStr(value);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ FreeToken(tokens);
|
||||||
|
+ return result;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
// Parse the KEY_METHOD2
|
||||||
|
UINT OvsParseKeyMethod2(OPENVPN_KEY_METHOD_2 *ret, UCHAR *data, UINT size, bool client_mode)
|
||||||
|
{
|
||||||
|
@@ -1527,6 +1558,16 @@ UINT OvsParseKeyMethod2(OPENVPN_KEY_METHOD_2 *ret, UCHAR *data, UINT size, bool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if(IsEmptyStr(ret->Username))
|
||||||
|
+ {
|
||||||
|
+ // keep it the same as softether protocol, which also sends entire profilekey as username and a password with any unimportant value
|
||||||
|
+ char *ProfileKey = ExtractProfileKeyAsUvTokenFromPeerInfo(ret->PeerInfo);
|
||||||
|
+ StrCpy(ret->Username, sizeof(ret->Username), ProfileKey);
|
||||||
|
+ ret->Password[0] = '\0'; // empty string
|
||||||
|
+
|
||||||
|
+ Free(ProfileKey);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
FreeBuf(b);
|
||||||
|
|
||||||
|
return read_size;
|
||||||
|
diff --git a/src/Cedar/Proto_OpenVPN.h b/src/Cedar/Proto_OpenVPN.h
|
||||||
|
index 0ca10f0..a0ad37b 100644
|
||||||
|
--- a/src/Cedar/Proto_OpenVPN.h
|
||||||
|
+++ b/src/Cedar/Proto_OpenVPN.h
|
||||||
|
@@ -255,6 +255,7 @@ void OvsSendControlPacketEx(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT
|
||||||
|
void OvsSendControlPacketWithAutoSplit(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size);
|
||||||
|
void OvsFreeControlPacket(OPENVPN_CONTROL_PACKET *p);
|
||||||
|
void OvsDeleteFromSendingControlPacketList(OPENVPN_CHANNEL *c, UINT num_acks, UINT *acks);
|
||||||
|
+char *ExtractProfileKeyAsUvTokenFromPeerInfo(char *str);
|
||||||
|
UINT OvsParseKeyMethod2(OPENVPN_KEY_METHOD_2 *ret, UCHAR *data, UINT size, bool client_mode);
|
||||||
|
bool OvsReadStringFromBuf(BUF *b, char *str, UINT str_size);
|
||||||
|
void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c, OPENVPN_KEY_METHOD_2 *data);
|
||||||
|
diff --git a/src/Cedar/Protocol.c b/src/Cedar/Protocol.c
|
||||||
|
index a0da6c7..d0c9838 100644
|
||||||
|
--- a/src/Cedar/Protocol.c
|
||||||
|
+++ b/src/Cedar/Protocol.c
|
||||||
|
@@ -2861,7 +2861,13 @@ bool ServerAccept(CONNECTION *c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a Session
|
||||||
|
- StrLower(username);
|
||||||
|
+ if (admin_mode == false && StrLen(username) == 6)
|
||||||
|
+ {
|
||||||
|
+ //concat password to username so it's the combined profileKey
|
||||||
|
+ //this is for recognizing L2TP clients
|
||||||
|
+ StrCat(username, sizeof(username), plain_password);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
s = NewServerSessionEx(c->Cedar, c, hub, username, policy, c->IsInProc,
|
||||||
|
(c->IsInProc && IsZero(assigned_ipc_mac_address, 6) == false) ? assigned_ipc_mac_address : NULL);
|
||||||
|
|
||||||
|
diff --git a/src/Cedar/Session.c b/src/Cedar/Session.c
|
||||||
|
index e0bb58a..09e77b3 100644
|
||||||
|
--- a/src/Cedar/Session.c
|
||||||
|
+++ b/src/Cedar/Session.c
|
||||||
|
@@ -2186,7 +2186,7 @@ SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username,
|
||||||
|
StrCpy(hub_name_upper, sizeof(hub_name_upper), h->Name);
|
||||||
|
StrUpper(hub_name_upper);
|
||||||
|
StrCpy(user_name_upper, sizeof(user_name_upper), username);
|
||||||
|
- StrUpper(user_name_upper);
|
||||||
|
+ // do not uppercase the profileKey
|
||||||
|
|
||||||
|
if ((StrCmpi(username, ADMINISTRATOR_USERNAME) != 0) && (StrCmpi(username, BRIDGE_USER_NAME) != 0) || (cedar->Server == NULL || cedar->Server->ServerType == SERVER_TYPE_STANDALONE))
|
||||||
|
{
|
||||||
12
patches/prevent-dmesg-call.patch
Normal file
12
patches/prevent-dmesg-call.patch
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
diff --git a/src/Mayaqua/Unix.c b/src/Mayaqua/Unix.c
|
||||||
|
index 0c3778d..657dea4 100644
|
||||||
|
--- a/src/Mayaqua/Unix.c
|
||||||
|
+++ b/src/Mayaqua/Unix.c
|
||||||
|
@@ -345,6 +345,7 @@ bool UnixIsInVmMain()
|
||||||
|
|
||||||
|
bool UnixIsInVm()
|
||||||
|
{
|
||||||
|
+ return false;
|
||||||
|
static bool is_in_vm_flag = false;
|
||||||
|
static bool is_in_vm_ret = false;
|
||||||
|
|
||||||
60
patches/simplify_l2tp_auth.patch
Normal file
60
patches/simplify_l2tp_auth.patch
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
diff --git a/src/Cedar/Proto_PPP.c b/src/Cedar/Proto_PPP.c
|
||||||
|
index e9908e0..120a65b 100644
|
||||||
|
--- a/src/Cedar/Proto_PPP.c
|
||||||
|
+++ b/src/Cedar/Proto_PPP.c
|
||||||
|
@@ -320,12 +320,12 @@ void PPPThread(THREAD *thread, void *param)
|
||||||
|
|
||||||
|
if (p->PPPStatus == PPP_STATUS_CONNECTED && authReqSent == false)
|
||||||
|
{
|
||||||
|
- // EAP code
|
||||||
|
+ // PAP code
|
||||||
|
PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
|
||||||
|
- USHORT eap_code = Endian16(PPP_LCP_AUTH_EAP);
|
||||||
|
+ USHORT pap_code = Endian16(PPP_LCP_AUTH_PAP);
|
||||||
|
|
||||||
|
- Debug("Request EAP\n");
|
||||||
|
- Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &eap_code, sizeof(eap_code)));
|
||||||
|
+ Debug("Request PAP\n");
|
||||||
|
+ Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &pap_code, sizeof(pap_code)));
|
||||||
|
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, c) == false)
|
||||||
|
{
|
||||||
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
|
@@ -1871,12 +1871,6 @@ bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
||||||
|
|
||||||
|
p->AuthOk = true;
|
||||||
|
}
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
|
- WHERE;
|
||||||
|
- return false;
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/src/Cedar/Proto_PPP.h b/src/Cedar/Proto_PPP.h
|
||||||
|
index 1278fbc..20500cc 100644
|
||||||
|
--- a/src/Cedar/Proto_PPP.h
|
||||||
|
+++ b/src/Cedar/Proto_PPP.h
|
||||||
|
@@ -32,18 +32,18 @@
|
||||||
|
#define PPP_CODE_IS_REQUEST(protocol, c) ((((protocol) == PPP_PROTOCOL_LCP || (protocol) == PPP_PROTOCOL_IPCP || (protocol) == PPP_PROTOCOL_IPV6CP) && PPP_LCP_CODE_IS_REQUEST(c)) || (((protocol) == PPP_PROTOCOL_PAP) && PPP_PAP_CODE_IS_REQUEST(c)) || (((protocol) == PPP_PROTOCOL_CHAP) && PPP_CHAP_CODE_IS_REQUEST(c)) || (((protocol) == PPP_PROTOCOL_EAP) && PPP_EAP_CODE_IS_REQUEST(c)))
|
||||||
|
#define PPP_CODE_IS_WITH_OPTION_LIST(protocol, c) ((((protocol) == PPP_PROTOCOL_LCP || (protocol) == PPP_PROTOCOL_IPCP || (protocol) == PPP_PROTOCOL_IPV6CP) && PPP_LCP_CODE_IS_WITH_OPTION_LIST(c)) || false)
|
||||||
|
|
||||||
|
-#define PPP_IS_SUPPORTED_PROTOCOL(p) ((p) == PPP_PROTOCOL_LCP || (p) == PPP_PROTOCOL_PAP || (p) == PPP_PROTOCOL_CHAP || (p) == PPP_PROTOCOL_IPCP || (p) == PPP_PROTOCOL_IPV6CP || (p) == PPP_PROTOCOL_IP || (p) == PPP_PROTOCOL_IPV6 || (p) == PPP_PROTOCOL_EAP )
|
||||||
|
+#define PPP_IS_SUPPORTED_PROTOCOL(p) ((p) == PPP_PROTOCOL_LCP || (p) == PPP_PROTOCOL_PAP || (p) == PPP_PROTOCOL_IPCP || (p) == PPP_PROTOCOL_IP)
|
||||||
|
|
||||||
|
#define PPP_STATUS_IS_UNAVAILABLE(c) ((c) == PPP_STATUS_FAIL || (c) == PPP_STATUS_AUTH_FAIL || (c) == PPP_STATUS_CLOSING || (c) == PPP_STATUS_CLOSING_WAIT || (c) == PPP_STATUS_CLOSED)
|
||||||
|
|
||||||
|
//// Constants
|
||||||
|
|
||||||
|
// Time-out value
|
||||||
|
-#define PPP_PACKET_RECV_TIMEOUT (15 * 1000) // Timeout until the next packet is received (3/4 of default policy)
|
||||||
|
+#define PPP_PACKET_RECV_TIMEOUT (90 * 1000) // Timeout until the next packet is received (3/4 of default policy)
|
||||||
|
#define PPP_PACKET_RESEND_INTERVAL (3 * 1000) // Retransmission interval of the last packet
|
||||||
|
#define PPP_TERMINATE_TIMEOUT 2000 // Timeout value to complete disconnection after requesting to disconnect in the PPP
|
||||||
|
#define PPP_ECHO_SEND_INTERVAL 4792 // Transmission interval of PPP Echo Request
|
||||||
|
-#define PPP_DATA_TIMEOUT (20 * 1000) // Communication time-out (from default policy)
|
||||||
|
+#define PPP_DATA_TIMEOUT (120 * 1000) // Communication time-out (from default policy)
|
||||||
|
|
||||||
|
// MRU
|
||||||
|
#define PPP_MRU_DEFAULT 1500 // Default value
|
||||||
13
patches/tap-name-no-prefix.patch
Normal file
13
patches/tap-name-no-prefix.patch
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
diff --git a/src/Cedar/VLanUnix.c b/src/Cedar/VLanUnix.c
|
||||||
|
index 784bd74..127d15e 100644
|
||||||
|
--- a/src/Cedar/VLanUnix.c
|
||||||
|
+++ b/src/Cedar/VLanUnix.c
|
||||||
|
@@ -339,7 +339,7 @@ void GenerateTunName(char *name, char *prefix, char *tun_name, size_t tun_name_l
|
||||||
|
StrCpy(instance_name_lower, sizeof(instance_name_lower), name);
|
||||||
|
Trim(instance_name_lower);
|
||||||
|
StrLower(instance_name_lower);
|
||||||
|
- Format(tun_name, tun_name_len, "%s_%s", prefix, instance_name_lower);
|
||||||
|
+ Format(tun_name, tun_name_len, "%s", instance_name_lower);
|
||||||
|
|
||||||
|
tun_name[15] = 0;
|
||||||
|
}
|
||||||
20
sha0/default.nix
Normal file
20
sha0/default.nix
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{ pkgs, stdenv, ... }:
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
pname = "sha0";
|
||||||
|
version = "0.1.0";
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
cc -O2 -o sha0 sha0.c main.c
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp sha0 $out/bin/
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with pkgs.lib; {
|
||||||
|
description = "SHA-0 hashing CLI tool";
|
||||||
|
};
|
||||||
|
}
|
||||||
25
sha0/main.c
Normal file
25
sha0/main.c
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
// Declare the function from sha0.c
|
||||||
|
const UCHAR* MY_SHA0_hash(const void* data, int len, UCHAR* digest);
|
||||||
|
|
||||||
|
#define SHA0_DIGEST_SIZE 20
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "Usage: %s <string>\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
UCHAR digest[SHA0_DIGEST_SIZE];
|
||||||
|
MY_SHA0_hash((const UCHAR *)argv[1], strlen(argv[1]), digest);
|
||||||
|
|
||||||
|
for (int i = 0; i < SHA0_DIGEST_SIZE; i++) {
|
||||||
|
printf("%02x", digest[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
148
sha0/sha0.c
Normal file
148
sha0/sha0.c
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
// Copied from softether's src/Cedar/Encrypt.c
|
||||||
|
|
||||||
|
// define custom types as defined in SoftEther's code
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
// rest is copied as is
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
|
// SHA0 implementation //
|
||||||
|
/////////////////////////
|
||||||
|
|
||||||
|
// Source codes from:
|
||||||
|
// https://android.googlesource.com/platform/system/core/+/81df1cc77722000f8d0025c1ab00ced123aa573c/libmincrypt/sha.c
|
||||||
|
// https://android.googlesource.com/platform/system/core/+/81df1cc77722000f8d0025c1ab00ced123aa573c/include/mincrypt/hash-internal.h
|
||||||
|
// https://android.googlesource.com/platform/system/core/+/81df1cc77722000f8d0025c1ab00ced123aa573c/include/mincrypt/sha.h
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2013 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of Google Inc. nor the names of its contributors may
|
||||||
|
* be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 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
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
||||||
|
|
||||||
|
typedef struct MY_SHA0_CTX {
|
||||||
|
// const HASH_VTAB * f;
|
||||||
|
UINT64 count;
|
||||||
|
UCHAR buf[64];
|
||||||
|
UINT state[8]; // upto SHA2
|
||||||
|
} MY_SHA0_CTX;
|
||||||
|
|
||||||
|
#define MY_SHA0_DIGEST_SIZE 20
|
||||||
|
|
||||||
|
static void MY_SHA0_Transform(MY_SHA0_CTX* ctx) {
|
||||||
|
UINT W[80];
|
||||||
|
UINT A, B, C, D, E;
|
||||||
|
UCHAR* p = ctx->buf;
|
||||||
|
int t;
|
||||||
|
for(t = 0; t < 16; ++t) {
|
||||||
|
UINT tmp = *p++ << 24;
|
||||||
|
tmp |= *p++ << 16;
|
||||||
|
tmp |= *p++ << 8;
|
||||||
|
tmp |= *p++;
|
||||||
|
W[t] = tmp;
|
||||||
|
}
|
||||||
|
for(; t < 80; t++) {
|
||||||
|
//W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
|
||||||
|
W[t] = (1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
|
||||||
|
}
|
||||||
|
A = ctx->state[0];
|
||||||
|
B = ctx->state[1];
|
||||||
|
C = ctx->state[2];
|
||||||
|
D = ctx->state[3];
|
||||||
|
E = ctx->state[4];
|
||||||
|
for(t = 0; t < 80; t++) {
|
||||||
|
UINT tmp = rol(5,A) + E + W[t];
|
||||||
|
if (t < 20)
|
||||||
|
tmp += (D^(B&(C^D))) + 0x5A827999;
|
||||||
|
else if ( t < 40)
|
||||||
|
tmp += (B^C^D) + 0x6ED9EBA1;
|
||||||
|
else if ( t < 60)
|
||||||
|
tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
|
||||||
|
else
|
||||||
|
tmp += (B^C^D) + 0xCA62C1D6;
|
||||||
|
E = D;
|
||||||
|
D = C;
|
||||||
|
C = rol(30,B);
|
||||||
|
B = A;
|
||||||
|
A = tmp;
|
||||||
|
}
|
||||||
|
ctx->state[0] += A;
|
||||||
|
ctx->state[1] += B;
|
||||||
|
ctx->state[2] += C;
|
||||||
|
ctx->state[3] += D;
|
||||||
|
ctx->state[4] += E;
|
||||||
|
}
|
||||||
|
void MY_SHA0_init(MY_SHA0_CTX* ctx) {
|
||||||
|
//ctx->f = &SHA_VTAB;
|
||||||
|
ctx->state[0] = 0x67452301;
|
||||||
|
ctx->state[1] = 0xEFCDAB89;
|
||||||
|
ctx->state[2] = 0x98BADCFE;
|
||||||
|
ctx->state[3] = 0x10325476;
|
||||||
|
ctx->state[4] = 0xC3D2E1F0;
|
||||||
|
ctx->count = 0;
|
||||||
|
}
|
||||||
|
void MY_SHA0_update(MY_SHA0_CTX* ctx, const void* data, int len) {
|
||||||
|
int i = (int) (ctx->count & 63);
|
||||||
|
const UCHAR* p = (const UCHAR*)data;
|
||||||
|
ctx->count += len;
|
||||||
|
while (len--) {
|
||||||
|
ctx->buf[i++] = *p++;
|
||||||
|
if (i == 64) {
|
||||||
|
MY_SHA0_Transform(ctx);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const UCHAR* MY_SHA0_final(MY_SHA0_CTX* ctx) {
|
||||||
|
UCHAR *p = ctx->buf;
|
||||||
|
UINT64 cnt = ctx->count * 8;
|
||||||
|
int i;
|
||||||
|
MY_SHA0_update(ctx, (UCHAR*)"\x80", 1);
|
||||||
|
while ((ctx->count & 63) != 56) {
|
||||||
|
MY_SHA0_update(ctx, (UCHAR*)"\0", 1);
|
||||||
|
}
|
||||||
|
for (i = 0; i < 8; ++i) {
|
||||||
|
UCHAR tmp = (UCHAR) (cnt >> ((7 - i) * 8));
|
||||||
|
MY_SHA0_update(ctx, &tmp, 1);
|
||||||
|
}
|
||||||
|
for (i = 0; i < 5; i++) {
|
||||||
|
UINT tmp = ctx->state[i];
|
||||||
|
*p++ = tmp >> 24;
|
||||||
|
*p++ = tmp >> 16;
|
||||||
|
*p++ = tmp >> 8;
|
||||||
|
*p++ = tmp >> 0;
|
||||||
|
}
|
||||||
|
return ctx->buf;
|
||||||
|
}
|
||||||
|
/* Convenience function */
|
||||||
|
const UCHAR* MY_SHA0_hash(const void* data, int len, UCHAR* digest) {
|
||||||
|
MY_SHA0_CTX ctx;
|
||||||
|
MY_SHA0_init(&ctx);
|
||||||
|
MY_SHA0_update(&ctx, data, len);
|
||||||
|
memcpy(digest, MY_SHA0_final(&ctx), MY_SHA0_DIGEST_SIZE);
|
||||||
|
return digest;
|
||||||
|
}
|
||||||
8
sha0/types.h
Normal file
8
sha0/types.h
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef TYPES_H
|
||||||
|
#define TYPES_H
|
||||||
|
|
||||||
|
typedef unsigned long long UINT64;
|
||||||
|
typedef unsigned char UCHAR;
|
||||||
|
typedef unsigned int UINT;
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Add table
Add a link
Reference in a new issue