Improve makefile, version code, and document

This commit is contained in:
Chord 2016-07-25 00:57:28 -04:00
parent 0d7703cf99
commit b068e6a7bd
6 changed files with 306 additions and 68 deletions

View file

@ -1,6 +1,12 @@
include Makefile.inc
$(info === Build configuration ===)
$(info Archtecture: $(ARCH))
$(info Operating system: $(OS))
CRYPTOPP_DIR=external/psf-cryptopp
CRYPTOPP_LIB=$(CRYPTOPP_DIR)/libcryptopp.a
PSCRYPTO=pscrypto/pscrypto.dll
PSCRYPTO=pscrypto/$(call lib-name,pscrypto)
all : $(CRYPTOPP_LIB) $(PSCRYPTO)
@ -13,3 +19,5 @@ $(PSCRYPTO) : $(CRYPTOPP_LIB)
clean :
$(MAKE) -C pscrypto/ clean
$(MAKE) -C $(CRYPTOPP_DIR) clean
.PHONY : all clean

68
Makefile.inc Normal file
View file

@ -0,0 +1,68 @@
# Common makefile helper file
# Note - := means expand all and save result, = means expand all each time
AR := $(PREFIX)ar
CC := $(PREFIX)gcc
CXX := $(PREFIX)g++
LD := $(PREFIX)ld
STRIP := $(PREFIX)strip
# Get a good guess as to our compile target
gcc_machine := $(subst -, ,$(shell $(CC) -dumpmachine))
GCC_ARCH := $(word 1,$(gcc_machine))
OS := $(word 3,$(gcc_machine))
ifeq "$(ARCH)" ""
ifeq "$(GCC_ARCH)" ""
$(error "Unable to determine architecture")
endif
endif
ifeq "$(OS)" ""
$(error "Unable to determine operating system")
endif
# Consolidate the GCC architecture value.
# If it was user defined, and it disagrees with the GCC value, we are probably
# trying a multilib build
ifdef ARCH
# user arch and GCC arch did not match
ifneq "$(ARCH)" "$(GCC_ARCH)"
ifeq ($(findstring $(ARCH), i686 x86_64),)
$(error "Unsupported architecture $(ARCH)")
endif
ifeq "$(ARCH)" "i686"
CFLAGS := $(CFLAGS) -m32
CXXFLAGS := $(CXXFLAGS) -m32
LDFLAGS := $(LDFLAGS) -m32
else ifeq "$(ARCH)" "x86_64")
CFLAGS := $(CFLAGS) -m64
CXXFLAGS := $(CXXFLAGS) -m64
LDFLAGS := $(LDFLAGS) -m64
endif
endif
else
ifeq ($(findstring $(GCC_ARCH), i686 x86_64),)
$(error "Unsupported architecture $(ARCH)")
endif
ARCH := $(GCC_ARCH)
endif
ifeq ($(findstring $(OS), linux cygwin mingw32),)
$(error "Unsupported operating system $(OS)")
endif
# Output artifact functions
ifeq "$(OS)" "mingw32"
lib-name = $(1).dll
exe-name = $(1).exe
else ifeq "$(OS)" "cygwin"
lib-name = $(1).dll
exe-name = $(1).exe
else
lib-name = lib$(1).so
exe-name = $(1)
endif

@ -1 +1 @@
Subproject commit d9be78c72cbe270efecd90193f16b10007b6aa1d
Subproject commit 81a4a88fbfafbebe874b14010422cf82ff23b1c5

View file

@ -1,17 +1,26 @@
include ../Makefile.inc
#### Sources
SRCS = pscrypto.cpp
OBJS := $(SRCS:.cpp=.o)
# TODO: this needs to be fixed for linux
LIB = pscrypto.dll
TEST = pscrypto
#### Artifacts
OUT_NAME=pscrypto
LIB = $(call lib-name,$(OUT_NAME))
TEST = $(call exe-name,$(OUT_NAME))
AR = $(PREFIX)ar
CXX = $(PREFIX)g++
LD = $(PREFIX)g++
STRIP = $(PREFIX)strip
#### Flags
CXXFLAGS := $(CFLAGS) -DBUILD_DLL -I../external/psf-cryptopp
LDFLAGS := -L../external/psf-cryptopp
CXXFLAGS := $(CFLAGS) -DBUILD_DLL -I../external/psf-cryptopp -fPIC
LDFLAGS := -L../external/psf-cryptopp -static-libgcc -static-libstdc++
# Handle OS compiler quirks
ifeq "$(OS)" "mingw32"
LDFLAGS := $(LDFLAGS) -static-libgcc -static-libstdc++
else ifeq "$(OS)" "cygwin"
LDFLAGS := $(LDFLAGS) -static-libgcc -static-libstdc++
else
CXXFLAGS := $(CXXFLAGS) -fPIC
endif
ifdef DEBUG
CXXFLAGS += -g
@ -22,7 +31,12 @@ endif
LIB_FLAGS=$(LDFLAGS) -Wl,-soname=$(LIB)
LIBS=-lcryptopp
all : $(OBJS) $(LIB) $(TEST)
#### Recipes
all : $(OBJS) $(LIB)
test : all $(TEST)
./$(TEST)
%.o : %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
@ -40,4 +54,6 @@ ifndef DEBUG
endif
clean :
rm -f $(OBJS) $(LIB) *.pyc
rm -f $(OBJS) $(LIB) $(TEST) *.pyc
.PHONY : all test clean

View file

