Skip to content

Commit

Permalink
ecc: add new ECC library
Browse files Browse the repository at this point in the history
Adding a new ECC library which will be used to implement
TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8. This library was developed in the
GOBI project: http://gobi.tzi.de and extended by me for ECDSA support.

Signed-off-by: Hauke Mehrtens <[email protected]>
  • Loading branch information
hauke committed May 18, 2013
1 parent 69b839a commit 8ff6472
Show file tree
Hide file tree
Showing 8 changed files with 1,029 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Makefile.contiki
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ LDFLAGS += -Wl,--gc-sections,--undefined=_reset_vector__,--undefined=InterruptVe

CFLAGS += -DUIP_CONF_TCP=0 -DSHA2_USE_INTTYPES_H

APPS += tinydtls/aes tinydtls/sha2 tinydtls
APPS += tinydtls/aes tinydtls/sha2 tinydtls/ecc tinydtls

ccm-test: tests/ccm-test

Expand Down
4 changes: 2 additions & 2 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ package = @PACKAGE_TARNAME@-@PACKAGE_VERSION@

# files and flags
SOURCES:= dtls.c crypto.c ccm.c hmac.c debug.c netq.c
OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) aes/rijndael.o @OPT_OBJS@
OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) aes/rijndael.o ecc/ecc.o @OPT_OBJS@
HEADERS:=dtls.h hmac.h debug.h config.h uthash.h numeric.h crypto.h global.h ccm.h \
netq.h t_list.h alert.h utlist.h prng.h
CFLAGS:=-Wall -pedantic -std=c99 @CFLAGS@
CPPFLAGS:=@CPPFLAGS@ -DDTLS_CHECK_CONTENTTYPE
SUBDIRS:=tests doc sha2 aes
SUBDIRS:=tests doc sha2 aes ecc
DISTDIR=$(top_builddir)/$(package)
FILES:=Makefile.in configure configure.in config.h.in $(SOURCES) $(HEADERS)
LIB:=libtinydtls.a
Expand Down
3 changes: 2 additions & 1 deletion configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,6 @@ AC_CONFIG_FILES([Makefile
doc/Doxyfile
tests/Makefile
sha2/Makefile
aes/Makefile])
aes/Makefile
ecc/Makefile])
AC_OUTPUT
147 changes: 147 additions & 0 deletions crypto.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* dtls -- a very basic DTLS implementation
*
* Copyright (C) 2011--2012 Olaf Bergmann <[email protected]>
* Copyright (C) 2013 Hauke Mehrtens <[email protected]>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
Expand Down Expand Up @@ -34,6 +35,7 @@
#include "dtls.h"
#include "crypto.h"
#include "ccm.h"
#include "ecc/ecc.h"

#ifndef WITH_CONTIKI
#include <stdlib.h>
Expand Down Expand Up @@ -240,6 +242,151 @@ dtls_psk_pre_master_secret(unsigned char *key, size_t keylen,
return (sizeof(uint16) + keylen) << 1;
}

static void dtls_ec_key_to_uint32(const unsigned char *key, size_t key_size,
uint32_t *result) {
int i;

for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) {
*result = ntohl(((uint32_t *)key)[i]);
result++;
}
}

static void dtls_ec_key_from_uint32(const uint32_t *key, size_t key_size,
unsigned char *result) {
int i;
uint32_t *result32 = (uint32_t *)result;

for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) {
*result32 = htonl(key[i]);
result32++;
}
}

size_t dtls_ecdh_pre_master_secret(unsigned char *priv_key,
unsigned char *pub_key_x,
unsigned char *pub_key_y,
size_t key_size,
unsigned char *result) {
uint32_t priv[8];
uint32_t pub_x[8];
uint32_t pub_y[8];
uint32_t result_x[8];
uint32_t result_y[8];

dtls_ec_key_to_uint32(priv_key, key_size, priv);
dtls_ec_key_to_uint32(pub_key_x, key_size, pub_x);
dtls_ec_key_to_uint32(pub_key_y, key_size, pub_y);

ecc_ecdh(pub_x, pub_y, priv, result_x, result_y);

dtls_ec_key_from_uint32(result_x, key_size, result);
return key_size;
}

