adding PRF TLSv1.2
This commit is contained in:
parent
1ee55d2589
commit
b9d6e1eb86
|
@ -69,16 +69,16 @@ uint8_t hfal_hmac_init(const hfdesc_t* hash_descriptor,
|
||||||
return 0;
|
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->desc = src->desc;
|
||||||
dest->ctx = malloc(dest->desc->ctxsize_B);
|
dest->ctx = malloc(dest->desc->ctxsize_B);
|
||||||
if(dest->ctx == NULL){
|
if(dest->ctx == NULL){
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
memcpy(dest->ctx, src->ctx, dest->desc->ctxsize_B);
|
memcpy(dest->ctx, src->ctx, dest->desc->ctxsize_B);
|
||||||
dest->finctx = malloc(dest->desc->ctxsize_B);
|
dest->finctx = malloc(dest->desc->ctxsize_B);
|
||||||
if(dest->finctx == NULL){
|
if(dest->finctx == NULL){
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
memcpy(dest->finctx, src->finctx, dest->desc->ctxsize_B);
|
memcpy(dest->finctx, src->finctx, dest->desc->ctxsize_B);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -29,7 +29,7 @@ typedef struct {
|
||||||
} hfhmacgen_ctx_t;
|
} hfhmacgen_ctx_t;
|
||||||
|
|
||||||
uint8_t hfal_hmac_init(const hfdesc_t* hash_descriptor, hfhmacgen_ctx_t* ctx, const void* key, uint16_t keylength_b);
|
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_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_lastBlock(hfhmacgen_ctx_t* ctx, const void* block, uint16_t length_b);
|
||||||
void hfal_hmac_ctx2mac(void* dest, hfhmacgen_ctx_t* ctx);
|
void hfal_hmac_ctx2mac(void* dest, hfhmacgen_ctx_t* ctx);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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_ */
|
|
@ -52,12 +52,12 @@ void sha1_init(sha1_ctx_t *state){
|
||||||
|
|
||||||
/********************************************************************************************************/
|
/********************************************************************************************************/
|
||||||
/* some helping functions */
|
/* some helping functions */
|
||||||
const
|
static const
|
||||||
uint32_t rotl32(uint32_t n, uint8_t bits){
|
uint32_t rotl32(uint32_t n, uint8_t bits){
|
||||||
return ((n<<bits) | (n>>(32-bits)));
|
return ((n<<bits) | (n>>(32-bits)));
|
||||||
}
|
}
|
||||||
|
|
||||||
const
|
static const
|
||||||
uint32_t change_endian32(uint32_t x){
|
uint32_t change_endian32(uint32_t x){
|
||||||
return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
|
return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ void sha256_init(sha256_ctx_t *state){
|
||||||
/**
|
/**
|
||||||
* rotate x right by n positions
|
* rotate x right by n positions
|
||||||
*/
|
*/
|
||||||
|
static
|
||||||
uint32_t rotr32( uint32_t x, uint8_t n){
|
uint32_t rotr32( uint32_t x, uint8_t n){
|
||||||
return ((x>>n) | (x<<(32-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))
|
// #define CHANGE_ENDIAN32(x) (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8))
|
||||||
|
static
|
||||||
uint32_t change_endian32(uint32_t x){
|
uint32_t change_endian32(uint32_t x){
|
||||||
return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
|
return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue