]> git.cryptolib.org Git - arm-crypto-lib.git/commitdiff
adding PRF TLSv1.2
authorbg <daniel.otte@rub.de>
Fri, 7 Oct 2011 02:46:05 +0000 (04:46 +0200)
committerbg <daniel.otte@rub.de>
Fri, 7 Oct 2011 02:46:05 +0000 (04:46 +0200)
hfal/hfal-hmac.c
hfal/hfal-hmac.h
mkfiles/prf_tls12.mk [new file with mode: 0644]
prf_tls12/prf_tls12.c [new file with mode: 0644]
prf_tls12/prf_tls12.h [new file with mode: 0644]
sha1/sha1.c
sha256/sha256.c
test_src/main-prf_tls12-test.c [new file with mode: 0644]

index f36b58e7683b75a7fba50ee5e5bf3ebc87f4b70d..6f5fbf9bc7c32ae546b9f4fce960ffca70a2d43e 100644 (file)
@@ -69,16 +69,16 @@ uint8_t hfal_hmac_init(const hfdesc_t* hash_descriptor,
        return 0;
 }
 
-int hfal_hmac_ctxcopy(hfhmacgen_ctx_t* dest, hfhmacgen_ctx_t* src){
+uint8_t hfal_hmac_ctxcopy(hfhmacgen_ctx_t* dest, hfhmacgen_ctx_t* src){
        dest->desc = src->desc;
        dest->ctx = malloc(dest->desc->ctxsize_B);
        if(dest->ctx == NULL){
-               return -1;
+               return 1;
        }
        memcpy(dest->ctx, src->ctx, dest->desc->ctxsize_B);
        dest->finctx = malloc(dest->desc->ctxsize_B);
        if(dest->finctx == NULL){
-               return -1;
+               return 1;
        }
        memcpy(dest->finctx, src->finctx, dest->desc->ctxsize_B);
        return 0;
index 63cb016eb0c4944f994e0cd50c29d5750df82879..4c1c738c86558fc6b79bd99ae6dcea099d27f46d 100644 (file)
@@ -29,7 +29,7 @@ typedef struct {
 } hfhmacgen_ctx_t;
 
 uint8_t hfal_hmac_init(const hfdesc_t* hash_descriptor, hfhmacgen_ctx_t* ctx, const void* key, uint16_t keylength_b);
-int hfal_hmac_ctxcopy(hfhmacgen_ctx_t* dest, hfhmacgen_ctx_t* src);
+uint8_t hfal_hmac_ctxcopy(hfhmacgen_ctx_t* dest, hfhmacgen_ctx_t* src);
 void hfal_hmac_nextBlock(hfhmacgen_ctx_t* ctx, const void* block);
 void hfal_hmac_lastBlock(hfhmacgen_ctx_t* ctx, const void* block, uint16_t length_b);
 void hfal_hmac_ctx2mac(void* dest, hfhmacgen_ctx_t* ctx);
diff --git a/mkfiles/prf_tls12.mk b/mkfiles/prf_tls12.mk
new file mode 100644 (file)
index 0000000..dcf8d62
--- /dev/null
@@ -0,0 +1,14 @@
+# Makefile for PRF Tlsv1.2
+ALGO_NAME := PRF_TLS12
+
+# comment out the following line for removement of PRF TLSv1.2 from the build process
+AUX += $(ALGO_NAME)
+
+$(ALGO_NAME)_DIR      := prf_tls12/
+$(ALGO_NAME)_INCDIR   := hmac/ sha1/ sha256/ hfal/
+$(ALGO_NAME)_OBJ      := prf_tls12.o
+$(ALGO_NAME)_TESTBIN := main-prf_tls12-test.o $(CLI_STD) hfal_sha1.o hfal_sha256.o $(HFAL_STD) \
+                        sha256.o sha1.o hfal-hmac.o
+                        
+$(ALGO_NAME)_PERFORMANCE_TEST := performance
+
diff --git a/prf_tls12/prf_tls12.c b/prf_tls12/prf_tls12.c
new file mode 100644 (file)
index 0000000..8b84d52
--- /dev/null
@@ -0,0 +1,135 @@
+/* prf_tls12.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file    prf_tls12.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2011-10-06
+ * \license GPLv3 or later
+ *
+ */
+/* from rfc5246
+
+
+      P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
+                             HMAC_hash(secret, A(2) + seed) +
+                             HMAC_hash(secret, A(3) + seed) + ...
+
+   where + indicates concatenation.
+
+   A() is defined as:
+
+      A(0) = seed
+      A(i) = HMAC_hash(secret, A(i-1))
+
+   P_hash can be iterated as many times as necessary to produce the
+   required quantity of data.  For example, if P_SHA256 is being used to
+   create 80 bytes of data, it will have to be iterated three times
+   (through A(3)), creating 96 bytes of output data; the last 16 bytes
+   of the final iteration will then be discarded, leaving 80 bytes of
+   output data.
+
+   TLS's PRF is created by applying P_hash to the secret as:
+
+      PRF(secret, label, seed) = P_<hash>(secret, label + seed)
+
+*/
+/* long story short:
+ * P(k,s) = H(k, A(1) | s) | H(k, A(2) | s) | ... | H(k, A(n) | s)
+ * A(0) = s
+ * A(i) = H(k, A(i-1))
+ *
+ * PRF(k,l,s) = P(k, l | s)
+ *
+ */
+
+/* This implementation is limited to hashfunctions which return a hash value
+ * of a length (in bits) which is divideable by 8.
+ *
+ * Also note that our HMAC implementation may fail on hashfunction which
+ * return a larger hash value then their nativ blocksize
+ *
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <crypto/hashfunction_descriptor.h>
+#include <crypto/hfal-basic.h>
+#include <crypto/hfal-hmac.h>
+#include "prf_tls12.h"
+
+uint8_t prf_tls12_init(prf_tls12_ctx_t* ctx, const hfdesc_t* hash,
+       const void* key, uint16_t keylength_b,
+       const void* seed, uint16_t seedlength_b){
+       hfhmacgen_ctx_t tmp_ctx;
+       ctx->blocklength_b = hfal_hash_getHashsize(hash);
+       ctx->seed_buffer = malloc(ctx->blocklength_b/8+(seedlength_b+7)/8);
+       if(!ctx->seed_buffer){
+               return 1;
+       }
+       ctx->bufferlength_b = ctx->blocklength_b + seedlength_b;
+       memcpy(ctx->seed_buffer+ctx->blocklength_b/8, seed, seedlength_b/8);
+       if(hfal_hmac_init(hash, &(ctx->mainctx), key, keylength_b)){
+               return 2;
+       }
+       if(hfal_hmac_ctxcopy(&tmp_ctx, &(ctx->mainctx))){
+               prf_tls12_free(ctx);
+               return 3;
+       }
+       hfal_hmac_lastBlock(&tmp_ctx, seed, seedlength_b);
+       hfal_hmac_ctx2mac(ctx->seed_buffer, &tmp_ctx);
+       hfal_hmac_free(&tmp_ctx);
+       return 0;
+}
+
+uint8_t prf_tls12_init_w_label(prf_tls12_ctx_t* ctx, const hfdesc_t* hash,
+       const void* key, uint16_t keylength_b,
+       const void* label, uint16_t labellength_B,
+       const void* seed, uint16_t seedlength_b){
+
+       uint8_t buffer[labellength_B+(seedlength_b+7)/8];
+       memcpy(buffer, label, labellength_B);
+       memcpy(buffer+labellength_B, seed, (seedlength_b+7)/8);
+       return prf_tls12_init(ctx, hash, key, keylength_b, buffer, labellength_B*8+seedlength_b);
+}
+
+
+void prf_tls12_free(prf_tls12_ctx_t* ctx){
+       free(ctx->seed_buffer);
+       hfal_hmac_free(&(ctx->mainctx));
+}
+
+uint8_t prf_tls12_next(void* dest, prf_tls12_ctx_t* ctx){
+       hfhmacgen_ctx_t tmp_ctx;
+       if(hfal_hmac_ctxcopy(&tmp_ctx, &(ctx->mainctx))){
+               return 1;
+       }
+       hfal_hmac_lastBlock(&tmp_ctx, ctx->seed_buffer, ctx->bufferlength_b);
+       hfal_hmac_ctx2mac(dest, &tmp_ctx);
+       hfal_hmac_free(&tmp_ctx);
+       if(hfal_hmac_ctxcopy(&tmp_ctx, &(ctx->mainctx))){
+               return 2;
+       }
+       hfal_hmac_lastBlock(&tmp_ctx, ctx->seed_buffer, ctx->blocklength_b);
+       hfal_hmac_ctx2mac(ctx->seed_buffer, &tmp_ctx);
+       hfal_hmac_free(&tmp_ctx);
+       return 0;
+}
+
diff --git a/prf_tls12/prf_tls12.h b/prf_tls12/prf_tls12.h
new file mode 100644 (file)
index 0000000..759580d
--- /dev/null
@@ -0,0 +1,48 @@
+/* prf_tls12.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2011 Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef PRF_TLS12_H_
+#define PRF_TLS12_H_
+
+#include <stdint.h>
+#include <crypto/hashfunction_descriptor.h>
+#include <crypto/hfal-basic.h>
+#include <crypto/hfal-hmac.h>
+
+typedef struct{
+       hfhmacgen_ctx_t mainctx;
+       uint16_t blocklength_b;
+       uint16_t bufferlength_b;
+       uint8_t* seed_buffer;
+} prf_tls12_ctx_t;
+
+uint8_t prf_tls12_init(prf_tls12_ctx_t* ctx, const hfdesc_t* hash,
+       const void* key, uint16_t keylength_b,
+       const void* seed, uint16_t seedlength_b);
+
+uint8_t prf_tls12_init_w_label(prf_tls12_ctx_t* ctx, const hfdesc_t* hash,
+       const void* key, uint16_t keylength_b,
+       const void* label, uint16_t labellength_B,
+       const void* seed, uint16_t seedlength_b);
+
+void prf_tls12_free(prf_tls12_ctx_t* ctx);
+uint8_t prf_tls12_next(void* dest, prf_tls12_ctx_t* ctx);
+
+
+#endif /* PRF_TLS12_H_ */
index a8b881219ee14855bf2e0e21e123a848ffdb3271..740fe67a96b5426d65da836aa13449af0715239f 100644 (file)
@@ -52,12 +52,12 @@ void sha1_init(sha1_ctx_t *state){
 
 /********************************************************************************************************/
 /* some helping functions */
-const
+static const
 uint32_t rotl32(uint32_t n, uint8_t bits){
        return ((n<<bits) | (n>>(32-bits)));
 }
 
-const
+static const
 uint32_t change_endian32(uint32_t x){
        return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
 }
index 83b3a438c21ff5d41fd7a65b0a65e4218d46af6f..c121466bc37685b5ccc755d1d740f29b6f2b67a6 100644 (file)
@@ -68,6 +68,7 @@ void sha256_init(sha256_ctx_t *state){
 /**
  * rotate x right by n positions
  */
+static
 uint32_t rotr32( uint32_t x, uint8_t n){
        return ((x>>n) | (x<<(32-n)));
 }
@@ -76,7 +77,7 @@ uint32_t rotr32( uint32_t x, uint8_t n){
 /*************************************************************************/
 
 // #define CHANGE_ENDIAN32(x) (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8))
-
+static
 uint32_t change_endian32(uint32_t x){
        return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
 }
diff --git a/test_src/main-prf_tls12-test.c b/test_src/main-prf_tls12-test.c
new file mode 100644 (file)
index 0000000..037b379
--- /dev/null
@@ -0,0 +1,124 @@
+/* main-prf_tls12-test.c */
+/*
+    This file is part of the ARM-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * DSA test-suit
+ *
+*/
+
+#include "main-test-common.h"
+#include "prf_tls12.h"
+#include <crypto/hashfunction_descriptor.h>
+#include <crypto/hfal_sha1.h>
+#include <crypto/hfal_sha256.h>
+const char* algo_name = "PRF-TLS1.2";
+
+/*****************************************************************************
+ *  additional validation-functions                                                                                     *
+ *****************************************************************************/
+
+/*
+# Generating 100 bytes of pseudo-randomness using TLS1.2PRF-SHA256
+Secret (16 bytes):
+0000    9b be 43 6b a9 40 f0 17    ..Ck....
+0008    b1 76 52 84 9a 71 db 35    .vR..q.5
+
+Seed (16 bytes):
+0000    a0 ba 9f 93 6c da 31 18    ....l.1.
+0008    27 a6 f7 96 ff d5 19 8c    ........
+
+Label (10 bytes):
+0000    74 65 73 74 20 6c 61 62    test lab
+0008    65 6c                      el
+
+Output (100 bytes):
+0000    e3 f2 29 ba 72 7b e1 7b    ....r...
+0008    8d 12 26 20 55 7c d4 53    ... U..S
+0010    c2 aa b2 1d 07 c3 d4 95    ........
+0018    32 9b 52 d4 e6 1e db 5a    2.R....Z
+0020    6b 30 17 91 e9 0d 35 c9    k0....5.
+0028    c9 a4 6b 4e 14 ba f9 af    ..kN....
+0030    0f a0 22 f7 07 7d ef 17    ........
+0038    ab fd 37 97 c0 56 4b ab    ..7..VK.
+0040    4f bc 91 66 6e 9d ef 9b    O..fn...
+0048    97 fc e3 4f 79 67 89 ba    ...Oyg..
+0050    a4 80 82 d1 22 ee 42 c5    ......B.
+0058    a7 2e 5a 51 10 ff f7 01    ..ZQ....
+0060    87 34 7b 66                .4.f
+ */
+
+const uint8_t test_secret[] = {
+       0x9b, 0xbe, 0x43, 0x6b, 0xa9, 0x40, 0xf0, 0x17,
+       0xb1, 0x76, 0x52, 0x84, 0x9a, 0x71, 0xdb, 0x35
+};
+
+const uint8_t test_seed[] = {
+       0xa0, 0xba, 0x9f, 0x93, 0x6c, 0xda, 0x31, 0x18,
+       0x27, 0xa6, 0xf7, 0x96, 0xff, 0xd5, 0x19, 0x8c
+};
+
+const char test_label[] = "test label";
+
+void test_prf(const hfdesc_t* hash){
+       prf_tls12_ctx_t ctx;
+       prf_tls12_init_w_label(&ctx, hash, test_secret, 16*8, test_label, strlen(test_label), test_seed, 16*8);
+       uint8_t buffer[ctx.blocklength_b/8];
+       uint16_t i=0;
+       cli_putstr("\r\n== Testing PRF-TLSv1.2 with ");
+       cli_putstr(hash->name);
+       cli_putstr(" ==\r\n");
+       do{
+               prf_tls12_next(buffer, &ctx);
+               cli_hexdump_block(buffer, ctx.blocklength_b/8, 4, 8);
+               i += ctx.blocklength_b/8;
+       }while(i<100);
+}
+
+void test_sha256(void){
+       test_prf(&sha256_desc);
+}
+
+void test_sha1(void){
+       test_prf(&sha1_desc);
+}
+/*****************************************************************************
+ *  main                                                                                                                                        *
+ *****************************************************************************/
+
+const char echo_test_str[]     = "echo-test";
+const char test_sha256_str[]   = "test-sha256";
+const char test_sha1_str[]     = "test-sha1";
+//const char performance_str[]   = "performance";
+const char echo_str[]          = "echo";
+
+cmdlist_entry_t cmdlist[] = {
+       { test_sha256_str,      NULL, test_sha256                   },
+       { test_sha1_str,        NULL, test_sha1                     },
+//     { performance_str,      NULL, testrun_performance_bigint    },
+       { echo_str,         (void*)1, (void_fpt)echo_ctrl           },
+       { NULL,                 NULL, NULL                          }
+};
+
+int main (void){
+       main_setup();
+
+       for(;;){
+               welcome_msg(algo_name);
+               cmd_interface(cmdlist);
+       }
+}