Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/raylib.h
Original file line number Diff line number Diff line change
Expand Up @@ -1161,9 +1161,10 @@ RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string (includes NULL terminator), memory must be MemFree()
RLAPI unsigned char *DecodeDataBase64(const char *text, int *outputSize); // Decode Base64 string (expected NULL terminated), memory must be MemFree()
RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
RLAPI unsigned int *ComputeSHA256(unsigned char *data, int dataSize); // Compute SHA256 hash code, returns static int[8] (32 bytes)

// Automation events functionality
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
Expand Down
106 changes: 106 additions & 0 deletions src/rcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -3080,6 +3080,112 @@ unsigned int *ComputeSHA1(unsigned char *data, int dataSize)
return hash;
}

// Compute SHA-256 hash code
// NOTE: Returns a static int[8] array (32 bytes)
unsigned int *ComputeSHA256(unsigned char *data, int dataSize)
{
#define ROTATE_RIGHT(x, c) ((x >> c) | (x << ((sizeof(unsigned int) * 8) - c)))
#define A0(x) (ROTATE_RIGHT(x, 7) ^ ROTATE_RIGHT(x, 18) ^ (x >> 3))
#define A1(x) (ROTATE_RIGHT(x, 17) ^ ROTATE_RIGHT(x, 19) ^ (x >> 10))

static const unsigned int k[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};

static unsigned int hash[8];
hash[0] = 0x6A09e667;
hash[1] = 0xbb67ae85;
hash[2] = 0x3c6ef372;
hash[3] = 0xa54ff53a;
hash[4] = 0x510e527f;
hash[5] = 0x9b05688c;
hash[6] = 0x1f83d9ab;
hash[7] = 0x5be0cd19;

unsigned long long const bitLen = dataSize*8;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes undefined behaviour for valid values of dataSize because both are signed integers (dataSize and the 8 literal)

unsigned long long paddedSize = dataSize + sizeof(dataSize);
paddedSize += (64 - (paddedSize%64));
unsigned char* const buffer = RL_CALLOC(paddedSize, sizeof(unsigned char));

memcpy(buffer, data, dataSize);
buffer[dataSize] = 0x80;
for (int i = 1; i <= sizeof(bitLen); i++)
buffer[(paddedSize - sizeof(bitLen)) + (i - 1)] = (bitLen >> (8*(sizeof(bitLen) - i))) & 0xFF;

for (size_t blockN = 0; blockN < paddedSize/64; blockN++)
{
unsigned int a = hash[0];
unsigned int b = hash[1];
unsigned int c = hash[2];
unsigned int d = hash[3];
unsigned int e = hash[4];
unsigned int f = hash[5];
unsigned int g = hash[6];
unsigned int h = hash[7];

unsigned char *block = buffer + (blockN*64);
unsigned int w[64];
for (int i = 0; i < 16; i++)
{
w[i] =
((unsigned int)block[i*4 + 0] << 24) |
((unsigned int)block[i*4 + 1] << 16) |
((unsigned int)block[i*4 + 2] << 8) |
((unsigned int)block[i*4 + 3]);
}
for (int t = 16; t < 64; t++) w[t] = A1(w[t - 2]) + w[t - 7] + A0(w[t - 15]) + w[t - 16];

for (size_t t = 0; t < 64; t++)
{
unsigned int e1 = (ROTATE_RIGHT(e, 6) ^ ROTATE_RIGHT(e, 11) ^ ROTATE_RIGHT(e, 25));
unsigned int ch = ((e & f) ^ (~e & g));
unsigned int t1 = (h + e1 + ch + k[t] + w[t]);
unsigned int e0 = (ROTATE_RIGHT(a, 2) ^ ROTATE_RIGHT(a, 13) ^ ROTATE_RIGHT(a, 22));
unsigned int maj = ((a & b) ^ (a & c) ^ (b & c));
unsigned int t2 = e0 + maj;

h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}

hash[0] += a;
hash[1] += b;
hash[2] += c;
hash[3] += d;
hash[4] += e;
hash[5] += f;
hash[6] += g;
hash[7] += h;
}
RL_FREE(buffer);
return hash;

#undef ROTATE_RIGHT
#undef A0
#undef A1
}

//----------------------------------------------------------------------------------
// Module Functions Definition: Automation Events Recording and Playing
//----------------------------------------------------------------------------------
Expand Down
Loading