void
dtls_ecdsa_generate_key(unsigned char *priv_key,
unsigned char *pub_key_x,
unsigned char *pub_key_y,
size_t key_size) {
uint32_t priv[8];
uint32_t pub_x[8];
uint32_t pub_y[8];

do {
prng((unsigned char *)priv, key_size);
} while (!ecc_is_valid_key(priv));

ecc_gen_pub_key(priv, pub_x, pub_y);

dtls_ec_key_from_uint32(priv, key_size, priv_key);
dtls_ec_key_from_uint32(pub_x, key_size, pub_key_x);
dtls_ec_key_from_uint32(pub_y, key_size, pub_key_y);
}

/* rfc4492#section-5.4 */
void
dtls_ecdsa_create_sig_hash(const unsigned char *priv_key, size_t key_size,
const unsigned char *sign_hash, size_t sign_hash_size,
unsigned char *result_r, unsigned char *result_s) {
int ret;
uint32_t priv[8];
uint32_t hash[8];
uint32_t rand[8];
uint32_t point_r[9];
uint32_t point_s[9];

dtls_ec_key_to_uint32(priv_key, key_size, priv);
dtls_ec_key_to_uint32(sign_hash, sign_hash_size, hash);
do {
prng((unsigned char *)rand, key_size);
ret = ecc_ecdsa_sign(priv, hash, rand, point_r, point_s);
} while (ret);

dtls_ec_key_from_uint32(point_r, key_size, result_r);
dtls_ec_key_from_uint32(point_s, key_size, result_s);
}

void
dtls_ecdsa_create_sig(const unsigned char *priv_key, size_t key_size,
const unsigned char *client_random, size_t client_random_size,
const unsigned char *server_random, size_t server_random_size,
const unsigned char *keyx_params, size_t keyx_params_size,
unsigned char *result_r, unsigned char *result_s) {
dtls_hash_ctx data;
unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE];

dtls_hash_init(&data);
dtls_hash_update(&data, client_random, client_random_size);
dtls_hash_update(&data, server_random, server_random_size);
dtls_hash_update(&data, keyx_params, keyx_params_size);
dtls_hash_finalize(sha256hash, &data);

dtls_ecdsa_create_sig_hash(priv_key, key_size, sha256hash,
sizeof(sha256hash), result_r, result_s);
}

/* rfc4492#section-5.4 */
int
dtls_ecdsa_verify_sig_hash(const unsigned char *pub_key_x,
const unsigned char *pub_key_y, size_t key_size,
const unsigned char *sign_hash, size_t sign_hash_size,
unsigned char *result_r, unsigned char *result_s) {
uint32_t pub_x[8];
uint32_t pub_y[8];
uint32_t hash[8];
uint32_t point_r[8];
uint32_t point_s[8];

dtls_ec_key_to_uint32(pub_key_x, key_size, pub_x);
dtls_ec_key_to_uint32(pub_key_y, key_size, pub_y);
dtls_ec_key_to_uint32(result_r, key_size, point_r);
dtls_ec_key_to_uint32(result_s, key_size, point_s);
dtls_ec_key_to_uint32(sign_hash, sign_hash_size, hash);

return ecc_ecdsa_validate(pub_x, pub_y, hash, point_r, point_s);
}

int
dtls_ecdsa_verify_sig(const unsigned char *pub_key_x,
const unsigned char *pub_key_y, size_t key_size,
const unsigned char *client_random, size_t client_random_size,
const unsigned char *server_random, size_t server_random_size,
const unsigned char *keyx_params, size_t keyx_params_size,
unsigned char *result_r, unsigned char *result_s) {
dtls_hash_ctx data;
unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE];

dtls_hash_init(&data);
dtls_hash_update(&data, client_random, client_random_size);
dtls_hash_update(&data, server_random, server_random_size);
dtls_hash_update(&data, keyx_params, keyx_params_size);
dtls_hash_finalize(sha256hash, &data);

return dtls_ecdsa_verify_sig_hash(pub_key_x, pub_key_y, key_size, sha256hash,
sizeof(sha256hash), result_r, result_s);
}

