Clean libthecore
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "libthecore/xmd5.h"
|
||||
#include <sodium.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "config.h"
|
||||
@@ -2365,26 +2365,21 @@ ACMD(do_in_game_mall)
|
||||
|
||||
char buf[512+1];
|
||||
char sas[33];
|
||||
MD5_CTX ctx;
|
||||
const char sas_key[] = "GF9001";
|
||||
|
||||
snprintf(buf, sizeof(buf), "%u%u%s", ch->GetPlayerID(), ch->GetAID(), sas_key);
|
||||
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, (const unsigned char *) buf, strlen(buf));
|
||||
#ifdef OS_FREEBSD
|
||||
MD5End(&ctx, sas);
|
||||
#else
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
unsigned char digest[16];
|
||||
MD5Final(digest, &ctx);
|
||||
int i;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
crypto_generichash(digest, sizeof(digest),
|
||||
(const unsigned char*)buf, strlen(buf),
|
||||
NULL, 0);
|
||||
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
sas[i+i] = hex[digest[i] >> 4];
|
||||
sas[i+i+1] = hex[digest[i] & 0x0f];
|
||||
}
|
||||
sas[i+i] = '\0';
|
||||
#endif
|
||||
sas[32] = '\0';
|
||||
|
||||
snprintf(buf, sizeof(buf), "mall http://%s/ishop?pid=%u&c=%s&sid=%d&sas=%s",
|
||||
g_strWebMallURL.c_str(), ch->GetPlayerID(), country_code, g_server_id, sas);
|
||||
|
||||
@@ -1,327 +0,0 @@
|
||||
#pragma once
|
||||
static DWORD SP_boxes[8][64]=
|
||||
{
|
||||
/* 0 */
|
||||
{
|
||||
0x00820200, 0x00020000, 0x80800000, 0x80820200,
|
||||
0x00800000, 0x80020200, 0x80020000, 0x80800000,
|
||||
0x80020200, 0x00820200, 0x00820000, 0x80000200,
|
||||
0x80800200, 0x00800000, 0x00000000, 0x80020000,
|
||||
0x00020000, 0x80000000, 0x00800200, 0x00020200,
|
||||
0x80820200, 0x00820000, 0x80000200, 0x00800200,
|
||||
0x80000000, 0x00000200, 0x00020200, 0x80820000,
|
||||
0x00000200, 0x80800200, 0x80820000, 0x00000000,
|
||||
0x00000000, 0x80820200, 0x00800200, 0x80020000,
|
||||
0x00820200, 0x00020000, 0x80000200, 0x00800200,
|
||||
0x80820000, 0x00000200, 0x00020200, 0x80800000,
|
||||
0x80020200, 0x80000000, 0x80800000, 0x00820000,
|
||||
0x80820200, 0x00020200, 0x00820000, 0x80800200,
|
||||
0x00800000, 0x80000200, 0x80020000, 0x00000000,
|
||||
0x00020000, 0x00800000, 0x80800200, 0x00820200,
|
||||
0x80000000, 0x80820000, 0x00000200, 0x80020200
|
||||
},
|
||||
|
||||
/* 1 */
|
||||
{
|
||||
0x10042004, 0x00000000, 0x00042000, 0x10040000,
|
||||
0x10000004, 0x00002004, 0x10002000, 0x00042000,
|
||||
0x00002000, 0x10040004, 0x00000004, 0x10002000,
|
||||
0x00040004, 0x10042000, 0x10040000, 0x00000004,
|
||||
0x00040000, 0x10002004, 0x10040004, 0x00002000,
|
||||
0x00042004, 0x10000000, 0x00000000, 0x00040004,
|
||||
0x10002004, 0x00042004, 0x10042000, 0x10000004,
|
||||
0x10000000, 0x00040000, 0x00002004, 0x10042004,
|
||||
0x00040004, 0x10042000, 0x10002000, 0x00042004,
|
||||
0x10042004, 0x00040004, 0x10000004, 0x00000000,
|
||||
0x10000000, 0x00002004, 0x00040000, 0x10040004,
|
||||
0x00002000, 0x10000000, 0x00042004, 0x10002004,
|
||||
0x10042000, 0x00002000, 0x00000000, 0x10000004,
|
||||
0x00000004, 0x10042004, 0x00042000, 0x10040000,
|
||||
0x10040004, 0x00040000, 0x00002004, 0x10002000,
|
||||
0x10002004, 0x00000004, 0x10040000, 0x00042000
|
||||
},
|
||||
|
||||
/* 2 */
|
||||
{
|
||||
0x41000000, 0x01010040, 0x00000040, 0x41000040,
|
||||
0x40010000, 0x01000000, 0x41000040, 0x00010040,
|
||||
0x01000040, 0x00010000, 0x01010000, 0x40000000,
|
||||
0x41010040, 0x40000040, 0x40000000, 0x41010000,
|
||||
0x00000000, 0x40010000, 0x01010040, 0x00000040,
|
||||
0x40000040, 0x41010040, 0x00010000, 0x41000000,
|
||||
0x41010000, 0x01000040, 0x40010040, 0x01010000,
|
||||
0x00010040, 0x00000000, 0x01000000, 0x40010040,
|
||||
0x01010040, 0x00000040, 0x40000000, 0x00010000,
|
||||
0x40000040, 0x40010000, 0x01010000, 0x41000040,
|
||||
0x00000000, 0x01010040, 0x00010040, 0x41010000,
|
||||
0x40010000, 0x01000000, 0x41010040, 0x40000000,
|
||||
0x40010040, 0x41000000, 0x01000000, 0x41010040,
|
||||
0x00010000, 0x01000040, 0x41000040, 0x00010040,
|
||||
0x01000040, 0x00000000, 0x41010000, 0x40000040,
|
||||
0x41000000, 0x40010040, 0x00000040, 0x01010000
|
||||
},
|
||||
|
||||
/* 3 */
|
||||
{
|
||||
0x00100402, 0x04000400, 0x00000002, 0x04100402,
|
||||
0x00000000, 0x04100000, 0x04000402, 0x00100002,
|
||||
0x04100400, 0x04000002, 0x04000000, 0x00000402,
|
||||
0x04000002, 0x00100402, 0x00100000, 0x04000000,
|
||||
0x04100002, 0x00100400, 0x00000400, 0x00000002,
|
||||
0x00100400, 0x04000402, 0x04100000, 0x00000400,
|
||||
0x00000402, 0x00000000, 0x00100002, 0x04100400,
|
||||
0x04000400, 0x04100002, 0x04100402, 0x00100000,
|
||||
0x04100002, 0x00000402, 0x00100000, 0x04000002,
|
||||
0x00100400, 0x04000400, 0x00000002, 0x04100000,
|
||||
0x04000402, 0x00000000, 0x00000400, 0x00100002,
|
||||
0x00000000, 0x04100002, 0x04100400, 0x00000400,
|
||||
0x04000000, 0x04100402, 0x00100402, 0x00100000,
|
||||
0x04100402, 0x00000002, 0x04000400, 0x00100402,
|
||||
0x00100002, 0x00100400, 0x04100000, 0x04000402,
|
||||
0x00000402, 0x04000000, 0x04000002, 0x04100400
|
||||
},
|
||||
|
||||
/* 4 */
|
||||
{
|
||||
0x02000000, 0x00004000, 0x00000100, 0x02004108,
|
||||
0x02004008, 0x02000100, 0x00004108, 0x02004000,
|
||||
0x00004000, 0x00000008, 0x02000008, 0x00004100,
|
||||
0x02000108, 0x02004008, 0x02004100, 0x00000000,
|
||||
0x00004100, 0x02000000, 0x00004008, 0x00000108,
|
||||
0x02000100, 0x00004108, 0x00000000, 0x02000008,
|
||||
0x00000008, 0x02000108, 0x02004108, 0x00004008,
|
||||
0x02004000, 0x00000100, 0x00000108, 0x02004100,
|
||||
0x02004100, 0x02000108, 0x00004008, 0x02004000,
|
||||
0x00004000, 0x00000008, 0x02000008, 0x02000100,
|
||||
0x02000000, 0x00004100, 0x02004108, 0x00000000,
|
||||
0x00004108, 0x02000000, 0x00000100, 0x00004008,
|
||||
0x02000108, 0x00000100, 0x00000000, 0x02004108,
|
||||
0x02004008, 0x02004100, 0x00000108, 0x00004000,
|
||||
0x00004100, 0x02004008, 0x02000100, 0x00000108,
|
||||
0x00000008, 0x00004108, 0x02004000, 0x02000008
|
||||
},
|
||||
|
||||
/* 5 */
|
||||
{
|
||||
0x20000010, 0x00080010, 0x00000000, 0x20080800,
|
||||
0x00080010, 0x00000800, 0x20000810, 0x00080000,
|
||||
0x00000810, 0x20080810, 0x00080800, 0x20000000,
|
||||
0x20000800, 0x20000010, 0x20080000, 0x00080810,
|
||||
0x00080000, 0x20000810, 0x20080010, 0x00000000,
|
||||
0x00000800, 0x00000010, 0x20080800, 0x20080010,
|
||||
0x20080810, 0x20080000, 0x20000000, 0x00000810,
|
||||
0x00000010, 0x00080800, 0x00080810, 0x20000800,
|
||||
0x00000810, 0x20000000, 0x20000800, 0x00080810,
|
||||
0x20080800, 0x00080010, 0x00000000, 0x20000800,
|
||||
0x20000000, 0x00000800, 0x20080010, 0x00080000,
|
||||
0x00080010, 0x20080810, 0x00080800, 0x00000010,
|
||||
0x20080810, 0x00080800, 0x00080000, 0x20000810,
|
||||
0x20000010, 0x20080000, 0x00080810, 0x00000000,
|
||||
0x00000800, 0x20000010, 0x20000810, 0x20080800,
|
||||
0x20080000, 0x00000810, 0x00000010, 0x20080010
|
||||
},
|
||||
|
||||
/* 6 */
|
||||
{
|
||||
0x00001000, 0x00000080, 0x00400080, 0x00400001,
|
||||
0x00401081, 0x00001001, 0x00001080, 0x00000000,
|
||||
0x00400000, 0x00400081, 0x00000081, 0x00401000,
|
||||
0x00000001, 0x00401080, 0x00401000, 0x00000081,
|
||||
0x00400081, 0x00001000, 0x00001001, 0x00401081,
|
||||
0x00000000, 0x00400080, 0x00400001, 0x00001080,
|
||||
0x00401001, 0x00001081, 0x00401080, 0x00000001,
|
||||
0x00001081, 0x00401001, 0x00000080, 0x00400000,
|
||||
0x00001081, 0x00401000, 0x00401001, 0x00000081,
|
||||
0x00001000, 0x00000080, 0x00400000, 0x00401001,
|
||||
0x00400081, 0x00001081, 0x00001080, 0x00000000,
|
||||
0x00000080, 0x00400001, 0x00000001, 0x00400080,
|
||||
0x00000000, 0x00400081, 0x00400080, 0x00001080,
|
||||
0x00000081, 0x00001000, 0x00401081, 0x00400000,
|
||||
0x00401080, 0x00000001, 0x00001001, 0x00401081,
|
||||
0x00400001, 0x00401080, 0x00401000, 0x00001001
|
||||
},
|
||||
|
||||
/* 7 */
|
||||
{
|
||||
0x08200020, 0x08208000, 0x00008020, 0x00000000,
|
||||
0x08008000, 0x00200020, 0x08200000, 0x08208020,
|
||||
0x00000020, 0x08000000, 0x00208000, 0x00008020,
|
||||
0x00208020, 0x08008020, 0x08000020, 0x08200000,
|
||||
0x00008000, 0x00208020, 0x00200020, 0x08008000,
|
||||
0x08208020, 0x08000020, 0x00000000, 0x00208000,
|
||||
0x08000000, 0x00200000, 0x08008020, 0x08200020,
|
||||
0x00200000, 0x00008000, 0x08208000, 0x00000020,
|
||||
0x00200000, 0x00008000, 0x08000020, 0x08208020,
|
||||
0x00008020, 0x08000000, 0x00000000, 0x00208000,
|
||||
0x08200020, 0x08008020, 0x08008000, 0x00200020,
|
||||
0x08208000, 0x00000020, 0x00200020, 0x08008000,
|
||||
0x08208020, 0x00200000, 0x08200000, 0x08000020,
|
||||
0x00208000, 0x00008020, 0x08008020, 0x08200000,
|
||||
0x00000020, 0x08208000, 0x00208020, 0x00000000,
|
||||
0x08000000, 0x08200020, 0x00008000, 0x00208020
|
||||
}
|
||||
};
|
||||
|
||||
static DWORD KeyPerm[8][64] =
|
||||
{
|
||||
/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
|
||||
{
|
||||
0x00000000,0x00000010,0x20000000,0x20000010,
|
||||
0x00010000,0x00010010,0x20010000,0x20010010,
|
||||
0x00000800,0x00000810,0x20000800,0x20000810,
|
||||
0x00010800,0x00010810,0x20010800,0x20010810,
|
||||
0x00000020,0x00000030,0x20000020,0x20000030,
|
||||
0x00010020,0x00010030,0x20010020,0x20010030,
|
||||
0x00000820,0x00000830,0x20000820,0x20000830,
|
||||
0x00010820,0x00010830,0x20010820,0x20010830,
|
||||
0x00080000,0x00080010,0x20080000,0x20080010,
|
||||
0x00090000,0x00090010,0x20090000,0x20090010,
|
||||
0x00080800,0x00080810,0x20080800,0x20080810,
|
||||
0x00090800,0x00090810,0x20090800,0x20090810,
|
||||
0x00080020,0x00080030,0x20080020,0x20080030,
|
||||
0x00090020,0x00090030,0x20090020,0x20090030,
|
||||
0x00080820,0x00080830,0x20080820,0x20080830,
|
||||
0x00090820,0x00090830,0x20090820,0x20090830
|
||||
},
|
||||
|
||||
/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
|
||||
{
|
||||
0x00000000,0x02000000,0x00002000,0x02002000,
|
||||
0x00200000,0x02200000,0x00202000,0x02202000,
|
||||
0x00000004,0x02000004,0x00002004,0x02002004,
|
||||
0x00200004,0x02200004,0x00202004,0x02202004,
|
||||
0x00000400,0x02000400,0x00002400,0x02002400,
|
||||
0x00200400,0x02200400,0x00202400,0x02202400,
|
||||
0x00000404,0x02000404,0x00002404,0x02002404,
|
||||
0x00200404,0x02200404,0x00202404,0x02202404,
|
||||
0x10000000,0x12000000,0x10002000,0x12002000,
|
||||
0x10200000,0x12200000,0x10202000,0x12202000,
|
||||
0x10000004,0x12000004,0x10002004,0x12002004,
|
||||
0x10200004,0x12200004,0x10202004,0x12202004,
|
||||
0x10000400,0x12000400,0x10002400,0x12002400,
|
||||
0x10200400,0x12200400,0x10202400,0x12202400,
|
||||
0x10000404,0x12000404,0x10002404,0x12002404,
|
||||
0x10200404,0x12200404,0x10202404,0x12202404
|
||||
},
|
||||
|
||||
/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
|
||||
{
|
||||
0x00000000,0x00000001,0x00040000,0x00040001,
|
||||
0x01000000,0x01000001,0x01040000,0x01040001,
|
||||
0x00000002,0x00000003,0x00040002,0x00040003,
|
||||
0x01000002,0x01000003,0x01040002,0x01040003,
|
||||
0x00000200,0x00000201,0x00040200,0x00040201,
|
||||
0x01000200,0x01000201,0x01040200,0x01040201,
|
||||
0x00000202,0x00000203,0x00040202,0x00040203,
|
||||
0x01000202,0x01000203,0x01040202,0x01040203,
|
||||
0x08000000,0x08000001,0x08040000,0x08040001,
|
||||
0x09000000,0x09000001,0x09040000,0x09040001,
|
||||
0x08000002,0x08000003,0x08040002,0x08040003,
|
||||
0x09000002,0x09000003,0x09040002,0x09040003,
|
||||
0x08000200,0x08000201,0x08040200,0x08040201,
|
||||
0x09000200,0x09000201,0x09040200,0x09040201,
|
||||
0x08000202,0x08000203,0x08040202,0x08040203,
|
||||
0x09000202,0x09000203,0x09040202,0x09040203
|
||||
},
|
||||
|
||||
/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
|
||||
{
|
||||
0x00000000,0x00100000,0x00000100,0x00100100,
|
||||
0x00000008,0x00100008,0x00000108,0x00100108,
|
||||
0x00001000,0x00101000,0x00001100,0x00101100,
|
||||
0x00001008,0x00101008,0x00001108,0x00101108,
|
||||
0x04000000,0x04100000,0x04000100,0x04100100,
|
||||
0x04000008,0x04100008,0x04000108,0x04100108,
|
||||
0x04001000,0x04101000,0x04001100,0x04101100,
|
||||
0x04001008,0x04101008,0x04001108,0x04101108,
|
||||
0x00020000,0x00120000,0x00020100,0x00120100,
|
||||
0x00020008,0x00120008,0x00020108,0x00120108,
|
||||
0x00021000,0x00121000,0x00021100,0x00121100,
|
||||
0x00021008,0x00121008,0x00021108,0x00121108,
|
||||
0x04020000,0x04120000,0x04020100,0x04120100,
|
||||
0x04020008,0x04120008,0x04020108,0x04120108,
|
||||
0x04021000,0x04121000,0x04021100,0x04121100,
|
||||
0x04021008,0x04121008,0x04021108,0x04121108
|
||||
},
|
||||
|
||||
/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
|
||||
{
|
||||
0x00000000,0x10000000,0x00010000,0x10010000,
|
||||
0x00000004,0x10000004,0x00010004,0x10010004,
|
||||
0x20000000,0x30000000,0x20010000,0x30010000,
|
||||
0x20000004,0x30000004,0x20010004,0x30010004,
|
||||
0x00100000,0x10100000,0x00110000,0x10110000,
|
||||
0x00100004,0x10100004,0x00110004,0x10110004,
|
||||
0x20100000,0x30100000,0x20110000,0x30110000,
|
||||
0x20100004,0x30100004,0x20110004,0x30110004,
|
||||
0x00001000,0x10001000,0x00011000,0x10011000,
|
||||
0x00001004,0x10001004,0x00011004,0x10011004,
|
||||
0x20001000,0x30001000,0x20011000,0x30011000,
|
||||
0x20001004,0x30001004,0x20011004,0x30011004,
|
||||
0x00101000,0x10101000,0x00111000,0x10111000,
|
||||
0x00101004,0x10101004,0x00111004,0x10111004,
|
||||
0x20101000,0x30101000,0x20111000,0x30111000,
|
||||
0x20101004,0x30101004,0x20111004,0x30111004
|
||||
},
|
||||
|
||||
/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
|
||||
{
|
||||
0x00000000,0x08000000,0x00000008,0x08000008,
|
||||
0x00000400,0x08000400,0x00000408,0x08000408,
|
||||
0x00020000,0x08020000,0x00020008,0x08020008,
|
||||
0x00020400,0x08020400,0x00020408,0x08020408,
|
||||
0x00000001,0x08000001,0x00000009,0x08000009,
|
||||
0x00000401,0x08000401,0x00000409,0x08000409,
|
||||
0x00020001,0x08020001,0x00020009,0x08020009,
|
||||
0x00020401,0x08020401,0x00020409,0x08020409,
|
||||
0x02000000,0x0A000000,0x02000008,0x0A000008,
|
||||
0x02000400,0x0A000400,0x02000408,0x0A000408,
|
||||
0x02020000,0x0A020000,0x02020008,0x0A020008,
|
||||
0x02020400,0x0A020400,0x02020408,0x0A020408,
|
||||
0x02000001,0x0A000001,0x02000009,0x0A000009,
|
||||
0x02000401,0x0A000401,0x02000409,0x0A000409,
|
||||
0x02020001,0x0A020001,0x02020009,0x0A020009,
|
||||
0x02020401,0x0A020401,0x02020409,0x0A020409
|
||||
},
|
||||
|
||||
/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
|
||||
{
|
||||
0x00000000,0x00000100,0x00080000,0x00080100,
|
||||
0x01000000,0x01000100,0x01080000,0x01080100,
|
||||
0x00000010,0x00000110,0x00080010,0x00080110,
|
||||
0x01000010,0x01000110,0x01080010,0x01080110,
|
||||
0x00200000,0x00200100,0x00280000,0x00280100,
|
||||
0x01200000,0x01200100,0x01280000,0x01280100,
|
||||
0x00200010,0x00200110,0x00280010,0x00280110,
|
||||
0x01200010,0x01200110,0x01280010,0x01280110,
|
||||
0x00000200,0x00000300,0x00080200,0x00080300,
|
||||
0x01000200,0x01000300,0x01080200,0x01080300,
|
||||
0x00000210,0x00000310,0x00080210,0x00080310,
|
||||
0x01000210,0x01000310,0x01080210,0x01080310,
|
||||
0x00200200,0x00200300,0x00280200,0x00280300,
|
||||
0x01200200,0x01200300,0x01280200,0x01280300,
|
||||
0x00200210,0x00200310,0x00280210,0x00280310,
|
||||
0x01200210,0x01200310,0x01280210,0x01280310
|
||||
},
|
||||
|
||||
/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
|
||||
{
|
||||
0x00000000,0x04000000,0x00040000,0x04040000,
|
||||
0x00000002,0x04000002,0x00040002,0x04040002,
|
||||
0x00002000,0x04002000,0x00042000,0x04042000,
|
||||
0x00002002,0x04002002,0x00042002,0x04042002,
|
||||
0x00000020,0x04000020,0x00040020,0x04040020,
|
||||
0x00000022,0x04000022,0x00040022,0x04040022,
|
||||
0x00002020,0x04002020,0x00042020,0x04042020,
|
||||
0x00002022,0x04002022,0x00042022,0x04042022,
|
||||
0x00000800,0x04000800,0x00040800,0x04040800,
|
||||
0x00000802,0x04000802,0x00040802,0x04040802,
|
||||
0x00002800,0x04002800,0x00042800,0x04042800,
|
||||
0x00002802,0x04002802,0x00042802,0x04042802,
|
||||
0x00000820,0x04000820,0x00040820,0x04040820,
|
||||
0x00000822,0x04000822,0x00040822,0x04040822,
|
||||
0x00002820,0x04002820,0x00042820,0x04042820,
|
||||
0x00002822,0x04002822,0x00042822,0x04042822
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
int GOST_Encrypt(DWORD * DstBuffer, const DWORD * SrcBuffer, const DWORD * KeyAddress, DWORD Length, DWORD *IVector);
|
||||
int GOST_Decrypt(DWORD * DstBuffer, const DWORD * SrcBuffer, const DWORD * KeyAddress, DWORD Length, DWORD *IVector);
|
||||
|
||||
int DES_Encrypt(DWORD *DstBuffer, const DWORD * SrcBuffer, const DWORD *KeyAddress, DWORD Length, DWORD *IVector);
|
||||
int DES_Decrypt(DWORD *DstBuffer, const DWORD * SrcBuffer, const DWORD *KeyAddress, DWORD Length, DWORD *IVector);
|
||||
@@ -1,280 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "DES_table.h"
|
||||
|
||||
#define DES_ECB_ENCRYPT 0
|
||||
#define DES_ECB_DECRYPT 1
|
||||
|
||||
// DES ECB encryption code
|
||||
extern DWORD SP_boxes[8][64];
|
||||
//extern DWORD KeyPerm[8][64];
|
||||
|
||||
/*
|
||||
* Macroses to transform array of 4 bytes to 32-bit dwords
|
||||
* (and reverse) without depending on the Little-Endian or
|
||||
* Big-Endian processor's architecture
|
||||
*/
|
||||
#define BYTES_TO_DWORD(b,d) (d = ((DWORD)(*((b)++))), \
|
||||
d |= ((DWORD)(*((b)++)))<< 8, \
|
||||
d |= ((DWORD)(*((b)++)))<<16, \
|
||||
d |= ((DWORD)(*((b)++)))<<24)
|
||||
|
||||
#define DWORD_TO_4BYTES(d,b) (*((b)++)=(BYTE)(((d) )&0xff), \
|
||||
*((b)++)=(BYTE)(((d)>> 8)&0xff), \
|
||||
*((b)++)=(BYTE)(((d)>>16)&0xff), \
|
||||
*((b)++)=(BYTE)(((d)>>24)&0xff))
|
||||
|
||||
/*
|
||||
* First of all, take into accounts the bytes and bites ordering
|
||||
* used in DES:
|
||||
*
|
||||
* DES: 1 2 3 4 5 6 7 8 .... 57 58 59 60 61 62 63 64
|
||||
* INTEL: 63 62 61 60 59 58 57 56 .... 7 6 5 4 3 2 1 0
|
||||
*
|
||||
* According to the DES, every 8-th bits is not used:
|
||||
* for DES the bites 8, 16, 32, ..., 64 are excluded,
|
||||
* for INTEL: 56, 48, 40, ..., 0 are excluded
|
||||
*
|
||||
* According to the above rool of numbering, the tables
|
||||
* used in DES (for Initial Permutation, Final Permutation,
|
||||
* Key Permutation, Compression Permutation, Expansion
|
||||
* Permutation and P-Box permutation) have to be re-written.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Some main ideas used to optimize DES software
|
||||
implementation:
|
||||
|
||||
a). Do not make an Expansion Permutation of 32-bit to
|
||||
48 bit (32-bit of data - right half of 64-bit of data),
|
||||
but make a correspondent preparation of the Key. So,
|
||||
the step of Expansion Permutation and XORing 48 bit of
|
||||
Expanded data and 48 bit of Compressed key will be
|
||||
replaced by 2 XOR operations: 32 bit of data XOR first
|
||||
32 bit part of prepeared key, then, the same 32 bit of
|
||||
data XOR second 32-bit part of prepeared key
|
||||
|
||||
b). Combine S-Box Substitution and P-Box Permutation
|
||||
operations.
|
||||
|
||||
c). For the best performance 56-bit encryption key
|
||||
have to be extendended to 128-byte array, i.e. for each
|
||||
of 16 rounds of DES we prepare a unique pair of two
|
||||
32-bit (4-bytes) words (see 'a)' above).
|
||||
|
||||
d). We can use XOR, SHIFT, AND operations to swap
|
||||
bits between words. For example, we have:
|
||||
|
||||
word A word B
|
||||
0 1 2 3 4 5 6 7
|
||||
|
||||
We want to get:
|
||||
|
||||
word A word B
|
||||
0 4 2 6 1 5 3 7
|
||||
|
||||
First, shift word A to get bites 1, 3 on the "right place"
|
||||
|
||||
word TMP = (word A) >> 1 = 1 2 3 -
|
||||
|
||||
TMP = TMP ^ B = 1^4 2^5 3^6 7
|
||||
|
||||
we don't want to change bits 5 and 7 in the B word, so
|
||||
|
||||
TMP = TMP & MASK = TMP & 1010 = 1^4 - 3^6 -
|
||||
|
||||
now we can easy get the word B:
|
||||
|
||||
B = B ^ TMP = (4 5 6 7) ^ (1^4 - 3^6 -) = 1 5 3 7
|
||||
|
||||
if we shift our "masking" TMP word reverse - we get
|
||||
a mask for A word:
|
||||
|
||||
TMP = TMP << 1 = - 1^4 - 3^6
|
||||
|
||||
now we can easy get the word A:
|
||||
|
||||
A = A ^ TMP = (0 1 2 3) ^ (- 1^4 - 3^6) = 0 4 2 6
|
||||
|
||||
The example above may be used to swap not only single
|
||||
bits, but also bit sequencies. In this case you should
|
||||
use shift on the value, equal to the number of bits
|
||||
in pattern.
|
||||
|
||||
As you see, all this opearations may be written like:
|
||||
TMP = ((A >> size) ^ B) & mask;
|
||||
B ^ = TMP;
|
||||
A ^= TMP << size;
|
||||
*/
|
||||
|
||||
#define PERMUTATION(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
|
||||
(b)^=(t),\
|
||||
(a)^=((t)<<(n)))
|
||||
|
||||
#define HPERMUTATION(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
|
||||
(a)=(a)^(t)^(t>>(16-(n))))
|
||||
|
||||
#define D_ENCRYPT(Left, Right, Ks, Num, TmpA, TmpB) \
|
||||
TmpA = (Right ^ Ks[Num ]); \
|
||||
TmpB = (Right ^ Ks[Num+1]); \
|
||||
TmpB = ((TmpB >> 4) + (TmpB << 28)); \
|
||||
Left ^= SP_boxes[1][(TmpB )&0x3f]| \
|
||||
SP_boxes[3][(TmpB>> 8)&0x3f]| \
|
||||
SP_boxes[5][(TmpB>>16)&0x3f]| \
|
||||
SP_boxes[7][(TmpB>>24)&0x3f]| \
|
||||
SP_boxes[0][(TmpA )&0x3f]| \
|
||||
SP_boxes[2][(TmpA>> 8)&0x3f]| \
|
||||
SP_boxes[4][(TmpA>>16)&0x3f]| \
|
||||
SP_boxes[6][(TmpA>>24)&0x3f];
|
||||
|
||||
void DES_ECB_mode(BYTE * Input, /* 8 bytes of input data */
|
||||
BYTE * Output, /* 8 bytes of output data */
|
||||
const DWORD * KeySchedule, /* [16][2] array of DWORDs */
|
||||
BYTE Operation) /* DES_ECB_ENCRYPT or DES_ECB_DECRYPT */
|
||||
{
|
||||
static BYTE * bInp, * bOut;
|
||||
static DWORD dwLeft, dwRigh, dwTmp, dwTmp1;
|
||||
|
||||
bInp = Input;
|
||||
bOut = Output;
|
||||
|
||||
BYTES_TO_DWORD(bInp, dwLeft);
|
||||
BYTES_TO_DWORD(bInp, dwRigh);
|
||||
|
||||
/* Initial Permutation */
|
||||
PERMUTATION(dwRigh, dwLeft, dwTmp, 4, 0x0f0f0f0f);
|
||||
PERMUTATION(dwLeft, dwRigh, dwTmp,16, 0x0000ffff);
|
||||
PERMUTATION(dwRigh, dwLeft, dwTmp, 2, 0x33333333);
|
||||
PERMUTATION(dwLeft, dwRigh, dwTmp, 8, 0x00ff00ff);
|
||||
PERMUTATION(dwRigh, dwLeft, dwTmp, 1, 0x55555555);
|
||||
|
||||
/* dwRigh and dwLeft has reversed bit orders - itwill be taken
|
||||
into account in the next step */
|
||||
|
||||
/* The initial rotate is done outside the loop. This required the
|
||||
* SP_boxes values to be rotated 1 bit to the right.
|
||||
*/
|
||||
dwTmp = (dwRigh<<1) | (dwRigh>>31);
|
||||
dwRigh = (dwLeft<<1) | (dwLeft>>31);
|
||||
dwLeft = dwTmp;
|
||||
|
||||
/* clear the top bits on machines with 8byte longs */
|
||||
dwLeft &= 0xffffffff;
|
||||
dwRigh &= 0xffffffff;
|
||||
|
||||
if (Operation == DES_ECB_ENCRYPT)
|
||||
{ /* Key order */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 0, dwTmp, dwTmp1); /* 1 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 2, dwTmp, dwTmp1); /* 2 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 4, dwTmp, dwTmp1); /* 3 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 6, dwTmp, dwTmp1); /* 4 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 8, dwTmp, dwTmp1); /* 5 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 10, dwTmp, dwTmp1); /* 6 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 12, dwTmp, dwTmp1); /* 7 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 14, dwTmp, dwTmp1); /* 8 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 16, dwTmp, dwTmp1); /* 9 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 18, dwTmp, dwTmp1); /* 10 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 20, dwTmp, dwTmp1); /* 11 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 22, dwTmp, dwTmp1); /* 12 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 24, dwTmp, dwTmp1); /* 13 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 26, dwTmp, dwTmp1); /* 14 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 28, dwTmp, dwTmp1); /* 15 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 30, dwTmp, dwTmp1); /* 16 */
|
||||
}
|
||||
else
|
||||
{
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 30, dwTmp, dwTmp1); /* 16 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 28, dwTmp, dwTmp1); /* 15 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 26, dwTmp, dwTmp1); /* 14 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 24, dwTmp, dwTmp1); /* 13 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 22, dwTmp, dwTmp1); /* 12 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 20, dwTmp, dwTmp1); /* 11 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 18, dwTmp, dwTmp1); /* 10 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 16, dwTmp, dwTmp1); /* 9 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 14, dwTmp, dwTmp1); /* 8 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 12, dwTmp, dwTmp1); /* 7 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 10, dwTmp, dwTmp1); /* 6 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 8, dwTmp, dwTmp1); /* 5 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 6, dwTmp, dwTmp1); /* 4 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 4, dwTmp, dwTmp1); /* 3 */
|
||||
D_ENCRYPT(dwLeft, dwRigh, KeySchedule, 2, dwTmp, dwTmp1); /* 2 */
|
||||
D_ENCRYPT(dwRigh, dwLeft, KeySchedule, 0, dwTmp, dwTmp1); /* 1 */
|
||||
}
|
||||
|
||||
dwLeft = (dwLeft>>1) | (dwLeft<<31);
|
||||
dwRigh = (dwRigh>>1) | (dwRigh<<31);
|
||||
|
||||
/* clear the top bits on machines with 8byte longs */
|
||||
dwLeft &= 0xffffffff;
|
||||
dwRigh &= 0xffffffff;
|
||||
|
||||
/*
|
||||
* Do we need to swap dwLeft and dwRigh?
|
||||
* We have not to do the swap
|
||||
* (We remember they are reversed)
|
||||
* So - all we have to do is to make a correspondent Final Permutation
|
||||
*/
|
||||
|
||||
PERMUTATION(dwRigh, dwLeft, dwTmp, 1,0x55555555);
|
||||
PERMUTATION(dwLeft, dwRigh, dwTmp, 8,0x00ff00ff);
|
||||
PERMUTATION(dwRigh, dwLeft, dwTmp, 2,0x33333333);
|
||||
PERMUTATION(dwLeft, dwRigh, dwTmp,16,0x0000ffff);
|
||||
PERMUTATION(dwRigh, dwLeft, dwTmp, 4,0x0f0f0f0f);
|
||||
|
||||
/* Place our two 32-bits results into 8 bytes of output data */
|
||||
DWORD_TO_4BYTES(dwLeft, bOut);
|
||||
DWORD_TO_4BYTES(dwRigh, bOut);
|
||||
}
|
||||
|
||||
//************ DES CBC mode encryption **************
|
||||
int DES_Encrypt(DWORD *DstBuffer, const DWORD * SrcBuffer, const DWORD *KeyAddress, DWORD Length, DWORD *IVector)
|
||||
{
|
||||
DWORD i;
|
||||
DWORD buffer[2];
|
||||
|
||||
buffer[0] = IVector[0];
|
||||
buffer[1] = IVector[1];
|
||||
|
||||
for (i = 0; i < (Length >> 2); i = i+2)
|
||||
{
|
||||
// do EBC encryption of (Initial_Vector XOR Data)
|
||||
buffer[0] ^= SrcBuffer[i];
|
||||
buffer[1] ^= SrcBuffer[i+1];
|
||||
|
||||
DES_ECB_mode((BYTE *) buffer, (BYTE *) buffer, KeyAddress, DES_ECB_ENCRYPT);
|
||||
|
||||
DstBuffer[i] = buffer[0];
|
||||
DstBuffer[i+1] = buffer[1];
|
||||
}
|
||||
|
||||
return Length;
|
||||
}
|
||||
|
||||
//************ DES CBC mode decryption **************
|
||||
int DES_Decrypt(DWORD *DstBuffer, const DWORD * SrcBuffer, const DWORD *KeyAddress, DWORD Length, DWORD *IVector)
|
||||
{
|
||||
DWORD i;
|
||||
DWORD buffer[2], ivectorL, ivectorR, oldSrcL, oldSrcR;
|
||||
|
||||
ivectorL = IVector[0];
|
||||
ivectorR = IVector[1];
|
||||
|
||||
for (i = 0; i < (Length >> 2); i = i + 2)
|
||||
{
|
||||
buffer[0] = oldSrcL = SrcBuffer[i];
|
||||
buffer[1] = oldSrcR = SrcBuffer[i+1];
|
||||
|
||||
// Encrypted Data -> new IV,
|
||||
// then do EBC decryption of Encrypted Data,
|
||||
// then XOR decrypted data with old IV
|
||||
DES_ECB_mode((BYTE *)buffer, (BYTE *)buffer, KeyAddress, DES_ECB_DECRYPT);
|
||||
|
||||
DstBuffer[i] = buffer[0] ^ ivectorL;
|
||||
DstBuffer[i+1] = buffer[1] ^ ivectorR;
|
||||
|
||||
ivectorL = oldSrcL;
|
||||
ivectorR = oldSrcR;
|
||||
}
|
||||
|
||||
return Length;
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
static unsigned char const k8[16] = { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 };
|
||||
static unsigned char const k7[16] = { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 };
|
||||
static unsigned char const k6[16] = { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 };
|
||||
static unsigned char const k5[16] = { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 };
|
||||
static unsigned char const k4[16] = { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 };
|
||||
static unsigned char const k3[16] = { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 };
|
||||
static unsigned char const k2[16] = { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 };
|
||||
static unsigned char const k1[16] = { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 };
|
||||
|
||||
/* Byte-at-a-time substitution boxes */
|
||||
static unsigned char k87[256];
|
||||
static unsigned char k65[256];
|
||||
static unsigned char k43[256];
|
||||
static unsigned char k21[256];
|
||||
|
||||
void GOST_Init()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
k87[i] = k8[i >> 4] << 4 | k7[i & 15];
|
||||
k65[i] = k6[i >> 4] << 4 | k5[i & 15];
|
||||
k43[i] = k4[i >> 4] << 4 | k3[i & 15];
|
||||
k21[i] = k2[i >> 4] << 4 | k1[i & 15];
|
||||
}
|
||||
}
|
||||
|
||||
INLINE static DWORD f(DWORD x)
|
||||
{
|
||||
x = k87[x >> 24 & 255] << 24 | k65[x >> 16 & 255] << 16 | k43[x >> 8 & 255] << 8 | k21[x & 255];
|
||||
return x << 11 | x >> (32 - 11);
|
||||
}
|
||||
|
||||
int GOST_Encrypt(DWORD * DstBuffer, const DWORD * SrcBuffer, const DWORD * KeyAddress, DWORD Length, DWORD *IVector)
|
||||
{
|
||||
DWORD i;
|
||||
DWORD N1,N2;
|
||||
|
||||
N1 = IVector[0];
|
||||
N2 = IVector[1];
|
||||
|
||||
for (i = 0; i < (Length >> 2); i = i+2)
|
||||
{
|
||||
DWORD n1, n2; // As named in the GOST
|
||||
|
||||
n1 = N1;
|
||||
n2 = N2;
|
||||
|
||||
// Instead of swapping halves, swap names each round
|
||||
n2 ^= f(n1+KeyAddress[0]);
|
||||
n1 ^= f(n2+KeyAddress[1]);
|
||||
n2 ^= f(n1+KeyAddress[2]);
|
||||
n1 ^= f(n2+KeyAddress[3]);
|
||||
n2 ^= f(n1+KeyAddress[4]);
|
||||
n1 ^= f(n2+KeyAddress[5]);
|
||||
n2 ^= f(n1+KeyAddress[6]);
|
||||
n1 ^= f(n2+KeyAddress[7]);
|
||||
|
||||
n2 ^= f(n1+KeyAddress[0]);
|
||||
n1 ^= f(n2+KeyAddress[1]);
|
||||
n2 ^= f(n1+KeyAddress[2]);
|
||||
n1 ^= f(n2+KeyAddress[3]);
|
||||
n2 ^= f(n1+KeyAddress[4]);
|
||||
n1 ^= f(n2+KeyAddress[5]);
|
||||
n2 ^= f(n1+KeyAddress[6]);
|
||||
n1 ^= f(n2+KeyAddress[7]);
|
||||
|
||||
n2 ^= f(n1+KeyAddress[0]);
|
||||
n1 ^= f(n2+KeyAddress[1]);
|
||||
n2 ^= f(n1+KeyAddress[2]);
|
||||
n1 ^= f(n2+KeyAddress[3]);
|
||||
n2 ^= f(n1+KeyAddress[4]);
|
||||
n1 ^= f(n2+KeyAddress[5]);
|
||||
n2 ^= f(n1+KeyAddress[6]);
|
||||
n1 ^= f(n2+KeyAddress[7]);
|
||||
|
||||
n2 ^= f(n1+KeyAddress[7]);
|
||||
n1 ^= f(n2+KeyAddress[6]);
|
||||
n2 ^= f(n1+KeyAddress[5]);
|
||||
n1 ^= f(n2+KeyAddress[4]);
|
||||
n2 ^= f(n1+KeyAddress[3]);
|
||||
n1 ^= f(n2+KeyAddress[2]);
|
||||
n2 ^= f(n1+KeyAddress[1]);
|
||||
n1 ^= f(n2+KeyAddress[0]);
|
||||
|
||||
N1 = n2;
|
||||
N2 = n1;
|
||||
//GOST_ECB_Encrypt(&N1, &N2, KeyAddress);
|
||||
// XOR plaintext with initial vector,
|
||||
// move rezult to ciphertext and to initial vector
|
||||
DstBuffer[i] = SrcBuffer[i] ^ N1;
|
||||
N1 = DstBuffer[i];
|
||||
|
||||
DstBuffer[i+1] = SrcBuffer[i+1] ^ N2;
|
||||
N2 = DstBuffer[i+1];
|
||||
}
|
||||
|
||||
return Length;
|
||||
}
|
||||
|
||||
|
||||
// ************ GOST CBC decryption **************
|
||||
int GOST_Decrypt(DWORD * DstBuffer, const DWORD * SrcBuffer, const DWORD * KeyAddress, DWORD Length, DWORD *IVector)
|
||||
{
|
||||
DWORD i;
|
||||
DWORD N1, N2, dwTmp;
|
||||
|
||||
N1 = IVector[0];
|
||||
N2 = IVector[1];
|
||||
|
||||
for (i = 0; i < (Length >> 2); i = i + 2)
|
||||
{
|
||||
DWORD n1, n2; // As named in the GOST
|
||||
|
||||
n1 = N1;
|
||||
n2 = N2;
|
||||
|
||||
// Instead of swapping halves, swap names each round
|
||||
n2 ^= f(n1+KeyAddress[0]);
|
||||
n1 ^= f(n2+KeyAddress[1]);
|
||||
n2 ^= f(n1+KeyAddress[2]);
|
||||
n1 ^= f(n2+KeyAddress[3]);
|
||||
n2 ^= f(n1+KeyAddress[4]);
|
||||
n1 ^= f(n2+KeyAddress[5]);
|
||||
n2 ^= f(n1+KeyAddress[6]);
|
||||
n1 ^= f(n2+KeyAddress[7]);
|
||||
|
||||
n2 ^= f(n1+KeyAddress[0]);
|
||||
n1 ^= f(n2+KeyAddress[1]);
|
||||
n2 ^= f(n1+KeyAddress[2]);
|
||||
n1 ^= f(n2+KeyAddress[3]);
|
||||
n2 ^= f(n1+KeyAddress[4]);
|
||||
n1 ^= f(n2+KeyAddress[5]);
|
||||
n2 ^= f(n1+KeyAddress[6]);
|
||||
n1 ^= f(n2+KeyAddress[7]);
|
||||
|
||||
n2 ^= f(n1+KeyAddress[0]);
|
||||
n1 ^= f(n2+KeyAddress[1]);
|
||||
n2 ^= f(n1+KeyAddress[2]);
|
||||
n1 ^= f(n2+KeyAddress[3]);
|
||||
n2 ^= f(n1+KeyAddress[4]);
|
||||
n1 ^= f(n2+KeyAddress[5]);
|
||||
n2 ^= f(n1+KeyAddress[6]);
|
||||
n1 ^= f(n2+KeyAddress[7]);
|
||||
|
||||
n2 ^= f(n1+KeyAddress[7]);
|
||||
n1 ^= f(n2+KeyAddress[6]);
|
||||
n2 ^= f(n1+KeyAddress[5]);
|
||||
n1 ^= f(n2+KeyAddress[4]);
|
||||
n2 ^= f(n1+KeyAddress[3]);
|
||||
n1 ^= f(n2+KeyAddress[2]);
|
||||
n2 ^= f(n1+KeyAddress[1]);
|
||||
n1 ^= f(n2+KeyAddress[0]);
|
||||
|
||||
// There is no swap after the last round
|
||||
N1 = n2;
|
||||
N2 = n1;
|
||||
//GOST_ECB_Encrypt(&N1, &N2, KeyAddress);
|
||||
// XOR encrypted text with encrypted initial vector (we get rezult - decrypted text),
|
||||
// move encrypted text to new initial vector.
|
||||
// We need dwTmp because SrcBuffer may be the same as DstBuffer
|
||||
dwTmp = SrcBuffer[i] ^ N1;
|
||||
N1 = SrcBuffer[i];
|
||||
DstBuffer[i] = dwTmp;
|
||||
|
||||
dwTmp = SrcBuffer[i+1] ^ N2;
|
||||
N2 = SrcBuffer[i+1];
|
||||
DstBuffer[i+1] = dwTmp;
|
||||
}
|
||||
|
||||
return Length;
|
||||
}
|
||||
|
||||
@@ -1,411 +0,0 @@
|
||||
/*
|
||||
* The GOST 28147-89 cipher
|
||||
*
|
||||
* This is based on the 25 Movember 1993 draft translation
|
||||
* by Aleksandr Malchik, with Whitfield Diffie, of the Government
|
||||
* Standard of the U.S.S.R. GOST 28149-89, "Cryptographic Transformation
|
||||
* Algorithm", effective 1 July 1990. (Whitfield.Diffie@eng.sun.com)
|
||||
*
|
||||
* That is a draft, and may contain errors, which will be faithfully
|
||||
* reflected here, along with possible exciting new bugs.
|
||||
*
|
||||
* Some details have been cleared up by the paper "Soviet Encryption
|
||||
* Algorithm" by Josef Pieprzyk and Leonid Tombak of the University
|
||||
* of Wollongong, New South Wales. (josef/leo@cs.adfa.oz.au)
|
||||
*
|
||||
* The standard is written by A. Zabotin (project leader), G.P. Glazkov,
|
||||
* and V.B. Isaeva. It was accepted and introduced into use by the
|
||||
* action of the State Standards Committee of the USSR on 2 June 89 as
|
||||
* No. 1409. It was to be reviewed in 1993, but whether anyone wishes
|
||||
* to take on this obligation from the USSR is questionable.
|
||||
*
|
||||
* This code is placed in the public domain.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If you read the standard, it belabors the point of copying corresponding
|
||||
* bits from point A to point B quite a bit. It helps to understand that
|
||||
* the standard is uniformly little-endian, although it numbers bits from
|
||||
* 1 rather than 0, so bit n has value 2^(n-1). The least significant bit
|
||||
* of the 32-bit words that are manipulated in the algorithm is the first,
|
||||
* lowest-numbered, in the bit string.
|
||||
*/
|
||||
|
||||
|
||||
/* A 32-bit data type */
|
||||
#ifdef __alpha /* Any other 64-bit machines? */
|
||||
typedef unsigned int word32;
|
||||
#else
|
||||
typedef unsigned long word32;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The standard does not specify the contents of the 8 4 bit->4 bit
|
||||
* substitution boxes, saying they're a parameter of the network
|
||||
* being set up. For illustration purposes here, I have used
|
||||
* the first rows of the 8 S-boxes from the DES. (Note that the
|
||||
* DES S-boxes are numbered starting from 1 at the msb. In keeping
|
||||
* with the rest of the GOST, I have used little-endian numbering.
|
||||
* Thus, k8 is S-box 1.
|
||||
*
|
||||
* Obviously, a careful look at the cryptographic properties of the cipher
|
||||
* must be undertaken before "production" substitution boxes are defined.
|
||||
*
|
||||
* The standard also does not specify a standard bit-string representation
|
||||
* for the contents of these blocks.
|
||||
*/
|
||||
static unsigned char const k8[16] = { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 };
|
||||
static unsigned char const k7[16] = { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 };
|
||||
static unsigned char const k6[16] = { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 };
|
||||
static unsigned char const k5[16] = { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 };
|
||||
static unsigned char const k4[16] = { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 };
|
||||
static unsigned char const k3[16] = { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 };
|
||||
static unsigned char const k2[16] = { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 };
|
||||
static unsigned char const k1[16] = { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 };
|
||||
|
||||
/* Byte-at-a-time substitution boxes */
|
||||
static unsigned char k87[256];
|
||||
static unsigned char k65[256];
|
||||
static unsigned char k43[256];
|
||||
static unsigned char k21[256];
|
||||
|
||||
/*
|
||||
* Build byte-at-a-time subtitution tables.
|
||||
* This must be called once for global setup.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
void kboxinit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
k87[i] = k8[i >> 4] << 4 | k7[i & 15];
|
||||
k65[i] = k6[i >> 4] << 4 | k5[i & 15];
|
||||
k43[i] = k4[i >> 4] << 4 | k3[i & 15];
|
||||
k21[i] = k2[i >> 4] << 4 | k1[i & 15];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the substitution and rotation that are the core of the operation,
|
||||
* like the expansion, substitution and permutation of the DES.
|
||||
* It would be possible to perform DES-like optimisations and store
|
||||
* the table entries as 32-bit words, already rotated, but the
|
||||
* efficiency gain is questionable.
|
||||
*
|
||||
* This should be inlined for maximum speed
|
||||
*/
|
||||
#if __GNUC__
|
||||
__inline__
|
||||
#endif
|
||||
static word32 f(word32 x)
|
||||
{
|
||||
/* Do substitutions */
|
||||
#if 0
|
||||
/* This is annoyingly slow */
|
||||
x = k8[x>>28 & 15] << 28 | k7[x>>24 & 15] << 24 |
|
||||
k6[x>>20 & 15] << 20 | k5[x>>16 & 15] << 16 |
|
||||
k4[x>>12 & 15] << 12 | k3[x>> 8 & 15] << 8 |
|
||||
k2[x>> 4 & 15] << 4 | k1[x & 15];
|
||||
#else
|
||||
/* This is faster */
|
||||
x = k87[x>>24 & 255] << 24 | k65[x>>16 & 255] << 16 | k43[x>> 8 & 255] << 8 | k21[x & 255];
|
||||
#endif
|
||||
|
||||
/* Rotate left 11 bits */
|
||||
return x << 11 | x >> (32 - 11);
|
||||
}
|
||||
|
||||
/*
|
||||
* The GOST standard defines the input in terms of bits 1..64, with
|
||||
* bit 1 being the lsb of in[0] and bit 64 being the msb of in[1].
|
||||
*
|
||||
* The keys are defined similarly, with bit 256 being the msb of key[7].
|
||||
*/
|
||||
void gostcrypt(word32 const in[2], word32 out[2], word32 const key[8])
|
||||
{
|
||||
word32 n1, n2; /* As named in the GOST */
|
||||
|
||||
n1 = in[0];
|
||||
n2 = in[1];
|
||||
|
||||
/* Instead of swapping halves, swap names each round */
|
||||
n2 ^= f(n1+key[0]);
|
||||
n1 ^= f(n2+key[1]);
|
||||
n2 ^= f(n1+key[2]);
|
||||
n1 ^= f(n2+key[3]);
|
||||
n2 ^= f(n1+key[4]);
|
||||
n1 ^= f(n2+key[5]);
|
||||
n2 ^= f(n1+key[6]);
|
||||
n1 ^= f(n2+key[7]);
|
||||
|
||||
n2 ^= f(n1+key[0]);
|
||||
n1 ^= f(n2+key[1]);
|
||||
n2 ^= f(n1+key[2]);
|
||||
n1 ^= f(n2+key[3]);
|
||||
n2 ^= f(n1+key[4]);
|
||||
n1 ^= f(n2+key[5]);
|
||||
n2 ^= f(n1+key[6]);
|
||||
n1 ^= f(n2+key[7]);
|
||||
|
||||
n2 ^= f(n1+key[0]);
|
||||
n1 ^= f(n2+key[1]);
|
||||
n2 ^= f(n1+key[2]);
|
||||
n1 ^= f(n2+key[3]);
|
||||
n2 ^= f(n1+key[4]);
|
||||
n1 ^= f(n2+key[5]);
|
||||
n2 ^= f(n1+key[6]);
|
||||
n1 ^= f(n2+key[7]);
|
||||
|
||||
n2 ^= f(n1+key[7]);
|
||||
n1 ^= f(n2+key[6]);
|
||||
n2 ^= f(n1+key[5]);
|
||||
n1 ^= f(n2+key[4]);
|
||||
n2 ^= f(n1+key[3]);
|
||||
n1 ^= f(n2+key[2]);
|
||||
n2 ^= f(n1+key[1]);
|
||||
n1 ^= f(n2+key[0]);
|
||||
|
||||
/* There is no swap after the last round */
|
||||
out[0] = n2;
|
||||
out[1] = n1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The key schedule is somewhat different for decryption.
|
||||
* (The key table is used once forward and three times backward.)
|
||||
* You could define an expanded key, or just write the code twice,
|
||||
* as done here.
|
||||
*/
|
||||
void gostdecrypt(word32 const in[2], word32 out[2], word32 const key[8])
|
||||
{
|
||||
word32 n1, n2; /* As named in the GOST */
|
||||
|
||||
n1 = in[0];
|
||||
n2 = in[1];
|
||||
|
||||
n2 ^= f(n1+key[0]);
|
||||
n1 ^= f(n2+key[1]);
|
||||
n2 ^= f(n1+key[2]);
|
||||
n1 ^= f(n2+key[3]);
|
||||
n2 ^= f(n1+key[4]);
|
||||
n1 ^= f(n2+key[5]);
|
||||
n2 ^= f(n1+key[6]);
|
||||
n1 ^= f(n2+key[7]);
|
||||
|
||||
n2 ^= f(n1+key[7]);
|
||||
n1 ^= f(n2+key[6]);
|
||||
n2 ^= f(n1+key[5]);
|
||||
n1 ^= f(n2+key[4]);
|
||||
n2 ^= f(n1+key[3]);
|
||||
n1 ^= f(n2+key[2]);
|
||||
n2 ^= f(n1+key[1]);
|
||||
n1 ^= f(n2+key[0]);
|
||||
|
||||
n2 ^= f(n1+key[7]);
|
||||
n1 ^= f(n2+key[6]);
|
||||
n2 ^= f(n1+key[5]);
|
||||
n1 ^= f(n2+key[4]);
|
||||
n2 ^= f(n1+key[3]);
|
||||
n1 ^= f(n2+key[2]);
|
||||
n2 ^= f(n1+key[1]);
|
||||
n1 ^= f(n2+key[0]);
|
||||
|
||||
n2 ^= f(n1+key[7]);
|
||||
n1 ^= f(n2+key[6]);
|
||||
n2 ^= f(n1+key[5]);
|
||||
n1 ^= f(n2+key[4]);
|
||||
n2 ^= f(n1+key[3]);
|
||||
n1 ^= f(n2+key[2]);
|
||||
n2 ^= f(n1+key[1]);
|
||||
n1 ^= f(n2+key[0]);
|
||||
|
||||
out[0] = n2;
|
||||
out[1] = n1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The GOST "Output feedback" standard. It seems closer morally
|
||||
* to the counter feedback mode some people have proposed for DES.
|
||||
* The avoidance of the short cycles that are possible in OFB seems
|
||||
* like a Good Thing.
|
||||
*
|
||||
* Calling it the stream mode makes more sense.
|
||||
*
|
||||
* The IV is encrypted with the key to produce the initial counter value.
|
||||
* Then, for each output block, a constant is added, modulo 2^32-1
|
||||
* (0 is represented as all-ones, not all-zeros), to each half of
|
||||
* the counter, and the counter is encrypted to produce the value
|
||||
* to XOR with the output.
|
||||
*
|
||||
* Len is the number of blocks. Sub-block encryption is
|
||||
* left as an exercise for the user. Remember that the
|
||||
* standard defines everything in a little-endian manner,
|
||||
* so you want to use the low bit of gamma[0] first.
|
||||
*
|
||||
* OFB is, of course, self-inverse, so there is only one function.
|
||||
*/
|
||||
|
||||
/* The constants for addition */
|
||||
#define C1 0x01010104
|
||||
#define C2 0x01010101
|
||||
|
||||
void gostofb(word32 const *in, word32 *out, int len, word32 const iv[2], word32 const key[8])
|
||||
{
|
||||
word32 temp[2]; /* Counter */
|
||||
word32 gamma[2]; /* Output XOR value */
|
||||
|
||||
/* Compute starting value for counter */
|
||||
gostcrypt(iv, temp, key);
|
||||
|
||||
while (len--)
|
||||
{
|
||||
temp[0] += C2;
|
||||
|
||||
if (temp[0] < C2) /* Wrap modulo 2^32? */
|
||||
temp[0]++; /* Make it modulo 2^32-1 */
|
||||
|
||||
temp[1] += C1;
|
||||
|
||||
if (temp[1] < C1) /* Wrap modulo 2^32? */
|
||||
temp[1]++; /* Make it modulo 2^32-1 */
|
||||
|
||||
gostcrypt(temp, gamma, key);
|
||||
|
||||
*out++ = *in++ ^ gamma[0];
|
||||
*out++ = *in++ ^ gamma[1];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The CFB mode is just what you'd expect. Each block of ciphertext y[] is
|
||||
* derived from the input x[] by the following pseudocode:
|
||||
* y[i] = x[i] ^ gostcrypt(y[i-1])
|
||||
* x[i] = y[i] ^ gostcrypt(y[i-1])
|
||||
* Where y[-1] is the IV.
|
||||
*
|
||||
* The IV is modified in place. Again, len is in *blocks*.
|
||||
*/
|
||||
|
||||
void gostcfbencrypt(word32 const *in, word32 *out, int len, word32 iv[2], word32 const key[8])
|
||||
{
|
||||
while (len--)
|
||||
{
|
||||
gostcrypt(iv, iv, key);
|
||||
iv[0] = *out++ ^= iv[0];
|
||||
iv[1] = *out++ ^= iv[1];
|
||||
}
|
||||
}
|
||||
|
||||
void gostcfbdecrypt(word32 const *in, word32 *out, int len, word32 iv[2], word32 const key[8])
|
||||
{
|
||||
word32 t;
|
||||
|
||||
while (len--)
|
||||
{
|
||||
gostcrypt(iv, iv, key);
|
||||
t = *out;
|
||||
*out++ ^= iv[0];
|
||||
iv[0] = t;
|
||||
t = *out;
|
||||
*out++ ^= iv[1];
|
||||
iv[1] = t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The message suthetication code uses only 16 of the 32 rounds.
|
||||
* There *is* a swap after the 16th round.
|
||||
* The last block should be padded to 64 bits with zeros.
|
||||
* len is the number of *blocks* in the input.
|
||||
*/
|
||||
void gostmac(word32 const *in, int len, word32 out[2], word32 const key[8])
|
||||
{
|
||||
word32 n1, n2; /* As named in the GOST */
|
||||
|
||||
n1 = 0;
|
||||
n2 = 0;
|
||||
|
||||
while (len--)
|
||||
{
|
||||
n1 ^= *in++;
|
||||
n2 = *in++;
|
||||
|
||||
/* Instead of swapping halves, swap names each round */
|
||||
n2 ^= f(n1+key[0]);
|
||||
n1 ^= f(n2+key[1]);
|
||||
n2 ^= f(n1+key[2]);
|
||||
n1 ^= f(n2+key[3]);
|
||||
n2 ^= f(n1+key[4]);
|
||||
n1 ^= f(n2+key[5]);
|
||||
n2 ^= f(n1+key[6]);
|
||||
n1 ^= f(n2+key[7]);
|
||||
|
||||
n2 ^= f(n1+key[0]);
|
||||
n1 ^= f(n2+key[1]);
|
||||
n2 ^= f(n1+key[2]);
|
||||
n1 ^= f(n2+key[3]);
|
||||
n2 ^= f(n1+key[4]);
|
||||
n1 ^= f(n2+key[5]);
|
||||
n2 ^= f(n1+key[6]);
|
||||
n1 ^= f(n2+key[7]);
|
||||
}
|
||||
|
||||
out[0] = n1;
|
||||
out[1] = n2;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Designed to cope with 15-bit rand() implementations */
|
||||
#define RAND32 ((word32)rand() << 17 ^ (word32)rand() << 9 ^ rand())
|
||||
|
||||
int main(void)
|
||||
{
|
||||
word32 key[8];
|
||||
word32 plain[2];
|
||||
word32 cipher[2];
|
||||
int i, j;
|
||||
|
||||
kboxinit();
|
||||
|
||||
printf("GOST 21847-89 test driver.\n");
|
||||
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
key[j] = RAND32;
|
||||
|
||||
plain[0] = RAND32;
|
||||
plain[1] = RAND32;
|
||||
|
||||
printf("%3d\r", i);
|
||||
fflush(stdout);
|
||||
|
||||
gostcrypt(plain, cipher, key);
|
||||
|
||||
for (j = 0; j < 99; j++)
|
||||
gostcrypt(cipher, cipher, key);
|
||||
|
||||
for (j = 0; j < 100; j++)
|
||||
gostdecrypt(cipher, cipher, key);
|
||||
|
||||
if (plain[0] != cipher[0] || plain[1] != cipher[1])
|
||||
{
|
||||
fprintf(stderr, "\nError! i = %d\n", i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("All tests passed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#include <atomic>
|
||||
|
||||
extern void GOST_Init();
|
||||
|
||||
LPHEART thecore_heart = NULL;
|
||||
|
||||
std::atomic<int> shutdowned = FALSE;
|
||||
@@ -60,8 +58,6 @@ int thecore_init(int fps, HEARTFUNC heartbeat_func)
|
||||
if (!pid_init())
|
||||
return false;
|
||||
|
||||
GOST_Init();
|
||||
|
||||
thecore_heart = heart_new(1000000 / fps, heartbeat_func);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -122,5 +122,4 @@ inline double rint(double x)
|
||||
#include "log.h"
|
||||
#include "main.h"
|
||||
#include "utils.h"
|
||||
#include "crypt.h"
|
||||
#include "memcpy.h"
|
||||
|
||||
@@ -1,341 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
/*
|
||||
* luau (Lib Update/Auto-Update): Simple Update Library
|
||||
* Copyright (C) 2003 David Eklund
|
||||
*
|
||||
* - This library is free software; you can redistribute it and/or -
|
||||
* - modify it under the terms of the GNU Lesser General Public -
|
||||
* - License as published by the Free Software Foundation; either -
|
||||
* - version 2.1 of the License, or (at your option) any later version. -
|
||||
* - -
|
||||
* - This library is distributed in the hope that it will be useful, -
|
||||
* - but WITHOUT ANY WARRANTY; without even the implied warranty of -
|
||||
* - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -
|
||||
* - Lesser General Public License for more details. -
|
||||
* - -
|
||||
* - You should have received a copy of the GNU Lesser General Public -
|
||||
* - License along with this library; if not, write to the Free Software -
|
||||
* - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -
|
||||
*/
|
||||
|
||||
/*
|
||||
* md5.h and md5.c are based off of md5hl.c, md5c.c, and md5.h from libmd, which in turn is
|
||||
* based off the FreeBSD libmd library. Their respective copyright notices follow:
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: md5.c,v 1.1.1.1 2004/04/02 05:11:38 deklund2 Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xmd5.h"
|
||||
|
||||
#if __BYTE_ORDER == 1234
|
||||
#define byteReverse(buf, len) /* Nothing */
|
||||
#else
|
||||
void byteReverse(unsigned char *buf, unsigned longs);
|
||||
|
||||
/*
|
||||
* Note: this code is harmless on little-endian machines.
|
||||
*/
|
||||
void byteReverse(unsigned char *buf, unsigned longs)
|
||||
{
|
||||
uint32_t t;
|
||||
do {
|
||||
t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
||||
((unsigned) buf[1] << 8 | buf[0]);
|
||||
*(uint32_t *) buf = t;
|
||||
buf += 4;
|
||||
} while (--longs);
|
||||
}
|
||||
#endif /* ! __BYTE_ORDER == 1234 */
|
||||
|
||||
|
||||
|
||||
|
||||
char *
|
||||
lutil_md5_file (const char *filename, char *buf)
|
||||
{
|
||||
unsigned char buffer[BUFSIZ];
|
||||
MD5_CTX ctx;
|
||||
int f,i,j;
|
||||
|
||||
MD5Init(&ctx);
|
||||
|
||||
#ifndef OS_WINDOWS
|
||||
f = open(filename,O_RDONLY);
|
||||
#else
|
||||
f = _open(filename, _O_RDONLY);
|
||||
#endif
|
||||
if (f < 0) return 0;
|
||||
while ((i = read(f,buffer,sizeof buffer)) > 0) {
|
||||
MD5Update(&ctx,buffer,i);
|
||||
}
|
||||
j = errno;
|
||||
close(f);
|
||||
errno = j;
|
||||
if (i < 0) return 0;
|
||||
return MD5End(&ctx, buf);
|
||||
}
|
||||
|
||||
char *
|
||||
lutil_md5_data (const unsigned char *data, unsigned int len, char *buf)
|
||||
{
|
||||
MD5_CTX ctx;
|
||||
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx,data,len);
|
||||
return MD5End(&ctx, buf);
|
||||
}
|
||||
|
||||
|
||||
/* Non-Interface Methods */
|
||||
|
||||
/* from md5hl.c */
|
||||
|
||||
char *
|
||||
MD5End(MD5_CTX *ctx, char *buf)
|
||||
{
|
||||
int i;
|
||||
unsigned char digest[MD5_HASHBYTES];
|
||||
static const char hex[]="0123456789abcdef";
|
||||
|
||||
if (!buf)
|
||||
buf = (char*)malloc(33);
|
||||
if (!buf)
|
||||
return 0;
|
||||
MD5Final(digest,ctx);
|
||||
for (i=0;i<MD5_HASHBYTES;i++) {
|
||||
buf[i+i] = hex[digest[i] >> 4];
|
||||
buf[i+i+1] = hex[digest[i] & 0x0f];
|
||||
}
|
||||
buf[i+i] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
* initialization constants.
|
||||
*/
|
||||
void MD5Init(MD5_CTX *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update context to reflect the concatenation of another buffer full
|
||||
* of bytes.
|
||||
*/
|
||||
void MD5Update(MD5_CTX *ctx, unsigned char const *buf, unsigned len)
|
||||
{
|
||||
uint32_t t;
|
||||
|
||||
/* Update bitcount */
|
||||
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
|
||||
ctx->bits[1]++; /* Carry from low to high */
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||
|
||||
/* Handle any leading odd-sized chunks */
|
||||
|
||||
if (t) {
|
||||
unsigned char *p = (unsigned char *) ctx->in + t;
|
||||
|
||||
t = 64 - t;
|
||||
if (len < t) {
|
||||
memcpy(p, buf, len);
|
||||
return;
|
||||
}
|
||||
memcpy(p, buf, t);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
/* Process data in 64-byte chunks */
|
||||
|
||||
while (len >= 64) {
|
||||
memcpy(ctx->in, buf, 64);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
|
||||
memcpy(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||
*/
|
||||
void MD5Final(unsigned char digest[16], MD5_CTX *ctx)
|
||||
{
|
||||
unsigned count;
|
||||
unsigned char *p;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
|
||||
/* Set the first char of padding to 0x80. This is safe since there is
|
||||
always at least one byte free */
|
||||
p = ctx->in + count;
|
||||
*p++ = 0x80;
|
||||
|
||||
/* Bytes of padding needed to make 64 bytes */
|
||||
count = 64 - 1 - count;
|
||||
|
||||
/* Pad out to 56 mod 64 */
|
||||
if (count < 8) {
|
||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||
memset(p, 0, count);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
|
||||
|
||||
/* Now fill the next block with 56 bytes */
|
||||
memset(ctx->in, 0, 56);
|
||||
} else {
|
||||
/* Pad block to 56 bytes */
|
||||
memset(p, 0, count - 8);
|
||||
}
|
||||
byteReverse(ctx->in, 14);
|
||||
|
||||
/* Append length in bits and transform */
|
||||
((uint32_t *) ctx->in)[14] = ctx->bits[0];
|
||||
((uint32_t *) ctx->in)[15] = ctx->bits[1];
|
||||
|
||||
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
|
||||
byteReverse((unsigned char *) ctx->buf, 4);
|
||||
memcpy(digest, ctx->buf, 16);
|
||||
memset((char *) ctx, 0, sizeof(ctx)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
void MD5Transform(uint32_t buf[4], uint32_t const in[16])
|
||||
{
|
||||
uint32_t a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
#pragma once
|
||||
/*
|
||||
* luau (Lib Update/Auto-Update): Simple Update Library
|
||||
* Copyright (C) 2003 David Eklund
|
||||
*
|
||||
* - This library is free software; you can redistribute it and/or -
|
||||
* - modify it under the terms of the GNU Lesser General Public -
|
||||
* - License as published by the Free Software Foundation; either -
|
||||
* - version 2.1 of the License, or (at your option) any later version. -
|
||||
* - -
|
||||
* - This library is distributed in the hope that it will be useful, -
|
||||
* - but WITHOUT ANY WARRANTY; without even the implied warranty of -
|
||||
* - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -
|
||||
* - Lesser General Public License for more details. -
|
||||
* - -
|
||||
* - You should have received a copy of the GNU Lesser General Public -
|
||||
* - License along with this library; if not, write to the Free Software -
|
||||
* - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -
|
||||
*/
|
||||
|
||||
/*
|
||||
* md5.h and md5.c are based off of md5hl.c, md5c.c, and md5.h from libmd, which in turn are
|
||||
* based off the FreeBSD libmd library. Their respective copyright notices follow:
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: md5.h,v 1.1.1.1 2004/04/02 05:11:38 deklund2 Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define MD5_HASHBYTES 16
|
||||
|
||||
typedef struct MD5Context {
|
||||
uint32_t buf[4];
|
||||
uint32_t bits[2];
|
||||
unsigned char in[64];
|
||||
} MD5_CTX;
|
||||
|
||||
void MD5Init(MD5_CTX *context);
|
||||
void MD5Update(MD5_CTX *context, unsigned char const *buf, unsigned len);
|
||||
void MD5Final(unsigned char digest[MD5_HASHBYTES], MD5_CTX *context);
|
||||
void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
|
||||
char* MD5End(MD5_CTX *, char *);
|
||||
|
||||
char* lutil_md5_file(const char *filename, char *buf);
|
||||
char* lutil_md5_data(const unsigned char *data, unsigned int len, char *buf);
|
||||
Reference in New Issue
Block a user