mirror of
https://github.com/psforever/PSCrypto.git
synced 2026-01-19 19:14:44 +00:00
Initial commit
This commit is contained in:
commit
b49a3d0301
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
*.o
|
||||
*.so
|
||||
*.dll
|
||||
*.exe
|
||||
*.a
|
||||
*.pyc
|
||||
*.stackdump
|
||||
.gdb_history
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "external/psf-cryptopp"]
|
||||
path = external/psf-cryptopp
|
||||
url = https://github.com/psforever/psf-cryptopp.git
|
||||
15
Makefile
Normal file
15
Makefile
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
CRYPTOPP_DIR=external/psf-cryptopp
|
||||
CRYPTOPP_LIB=$(CRYPTOPP_DIR)/libcryptopp.a
|
||||
PSCRYPTO=pscrypto/pscrypto.dll
|
||||
|
||||
all : $(CRYPTOPP_LIB) $(PSCRYPTO)
|
||||
|
||||
$(CRYPTOPP_LIB) :
|
||||
$(MAKE) -C $(CRYPTOPP_DIR)
|
||||
|
||||
$(PSCRYPTO) : $(CRYPTOPP_LIB)
|
||||
$(MAKE) -C pscrypto/
|
||||
|
||||
clean :
|
||||
$(MAKE) -C pscrypto/ clean
|
||||
$(MAKE) -C $(CRYPTOPP_DIR) clean
|
||||
28
README.md
Normal file
28
README.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# PSCrypto
|
||||
A wrapper around CryptoPP for use with Scala or Java.
|
||||
|
||||
```shell
|
||||
$ git clone --recursive https://github.com/psforever/psf-cryptopp.git
|
||||
```
|
||||
|
||||
Or if you already cloned without getting the submodules
|
||||
|
||||
```shell
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
## Building
|
||||
GNU Make and a c++ compiler required.
|
||||
|
||||
```shell
|
||||
$ make -j4
|
||||
```
|
||||
|
||||
## Cross Compiling
|
||||
Use the environment variable `PREFIX` to define a compiler tuple for building. For example
|
||||
|
||||
```shell
|
||||
$ PREFIX=x86_64-w64-mingw32- make -j4
|
||||
```
|
||||
|
||||
This will build a `pscrypto.dll` for 64-bit Windows.
|
||||
1
external/psf-cryptopp
vendored
Submodule
1
external/psf-cryptopp
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit d9be78c72cbe270efecd90193f16b10007b6aa1d
|
||||
2
pscrypto/.gitignore
vendored
Normal file
2
pscrypto/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
pscrypto
|
||||
test
|
||||
43
pscrypto/Makefile
Normal file
43
pscrypto/Makefile
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
SRCS = pscrypto.cpp
|
||||
OBJS := $(SRCS:.cpp=.o)
|
||||
|
||||
# TODO: this needs to be fixed for linux
|
||||
LIB = pscrypto.dll
|
||||
TEST = pscrypto
|
||||
|
||||
AR = $(PREFIX)ar
|
||||
CXX = $(PREFIX)g++
|
||||
LD = $(PREFIX)g++
|
||||
STRIP = $(PREFIX)strip
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -DBUILD_DLL -I../external/psf-cryptopp -fPIC
|
||||
LDFLAGS := -L../external/psf-cryptopp -static-libgcc -static-libstdc++
|
||||
|
||||
ifdef DEBUG
|
||||
CXXFLAGS += -g
|
||||
else
|
||||
CXXFLAGS += -O2 -DNDEBUG
|
||||
endif
|
||||
|
||||
LIB_FLAGS=$(LDFLAGS) -Wl,-soname=$(LIB)
|
||||
LIBS=-lcryptopp
|
||||
|
||||
all : $(OBJS) $(LIB) $(TEST)
|
||||
|
||||
%.o : %.cpp
|
||||
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
$(LIB) : $(OBJS)
|
||||
$(CXX) -shared $< -o $(LIB) $(LIB_FLAGS) $(LIBS)
|
||||
ifndef DEBUG
|
||||
$(STRIP) $(LIB)
|
||||
endif
|
||||
|
||||
$(TEST) : $(OBJS)
|
||||
$(CXX) $(OBJS) -o $(TEST) $(LDFLAGS) $(LIBS)
|
||||
ifndef DEBUG
|
||||
$(STRIP) $(TEST)
|
||||
endif
|
||||
|
||||
clean :
|
||||
rm -f $(OBJS) $(LIB) *.pyc
|
||||
0
pscrypto/__init__.py
Normal file
0
pscrypto/__init__.py
Normal file
401
pscrypto/pscrypto.cpp
Normal file
401
pscrypto/pscrypto.cpp
Normal file
|
|
@ -0,0 +1,401 @@
|
|||
// PSCrypto - PSForever
|
||||
// https://cryptopp.com/wiki/Diffie-Hellman
|
||||
|
||||
#ifdef BUILD_DLL
|
||||
#define DLL_EXPORT extern "C" __declspec(dllexport)
|
||||
#else
|
||||
#define DLL_EXPORT extern "C" __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#include "osrng.h"
|
||||
using CryptoPP::AutoSeededRandomPool;
|
||||
|
||||
#include <iostream>
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
#include <string>
|
||||
using std::string;
|
||||
|
||||
#include <cstdlib>
|
||||
using std::exit;
|
||||
|
||||
#include "cryptlib.h"
|
||||
using CryptoPP::Exception;
|
||||
|
||||
#include "hmac.h"
|
||||
using CryptoPP::HMAC;
|
||||
|
||||
#include "sha.h"
|
||||
using CryptoPP::SHA256;
|
||||
|
||||
#include "md5.h"
|
||||
using CryptoPP::MD5;
|
||||
|
||||
#include "rc5.h"
|
||||
using CryptoPP::RC5;
|
||||
|
||||
#include "dh.h"
|
||||
using CryptoPP::DH;
|
||||
using CryptoPP::DH_Domain;
|
||||
using CryptoPP::DL_GroupParameters_GFP_DefaultSafePrime;
|
||||
using CryptoPP::DL_GroupParameters_IntegerBasedImpl;
|
||||
|
||||
#include "integer.h"
|
||||
using CryptoPP::Integer;
|
||||
|
||||
#include "hex.h"
|
||||
using CryptoPP::HexEncoder;
|
||||
using CryptoPP::HexDecoder;
|
||||
|
||||
#include "md5mac.h"
|
||||
using CryptoPP::MD5MAC;
|
||||
|
||||
#include "filters.h"
|
||||
using CryptoPP::StringSink;
|
||||
using CryptoPP::StringSource;
|
||||
using CryptoPP::HashFilter;
|
||||
using CryptoPP::HashVerificationFilter;
|
||||
|
||||
#include "secblock.h"
|
||||
using CryptoPP::SecByteBlock;
|
||||
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
using namespace std;
|
||||
|
||||
DLL_EXPORT DH * DH_Start(const byte * p, const byte * g, byte * privKey, byte * pubKey);
|
||||
bool ValidateMD5MAC();
|
||||
|
||||
#define min(x, y) (((x) > (y)) ? (y) : (x))
|
||||
|
||||
/*key = "377b60f8790f91b35a9da82945743da9"
|
||||
label = "master secret"
|
||||
msg = "b4aea1559444a20b6112a2892de40eac00000000c8aea155b53d187076b79abab59001b600000000"
|
||||
#msg = ""
|
||||
expect = "5aa15de41f5220cf5cca489155e1438c5aa15de4"
|
||||
|
||||
print "Key: " + key
|
||||
print "Msg: " + msg
|
||||
|
||||
# append the label
|
||||
msg = label + hexToBin(msg)*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
DH dh;
|
||||
AutoSeededRandomPool rnd(0x128);
|
||||
|
||||
cout << "Generating parameters..." << endl;
|
||||
dh.AccessGroupParameters().Initialize(rnd, 128);
|
||||
// for server, we are given p and g
|
||||
// use this: dh.AccessGroupParameters().Initialize(p, g);
|
||||
|
||||
cout << "Generating Keypair..." << endl;
|
||||
|
||||
SecByteBlock privKey(dh.PrivateKeyLength());
|
||||
SecByteBlock pubKey(dh.PublicKeyLength());
|
||||
dh.GenerateKeyPair(rnd, privKey, pubKey);
|
||||
|
||||
const Integer& p = dh.GetGroupParameters().GetModulus();
|
||||
cout << "P: " << hex << p << endl;
|
||||
|
||||
Integer q = (p-1)/2;
|
||||
cout << "Q: " << q << endl;
|
||||
|
||||
const Integer& g = dh.GetGroupParameters().GetGenerator();
|
||||
cout << "G: " << g << endl;
|
||||
|
||||
Integer r = dh.GetGroupParameters().GetSubgroupOrder();
|
||||
cout << "Subgroup order: " << r << endl;
|
||||
|
||||
cout << "Key generation test..." << endl;
|
||||
|
||||
byte buf1[16] = {
|
||||
'a','a','b','b',
|
||||
'a','a','b','b',
|
||||
'a','a','b','b',
|
||||
'a','a','b','c'};
|
||||
byte buf2[16];
|
||||
byte buf3[16];
|
||||
|
||||
|
||||
cout << "Output " << DH_Start(buf1, buf1, buf2, buf3) << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DLL_EXPORT DH * DH_Start(const byte * p, const byte * g, byte * privKey, byte * pubKey)
|
||||
{
|
||||
DH * dh = new DH();
|
||||
if(!dh)
|
||||
return NULL;
|
||||
|
||||
AutoSeededRandomPool rnd(0x128);
|
||||
Integer pInt(p, 0x10);
|
||||
Integer gInt(g, 0x10);
|
||||
|
||||
dh->AccessGroupParameters().Initialize(pInt, gInt);
|
||||
dh->GenerateKeyPair(rnd, privKey, pubKey);
|
||||
|
||||
return dh;
|
||||
}
|
||||
|
||||
DLL_EXPORT DH * DH_Start_Generate(byte * privKey, byte * pubKey, byte * p, byte * g)
|
||||
{
|
||||
DH * dh = new DH();
|
||||
AutoSeededRandomPool rnd;
|
||||
|
||||
if(!dh)
|
||||
return NULL;
|
||||
|
||||
dh->AccessGroupParameters().Initialize(rnd, 128);
|
||||
dh->GenerateKeyPair(rnd, privKey, pubKey);
|
||||
|
||||
const Integer& pInt = dh->GetGroupParameters().GetModulus();
|
||||
const Integer& gInt = dh->GetGroupParameters().GetGenerator();
|
||||
|
||||
pInt.Encode(p, 0x10);
|
||||
gInt.Encode(g, 0x10);
|
||||
|
||||
return dh;
|
||||
}
|
||||
|
||||
DLL_EXPORT bool DH_Agree(DH * dh, byte * agreedValue, const byte * privKey,
|
||||
const byte * otherPubKey)
|
||||
{
|
||||
if(!dh || !agreedValue || !privKey || !otherPubKey)
|
||||
return false;
|
||||
|
||||
return dh->Agree(agreedValue, privKey, otherPubKey, true);
|
||||
}
|
||||
|
||||
DLL_EXPORT void * RC5_Init(byte * key, size_t keyLen, bool encrypt)
|
||||
{
|
||||
if(!key || !keyLen)
|
||||
return NULL;
|
||||
|
||||
if(encrypt)
|
||||
return new RC5::Encryption(key, keyLen);
|
||||
else
|
||||
return new RC5::Decryption(key, keyLen);
|
||||
|
||||
}
|
||||
|
||||
DLL_EXPORT bool RC5_Decrypt(RC5::Decryption * dec, byte * ct, size_t ctLen, byte * pt)
|
||||
{
|
||||
if(!dec || !ct || !pt || ctLen & (dec->BlockSize()-1))
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < ctLen; i+=dec->BlockSize())
|
||||
dec->ProcessAndXorBlock(ct+i, NULL, pt+i);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DLL_EXPORT bool RC5_Encrypt(RC5::Encryption * enc, byte * pt, size_t ptLen, byte * ct)
|
||||
{
|
||||
if(!enc || !ct || !pt || ptLen & (enc->BlockSize()-1))
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < ptLen; i+= enc->BlockSize())
|
||||
enc->ProcessAndXorBlock(pt+i, NULL, ct+i);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DLL_EXPORT bool MD5_MAC(byte * key, size_t keyLen, byte * msg, size_t msgLen, byte * outBuf, size_t outBufLen)
|
||||
{
|
||||
if(!key || !msg || !outBuf)
|
||||
return false;
|
||||
|
||||
byte localKey[16];
|
||||
byte digest[MD5MAC::DIGESTSIZE];
|
||||
|
||||
memset(digest, 0, sizeof(digest));
|
||||
memset(localKey, 0, sizeof(localKey));
|
||||
memcpy(localKey, key, min(keyLen, 16));
|
||||
|
||||
// key length of 16 bytes or less
|
||||
MD5MAC mac(localKey);
|
||||
|
||||
mac.Update(msg, msgLen);
|
||||
mac.Final(digest);
|
||||
|
||||
for(size_t i = 0; i < outBufLen; i += MD5MAC::DIGESTSIZE)
|
||||
memcpy(outBuf+i, digest, min(MD5MAC::DIGESTSIZE, outBufLen-i));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DLL_EXPORT void Free_DH(DH * ptr)
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
DLL_EXPORT void Free_RC5(RC5 * ptr)
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
DLL_EXPORT void MD5Test()
|
||||
{
|
||||
const byte key[] = {0x37, 0x7b, 0x60, 0xf8, 0x79, 0x0f, 0x91, 0xb3, 0x5a, 0x9d, 0xa8, 0x29, 0x45, 0x74, 0x3d, 0xa9};
|
||||
const byte msg[] = {'m', 'a', 's', 't', 'e', 'r', ' ', 's', 'e', 'c', 'r', 'e', 't',
|
||||
0xb4, 0xae, 0xa1, 0x55, 0x94, 0x44, 0xa2, 0x0b, 0x61, 0x12, 0xa2, 0x89, 0x2d, 0xe4, 0x0e, 0xac, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xae, 0xa1, 0x55, 0xb5, 0x3d, 0x18, 0x70, 0x76, 0xb7, 0x9a, 0xba, 0xb5, 0x90, 0x01, 0xb6, 0x00, 0x00, 0x00, 0x00};
|
||||
const byte output[] = {0x5a, 0xa1, 0x5d, 0xe4, 0x1f, 0x52, 0x20, 0xcf, 0x5c, 0xca, 0x48, 0x91, 0x55, 0xe1, 0x43, 0x8c, 0x5a, 0xa1, 0x5d, 0xe4};
|
||||
byte digest[MD5MAC::DIGESTSIZE+4];
|
||||
string encoded;
|
||||
|
||||
std::ios::sync_with_stdio(true);
|
||||
|
||||
MD5MAC mac(key);
|
||||
|
||||
StringSource(key, sizeof(key), true,
|
||||
new HexEncoder(
|
||||
new StringSink(encoded)
|
||||
) // HexEncoder
|
||||
); // StringSource
|
||||
cout << "key: " << encoded << endl;
|
||||
|
||||
encoded = "";
|
||||
|
||||
StringSource(msg, sizeof(msg), true,
|
||||
new HexEncoder(
|
||||
new StringSink(encoded)
|
||||
) // HexEncoder
|
||||
); // StringSource
|
||||
cout << "msg: " << encoded << endl;
|
||||
|
||||
encoded = "";
|
||||
|
||||
StringSource(output, sizeof(output), true,
|
||||
new HexEncoder(
|
||||
new StringSink(encoded)
|
||||
) // HexEncoder
|
||||
); // StringSource
|
||||
cout << "expected: " << encoded << endl;
|
||||
|
||||
mac.Update(msg, sizeof(msg));
|
||||
mac.Final(digest);
|
||||
|
||||
encoded = "";
|
||||
|
||||
StringSource(digest, sizeof(digest), true,
|
||||
new HexEncoder(
|
||||
new StringSink(encoded)
|
||||
) // HexEncoder
|
||||
); // StringSource
|
||||
cout << "got: " << encoded << endl;
|
||||
|
||||
}
|
||||
|
||||
void HMACTest()
|
||||
{
|
||||
AutoSeededRandomPool prng;
|
||||
|
||||
unsigned char fixedKey[16] = {0x37, 0x7b, 0x60, 0xf8, 0x79, 0x0f, 0x91, 0xb3, 0x5a, 0x9d, 0xa8, 0x29, 0x45, 0x74, 0x3d, 0xa9};
|
||||
SecByteBlock key(fixedKey, 16);
|
||||
|
||||
//for(int i = 0; i++; i < 16)
|
||||
//key[i] = fixedKey[i];
|
||||
//prng.GenerateBlock(key, key.size());
|
||||
|
||||
string plain = "master secret";
|
||||
string mac, encoded;
|
||||
|
||||
/*********************************\
|
||||
\*********************************/
|
||||
|
||||
// Pretty print key
|
||||
encoded.clear();
|
||||
StringSource(key, key.size(), true,
|
||||
new HexEncoder(
|
||||
new StringSink(encoded)
|
||||
) // HexEncoder
|
||||
); // StringSource
|
||||
cout << "key: " << encoded << endl;
|
||||
|
||||
cout << "plain text: " << plain << endl;
|
||||
|
||||
/*********************************\
|
||||
\*********************************/
|
||||
|
||||
try
|
||||
{
|
||||
HMAC< MD5 > hmac(key, key.size());
|
||||
|
||||
StringSource(plain, true,
|
||||
new HashFilter(hmac,
|
||||
new StringSink(mac)
|
||||
) // HashFilter
|
||||
); // StringSource
|
||||
}
|
||||
catch(const CryptoPP::Exception& e)
|
||||
{
|
||||
cerr << e.what() << endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
bool ValidateMD5MAC()
|
||||
{
|
||||
const byte keys[2][MD5MAC::KEYLENGTH]={
|
||||
{0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff},
|
||||
{0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}};
|
||||
|
||||
const char *TestVals[7]={
|
||||
"",
|
||||
"a",
|
||||
"abc",
|
||||
"message digest",
|
||||
"abcdefghijklmnopqrstuvwxyz",
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
"12345678901234567890123456789012345678901234567890123456789012345678901234567890"};
|
||||
|
||||
const byte output[2][7][MD5MAC::DIGESTSIZE]={
|
||||
{{0x1f,0x1e,0xf2,0x37,0x5c,0xc0,0xe0,0x84,0x4f,0x98,0xe7,0xe8,0x11,0xa3,0x4d,0xa8},
|
||||
{0x7a,0x76,0xee,0x64,0xca,0x71,0xef,0x23,0x7e,0x26,0x29,0xed,0x94,0x52,0x73,0x65},
|
||||
{0xe8,0x01,0x3c,0x11,0xf7,0x20,0x9d,0x13,0x28,0xc0,0xca,0xa0,0x4f,0xd0,0x12,0xa6},
|
||||
{0xc8,0x95,0x53,0x4f,0x22,0xa1,0x74,0xbc,0x3e,0x6a,0x25,0xa2,0xb2,0xef,0xd6,0x30},
|
||||
{0x91,0x72,0x86,0x7e,0xb6,0x00,0x17,0x88,0x4c,0x6f,0xa8,0xcc,0x88,0xeb,0xe7,0xc9},
|
||||
{0x3b,0xd0,0xe1,0x1d,0x5e,0x09,0x4c,0xb7,0x1e,0x35,0x44,0xac,0xa9,0xb8,0xbf,0xa2},
|
||||
{0x93,0x37,0x16,0x64,0x44,0xcc,0x95,0x35,0xb7,0xd5,0xb8,0x0f,0x91,0xe5,0x29,0xcb}},
|
||||
{{0x2f,0x6e,0x73,0x13,0xbf,0xbb,0xbf,0xcc,0x3a,0x2d,0xde,0x26,0x8b,0x59,0xcc,0x4d},
|
||||
{0x69,0xf6,0xca,0xff,0x40,0x25,0x36,0xd1,0x7a,0xe1,0x38,0x03,0x2c,0x0c,0x5f,0xfd},
|
||||
{0x56,0xd3,0x2b,0x6c,0x34,0x76,0x65,0xd9,0x74,0xd6,0xf7,0x5c,0x3f,0xc6,0xf0,0x40},
|
||||
{0xb8,0x02,0xb2,0x15,0x4e,0x59,0x8b,0x6f,0x87,0x60,0x56,0xc7,0x85,0x46,0x2c,0x0b},
|
||||
{0x5a,0xde,0xf4,0xbf,0xf8,0x04,0xbe,0x08,0x58,0x7e,0x94,0x41,0xcf,0x6d,0xbd,0x57},
|
||||
{0x18,0xe3,0x49,0xa5,0x24,0x44,0xb3,0x0e,0x5e,0xba,0x5a,0xdd,0xdc,0xd9,0xf1,0x8d},
|
||||
{0xf2,0xb9,0x06,0xa5,0xb8,0x4b,0x9b,0x4b,0xbe,0x95,0xed,0x32,0x56,0x4e,0xe7,0xeb}}};
|
||||
|
||||
byte digest[MD5MAC::DIGESTSIZE];
|
||||
bool pass=true, fail;
|
||||
|
||||
cout << "\nMD5MAC validation suite running...\n";
|
||||
|
||||
for (int k=0; k<2; k++)
|
||||
{
|
||||
MD5MAC mac(keys[k]);
|
||||
cout << "\nKEY: ";
|
||||
for (int j=0;j<MD5MAC::KEYLENGTH;j++)
|
||||
cout << setw(2) << setfill('0') << hex << (int)keys[k][j];
|
||||
cout << endl << endl;
|
||||
for (int i=0;i<7;i++)
|
||||
{
|
||||
mac.Update((byte *)TestVals[i], strlen(TestVals[i]));
|
||||
mac.Final(digest);
|
||||
fail = memcmp(digest, output[k][i], MD5MAC::DIGESTSIZE)
|
||||
|| !mac.VerifyDigest(output[k][i], (byte *)TestVals[i], strlen(TestVals[i]));
|
||||
pass = pass && !fail;
|
||||
cout << (fail ? "FAILED " : "passed ");
|
||||
for (int j=0;j<MD5MAC::DIGESTSIZE;j++)
|
||||
cout << setw(2) << setfill('0') << hex << (int)digest[j];
|
||||
cout << " \"" << TestVals[i] << '\"' << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return pass;
|
||||
}
|
||||
100
pscrypto/pscrypto.py
Normal file
100
pscrypto/pscrypto.py
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
#!/usr/bin/env python2
|
||||
from binascii import hexlify
|
||||
from ctypes import *
|
||||
import os
|
||||
|
||||
lib = cdll.LoadLibrary(os.path.dirname(os.path.realpath(__file__)) + "/pscrypto.dll")
|
||||
|
||||
lib.MD5_MAC.restype = c_bool
|
||||
lib.MD5_MAC.prototype = [c_char_p, c_uint, c_char_p, c_uint, c_char_p, c_uint]
|
||||
|
||||
lib.DH_Start.restype = c_void_p
|
||||
lib.DH_Start.prototype = [c_char_p, c_char_p, c_char_p]
|
||||
|
||||
lib.DH_Agree.restype = c_bool
|
||||
lib.DH_Agree.prototype = [c_void_p, c_char_p, c_char_p, c_char_p]
|
||||
|
||||
lib.RC5_Init.restype = c_void_p
|
||||
lib.RC5_Init.prototype = [c_char_p, c_uint, c_bool]
|
||||
|
||||
lib.RC5_Decrypt.restype = c_bool
|
||||
lib.RC5_Decrypt.prototype = [c_void_p, c_char_p, c_uint, c_char_p]
|
||||
|
||||
lib.RC5_Encrypt.restype = c_bool
|
||||
lib.RC5_Encrypt.prototype = [c_void_p, c_char_p, c_uint, c_char_p]
|
||||
|
||||
def hexToBin(data):
|
||||
return data.decode('hex')
|
||||
|
||||
def binToHex(data):
|
||||
return hexlify(data)
|
||||
|
||||
def md5mac(key, msg, outSz):
|
||||
outBuf = create_string_buffer(outSz)
|
||||
lib.MD5_MAC(key, len(key), msg, len(msg), outBuf, outSz)
|
||||
|
||||
return outBuf.raw
|
||||
|
||||
def ServerDHStart(p, g):
|
||||
outPrivate = create_string_buffer(16)
|
||||
outPublic = create_string_buffer(16)
|
||||
dhHandle = lib.DH_Start(p, g, outPrivate, outPublic)
|
||||
|
||||
return (dhHandle, outPrivate.raw, outPublic.raw)
|
||||
|
||||
def ServerDHAgree(dhHandle, privKey, otherPubKey):
|
||||
outAgree = create_string_buffer(16)
|
||||
status = lib.DH_Agree(dhHandle, outAgree, privKey, otherPubKey)
|
||||
|
||||
return (status, outAgree.raw)
|
||||
|
||||
def ServerInitEnc(key):
|
||||
return lib.RC5_Init(key, len(key), True)
|
||||
|
||||
def ServerInitDec(key):
|
||||
return lib.RC5_Init(key, len(key), False)
|
||||
|
||||
def ServerDec(decHandle, ct):
|
||||
pt = create_string_buffer(len(ct))
|
||||
ret = lib.RC5_Decrypt(decHandle, ct, len(ct), pt)
|
||||
|
||||
if not ret:
|
||||
print "Decryption failed!"
|
||||
return ""
|
||||
|
||||
return pt.raw
|
||||
|
||||
def ServerEnc(encHandle, pt):
|
||||
ct = create_string_buffer(len(pt))
|
||||
ret = lib.RC5_Encrypt(encHandle, pt, len(pt), ct)
|
||||
|
||||
if not ret:
|
||||
print "Encryption failed!"
|
||||
return ""
|
||||
|
||||
return ct.raw
|
||||
|
||||
def main():
|
||||
raw_input()
|
||||
(dhHandle, priv, pub) = ServerDHStart("\x41\x75"*8, "\x01"*15 + "\x03")
|
||||
print "Started"
|
||||
print ServerDHAgree(dhHandle, priv, "A"*16)
|
||||
|
||||
key = "377b60f8790f91b35a9da82945743da9"
|
||||
label = "master secret"
|
||||
msg = "b4aea1559444a20b6112a2892de40eac00000000c8aea155b53d187076b79abab59001b600000000"
|
||||
expect = "5aa15de41f5220cf5cca489155e1438c5aa15de4"
|
||||
|
||||
print "Key: " + key
|
||||
print "Msg: " + msg
|
||||
|
||||
# append the label
|
||||
key = hexToBin(key)
|
||||
msg = label + hexToBin(msg)
|
||||
outBuf = md5mac(key, msg, 20)
|
||||
|
||||
print "Expect: " + expect
|
||||
print "Got: " + binToHex(outBuf)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
20
pscrypto/test.c
Normal file
20
pscrypto/test.c
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
void *handle;
|
||||
char *error;
|
||||
|
||||
handle = dlopen("./libpscrypto.so", RTLD_LAZY);
|
||||
if (!handle) {
|
||||
fprintf(stderr, "%s\n", dlerror());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
dlclose(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue