adding PRF TLSv1.2

This commit is contained in:
bg 2011-10-07 04:46:05 +02:00
parent 1ee55d2589
commit b9d6e1eb86
8 changed files with 329 additions and 7 deletions

View 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;

View 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);

14
mkfiles/prf_tls12.mk Normal file
View File

@ -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

135
prf_tls12/prf_tls12.c Normal file
View File

@ -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;
}

48
prf_tls12/prf_tls12.h Normal file
View File

@ -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_ */

View 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));
}

View 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));
}

View File

@ -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);
}
}