RRID port part 1
last commit of this set is 2925843e
This commit is contained in:
parent
ca51695870
commit
d6eab04a7a
22 changed files with 3586 additions and 4 deletions
|
|
@ -276,6 +276,7 @@ add_subdirectory(sdl)
|
|||
add_subdirectory(objects)
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(acs)
|
||||
add_subdirectory(monocypher)
|
||||
|
||||
# OS macros
|
||||
if (UNIX)
|
||||
|
|
|
|||
123
src/d_clisrv.c
123
src/d_clisrv.c
|
|
@ -47,6 +47,8 @@
|
|||
#include "lonesha256.h"
|
||||
#include "m_perfstats.h"
|
||||
|
||||
#include "monocypher/monocypher.h"
|
||||
|
||||
// SRB2Kart
|
||||
#include "k_kart.h"
|
||||
#include "k_battle.h"
|
||||
|
|
@ -181,9 +183,19 @@ char connectedserverdescription[MAXSERVERDESCRIPTION];
|
|||
/// \todo WORK!
|
||||
boolean acceptnewnode = true;
|
||||
|
||||
uint8_t lastReceivedKey[MAXNETNODES][32];
|
||||
uint8_t lastSentChallenge[MAXNETNODES][32];
|
||||
|
||||
boolean serverisfull = false; //lets us be aware if the server was full after we check files, but before downloading, so we can ask if the user still wants to download or not
|
||||
tic_t firstconnectattempttime = 0;
|
||||
|
||||
uint8_t awaitingChallenge[32];
|
||||
|
||||
#ifdef DEVELOP
|
||||
consvar_t cv_sigfail = CVAR_INIT ("sigfail", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
#endif
|
||||
|
||||
|
||||
// engine
|
||||
|
||||
// Must be a power of two
|
||||
|
|
@ -905,10 +917,40 @@ static boolean CL_SendJoin(void)
|
|||
|
||||
memcpy(&netbuffer->u.clientcfg.availabilities, R_GetSkinAvailabilities(), MAXAVAILABILITY*sizeof(UINT8));
|
||||
|
||||
// Don't leak old signatures from prior sessions.
|
||||
memset(&netbuffer->u.clientcfg.challengeResponse, 0, sizeof(((clientconfig_pak *)0)->challengeResponse));
|
||||
|
||||
uint8_t signature[64];
|
||||
crypto_eddsa_sign(signature, secret_key, awaitingChallenge, 32);
|
||||
|
||||
if (crypto_eddsa_check(signature, public_key, awaitingChallenge, 32) != 0)
|
||||
I_Error("Couldn't verify own key, may be corrupted?");
|
||||
|
||||
#ifdef DEVELOP
|
||||
if (cv_sigfail.value)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "SIGFAIL enabled, scrubbing signature from CL_SendJoin\n");
|
||||
memset(signature, 0, 64);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Testing
|
||||
// memset(signature, 0, sizeof(signature));
|
||||
|
||||
memcpy(&netbuffer->u.clientcfg.challengeResponse, signature, sizeof(signature));
|
||||
|
||||
return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak));
|
||||
}
|
||||
|
||||
static boolean CL_SendKey(void)
|
||||
{
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
netbuffer->packettype = PT_CLIENTKEY;
|
||||
|
||||
memcpy(netbuffer->u.clientkey.key, public_key, sizeof(public_key));
|
||||
return HSendPacket(servernode, false, 0, sizeof (clientkey_pak) );
|
||||
}
|
||||
|
||||
void
|
||||
CopyCaretColors (char *p, const char *s, int n)
|
||||
{
|
||||
|
|
@ -2039,7 +2081,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
{
|
||||
*asksent = 0; //This ensure the first join ask is right away
|
||||
firstconnectattempttime = I_GetTime();
|
||||
cl_mode = CL_ASKJOIN;
|
||||
cl_mode = CL_SENDKEY;
|
||||
}
|
||||
break;
|
||||
case CL_ASKJOIN:
|
||||
|
|
@ -2075,6 +2117,19 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
cl_mode = CL_ASKJOIN;
|
||||
}
|
||||
break;
|
||||
case CL_SENDKEY:
|
||||
if (I_GetTime() >= *asksent && CL_SendKey())
|
||||
{
|
||||
*asksent = I_GetTime() + NEWTICRATE*3;
|
||||
cl_mode = CL_WAITCHALLENGE;
|
||||
}
|
||||
break;
|
||||
case CL_WAITCHALLENGE:
|
||||
if (I_GetTime() >= *asksent)
|
||||
{
|
||||
cl_mode = CL_SENDKEY;
|
||||
}
|
||||
break;
|
||||
case CL_DOWNLOADSAVEGAME:
|
||||
// At this state, the first (and only) needed file is the gamestate
|
||||
if (fileneeded[0].status == FS_FOUND)
|
||||
|
|
@ -2795,7 +2850,7 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
|
|||
startedInFreePlay = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Reset map headers' justPlayed and anger records
|
||||
// when there are no players in a dedicated server.
|
||||
// Otherwise maps get angry at newly-joined players
|
||||
|
|
@ -2934,6 +2989,8 @@ static void Command_Nodes(void)
|
|||
CONS_Printf(" - %s", address);
|
||||
}
|
||||
|
||||
CONS_Printf(" [RRID-%s] ", GetPrettyRRID(players[i].public_key, true));
|
||||
|
||||
if (IsPlayerAdmin(i))
|
||||
CONS_Printf(M_GetText(" (verified admin)"));
|
||||
|
||||
|
|
@ -3381,6 +3438,11 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
HU_AddChatText(va("\x82*%s left the game (Connection timeout)", player_names[pnum]), false);
|
||||
kickreason = KR_TIMEOUT;
|
||||
break;
|
||||
case KICK_MSG_SIGFAIL:
|
||||
HU_AddChatText(va("\x82*%s left the game (Invalid signature)", player_names[pnum]), false);
|
||||
kickreason = KR_TIMEOUT;
|
||||
break;
|
||||
|
||||
case KICK_MSG_PLAYER_QUIT:
|
||||
if (netgame) // not splitscreen/bots
|
||||
HU_AddChatText(va("\x82*%s left the game", player_names[pnum]), false);
|
||||
|
|
@ -3933,11 +3995,20 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
|
||||
D_SendPlayerConfig(splitscreenplayer);
|
||||
addedtogame = true;
|
||||
|
||||
CONS_Printf("It's me, node %d, with ID %s! (This is uninitialized memory because Tyron is a nice person :)!)\n", node, GetPrettyRRID(lastReceivedKey[node], true));
|
||||
memcpy(lastReceivedKey[node], public_key, 32);
|
||||
}
|
||||
|
||||
players[newplayernum].splitscreenindex = splitscreenplayer;
|
||||
players[newplayernum].bot = false;
|
||||
|
||||
// player_t is the only place in the game that a key is null-terminated, for ease of Lua push.
|
||||
memset(players[newplayernum].public_key, 0, 32 + 1);
|
||||
CONS_Printf("Adding player from node %d with ID %s\n", node, GetPrettyRRID(lastReceivedKey[node], true));
|
||||
memcpy(players[newplayernum].public_key, lastReceivedKey[node], 32);
|
||||
CONS_Printf("Node %d now has ID %s\n", node, GetPrettyRRID(players[newplayernum].public_key, true));
|
||||
|
||||
// Previously called at the top of this function, commented as
|
||||
// "caused desyncs in this spot :(". But we can't do this in
|
||||
// G_PlayerReborn, since that only runs for level contexts and
|
||||
|
|
@ -4395,6 +4466,9 @@ static void HandleConnect(SINT8 node)
|
|||
}
|
||||
}
|
||||
|
||||
// Testing
|
||||
// memset(netbuffer->u.clientcfg.challengeResponse, 0, sizeof(netbuffer->u.clientcfg.challengeResponse));
|
||||
|
||||
if (bannednode && bannednode[node].banid != SIZE_MAX)
|
||||
{
|
||||
const char *reason = NULL;
|
||||
|
|
@ -4478,6 +4552,7 @@ static void HandleConnect(SINT8 node)
|
|||
}
|
||||
else
|
||||
{
|
||||
int sigcheck;
|
||||
boolean newnode = false;
|
||||
|
||||
for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++)
|
||||
|
|
@ -4488,6 +4563,24 @@ static void HandleConnect(SINT8 node)
|
|||
SV_SendRefuse(node, "Bad player name");
|
||||
return;
|
||||
}
|
||||
|
||||
if (node == 0) // Server
|
||||
{
|
||||
memcpy(lastReceivedKey[node], public_key, sizeof(lastReceivedKey[node]));
|
||||
CONS_Printf("Adding SERVER. Setting lastReceivedKey on node %d to %s\n", node, GetPrettyRRID(lastReceivedKey[node], true));
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf("Adding client. Doing sigcheck for node %d, ID %s\n", node, GetPrettyRRID(lastReceivedKey[node], true));
|
||||
|
||||
sigcheck = crypto_eddsa_check(netbuffer->u.clientcfg.challengeResponse, lastReceivedKey[node], lastSentChallenge[node], 32);
|
||||
|
||||
if (netgame && sigcheck != 0)
|
||||
{
|
||||
SV_SendRefuse(node, M_GetText("Signature verification failed."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(availabilitiesbuffer, netbuffer->u.clientcfg.availabilities, sizeof(availabilitiesbuffer));
|
||||
|
|
@ -5576,6 +5669,16 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
case PT_SERVERTICS : PT_ServerTics (node, -1); break;
|
||||
case PT_CLIENTCMD : break; // This is not an "unknown packet"
|
||||
case PT_PLAYERINFO : HandlePlayerInfo (node ); break;
|
||||
case PT_CLIENTKEY:
|
||||
if (server)
|
||||
PT_ClientKey(node);
|
||||
break;
|
||||
case PT_SERVERCHALLENGE:
|
||||
if (cl_mode != CL_WAITCHALLENGE)
|
||||
break;
|
||||
memcpy(awaitingChallenge, netbuffer->u.serverchallenge.secret, sizeof(awaitingChallenge));
|
||||
cl_mode = CL_ASKJOIN;
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBFILE(va("unknown packet received (%d) from unknown host\n",netbuffer->packettype));
|
||||
|
|
@ -5605,6 +5708,22 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
I_Error("bad table nodetoplayer: node %d player %d", doomcom->remotenode, netconsole);
|
||||
#endif
|
||||
|
||||
uint8_t allzero[32];
|
||||
memset(allzero, 0, sizeof(allzero));
|
||||
|
||||
if (IsPacketSigned(netbuffer->packettype))
|
||||
{
|
||||
const void* message = &netbuffer->u;
|
||||
if (crypto_eddsa_check(netbuffer->signature, lastReceivedKey[node], message, doomcom->datalength - BASEPACKETSIZE))
|
||||
{
|
||||
//CONS_Alert(CONS_ERROR, "SIGFAIL! Packet type %d from node %d \nkey %s size %d\n",
|
||||
//netbuffer->packettype, node,
|
||||
//GetPrettyRRID(lastReceivedKey[node], true), doomcom->datalength - BASEPACKETSIZE);
|
||||
// SendKick(netconsole, KICK_MSG_CON_FAIL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (netbuffer->packettype)
|
||||
{
|
||||
// SERVER RECEIVE
|
||||
|
|
|
|||
|
|
@ -138,6 +138,9 @@ typedef enum
|
|||
PT_SAY, // "Hey server, please send this chat message to everyone via XD_SAY"
|
||||
PT_REQMAPQUEUE, // Client requesting a roundqueue operation
|
||||
|
||||
PT_CLIENTKEY, // "Here's my public key"
|
||||
PT_SERVERCHALLENGE, // "Prove it"
|
||||
|
||||
NUMPACKETTYPE
|
||||
} packettype_t;
|
||||
|
||||
|
|
@ -291,6 +294,7 @@ struct clientconfig_pak
|
|||
UINT8 mode;
|
||||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME];
|
||||
UINT8 availabilities[MAXAVAILABILITY];
|
||||
uint8_t challengeResponse[64];
|
||||
} ATTRPACK;
|
||||
|
||||
#define SV_SPEEDMASK 0x03 // used to send kartspeed
|
||||
|
|
@ -385,6 +389,16 @@ struct reqmapqueue_pak
|
|||
UINT8 source;
|
||||
} ATTRPACK;
|
||||
|
||||
struct clientkey_pak
|
||||
{
|
||||
char key[32];
|
||||
} ATTRPACK;
|
||||
|
||||
struct serverchallenge_pak
|
||||
{
|
||||
char secret[32];
|
||||
} ATTRPACK;
|
||||
|
||||
struct netinfo_pak
|
||||
{
|
||||
UINT32 pingtable[MAXPLAYERS+1];
|
||||
|
|
@ -410,6 +424,7 @@ struct doomdata_t
|
|||
UINT8 ackreturn; // The return of the ack number
|
||||
|
||||
UINT8 packettype;
|
||||
uint8_t signature[64];
|
||||
UINT8 packetindex;
|
||||
union
|
||||
{
|
||||
|
|
@ -437,6 +452,8 @@ struct doomdata_t
|
|||
netinfo_pak netinfo;
|
||||
say_pak say;
|
||||
reqmapqueue_pak reqmapqueue; // Formerly XD_REQMAPQUEUE
|
||||
clientkey_pak clientkey; // TODO: Tyron, does anyone take any of these sizes even remotely seriously
|
||||
serverchallenge_pak serverchallenge; // Are you even going to update this shit, are you even going to remove this comment
|
||||
} u; // This is needed to pack diff packet types data together
|
||||
} ATTRPACK;
|
||||
|
||||
|
|
@ -478,6 +495,7 @@ extern consvar_t cv_serverinfoscreen;
|
|||
#define KICK_MSG_GRIEF 7
|
||||
#define KICK_MSG_CUSTOM_KICK 8
|
||||
#define KICK_MSG_CUSTOM_BAN 9
|
||||
#define KICK_MSG_SIGFAIL 10
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
@ -528,6 +546,10 @@ extern consvar_t cv_joinnextround;
|
|||
|
||||
extern consvar_t cv_discordinvites;
|
||||
|
||||
#ifdef DEVELOP
|
||||
extern consvar_t cv_sigfail;
|
||||
#endif
|
||||
|
||||
// Used in d_net, the only dependence
|
||||
tic_t ExpandTics(INT32 low, tic_t basetic);
|
||||
void D_ClientServerInit(void);
|
||||
|
|
@ -558,6 +580,8 @@ typedef enum
|
|||
CL_PREPAREHTTPFILES,
|
||||
CL_DOWNLOADHTTPFILES,
|
||||
#endif
|
||||
CL_SENDKEY,
|
||||
CL_WAITCHALLENGE,
|
||||
} cl_mode_t;
|
||||
|
||||
// Create any new ticcmds and broadcast to other players.
|
||||
|
|
@ -677,6 +701,9 @@ void DoSayPacket(SINT8 target, UINT8 flags, UINT8 source, char *message);
|
|||
void DoSayPacketFromCommand(SINT8 target, size_t usedargs, UINT8 flags);
|
||||
void SendServerNotice(SINT8 target, char *message);
|
||||
|
||||
extern uint8_t lastReceivedKey[MAXNETNODES][32];
|
||||
extern uint8_t lastSentChallenge[MAXNETNODES][32];
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -74,6 +74,9 @@
|
|||
#include "m_perfstats.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
#include "monocypher/monocypher.h"
|
||||
#include "stun.h"
|
||||
|
||||
// SRB2Kart
|
||||
#include "k_grandprix.h"
|
||||
#include "k_boss.h"
|
||||
|
|
@ -179,6 +182,10 @@ INT32 eventhead, eventtail;
|
|||
|
||||
boolean dedicated = false;
|
||||
|
||||
// For identity negotiation with netgame servers
|
||||
uint8_t public_key[32];
|
||||
uint8_t secret_key[64];
|
||||
|
||||
boolean loaded_config = false;
|
||||
|
||||
//
|
||||
|
|
@ -1868,6 +1875,37 @@ void D_SRB2Main(void)
|
|||
ACS_Init();
|
||||
CON_SetLoadingProgress(LOADED_ACSINIT);
|
||||
|
||||
// TODO: This file should probably give a fuck about command line params,
|
||||
// or not be stored next to the EXE in a way that allows people to unknowingly send it to others.
|
||||
// I'm thinking ~/.config on nix and %appdata on windows since we don't have profiles. - Nep
|
||||
static char keyfile[16] = "rrid.dat";
|
||||
|
||||
static uint8_t seed[32];
|
||||
csprng(seed, 32);
|
||||
crypto_eddsa_key_pair(secret_key, public_key, seed);
|
||||
|
||||
int sk_size = sizeof(secret_key);
|
||||
int pk_size = sizeof(public_key);
|
||||
int totalsize = sk_size + pk_size;
|
||||
|
||||
if (FIL_ReadFileOK(keyfile))
|
||||
{
|
||||
UINT8 *readbuffer = NULL;
|
||||
UINT16 lengthRead = FIL_ReadFile(keyfile, &readbuffer);
|
||||
if (readbuffer == NULL || lengthRead != totalsize)
|
||||
I_Error("Malformed keyfile");
|
||||
memcpy(secret_key, readbuffer, sk_size);
|
||||
memcpy(public_key, readbuffer + sk_size, pk_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t keybuffer[totalsize];
|
||||
memcpy(keybuffer, secret_key, sk_size);
|
||||
memcpy(keybuffer + sk_size, public_key, pk_size);
|
||||
if (!FIL_WriteFile(keyfile, keybuffer, totalsize))
|
||||
I_Error("Couldn't open keyfile");
|
||||
}
|
||||
|
||||
//------------------------------------------------ COMMAND LINE PARAMS
|
||||
|
||||
// this must be done after loading gamedata,
|
||||
|
|
|
|||
|
|
@ -64,6 +64,9 @@ extern char srb2path[256]; //Alam: SRB2's Home
|
|||
|
||||
const char *D_GetFancyBranchName(void);
|
||||
|
||||
extern uint8_t public_key[32];
|
||||
extern uint8_t secret_key[64];
|
||||
|
||||
// the infinite loop of D_SRB2Loop() called from win_main for windows version
|
||||
void D_SRB2Loop(void) FUNCNORETURN;
|
||||
|
||||
|
|
|
|||
55
src/d_net.c
55
src/d_net.c
|
|
@ -31,6 +31,7 @@
|
|||
#include "d_main.h" // srb2home
|
||||
#include "stun.h"
|
||||
#include "byteptr.h"
|
||||
#include "monocypher/monocypher.h"
|
||||
|
||||
#include "qs22j.h"
|
||||
|
||||
|
|
@ -470,7 +471,12 @@ static void InitAck(void)
|
|||
ackpak[i].acknum = 0;
|
||||
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
{
|
||||
InitNode(&nodes[i]);
|
||||
|
||||
csprng(lastSentChallenge[i], sizeof(lastSentChallenge[i]));
|
||||
csprng(lastReceivedKey[i], sizeof(lastReceivedKey[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes all acks of a given packet type
|
||||
|
|
@ -547,6 +553,9 @@ void Net_CloseConnection(INT32 node)
|
|||
if (server)
|
||||
SV_AbortLuaFileTransfer(node);
|
||||
I_NetFreeNodenum(node);
|
||||
|
||||
csprng(lastSentChallenge[node], sizeof(lastSentChallenge[node]));
|
||||
csprng(lastReceivedKey[node], sizeof(lastReceivedKey[node]));
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -835,6 +844,31 @@ static boolean ShouldDropPacket(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
boolean IsPacketSigned(int packettype)
|
||||
{
|
||||
switch (packettype)
|
||||
{
|
||||
case PT_CLIENTCMD:
|
||||
case PT_CLIENT2CMD:
|
||||
case PT_CLIENT3CMD:
|
||||
case PT_CLIENT4CMD:
|
||||
case PT_CLIENTMIS:
|
||||
case PT_CLIENT2MIS:
|
||||
case PT_CLIENT3MIS:
|
||||
case PT_CLIENT4MIS:
|
||||
case PT_TEXTCMD:
|
||||
case PT_TEXTCMD2:
|
||||
case PT_TEXTCMD3:
|
||||
case PT_TEXTCMD4:
|
||||
case PT_LOGIN:
|
||||
case PT_ASKLUAFILE:
|
||||
case PT_SENDINGLUAFILE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// HSendPacket
|
||||
//
|
||||
|
|
@ -842,6 +876,27 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
|
|||
{
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
doomcom->datalength = (INT16)(packetlength + BASEPACKETSIZE);
|
||||
|
||||
if (IsPacketSigned(netbuffer->packettype))
|
||||
{
|
||||
const void* message = &netbuffer->u;
|
||||
//CONS_Printf("Signing packet type %d of length %d\n", netbuffer->packettype, packetlength);
|
||||
crypto_eddsa_sign(netbuffer->signature, secret_key, message, packetlength);
|
||||
|
||||
#ifdef DEVELOP
|
||||
if (cv_sigfail.value)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "SIGFAIL enabled, scrubbing signature from HSendPacket\n");
|
||||
memset(netbuffer->signature, 0, sizeof(netbuffer->signature));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONS_Printf("NOT signing PT_%d of length %d, it doesn't need to be\n", netbuffer->packettype, packetlength);
|
||||
memset(netbuffer->signature, 0, sizeof(netbuffer->signature));
|
||||
}
|
||||
|
||||
if (node == 0) // Packet is to go back to us
|
||||
{
|
||||
if ((rebound_head+1) % MAXREBOUND == rebound_tail)
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ void Net_AbortPacketType(UINT8 packettype);
|
|||
void Net_SendAcks(INT32 node);
|
||||
void Net_WaitAllAckReceived(UINT32 timeout);
|
||||
|
||||
boolean IsPacketSigned(int packettype);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1347,6 +1347,10 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_netticbuffer);
|
||||
CV_RegisterVar(&cv_mindelay);
|
||||
|
||||
#ifdef DEVELOP
|
||||
CV_RegisterVar(&cv_sigfail);
|
||||
#endif
|
||||
|
||||
// HUD
|
||||
CV_RegisterVar(&cv_itemfinder);
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@
|
|||
#include "m_misc.h"
|
||||
#include "m_menu.h"
|
||||
#include "filesrch.h"
|
||||
#include "stun.h"
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
|
@ -1339,6 +1341,22 @@ void PT_FileReceived(SINT8 node)
|
|||
SV_EndFileSend(doomcom->remotenode);
|
||||
}
|
||||
|
||||
void PT_ClientKey(INT32 node)
|
||||
{
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
clientkey_pak *packet = (void*)&netbuffer->u.clientkey;
|
||||
|
||||
memcpy(lastReceivedKey[node], packet->key, sizeof(lastReceivedKey[node]));
|
||||
|
||||
CONS_Printf("Got keys from node %d, %s\n", node, GetPrettyRRID(lastReceivedKey[node], true));
|
||||
|
||||
netbuffer->packettype = PT_SERVERCHALLENGE;
|
||||
|
||||
csprng(lastSentChallenge[node], sizeof(serverchallenge_pak));
|
||||
memcpy(&netbuffer->u.serverchallenge, lastSentChallenge[node], sizeof(serverchallenge_pak));
|
||||
HSendPacket(node, false, 0, sizeof (serverchallenge_pak));
|
||||
}
|
||||
|
||||
static void SendAckPacket(fileack_pak *packet, UINT8 fileid)
|
||||
{
|
||||
size_t packetsize;
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ boolean CL_CheckDownloadable(void);
|
|||
boolean CL_SendFileRequest(void);
|
||||
void PT_RequestFile(INT32 node);
|
||||
|
||||
void PT_ClientKey(INT32 node);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LFTNS_NONE, // This node is not connected
|
||||
|
|
|
|||
|
|
@ -890,6 +890,8 @@ struct player_t
|
|||
boolean walltransfered;
|
||||
UINT8 walltransferboost;
|
||||
|
||||
uint8_t public_key[32 + 1];
|
||||
|
||||
#ifdef HWRENDER
|
||||
fixed_t fovadd; // adjust FOV for hw rendering
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3174,6 +3174,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
|
||||
SINT8 xtralife;
|
||||
|
||||
uint8_t public_key[32];
|
||||
|
||||
// SRB2kart
|
||||
INT32 itemtype;
|
||||
INT32 itemamount;
|
||||
|
|
@ -3255,6 +3257,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
|
||||
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE|PF_FLIPCAM));
|
||||
|
||||
memcpy(&public_key, &players[player].public_key, sizeof(public_key));
|
||||
|
||||
// SRB2kart
|
||||
if (betweenmaps || leveltime <= starttime || spectator == true)
|
||||
{
|
||||
|
|
@ -3531,6 +3535,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
|
||||
K_BotReborn(p);
|
||||
|
||||
memcpy(&p->public_key, &public_key, sizeof(p->public_key));
|
||||
|
||||
if (follower)
|
||||
P_RemoveMobj(follower);
|
||||
|
||||
|
|
|
|||
|
|
@ -465,7 +465,8 @@ static int lib_lenLocalplayers(lua_State *L)
|
|||
X(recoverydashcharge) \
|
||||
X(recoverydash) \
|
||||
X(tripwireunstuck) \
|
||||
X(bumpunstuck)
|
||||
X(bumpunstuck) \
|
||||
X(public_key)
|
||||
|
||||
enum player_e
|
||||
{
|
||||
|
|
@ -1194,6 +1195,9 @@ static int player_get(lua_State *L)
|
|||
case player_ping:
|
||||
lua_pushinteger(L, playerpingtable[( plr - players )]);
|
||||
break;
|
||||
case player_public_key:
|
||||
lua_pushstring(L, plr->public_key);
|
||||
break;
|
||||
case player_packetloss:
|
||||
lua_pushinteger(L, playerpacketlosstable[plr - players]);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2589,3 +2589,29 @@ int M_RoundUp(double number)
|
|||
|
||||
return (int)number;
|
||||
}
|
||||
|
||||
|
||||
char *GetPrettyRRID(const unsigned char *bin, boolean brief)
|
||||
{
|
||||
char *out;
|
||||
size_t i;
|
||||
size_t len = 32;
|
||||
|
||||
if (brief)
|
||||
len = 8;
|
||||
|
||||
if (bin == NULL || len == 0)
|
||||
return NULL;
|
||||
|
||||
out = (char *)malloc(len*2 + 1);
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
out[i*2] = "0123456789ABCDEF"[bin[i] >> 4];
|
||||
out[i*2+1] = "0123456789ABCDEF"[bin[i] & 0x0F];
|
||||
}
|
||||
|
||||
out[len*2] = '\0';
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,6 +130,8 @@ boolean M_IsStringEmpty(const char *s);
|
|||
|
||||
int M_RoundUp(double number);
|
||||
|
||||
char *GetPrettyRRID(const unsigned char *bin, boolean brief);
|
||||
|
||||
#include "w_wad.h"
|
||||
extern char configfile[MAX_WADPATH];
|
||||
|
||||
|
|
|
|||
4
src/monocypher/CMakeLists.txt
Normal file
4
src/monocypher/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
target_sources(BLANKART PRIVATE
|
||||
monocypher.c
|
||||
monocypher.h
|
||||
)
|
||||
2938
src/monocypher/monocypher.c
Normal file
2938
src/monocypher/monocypher.c
Normal file
File diff suppressed because it is too large
Load diff
321
src/monocypher/monocypher.h
Normal file
321
src/monocypher/monocypher.h
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
// Monocypher version 4.0.0
|
||||
//
|
||||
// This file is dual-licensed. Choose whichever licence you want from
|
||||
// the two licences listed below.
|
||||
//
|
||||
// The first licence is a regular 2-clause BSD licence. The second licence
|
||||
// is the CC-0 from Creative Commons. It is intended to release Monocypher
|
||||
// to the public domain. The BSD licence serves as a fallback option.
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
|
||||
//
|
||||
// ------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2017-2019, Loup Vaillant
|
||||
// All rights reserved.
|
||||
//
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. 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.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "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 THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS 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.
|
||||
//
|
||||
// ------------------------------------------------------------------------
|
||||
//
|
||||
// Written in 2017-2019 by Loup Vaillant
|
||||
//
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
//
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along
|
||||
// with this software. If not, see
|
||||
// <https://creativecommons.org/publicdomain/zero/1.0/>
|
||||
|
||||
#ifndef MONOCYPHER_H
|
||||
#define MONOCYPHER_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef MONOCYPHER_CPP_NAMESPACE
|
||||
namespace MONOCYPHER_CPP_NAMESPACE {
|
||||
#elif defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Constant time comparisons
|
||||
// -------------------------
|
||||
|
||||
// Return 0 if a and b are equal, -1 otherwise
|
||||
int crypto_verify16(const uint8_t a[16], const uint8_t b[16]);
|
||||
int crypto_verify32(const uint8_t a[32], const uint8_t b[32]);
|
||||
int crypto_verify64(const uint8_t a[64], const uint8_t b[64]);
|
||||
|
||||
|
||||
// Erase sensitive data
|
||||
// --------------------
|
||||
void crypto_wipe(void *secret, size_t size);
|
||||
|
||||
|
||||
// Authenticated encryption
|
||||
// ------------------------
|
||||
void crypto_aead_lock(uint8_t *cipher_text,
|
||||
uint8_t mac [16],
|
||||
const uint8_t key [32],
|
||||
const uint8_t nonce[24],
|
||||
const uint8_t *ad, size_t ad_size,
|
||||
const uint8_t *plain_text, size_t text_size);
|
||||
int crypto_aead_unlock(uint8_t *plain_text,
|
||||
const uint8_t mac [16],
|
||||
const uint8_t key [32],
|
||||
const uint8_t nonce[24],
|
||||
const uint8_t *ad, size_t ad_size,
|
||||
const uint8_t *cipher_text, size_t text_size);
|
||||
|
||||
// Authenticated stream
|
||||
// --------------------
|
||||
typedef struct {
|
||||
uint64_t counter;
|
||||
uint8_t key[32];
|
||||
uint8_t nonce[8];
|
||||
} crypto_aead_ctx;
|
||||
|
||||
void crypto_aead_init_x(crypto_aead_ctx *ctx,
|
||||
const uint8_t key[32], const uint8_t nonce[24]);
|
||||
void crypto_aead_init_djb(crypto_aead_ctx *ctx,
|
||||
const uint8_t key[32], const uint8_t nonce[8]);
|
||||
void crypto_aead_init_ietf(crypto_aead_ctx *ctx,
|
||||
const uint8_t key[32], const uint8_t nonce[12]);
|
||||
|
||||
void crypto_aead_write(crypto_aead_ctx *ctx,
|
||||
uint8_t *cipher_text,
|
||||
uint8_t mac[16],
|
||||
const uint8_t *ad , size_t ad_size,
|
||||
const uint8_t *plain_text, size_t text_size);
|
||||
int crypto_aead_read(crypto_aead_ctx *ctx,
|
||||
uint8_t *plain_text,
|
||||
const uint8_t mac[16],
|
||||
const uint8_t *ad , size_t ad_size,
|
||||
const uint8_t *cipher_text, size_t text_size);
|
||||
|
||||
|
||||
// General purpose hash (BLAKE2b)
|
||||
// ------------------------------
|
||||
|
||||
// Direct interface
|
||||
void crypto_blake2b(uint8_t *hash, size_t hash_size,
|
||||
const uint8_t *message, size_t message_size);
|
||||
|
||||
void crypto_blake2b_keyed(uint8_t *hash, size_t hash_size,
|
||||
const uint8_t *key, size_t key_size,
|
||||
const uint8_t *message, size_t message_size);
|
||||
|
||||
// Incremental interface
|
||||
typedef struct {
|
||||
// Do not rely on the size or contents of this type,
|
||||
// for they may change without notice.
|
||||
uint64_t hash[8];
|
||||
uint64_t input_offset[2];
|
||||
uint64_t input[16];
|
||||
size_t input_idx;
|
||||
size_t hash_size;
|
||||
} crypto_blake2b_ctx;
|
||||
|
||||
void crypto_blake2b_init(crypto_blake2b_ctx *ctx, size_t hash_size);
|
||||
void crypto_blake2b_keyed_init(crypto_blake2b_ctx *ctx, size_t hash_size,
|
||||
const uint8_t *key, size_t key_size);
|
||||
void crypto_blake2b_update(crypto_blake2b_ctx *ctx,
|
||||
const uint8_t *message, size_t message_size);
|
||||
void crypto_blake2b_final(crypto_blake2b_ctx *ctx, uint8_t *hash);
|
||||
|
||||
|
||||
// Password key derivation (Argon2)
|
||||
// --------------------------------
|
||||
#define CRYPTO_ARGON2_D 0
|
||||
#define CRYPTO_ARGON2_I 1
|
||||
#define CRYPTO_ARGON2_ID 2
|
||||
|
||||
typedef struct {
|
||||
uint32_t algorithm; // Argon2d, Argon2i, Argon2id
|
||||
uint32_t nb_blocks; // memory hardness, >= 8 * nb_lanes
|
||||
uint32_t nb_passes; // CPU hardness, >= 1 (>= 3 recommended for Argon2i)
|
||||
uint32_t nb_lanes; // parallelism level (single threaded anyway)
|
||||
} crypto_argon2_config;
|
||||
|
||||
typedef struct {
|
||||
const uint8_t *pass;
|
||||
const uint8_t *salt;
|
||||
uint32_t pass_size;
|
||||
uint32_t salt_size; // 16 bytes recommended
|
||||
} crypto_argon2_inputs;
|
||||
|
||||
typedef struct {
|
||||
const uint8_t *key; // may be NULL if no key
|
||||
const uint8_t *ad; // may be NULL if no additional data
|
||||
uint32_t key_size; // 0 if no key (32 bytes recommended otherwise)
|
||||
uint32_t ad_size; // 0 if no additional data
|
||||
} crypto_argon2_extras;
|
||||
|
||||
extern const crypto_argon2_extras crypto_argon2_no_extras;
|
||||
|
||||
void crypto_argon2(uint8_t *hash, uint32_t hash_size, void *work_area,
|
||||
crypto_argon2_config config,
|
||||
crypto_argon2_inputs inputs,
|
||||
crypto_argon2_extras extras);
|
||||
|
||||
|
||||
// Key exchange (X-25519)
|
||||
// ----------------------
|
||||
|
||||
// Shared secrets are not quite random.
|
||||
// Hash them to derive an actual shared key.
|
||||
void crypto_x25519_public_key(uint8_t public_key[32],
|
||||
const uint8_t secret_key[32]);
|
||||
void crypto_x25519(uint8_t raw_shared_secret[32],
|
||||
const uint8_t your_secret_key [32],
|
||||
const uint8_t their_public_key [32]);
|
||||
|
||||
// Conversion to EdDSA
|
||||
void crypto_x25519_to_eddsa(uint8_t eddsa[32], const uint8_t x25519[32]);
|
||||
|
||||
// scalar "division"
|
||||
// Used for OPRF. Be aware that exponential blinding is less secure
|
||||
// than Diffie-Hellman key exchange.
|
||||
void crypto_x25519_inverse(uint8_t blind_salt [32],
|
||||
const uint8_t private_key[32],
|
||||
const uint8_t curve_point[32]);
|
||||
|
||||
// "Dirty" versions of x25519_public_key().
|
||||
// Use with crypto_elligator_rev().
|
||||
// Leaks 3 bits of the private key.
|
||||
void crypto_x25519_dirty_small(uint8_t pk[32], const uint8_t sk[32]);
|
||||
void crypto_x25519_dirty_fast (uint8_t pk[32], const uint8_t sk[32]);
|
||||
|
||||
|
||||
// Signatures
|
||||
// ----------
|
||||
|
||||
// EdDSA with curve25519 + BLAKE2b
|
||||
void crypto_eddsa_key_pair(uint8_t secret_key[64],
|
||||
uint8_t public_key[32],
|
||||
uint8_t seed[32]);
|
||||
void crypto_eddsa_sign(uint8_t signature [64],
|
||||
const uint8_t secret_key[64],
|
||||
const uint8_t *message, size_t message_size);
|
||||
int crypto_eddsa_check(const uint8_t signature [64],
|
||||
const uint8_t public_key[32],
|
||||
const uint8_t *message, size_t message_size);
|
||||
|
||||
// Conversion to X25519
|
||||
void crypto_eddsa_to_x25519(uint8_t x25519[32], const uint8_t eddsa[32]);
|
||||
|
||||
// EdDSA building blocks
|
||||
void crypto_eddsa_trim_scalar(uint8_t out[32], const uint8_t in[32]);
|
||||
void crypto_eddsa_reduce(uint8_t reduced[32], const uint8_t expanded[64]);
|
||||
void crypto_eddsa_mul_add(uint8_t r[32],
|
||||
const uint8_t a[32],
|
||||
const uint8_t b[32],
|
||||
const uint8_t c[32]);
|
||||
void crypto_eddsa_scalarbase(uint8_t point[32], const uint8_t scalar[32]);
|
||||
int crypto_eddsa_check_equation(const uint8_t signature[64],
|
||||
const uint8_t public_key[32],
|
||||
const uint8_t h_ram[32]);
|
||||
|
||||
|
||||
// Chacha20
|
||||
// --------
|
||||
|
||||
// Specialised hash.
|
||||
// Used to hash X25519 shared secrets.
|
||||
void crypto_chacha20_h(uint8_t out[32],
|
||||
const uint8_t key[32],
|
||||
const uint8_t in [16]);
|
||||
|
||||
// Unauthenticated stream cipher.
|
||||
// Don't forget to add authentication.
|
||||
uint64_t crypto_chacha20_djb(uint8_t *cipher_text,
|
||||
const uint8_t *plain_text,
|
||||
size_t text_size,
|
||||
const uint8_t key[32],
|
||||
const uint8_t nonce[8],
|
||||
uint64_t ctr);
|
||||
uint32_t crypto_chacha20_ietf(uint8_t *cipher_text,
|
||||
const uint8_t *plain_text,
|
||||
size_t text_size,
|
||||
const uint8_t key[32],
|
||||
const uint8_t nonce[12],
|
||||
uint32_t ctr);
|
||||
uint64_t crypto_chacha20_x(uint8_t *cipher_text,
|
||||
const uint8_t *plain_text,
|
||||
size_t text_size,
|
||||
const uint8_t key[32],
|
||||
const uint8_t nonce[24],
|
||||
uint64_t ctr);
|
||||
|
||||
|
||||
// Poly 1305
|
||||
// ---------
|
||||
|
||||
// This is a *one time* authenticator.
|
||||
// Disclosing the mac reveals the key.
|
||||
// See crypto_lock() on how to use it properly.
|
||||
|
||||
// Direct interface
|
||||
void crypto_poly1305(uint8_t mac[16],
|
||||
const uint8_t *message, size_t message_size,
|
||||
const uint8_t key[32]);
|
||||
|
||||
// Incremental interface
|
||||
typedef struct {
|
||||
// Do not rely on the size or contents of this type,
|
||||
// for they may change without notice.
|
||||
uint8_t c[16]; // chunk of the message
|
||||
size_t c_idx; // How many bytes are there in the chunk.
|
||||
uint32_t r [4]; // constant multiplier (from the secret key)
|
||||
uint32_t pad[4]; // random number added at the end (from the secret key)
|
||||
uint32_t h [5]; // accumulated hash
|
||||
} crypto_poly1305_ctx;
|
||||
|
||||
void crypto_poly1305_init (crypto_poly1305_ctx *ctx, const uint8_t key[32]);
|
||||
void crypto_poly1305_update(crypto_poly1305_ctx *ctx,
|
||||
const uint8_t *message, size_t message_size);
|
||||
void crypto_poly1305_final (crypto_poly1305_ctx *ctx, uint8_t mac[16]);
|
||||
|
||||
|
||||
// Elligator 2
|
||||
// -----------
|
||||
|
||||
// Elligator mappings proper
|
||||
void crypto_elligator_map(uint8_t curve [32], const uint8_t hidden[32]);
|
||||
int crypto_elligator_rev(uint8_t hidden[32], const uint8_t curve [32],
|
||||
uint8_t tweak);
|
||||
|
||||
// Easy to use key pair generation
|
||||
void crypto_elligator_key_pair(uint8_t hidden[32], uint8_t secret_key[32],
|
||||
uint8_t seed[32]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MONOCYPHER_H
|
||||
|
|
@ -860,6 +860,12 @@ static void P_NetSyncPlayers(savebuffer_t *save)
|
|||
|
||||
SYNC(players[i].itemusecooldown);
|
||||
SYNC(players[i].itemusecooldownmax);
|
||||
|
||||
if (save->write)
|
||||
WRITESTRINGN(save->p, players[i].public_key, 32 + 1);
|
||||
else
|
||||
READSTRINGN(save->p, players[i].public_key, 32 + 1);
|
||||
|
||||
}
|
||||
TracyCZoneEnd(__zone);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ STUN_node (void)
|
|||
return node;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
csprng
|
||||
(
|
||||
void * const buffer,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ extern "C" {
|
|||
|
||||
typedef void (*stun_callback_t)(UINT32 address);
|
||||
|
||||
void csprng (void * const buffer, const size_t size);
|
||||
|
||||
void STUN_bind (stun_callback_t);
|
||||
boolean STUN_got_response (const char * const buffer, const size_t size);
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ TYPEDEF (rewind_t);
|
|||
TYPEDEF (netinfo_pak);
|
||||
TYPEDEF (say_pak);
|
||||
TYPEDEF (reqmapqueue_pak);
|
||||
TYPEDEF (clientkey_pak);
|
||||
TYPEDEF (serverchallenge_pak);
|
||||
|
||||
// d_event.h
|
||||
TYPEDEF (event_t);
|
||||
|
|
|
|||
Loading…
Reference in a new issue