void
dtls_cipher_set_iv(dtls_cipher_context_t *ctx,
unsigned char *iv, size_t length) {
Expand Down
34 changes: 34 additions & 0 deletions crypto.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* dtls -- a very basic DTLS implementation
*
* Copyright (C) 2011--2012 Olaf Bergmann <[email protected]>
* Copyright (C) 2013 Hauke Mehrtens <[email protected]>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
Expand Down Expand Up @@ -267,6 +268,39 @@ int dtls_decrypt(dtls_cipher_context_t *ctx,
size_t dtls_psk_pre_master_secret(unsigned char *key, size_t keylen,
unsigned char *result);

size_t dtls_ecdh_pre_master_secret(unsigned char *priv_key,
unsigned char *pub_key_x,
unsigned char *pub_key_y,
size_t key_size,
unsigned char *result);

void dtls_ecdsa_generate_key(unsigned char *priv_key,
unsigned char *pub_key_x,
unsigned char *pub_key_y,
size_t key_size);

void dtls_ecdsa_create_sig_hash(const unsigned char *priv_key, size_t key_size,
const unsigned char *sign_hash, size_t sign_hash_size,
unsigned char *result_r, unsigned char *result_s);

void dtls_ecdsa_create_sig(const unsigned char *priv_key, size_t key_size,
const unsigned char *client_random, size_t client_random_size,
const unsigned char *server_random, size_t server_random_size,
const unsigned char *keyx_params, size_t keyx_params_size,
unsigned char *result_r, unsigned char *result_s);

int dtls_ecdsa_verify_sig_hash(const unsigned char *pub_key_x,
const unsigned char *pub_key_y, size_t key_size,
const unsigned char *sign_hash, size_t sign_hash_size,
unsigned char *result_r, unsigned char *result_s);

int dtls_ecdsa_verify_sig(const unsigned char *pub_key_x,
const unsigned char *pub_key_y, size_t key_size,
const unsigned char *client_random, size_t client_random_size,
const unsigned char *server_random, size_t server_random_size,
const unsigned char *keyx_params, size_t keyx_params_size,
unsigned char *result_r, unsigned char *result_s);

/**
* Creates a new dtls_cipher_context_t object for given @c cipher.
* The storage allocated for this object must be released using
Expand Down
73 changes: 73 additions & 0 deletions ecc/Makefile.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Makefile for tinydtls
#
# Copyright (C) 2011 Olaf Bergmann <[email protected]>
# Copyright (C) 2013 Hauke Mehrtens <[email protected]>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use, copy,
# modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# the library's version
VERSION:=@PACKAGE_VERSION@

# tools
@SET_MAKE@
SHELL = /bin/sh
MKDIR = mkdir

abs_builddir = @abs_builddir@
top_builddir = @top_builddir@
top_srcdir:= @top_srcdir@

SOURCES:= ecc.c
HEADERS:= ecc.h
OBJECTS:= $(patsubst %.c, %.o, $(SOURCES))
CPPFLAGS=@CPPFLAGS@
CFLAGS=-Wall -std=c99 -pedantic @CFLAGS@
LDLIBS=@LIBS@
FILES:=Makefile.in $(SOURCES) $(HEADERS)
DISTDIR=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@

.PHONY: all dirs clean distclean .gitignore doc

.SUFFIXES:
.SUFFIXES: .c .o

all:

check:
echo DISTDIR: $(DISTDIR)
echo top_builddir: $(top_builddir)

clean:
@rm -f $(PROGRAMS) main.o $(LIB) $(OBJECTS)
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir clean ; \
done

distclean: clean
@rm -rf $(DISTDIR)
@rm -f *~ $(DISTDIR).tar.gz

dist: $(FILES)
test -d $(DISTDIR)/ecc || mkdir $(DISTDIR)/ecc
cp -p $(FILES) $(DISTDIR)/ecc

.gitignore:
echo "core\n*~\n*.[oa]\n*.gz\n*.cap\n$(PROGRAM)\n$(DISTDIR)\n.gitignore" >$@
Loading

0 comments on commit 8ff6472

Please sign in to comment.