Skip to content

Commit

Permalink
Tidy up a number of uglies in the code, remove some magic consts, make++
Browse files Browse the repository at this point in the history
This code:

 * Adds NULL guard checks.
 * Detects mlen overflow in encrypt.
 * Allows you to specify CSTD=c89, CSTD=c99, CSTD=c11 for the library.
 * Supports E4_OUTPUT_DIR for building code anywhere.
  • Loading branch information
diagprov committed Jan 6, 2020
1 parent 1ce0e66 commit bf6c791
Show file tree
Hide file tree
Showing 14 changed files with 142 additions and 89 deletions.
18 changes: 14 additions & 4 deletions include/e4/e4.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ extern "C" {
#define E4_RESULT_OK 0
/* A control message was handled. Applications may discard the resulting buffer */
#define E4_RESULT_OK_CONTROL -1

/* Internal error: for exception conditions that indicate the code has a bug */
#define E4_ERROR_INTERNAL -100
/* Invalid authentication tag indicates corrupted ciphertext */
#define E4_ERROR_INVALID_TAG -101
/* Message received outside of error window for clock. */
Expand All @@ -48,15 +51,18 @@ extern "C" {
#define E4_ERROR_INVALID_COMMAND -107
/* E4 Persistence layer reported an error. */
#define E4_ERROR_PERSISTENCE_ERROR -108

/* Unable to find public key for device;e4 */
#define E4_ERROR_DEVICEPK_MISSING -109
/* Signature verification failed */
#define E4_ERROR_PK_SIGVERIF_FAILED -110

/* Overflow detected */
#define E4_ERROR_PARAMETER_OVERFLOW -111
/* Invalid parameters, e.g. NULL pointers */
#define E4_ERROR_PARAMETER_INVALID -112

/* Size of the timestamp field */
#define E4_TS_LEN 8
#define E4_TIMESTAMP_LEN 8
/* Size of the ID, truncated sha3(alias) */
#define E4_ID_LEN 16

Expand All @@ -70,7 +76,7 @@ extern "C" {
#define E4_CTRLTOPIC_LEN (2 * E4_ID_LEN) + 3

#define E4_TAG_LEN 16
#define E4_TIMESTAMP_LEN 8

#define E4_MSGHDR_LEN (E4_TAG_LEN + E4_TIMESTAMP_LEN)

/* Public key support */
Expand Down Expand Up @@ -152,7 +158,8 @@ int e4c_unprotect_message(uint8_t *message,
const uint8_t *ciphertext,
size_t ciphertext_len,
const char *topic_name,
e4storage *storage);
e4storage *storage
);


/* the e4storage type pre-defined above implements these API calls */
Expand All @@ -168,10 +175,13 @@ int e4c_set_topic_key(e4storage *store, const uint8_t *topic_hash, const uint8_t
int e4c_remove_topic(e4storage *store, const uint8_t *topic_hash);
int e4c_reset_topics(e4storage *store);

#ifdef E4_MODE_SYMKEY
int e4c_set_idkey(e4storage *store, const uint8_t *key);
#endif
#ifdef E4_MODE_PUBKEY
/* pubkey storage apis */
int e4c_set_idpubkey(e4storage *store, const uint8_t *pubkey);
int e4c_set_idseckey(e4storage *store, const uint8_t *key);
int e4c_getdeviceindex(e4storage *store, const uint8_t* id);
int e4c_getdevicekey(uint8_t* key, e4storage *store, const int index);
int e4c_set_device_key(e4storage *store, const uint8_t *id, const uint8_t *key);
Expand Down
1 change: 1 addition & 0 deletions include/e4/stdint.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extern "C" {
#endif

#if __STDC_VERSION__ >= 199901L
#include <stddef.h>
#include <stdint.h>
#else
#include "e4/pstdint.h"
Expand Down
21 changes: 21 additions & 0 deletions mk/conf.mk
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@

VERSION=1.0.0

CC ?= clang
AR ?= ar
LD ?= clang
ARFLAGS = rcs
CFLAGS = -Wall -Werror -fPIC -std=$(CSTD) $(E4_CFLAGS)
LDFLAGS = -L. $(E4_LDFLAGS)

O = o

TESTCFLAGS = -Wall -Werror -g -std=c11 $(E4_CFLAGS)
TESTLDFLAGS= $(E4_LDFLAGS)

GITCOMMIT=$(shell git rev-list -1 HEAD)
NOW=$(shell date "+%Y%m%d%H%M")

INCDIR = include
SRCDIR = src
DOCDIR = doc

LIBNAME = libe4


35 changes: 10 additions & 25 deletions mk/pubkey/conf.mk
Original file line number Diff line number Diff line change
@@ -1,34 +1,19 @@

CC ?= clang
AR ?= ar
LD ?= clang
ARFLAGS = rcs
CFLAGS = -Wall -Werror -fPIC -std=c89 $(E4_CFLAGS)
LDFLAGS = -L. $(E4_CFLAGS)
LDSOFLAGS = -shared -fPIC -Wl,-soname,libe4p.so.1
INCLUDES = -Iinclude/ -Ibuild/pubkey/include/
E4_OUTPUT_DIR ?= build/pubkey

# BUILD environment
GITCOMMIT=$(shell git rev-list -1 HEAD)
NOW=$(shell date "+%Y%m%d%H%M")
LDSOFLAGS = -shared -fPIC -Wl,-soname,libe4p.so.1
INCLUDES = -Iinclude/ -I$(E4_OUTPUT_DIR)/include/

# OBJ paths match their src folder equivalents
INCDIR = include
OBJDIR = tmp/pubkey/build
TESTOBJDIR = tmp/pubkey/test
SRCDIR = src
DOCDIR = doc
BUILDDIR = build/pubkey
LIBDIR = build/pubkey/lib
OUTINCDIR = build/pubkey/include
LIBNAME = libe4
LIB = $(LIBDIR)/$(LIBNAME).a
LIBSO = $(LIBDIR)/$(LIBNAME)p.so.$(VERSION)

BUILDDIR = $(E4_OUTPUT_DIR)
LIBDIR = $(BUILDDIR)/lib
OUTINCDIR = $(BUILDDIR)/include
DISTDIR = dist/pubkey/
TESTDIR = build/pubkey/test
TESTDIR = $(BUILDDIR)/test

O = o
LIB = $(LIBDIR)/$(LIBNAME).a
LIBSO = $(LIBDIR)/$(LIBNAME)p.so.$(VERSION)

# test specific parts:
TESTCFLAGS = -Wall -Werror -g -std=c11 -Wno-unused-variable $(E4_CFLAGS)
TESTLDFLAGS = $(LDFLAGS)
4 changes: 2 additions & 2 deletions mk/pubkey/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ pub_so: setup pub_header $(OBJS)
cp -rfv $(INCDIR)/* $(OUTINCDIR)/; \
$(CC) $(LDSOFLAGS) $(OBJS) -o $(LIBSO)

.PHONY pub_header: build/pubkey/include/e4config/e4_config.h
.PHONY pub_header: $(BUILDDIR)/include/e4config/e4_config.h

build/pubkey/include/e4config/e4_config.h:
$(BUILDDIR)/include/e4config/e4_config.h:
echo '#define E4_MODE_PUBKEY 1' > $@
ifeq ("$(STORE)", "mem")
echo "#define E4_STORE_MEM 1" >> $@
Expand Down
35 changes: 11 additions & 24 deletions mk/symkey/conf.mk
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@

CC ?= clang
AR ?= ar
ARFLAGS = rcs
CFLAGS = -Wall -fPIC -Werror -std=c89 $(E4_CFLAGS)
LDFLAGS = -L. $(E4_CFLAGS)
LDSOFLAGS = -shared -fPIC -Wl,-soname,libe4s.so.1
INCLUDES = -Iinclude/ -Ibuild/symkey/include/
E4_OUTPUT_DIR ?= build/symkey

# BUILD environment
GITCOMMIT=$(shell git rev-list -1 HEAD)
NOW=$(shell date "+%Y%m%d%H%M")
LDSOFLAGS = -shared -fPIC -Wl,-soname,libe4s.so.1
INCLUDES = -Iinclude/ -I$(E4_OUTPUT_DIR)/include/

# OBJ paths match their src folder equivalents
INCDIR = include
OBJDIR = tmp/symkey/build
TESTOBJDIR = tmp/symkey/test
SRCDIR = src
DOCDIR = doc
BUILDDIR = build/symkey
LIBDIR = build/symkey/lib
OUTINCDIR = build/symkey/include
LIBNAME = libe4
LIB = $(LIBDIR)/$(LIBNAME).a
LIBSO = $(LIBDIR)/$(LIBNAME).so.$(VERSION)

BUILDDIR = $(E4_OUTPUT_DIR)
LIBDIR = $(BUILDDIR)/lib
OUTINCDIR = $(BUILDDIR)/include
DISTDIR = dist/symkey/
TESTDIR = build/symkey/test
TESTDIR = $(BUILDDIR)/test

LIB = $(LIBDIR)/$(LIBNAME).a
LIBSO = $(LIBDIR)/$(LIBNAME)s.so.$(VERSION)

O = o

# test specific parts:
TESTCFLAGS = -Wall -Werror -g -std=c11 $(E4_CFLAGS)
TESTLDFLAGS =
4 changes: 2 additions & 2 deletions mk/symkey/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ sym_so: setup sym_header $(OBJS)
cp -rfv $(INCDIR)/* $(OUTINCDIR)/; \
$(CC) $(LDSOFLAGS) $(OBJS) -o $(LIBSO)

.PHONY sym_header: build/symkey/include/e4config/e4_config.h
.PHONY sym_header: $(BUILDDIR)/include/e4config/e4_config.h

build/symkey/include/e4config/e4_config.h:
$(BUILDDIR)/include/e4config/e4_config.h:
echo '#define E4_MODE_SYMKEY 1' > $@
ifeq ("$(STORE)", "mem")
echo "#define E4_STORE_MEM 1" >> $@
Expand Down
2 changes: 2 additions & 0 deletions mk/unix.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ include mk/conf.mk

CONF ?= symkey
STORE ?= file
CSTD ?= -std=c89

include mk/$(CONF)/conf.mk
include mk/$(CONF)/objects.mk
include mk/$(CONF)/tests.mk
Expand Down
2 changes: 1 addition & 1 deletion src/e4c_pk_store_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ int e4c_set_id(e4storage *store, const uint8_t *id)
exit:
return r;
}
int e4c_set_idkey(e4storage *store, const uint8_t *key)
int e4c_set_idseckey(e4storage *store, const uint8_t *key)
{
memmove(store->privkey, key, sizeof store->privkey);
e4c_sync(store);
Expand Down
2 changes: 1 addition & 1 deletion src/e4c_pk_store_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ int e4c_set_id(e4storage *store, const uint8_t *id)
return r;
}

int e4c_set_idkey(e4storage *store, const uint8_t *key)
int e4c_set_idseckey(e4storage *store, const uint8_t *key)
{
memmove(store->privkey, key, sizeof store->privkey);
e4c_sync(store);
Expand Down
59 changes: 43 additions & 16 deletions src/e4pkcclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,30 @@ int e4c_protect_message(uint8_t *cptr,
e4storage *storage)
{
int i = 0;
size_t clen2 = 0;
size_t clen_siv = 0;
uint8_t key[E4_KEY_LEN];
uint64_t time_now = 0;
uint8_t* signaturep = NULL;
size_t signeddatalen=0;

/* pubkey messages are: Timestamp (8) | id (16) | IV (16) | Ciphertext (n) | sig (64) */

if (mlen + E4_PK_TOPICMSGHDR_LEN + E4_PK_EDDSA_SIG_LEN > cmax) /* actually: not enough space */
return E4_ERROR_CIPHERTEXT_TOO_SHORT;
*clen = mlen + E4_MSGHDR_LEN;

if (mlen + E4_PK_TOPICMSGHDR_LEN + E4_PK_EDDSA_SIG_LEN < mlen) /* overflow */
return E4_ERROR_PARAMETER_OVERFLOW;

if (cptr == NULL ||
mptr == NULL ||
topic == NULL ||
clen == NULL ||
storage == NULL)
{
return E4_ERROR_PARAMETER_INVALID;
}

*clen = mlen + E4_PK_TOPICMSGHDR_LEN;


/* get the key */
i = e4c_getindex(storage, topic);
Expand All @@ -86,17 +99,15 @@ int e4c_protect_message(uint8_t *cptr,
time_now >>= 8;
}

/* set our ID in the output buffer
* if Avi is reading this code, hope you are enjoying this memcpy.
*/
memcpy(cptr + E4_TS_LEN, storage->id, E4_ID_LEN);
/* set our ID in the output buffer */
memcpy(cptr + E4_TIMESTAMP_LEN, storage->id, E4_ID_LEN);

/* encrypt */
clen2 = 0;
aes256_encrypt_siv(cptr + E4_TS_LEN + E4_ID_LEN, &clen2, cptr, 8, mptr, mlen, key);
clen_siv = 0;
aes256_encrypt_siv(cptr + E4_TIMESTAMP_LEN + E4_ID_LEN, &clen_siv, cptr, 8, mptr, mlen, key);

/* sign the result */
signeddatalen = E4_TS_LEN + E4_ID_LEN + E4_TAG_LEN + mlen;
signeddatalen = E4_TIMESTAMP_LEN + E4_ID_LEN + E4_TAG_LEN + mlen;
signaturep = &cptr[0] + signeddatalen;

/*
Expand All @@ -112,6 +123,13 @@ int e4c_protect_message(uint8_t *cptr,
storage->pubkey,
storage->privkey);

/* pubkey messages are: Timestamp (8) | id (16) | IV (16) | Ciphertext (n) | sig (64) */
/* safety check. clen_siv = msglen+E4_TAG_LEN. Therefore adding E4_PK_EDDSA_SIG_LEN + E4_TIMESTAMP_LEN + E4_ID_LEN should
* equal clen */
if ( *clen != clen_siv + E4_PK_EDDSA_SIG_LEN + E4_TIMESTAMP_LEN + E4_ID_LEN ) {
return E4_ERROR_INTERNAL;
}

return E4_RESULT_OK;
}

Expand All @@ -138,6 +156,15 @@ int e4c_unprotect_message(uint8_t *mptr,
secs1970 = (uint64_t)time(NULL); / this system has a RTC */
#endif

if (cptr == NULL ||
mptr == NULL ||
topic == NULL ||
storage == NULL)
{
return E4_ERROR_PARAMETER_INVALID;
}


/* There are two possible message formats:
Expand Down Expand Up @@ -175,8 +202,8 @@ int e4c_unprotect_message(uint8_t *mptr,

/* set things up for symmetric decryption: */
/* From the C2: Timestamp (8) | IV (16) | Ciphertext (n) */
assocdatalen = E4_TS_LEN;
sivpayloadlen = clen - E4_TS_LEN;
assocdatalen = E4_TIMESTAMP_LEN;
sivpayloadlen = clen - E4_TIMESTAMP_LEN;
}
else
{
Expand Down Expand Up @@ -234,8 +261,8 @@ int e4c_unprotect_message(uint8_t *mptr,

/* set things up for symmetric decryption: */
/* From other clients: Timestamp (8) | id (16) | IV (16) | Ciphertext (n) | sig (64) */
assocdatalen = E4_ID_LEN + E4_TS_LEN;
sivpayloadlen = clen - (E4_TS_LEN + E4_ID_LEN + E4_PK_EDDSA_SIG_LEN);
assocdatalen = E4_ID_LEN + E4_TIMESTAMP_LEN;
sivpayloadlen = clen - (E4_TIMESTAMP_LEN + E4_ID_LEN + E4_PK_EDDSA_SIG_LEN);
}

/* Retrieve timestamp encoded as little endian */
Expand Down Expand Up @@ -320,8 +347,8 @@ int e4c_unprotect_message(uint8_t *mptr,
return r == 0 ? E4_RESULT_OK_CONTROL : r;

case 0x02: /* SetIdKey(key) */
if (*mlen != (1 + E4_KEY_LEN)) return E4_ERROR_INVALID_COMMAND;
r = e4c_set_idkey(storage, mptr + 1);
if (*mlen != (1 + E4_PK_EDDSA_PRIVKEY_LEN)) return E4_ERROR_INVALID_COMMAND;
r = e4c_set_idseckey(storage, mptr + 1);
return r == 0 ? E4_RESULT_OK_CONTROL : r;

case 0x03: /* SetTopicKey(topic, key) */
Expand Down
Loading

0 comments on commit bf6c791

Please sign in to comment.