Skip to content

Commit

Permalink
feat: sign demos with ed25519
Browse files Browse the repository at this point in the history
  • Loading branch information
mlugg committed Aug 14, 2022
1 parent cdc5bc5 commit 7d30dc4
Show file tree
Hide file tree
Showing 26 changed files with 5,135 additions and 60 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/CD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ jobs:
- name: Build
env:
RELEASE_BUILD: 1
DEMO_SIGN_PUBKEY: ${{ secrets.SAR_DEMO_SIGN_PUBKEY }}
DEMO_SIGN_PRIVKEY: ${{ secrets.SAR_DEMO_SIGN_PRIVKEY }}
run: make -j$(nproc)
- name: Upload Artifact
uses: actions/upload-artifact@v3
Expand All @@ -40,6 +42,8 @@ jobs:
- name: Build
env:
RELEASE_BUILD: 1
DEMO_SIGN_PUBKEY: ${{ secrets.SAR_DEMO_SIGN_PUBKEY }}
DEMO_SIGN_PRIVKEY: ${{ secrets.SAR_DEMO_SIGN_PRIVKEY }}
run: msbuild -m -t:SourceAutoRecord -p:"Configuration=Release;Platform=x86" SourceAutoRecord.sln
- name: Upload Artifact
uses: actions/upload-artifact@v3
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ jobs:
sudo apt-get update
sudo apt-get install -y g++-10-multilib
- name: Build
env:
DEMO_SIGN_PUBKEY: ${{ secrets.SAR_DEMO_SIGN_PUBKEY }}
DEMO_SIGN_PRIVKEY: ${{ secrets.SAR_DEMO_SIGN_PRIVKEY }}
run: make -j$(nproc)
- name: Upload Artifact
uses: actions/upload-artifact@v3
Expand All @@ -49,6 +52,9 @@ jobs:
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v1.1
- name: Build
env:
DEMO_SIGN_PUBKEY: ${{ secrets.SAR_DEMO_SIGN_PUBKEY }}
DEMO_SIGN_PRIVKEY: ${{ secrets.SAR_DEMO_SIGN_PRIVKEY }}
run: msbuild -m -t:SourceAutoRecord -p:"Configuration=Release;Platform=x86" SourceAutoRecord.sln
- name: Upload Artifact
uses: actions/upload-artifact@v3
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ SRCS+=$(wildcard $(SDIR)/Games/*.cpp)
SRCS+=$(wildcard $(SDIR)/Modules/*.cpp)
SRCS+=$(wildcard $(SDIR)/Utils/*.cpp)
SRCS+=$(wildcard $(SDIR)/Utils/SDK/*.cpp)
SRCS+=$(wildcard $(SDIR)/Utils/ed25519/*.cpp)

OBJS=$(patsubst $(SDIR)/%.cpp, $(ODIR)/%.o, $(SRCS))

Expand Down Expand Up @@ -52,6 +53,8 @@ $(ODIR)/%.o: $(SDIR)/%.cpp
src/Version.hpp: .FORCE
echo "#define SAR_VERSION \"$(VERSION)\"" >"$@"
if [ -z "$$RELEASE_BUILD" ]; then echo "#define SAR_DEV_BUILD 1" >>"$@"; fi
echo "#define SAR_DEMO_SIGN_PUBKEY { $$DEMO_SIGN_PUBKEY }" >>"$@"
echo "#define SAR_DEMO_SIGN_PRIVKEY { $$DEMO_SIGN_PRIVKEY }" >>"$@"

cvars: doc/cvars.md
doc/cvars.md:
Expand Down
2 changes: 2 additions & 0 deletions genversion.bat
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
for /f "tokens=* usebackq" %%x in (`git describe --tags`) do (set version=%%x)
echo #define SAR_VERSION "%version%">Version.hpp
if "%RELEASE_BUILD%"=="" echo #define SAR_DEV_BUILD 1>>Version.hpp
echo #define SAR_DEMO_SIGN_PUBKEY { %DEMO_SIGN_PUBKEY% }>>Version.hpp
echo #define SAR_DEMO_SIGN_PRIVKEY { %DEMO_SIGN_PRIVKEY% }>>Version.hpp
89 changes: 37 additions & 52 deletions src/Checksum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "Utils.hpp"
#include "Event.hpp"
#include "Modules/Engine.hpp"
#include "Utils/ed25519/ed25519.h"
#include "Version.hpp"

#include <cstdint>
#include <cstdio>
Expand Down Expand Up @@ -148,7 +150,6 @@ static bool fileChecksum(FILE *fp, size_t ignoreEnd, uint32_t *crcOut) {

if (fseek(fp, 0, SEEK_SET)) return false;

// what the fuck c++ why do you not have vlas
char *buf = (char *)malloc(size);

fread(buf, 1, size, fp);
Expand All @@ -165,31 +166,60 @@ static bool fileChecksum(FILE *fp, size_t ignoreEnd, uint32_t *crcOut) {

static uint32_t sarChecksum;

static bool signDemo(FILE *fp, unsigned char *signature) {
if (fseek(fp, 0, SEEK_END)) return false;

long size = ftell(fp);
if (size == -1) return false;

if (fseek(fp, 0, SEEK_SET)) return false;

char *buf = (char *)malloc(size + 4); // extra bytes for SAR checksum
fread(buf, 1, size, fp);
if (ferror(fp)) {
free(buf);
return false;
}

// write sar checksum to end so that it's also signed
*(uint32_t *)(buf + size) = sarChecksum;

unsigned char pubkey[32] = SAR_DEMO_SIGN_PUBKEY;
unsigned char privkey[64] = SAR_DEMO_SIGN_PRIVKEY;

ed25519_sign(signature, (unsigned char *)buf, size + 4, pubkey, privkey);

free(buf);
return true;
}

bool AddDemoChecksum(const char *filename) {
FILE *fp = fopen(filename, "ab+"); // Open for binary appending and reading
if (!fp) return false;

uint32_t checksum;
if (!fileChecksum(fp, 0, &checksum)) {
unsigned char signature[64];
if (!signDemo(fp, signature)) {
fclose(fp);
return false;
}

uint8_t checkBuf[] = {
uint8_t checkBuf[91] = {
0x08, // Type: CustomData
WRITE_LE32(0xFFFFFFFF), // Tick
0x00, // Slot (TODO: what is this?)

// CustomData packet data:
WRITE_LE32(0x00), // ID - see RecordData for an explanation of why we use 0
WRITE_LE32(0x11), // Size: 17 bytes
WRITE_LE32(0x4D), // Size: 77 bytes
WRITE_LE32(0xFFFFFFFF), // Cursor x
WRITE_LE32(0xFFFFFFFF), // Cursor y
0xFF, // First byte of data: SAR message ID (0xFF = checksum)
WRITE_LE32(checksum), // Demo checksum
0xFE, // First byte of data: SAR message ID (0xFE = v2 checksum)
WRITE_LE32(sarChecksum), // SAR checksum
// 64 bytes remain to be filled with signature
};

memcpy(checkBuf + 27, signature, sizeof signature);

if (fwrite(checkBuf, 1, sizeof checkBuf, fp) != sizeof checkBuf) {
fclose(fp);
return false;
Expand All @@ -199,51 +229,6 @@ bool AddDemoChecksum(const char *filename) {
return true;
}

std::pair<VerifyResult, uint32_t> VerifyDemoChecksum(const char *filename) {
FILE *fp = fopen(filename, "rb");
if (!fp) return std::pair(VERIFY_BAD_DEMO, 0);

uint32_t realChecksum;
if (!fileChecksum(fp, 31, &realChecksum)) {
fclose(fp);
return std::pair(VERIFY_BAD_DEMO, 0);
}

// The start of the checksum should come 31 bytes before the end
if (fseek(fp, -31, SEEK_END)) {
fclose(fp);
return std::pair(VERIFY_BAD_DEMO, 0);
}

uint8_t buf[31];
fread(buf, 1, sizeof buf, fp);
if (ferror(fp)) {
fclose(fp);
return std::pair(VERIFY_BAD_DEMO, 0);
}

// We've got all the data we need from the file
fclose(fp);

if (buf[0] != 0x08 || READ_LE32(buf, 1) != 0xFFFFFFFF || buf[5] != 0x00) {
// Couldn't find checksum field!
return std::pair(VERIFY_NO_CHECKSUM, 0);
}

if (READ_LE32(buf, 6) != 0x00 || (READ_LE32(buf, 10) != 0x11 && READ_LE32(buf, 10) != 0x0D) // workaround for bug in initial 1.12 release
|| READ_LE32(buf, 14) != 0xFFFFFFFF || READ_LE32(buf, 18) != 0xFFFFFFFF || buf[22] != 0xFF) {
// SAR message field not a valid checksum!
return std::pair(VERIFY_NO_CHECKSUM, 0);
}

uint32_t storedChecksum = READ_LE32(buf, 23);
uint32_t storedSarChecksum = READ_LE32(buf, 27);

VerifyResult res = realChecksum == storedChecksum ? VERIFY_VALID_CHECKSUM : VERIFY_INVALID_CHECKSUM;

return std::pair(res, storedSarChecksum);
}

#define NUM_FILE_SUM_THREADS 1

static std::thread g_sumthreads[NUM_FILE_SUM_THREADS];
Expand Down
8 changes: 0 additions & 8 deletions src/Checksum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,4 @@
bool AddDemoChecksum(const char *filename);
void AddDemoFileChecksums();

enum VerifyResult {
VERIFY_BAD_DEMO,
VERIFY_NO_CHECKSUM,
VERIFY_INVALID_CHECKSUM,
VERIFY_VALID_CHECKSUM,
};
std::pair<VerifyResult, uint32_t> VerifyDemoChecksum(const char *filename);

void InitSARChecksum();
16 changes: 16 additions & 0 deletions src/SourceAutoRecord.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,15 @@
<ClCompile Include="Plugin.cpp" />
<ClCompile Include="SAR.cpp" />
<ClCompile Include="Utils.cpp" />
<ClCompile Include="Utils\ed25519\add_scalar.cpp" />
<ClCompile Include="Utils\ed25519\fe.cpp" />
<ClCompile Include="Utils\ed25519\ge.cpp" />
<ClCompile Include="Utils\ed25519\key_exchange.cpp" />
<ClCompile Include="Utils\ed25519\keypair.cpp" />
<ClCompile Include="Utils\ed25519\sc.cpp" />
<ClCompile Include="Utils\ed25519\sha512.cpp" />
<ClCompile Include="Utils\ed25519\sign.cpp" />
<ClCompile Include="Utils\ed25519\verify.cpp" />
<ClCompile Include="Utils\json11.cpp" />
<ClCompile Include="Utils\lodepng.cpp" />
<ClCompile Include="Utils\Math.cpp" />
Expand Down Expand Up @@ -418,6 +427,13 @@
<ClInclude Include="Plugin.hpp" />
<ClInclude Include="SAR.hpp" />
<ClInclude Include="Utils.hpp" />
<ClInclude Include="Utils\ed25519\ed25519.h" />
<ClInclude Include="Utils\ed25519\fe.h" />
<ClInclude Include="Utils\ed25519\fixedint.h" />
<ClInclude Include="Utils\ed25519\ge.h" />
<ClInclude Include="Utils\ed25519\precomp_data.h" />
<ClInclude Include="Utils\ed25519\sc.h" />
<ClInclude Include="Utils\ed25519\sha512.h" />
<ClInclude Include="Utils\json11.hpp" />
<ClInclude Include="Utils\lodepng.hpp" />
<ClInclude Include="Utils\Math.hpp" />
Expand Down
48 changes: 48 additions & 0 deletions src/SourceAutoRecord.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,33 @@
<ClCompile Include="Features\Hud\CheatWarn.cpp">
<Filter>SourceAutoRecord\Features\Hud</Filter>
</ClCompile>
<ClCompile Include="Utils\ed25519\add_scalar.cpp">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClCompile>
<ClCompile Include="Utils\ed25519\fe.cpp">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClCompile>
<ClCompile Include="Utils\ed25519\ge.cpp">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClCompile>
<ClCompile Include="Utils\ed25519\key_exchange.cpp">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClCompile>
<ClCompile Include="Utils\ed25519\keypair.cpp">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClCompile>
<ClCompile Include="Utils\ed25519\sc.cpp">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClCompile>
<ClCompile Include="Utils\ed25519\sha512.cpp">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClCompile>
<ClCompile Include="Utils\ed25519\sign.cpp">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClCompile>
<ClCompile Include="Utils\ed25519\verify.cpp">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClCompile>
<ClCompile Include="Utils\json11.cpp">
<Filter>SourceAutoRecord\Utils</Filter>
</ClCompile>
Expand Down Expand Up @@ -717,6 +744,27 @@
<ClInclude Include="Features\Hud\Crosshair.hpp">
<Filter>SourceAutoRecord\Features\Hud</Filter>
</ClInclude>
<ClInclude Include="Utils\ed25519\ed25519.h">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClInclude>
<ClInclude Include="Utils\ed25519\fe.h">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClInclude>
<ClInclude Include="Utils\ed25519\fixedint.h">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClInclude>
<ClInclude Include="Utils\ed25519\ge.h">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClInclude>
<ClInclude Include="Utils\ed25519\precomp_data.h">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClInclude>
<ClInclude Include="Utils\ed25519\sc.h">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClInclude>
<ClInclude Include="Utils\ed25519\sha512.h">
<Filter>SourceAutoRecord\Utils\ed25519</Filter>
</ClInclude>
<ClInclude Include="Utils\json11.hpp">
<Filter>SourceAutoRecord\Utils</Filter>
</ClInclude>
Expand Down
69 changes: 69 additions & 0 deletions src/Utils/ed25519/add_scalar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include "ed25519.h"
#include "ge.h"
#include "sc.h"
#include "sha512.h"


/* see http://crypto.stackexchange.com/a/6215/4697 */
void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar) {
const unsigned char SC_1[32] = {1}; /* scalar with value 1 */

unsigned char n[32];
ge_p3 nB;
ge_p1p1 A_p1p1;
ge_p3 A;
ge_p3 public_key_unpacked;
ge_cached T;

sha512_context hash;
unsigned char hashbuf[64];

int i;

/* copy the scalar and clear highest bit */
for (i = 0; i < 31; ++i) {
n[i] = scalar[i];
}
n[31] = scalar[31] & 127;

/* private key: a = n + t */
if (private_key) {
sc_muladd(private_key, SC_1, n, private_key);

// https://github.com/orlp/ed25519/issues/3
sha512_init(&hash);
sha512_update(&hash, private_key + 32, 32);
sha512_update(&hash, scalar, 32);
sha512_final(&hash, hashbuf);
for (i = 0; i < 32; ++i) {
private_key[32 + i] = hashbuf[i];
}
}

/* public key: A = nB + T */
if (public_key) {
/* if we know the private key we don't need a point addition, which is faster */
/* using a "timing attack" you could find out wether or not we know the private
key, but this information seems rather useless - if this is important pass
public_key and private_key seperately in 2 function calls */
if (private_key) {
ge_scalarmult_base(&A, private_key);
} else {
/* unpack public key into T */
ge_frombytes_negate_vartime(&public_key_unpacked, public_key);
fe_neg(public_key_unpacked.X, public_key_unpacked.X); /* undo negate */
fe_neg(public_key_unpacked.T, public_key_unpacked.T); /* undo negate */
ge_p3_to_cached(&T, &public_key_unpacked);

/* calculate n*B */
ge_scalarmult_base(&nB, n);

/* A = n*B + T */
ge_add(&A_p1p1, &nB, &T);
ge_p1p1_to_p3(&A, &A_p1p1);
}

/* pack public key */
ge_p3_tobytes(public_key, &A);
}
}
Loading

0 comments on commit 7d30dc4

Please sign in to comment.