@ -66,65 +66,27 @@ using CryptoPP::SecByteBlock;
#include <iomanip>
using namespace std;
DLL_EXPORT DH * DH_Start(const byte * p, const byte * g, byte * privKey, byte * pubKey);
bool ValidateMD5MAC();
#include "pscrypto.h"
#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[])
DLL_EXPORT bool PSCrypto_Init(int major, int minor)
{
DH dh;
AutoSeededRandomPool rnd(0x128);
return PSCRYPTO_VERSION_MAJOR == major && PSCRYPTO_VERSION_MINOR == minor;
}
cout << "Generating parameters..." << endl;
dh.AccessGroupParameters().Initialize(rnd, 128);
// for server, we are given p and g
// use this: dh.AccessGroupParameters().Initialize(p, g);
DLL_EXPORT void PSCrypto_Get_Version(int * major, int * minor)
{
if(major && minor)
{
*major = PSCRYPTO_VERSION_MAJOR;
*minor = PSCRYPTO_VERSION_MINOR;
}
}
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 const char * PSCrypto_Version_String()
{
return PSCRYPTO_VERSION_STRING;
}
DLL_EXPORT DH * DH_Start(const byte * p, const byte * g, byte * privKey, byte * pubKey)
@ -292,7 +254,7 @@ DLL_EXPORT void MD5Test()
}
void HMACTest()
static void HMACTest()
{
AutoSeededRandomPool prng;
@ -340,7 +302,7 @@ void HMACTest()
}
}
bool ValidateMD5MAC()
static bool ValidateMD5MAC()
{
const byte keys[2][MD5MAC::KEYLENGTH]={
{0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff},
@ -399,3 +361,59 @@ bool ValidateMD5MAC()
return pass;
}
/*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;
}

128
pscrypto/pscrypto.h Normal file
View file

@ -0,0 +1,128 @@
#ifndef PSCRYPTO_H
#define PSCRYPTO_H
#define _PS_STRINGIZE(S) #S
#define PSCRYPTO_VERSION_MAJOR 1
#define PSCRYPTO_VERSION_MINOR 0
#define PSCRYPTO_VERSION_STRING _PS_STRINGIZE(PSCRYPTO_VERSION_MAJOR) "." _PS_STRINGIZE(PSCRYPTO_VERSION_MINOR)
#ifdef __cplusplus
extern "C" {
#endif
// NOTE: all crypto is 128-bit (16 bytes) which is terrible and pretty much ineffective.
// Version verification
/// Returns initialization status. 1 for okay, 0 for failure
bool PSCrypto_Init(int major, int minor);
/// Returns version numbers
void PSCrypto_Get_Version(int * major, int * minor);
/// Returns version string
const char * PSCrypto_Version_String();
// Diffie-Helman (shared secret agreement)
/**
* Starts a Diffie-Helman key exchange with another party who's P and G values
* are already known.
*
* @param p 16 bytes of P value
* @param g 16 bytes of G value
* @param privKey A generated private key (16 bytes) [out]
* @param pubKey A generated public key (16 bytes) [out]
* @returns Newly created CryptoPP DH object or NULL on failure
*/
DH * DH_Start(const byte * p, const byte * g, byte * privKey, byte * pubKey);
/**
* Starts a new Diffie-Helman key exchange
*
* @param privKey A generated private key (16 bytes) [out]
* @param pubKey A generated public key (16 bytes) [out]
* @param p Generated P value (16 bytes) [out]
* @param g Generated G value (16 bytes) [out]
* @returns Newly created CryptoPP DH object or NULL on failure
*/
DH * DH_Start_Generate(byte * privKey, byte * pubKey, byte * p, byte * g);
/**
* Perform an agreement with another party to come to a shared secret
*
* @param dh A previously created DH object
* @param agreedValue A generated 128-bit shared secret when function returns true [out]
* @param privKey Our private key
* @param otherPubKey The other party's public key
* @returns True on a successful agreement. False on some failure
*/
bool DH_Agree(DH * dh, byte * agreedValue, const byte * privKey, const byte * otherPubKey);
/// Free created DH object
void Free_DH(DH * ptr);
// RC5 (encryption and decryption)
/**
* Initialize an RC5 instance with the specfied key
*
* @param key The input key buffer
* @param keyLen The input key length in bytes
* @param encrypt True for an encryption instance. False for decryption
* @returns A newly created RC5 instance or NULL on failure
*/
void * RC5_Init(byte * key, size_t keyLen, bool encrypt);
/**
* Perform an RC5 decryption
*
* @param dec A previously created RC5 decryption instance
* @param ct A ciphertext buffer
* @param ptLen The length of the ciphertext. Must be aligned to the size of an
* RC5 block (16 bytes)
* @param pt A pointer to a destination plaintext buffer of size ctLen [out]
* @returns True on a successful decryption
*/
bool RC5_Decrypt(RC5::Decryption * dec, byte * ct, size_t ctLen, byte * pt);
/**
* Perform an RC5 encryption
*
* @param enc A previously created RC5 encryption instance
* @param pt A plaintext buffer
* @param ptLen The length of the plaintext. Must be aligned to the size of an
* RC5 block (16 bytes)
* @param ct A pointer to a destination ciphertext buffer of size ptLen [out]
* @returns True on a successful encryption
*/
bool RC5_Encrypt(RC5::Encryption * enc, byte * pt, size_t ptLen, byte * ct);
/// Free a previously created RC5 object
void Free_RC5(RC5 * ptr);
// MD5MAC (packet integrity and authenticity)
/**
* Performs a single MD5 MAC computation
*
* @param key Input key buffer
* @param keyLen Size of the input key buffer
* @param msg Message to create a MAC for
* @param msgLen Length of the message
* @param outBuf Output buffer to receive the MAC value (16 for a full MAC)
* @param outBufLen Output buffer length. If the length is smaller than the size
* of a single MAC, the result will be truncated. If it is
* bigger, multiple MAC values will be concatenated until the
* size is reached.
* @returns Returns true on a successful MAC
*/
bool MD5_MAC(byte * key, size_t keyLen, byte * msg, size_t msgLen, byte * outBuf, size_t outBufLen);
#ifdef __cplusplus
}
#endif
#endif