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;
} 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);
--- /dev/null
+# 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
+
--- /dev/null
+/* 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;
+}
+
--- /dev/null
+/* 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_ */
/********************************************************************************************************/
/* 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));
}
/**
* rotate x right by n positions
*/
+static
uint32_t rotr32( uint32_t x, uint8_t n){
return ((x>>n) | (x<<(32-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));
}
--- /dev/null
+/* 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);
+ }
+}