From a13302adf489028265a98b192e5aa9684b203654 Mon Sep 17 00:00:00 2001 From: Gregory Date: Fri, 29 Mar 2019 02:06:29 +0200 Subject: [PATCH] pbkdf2 sha256 done --- Makefile | 4 +- inc/ft_pbkdf2.h | 51 ++++++++- src/pbkdf2/ft_hmac_sha256.c | 63 ++++++----- src/pbkdf2/ft_hmac_sha256_init_ctx.c | 3 +- src/pbkdf2/ft_pbkdf2_sha256.c | 102 +++++++++++++++++ src/pbkdf2/ft_pbkdf2_sha256_init_ctx.c | 16 +++ t/pbkdf2_tests.c | 148 +++++++++++++++++++++++-- 7 files changed, 349 insertions(+), 38 deletions(-) create mode 100644 src/pbkdf2/ft_pbkdf2_sha256.c create mode 100644 src/pbkdf2/ft_pbkdf2_sha256_init_ctx.c diff --git a/Makefile b/Makefile index b9df8265..f3170572 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,9 @@ DES_SRC = ft_des_initial_permutation.c \ ft_des_ecb_finish_encrypt.c KD2_SRC = ft_hmac_sha256_init_ctx.c \ - ft_hmac_sha256.c + ft_hmac_sha256.c \ + ft_pbkdf2_sha256_init_ctx.c \ + ft_pbkdf2_sha256.c SRC = main.c \ ft_ssl_usage.c diff --git a/inc/ft_pbkdf2.h b/inc/ft_pbkdf2.h index e8e64270..55ffe5cb 100644 --- a/inc/ft_pbkdf2.h +++ b/inc/ft_pbkdf2.h @@ -2,25 +2,68 @@ #ifndef FT_PBKDF2_H # define FT_PBKDF2_H -#define FT_PBKDF2_RESULT 32 +# include "ft_sha.h" + +typedef struct s_pbkdf2_sha256_ctx +{ + unsigned char *pass; + unsigned char *salt; + unsigned char *key; + unsigned int key_len; + unsigned int pass_len; + unsigned int salt_len; + unsigned int iterations; +} t_pbkdf2_sha256_ctx; typedef struct s_hmac_sha256_ctx { unsigned char *key; unsigned char *msg; - unsigned char out[FT_PBKDF2_RESULT]; unsigned int key_size; unsigned int msg_size; + unsigned char ipad[FT_SHA256_BLOCK_SIZE]; + unsigned char opad[FT_SHA256_BLOCK_SIZE]; + t_sha256_ctx sha_ctx; } t_hmac_sha256_ctx; -void ft_hmac_sha256_init_ctx +void ft_hmac_sha256_init_ctx ( t_hmac_sha256_ctx *ctx ); -void ft_hmac_sha256 +void ft_hmac_sha256 +( + t_hmac_sha256_ctx *ctx, + unsigned char out[FT_SHA256_DIGEST_LENGTH_BYTE] +); + +void ft_hmac_sha256_start ( t_hmac_sha256_ctx *ctx ); +void ft_hmac_sha256_update +( + t_hmac_sha256_ctx *ctx, + unsigned char *msg, + unsigned int msg_size +); + +void ft_hmac_sha256_finish +( + t_hmac_sha256_ctx *ctx, + unsigned char out[FT_SHA256_DIGEST_LENGTH_BYTE] +); + +void ft_pbkdf2_sha256_init_ctx +( + t_pbkdf2_sha256_ctx *ctx +); + +void ft_pbkdf2_sha256 +( + t_pbkdf2_sha256_ctx *ctx +); + + #endif \ No newline at end of file diff --git a/src/pbkdf2/ft_hmac_sha256.c b/src/pbkdf2/ft_hmac_sha256.c index 22737f45..4e43e166 100644 --- a/src/pbkdf2/ft_hmac_sha256.c +++ b/src/pbkdf2/ft_hmac_sha256.c @@ -4,8 +4,7 @@ static void set_padding ( - unsigned char ipad[FT_SHA256_BLOCK_SIZE], - unsigned char opad[FT_SHA256_BLOCK_SIZE], + t_hmac_sha256_ctx *ctx, unsigned char key[FT_SHA256_BLOCK_SIZE] ) { @@ -14,49 +13,63 @@ static void set_padding i = 0; while(i < FT_SHA256_BLOCK_SIZE) { - ipad[i] = key[i] ^ 0x36; - opad[i] = key[i] ^ 0x5c; + ctx->ipad[i] = key[i] ^ 0x36; + ctx->opad[i] = key[i] ^ 0x5c; i++; } } -static void finish +void ft_hmac_sha256_finish ( t_hmac_sha256_ctx *ctx, - t_sha256_ctx *sha256_ctx, - unsigned char ipad[FT_SHA256_BLOCK_SIZE], - unsigned char opad[FT_SHA256_BLOCK_SIZE] + unsigned char out[FT_SHA256_DIGEST_LENGTH_BYTE] ) { - ft_sha256_init(sha256_ctx); - ft_sha256_update(sha256_ctx, ipad, FT_SHA256_BLOCK_SIZE); - ft_sha256_update(sha256_ctx, ctx->msg, ctx->msg_size); - ft_sha256_final(ctx->out, sha256_ctx); - ft_sha256_init(sha256_ctx); - ft_sha256_update(sha256_ctx, opad, FT_SHA256_BLOCK_SIZE); - ft_sha256_update(sha256_ctx, ctx->out, FT_SHA256_DIGEST_LENGTH_BYTE); - ft_sha256_final(ctx->out, sha256_ctx); + ft_sha256_final(out, &ctx->sha_ctx); + ft_sha256_init(&ctx->sha_ctx); + ft_sha256_update(&ctx->sha_ctx, ctx->opad, FT_SHA256_BLOCK_SIZE); + ft_sha256_update(&ctx->sha_ctx, out, FT_SHA256_DIGEST_LENGTH_BYTE); + ft_sha256_final(out, &ctx->sha_ctx); } -void ft_hmac_sha256 +void ft_hmac_sha256_start ( t_hmac_sha256_ctx *ctx ) { - t_sha256_ctx sha256_ctx; unsigned char key[FT_SHA256_BLOCK_SIZE]; - unsigned char ipad[FT_SHA256_BLOCK_SIZE]; - unsigned char opad[FT_SHA256_BLOCK_SIZE]; ft_bzero(key, FT_SHA256_BLOCK_SIZE); if (ctx->key_size > FT_SHA256_BLOCK_SIZE) { - ft_sha256_init(&sha256_ctx); - ft_sha256_update(&sha256_ctx, ctx->key, ctx->key_size); - ft_sha256_final(key, &sha256_ctx); + ft_sha256_init(&ctx->sha_ctx); + ft_sha256_update(&ctx->sha_ctx, ctx->key, ctx->key_size); + ft_sha256_final(key, &ctx->sha_ctx); } else ft_memcpy(key, ctx->key, ctx->key_size); - set_padding(ipad, opad, key); - finish(ctx, &sha256_ctx, ipad, opad); + set_padding(ctx, key); + ft_sha256_init(&ctx->sha_ctx); + ft_sha256_update(&ctx->sha_ctx, ctx->ipad, FT_SHA256_BLOCK_SIZE); +} + +void ft_hmac_sha256_update +( + t_hmac_sha256_ctx *ctx, + unsigned char *msg, + unsigned int msg_size +) +{ + ft_sha256_update(&ctx->sha_ctx, msg, msg_size); +} + +void ft_hmac_sha256 +( + t_hmac_sha256_ctx *ctx, + unsigned char out[FT_SHA256_DIGEST_LENGTH_BYTE] +) +{ + ft_hmac_sha256_start(ctx); + ft_hmac_sha256_update(ctx, ctx->msg, ctx->msg_size); + ft_hmac_sha256_finish(ctx, out); } \ No newline at end of file diff --git a/src/pbkdf2/ft_hmac_sha256_init_ctx.c b/src/pbkdf2/ft_hmac_sha256_init_ctx.c index 42cb3491..b63b4026 100644 --- a/src/pbkdf2/ft_hmac_sha256_init_ctx.c +++ b/src/pbkdf2/ft_hmac_sha256_init_ctx.c @@ -12,5 +12,6 @@ void ft_hmac_sha256_init_ctx ctx->msg = NULL; ctx->key_size = 0; ctx->msg_size = 0; - ft_bzero(ctx->out, FT_SHA256_DIGEST_LENGTH_BYTE); + ft_bzero(ctx->opad, FT_SHA256_BLOCK_SIZE); + ft_bzero(ctx->ipad, FT_SHA256_BLOCK_SIZE); } \ No newline at end of file diff --git a/src/pbkdf2/ft_pbkdf2_sha256.c b/src/pbkdf2/ft_pbkdf2_sha256.c new file mode 100644 index 00000000..8e2c6e3a --- /dev/null +++ b/src/pbkdf2/ft_pbkdf2_sha256.c @@ -0,0 +1,102 @@ +#include "ft_pbkdf2.h" +#include "ft_sha.h" +#include "libft.h" + +static void set_key_and_message +( + t_pbkdf2_sha256_ctx *ctx, + t_hmac_sha256_ctx *hmac_ctx +) +{ + hmac_ctx->key = ctx->pass; + hmac_ctx->key_size = ctx->pass_len; + hmac_ctx->msg = ctx->salt; + hmac_ctx->msg_size = ctx->salt_len; +} + +static void xor +( + unsigned char x[FT_SHA256_DIGEST_LENGTH_BYTE], + unsigned char y[FT_SHA256_DIGEST_LENGTH_BYTE], + unsigned char result[FT_SHA256_DIGEST_LENGTH_BYTE] +) +{ + unsigned int i; + + i = 0; + while(i < FT_SHA256_DIGEST_LENGTH_BYTE) + { + result[i] = x[i] ^ y[i]; + i++; + } +} + +static int ceil +( + unsigned int x, + unsigned int y +) +{ + return 1 + ((x - 1) / y); +} + +static void block_function +( + t_pbkdf2_sha256_ctx *ctx, + t_hmac_sha256_ctx *hmac_ctx, + unsigned int iteration, + unsigned char block[FT_SHA256_DIGEST_LENGTH_BYTE] +) + +{ + unsigned int i; + unsigned char c[4]; + unsigned char prev[FT_SHA256_DIGEST_LENGTH_BYTE]; + + c[0] = (iteration >> 24) & 0xff; + c[1] = (iteration >> 16) & 0xff; + c[2] = (iteration >> 8) & 0xff; + c[3] = (iteration >> 0) & 0xff; + ft_hmac_sha256_start(hmac_ctx); + ft_hmac_sha256_update(hmac_ctx, hmac_ctx->msg, hmac_ctx->msg_size); + ft_hmac_sha256_update(hmac_ctx, c, 4); + ft_hmac_sha256_finish(hmac_ctx, prev); + ft_memcpy(block, prev, FT_SHA256_DIGEST_LENGTH_BYTE); + i = 1; + while (i < ctx->iterations) + { + ft_hmac_sha256_start(hmac_ctx); + ft_hmac_sha256_update(hmac_ctx, prev, FT_SHA256_DIGEST_LENGTH_BYTE); + ft_hmac_sha256_finish(hmac_ctx, prev); + xor(prev, block, block); + i++; + } +} + +void ft_pbkdf2_sha256 +( + t_pbkdf2_sha256_ctx *c +) +{ + t_hmac_sha256_ctx hmac_ctx; + unsigned char block[FT_SHA256_DIGEST_LENGTH_BYTE]; + unsigned int block_count; + unsigned int i; + unsigned int key_index; + + ft_hmac_sha256_init_ctx(&hmac_ctx); + set_key_and_message(c, &hmac_ctx); + block_count = ceil(c->key_len, FT_SHA256_DIGEST_LENGTH_BYTE); + i = 1; + key_index = 0; + while(i < block_count) + { + block_function(c, &hmac_ctx, i, block); + ft_memcpy(c->key + key_index, block, FT_SHA256_DIGEST_LENGTH_BYTE); + key_index += i * FT_SHA256_DIGEST_LENGTH_BYTE; + i++; + } + block_function(c, &hmac_ctx, i, block); + ft_memcpy(c->key + key_index ,block, + c->key_len - (block_count - 1) * FT_SHA256_DIGEST_LENGTH_BYTE); +} \ No newline at end of file diff --git a/src/pbkdf2/ft_pbkdf2_sha256_init_ctx.c b/src/pbkdf2/ft_pbkdf2_sha256_init_ctx.c new file mode 100644 index 00000000..2f916091 --- /dev/null +++ b/src/pbkdf2/ft_pbkdf2_sha256_init_ctx.c @@ -0,0 +1,16 @@ +#include +#include "ft_pbkdf2.h" + +void ft_pbkdf2_sha256_init_ctx +( + t_pbkdf2_sha256_ctx *ctx +) +{ + ctx->iterations = 0; + ctx->key = NULL; + ctx->pass = NULL; + ctx->salt = NULL; + ctx->key_len = 0; + ctx->pass_len = 0; + ctx->salt_len = 0; +} \ No newline at end of file diff --git a/t/pbkdf2_tests.c b/t/pbkdf2_tests.c index 61814eff..89d4523e 100644 --- a/t/pbkdf2_tests.c +++ b/t/pbkdf2_tests.c @@ -2,20 +2,22 @@ #include "tests.h" #include "ft_pbkdf2.h" #include "ft_sha.h" +#include "libft.h" static int init_hmac_sha256_ctx() { t_hmac_sha256_ctx ctx; - int i = 0; ft_hmac_sha256_init_ctx(&ctx); _is(ctx.key == NULL); _is(ctx.msg == NULL); _is(ctx.key_size == 0); _is(ctx.msg_size == 0); - while(i < FT_SHA256_DIGEST_LENGTH_BYTE) + int i = 0; + while(i < FT_SHA256_BLOCK_SIZE) { - _is(ctx.out[i] == 0); + _is(ctx.opad[i] == 0); + _is(ctx.ipad[i] == 0); i++; } _end("init hmac sha256 ctx"); @@ -39,17 +41,18 @@ static int perform_hmac_256_computation_short_key() 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7, }; + unsigned char out[FT_SHA256_DIGEST_LENGTH_BYTE]; ft_hmac_sha256_init_ctx(&ctx); ctx.key = key; ctx.msg = msg; ctx.key_size = 20; ctx.msg_size = 8; - ft_hmac_sha256(&ctx); + ft_hmac_sha256(&ctx, out); int i = 0; while(i < FT_SHA256_DIGEST_LENGTH_BYTE) { - _is(ctx.out[i] == expected_result[i]); + _is(out[i] == expected_result[i]); i++; } _end("perform hamc sha256 computation with short key"); @@ -104,26 +107,157 @@ static int perform_hmac_256_computation_long_key() 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2, }; + unsigned char out[FT_SHA256_DIGEST_LENGTH_BYTE]; + ft_hmac_sha256_init_ctx(&ctx); ctx.key = key; ctx.msg = msg; ctx.key_size = 131; ctx.msg_size = 152; - ft_hmac_sha256(&ctx); + ft_hmac_sha256(&ctx, out); int i = 0; while(i < FT_SHA256_DIGEST_LENGTH_BYTE) { - _is(ctx.out[i] == expected_result[i]); + _is(out[i] == expected_result[i]); i++; } _end("perform hamc sha256 computation with long key"); } +int init_pbkdf2_sha256_ctx() +{ + t_pbkdf2_sha256_ctx ctx; + + ft_pbkdf2_sha256_init_ctx(&ctx); + + _is(ctx.iterations == 0); + _is(ctx.key_len == 0); + _is(ctx.salt_len == 0); + _is(ctx.pass_len == 0); + _is(ctx.salt == NULL); + _is(ctx.key == NULL); + _is(ctx.pass == NULL); + + _end("init pbkdf2 sha256 ctx"); +} + +int perform_pbkdf2_sha256() +{ + t_pbkdf2_sha256_ctx ctx; + int i; + + unsigned char pass1[] = "password"; + unsigned char salt1[] = "salt"; + unsigned char expected1[32] = { + 0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c, + 0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37, + 0xa8, 0x65, 0x48, 0xc9, 0x2c, 0xcc, 0x35, 0x48, + 0x08, 0x05, 0x98, 0x7c, 0xb7, 0x0b, 0xe1, 0x7b, + }; + unsigned char key1[32]; + + ft_pbkdf2_sha256_init_ctx(&ctx); + ctx.key = key1; + ctx.pass = pass1; + ctx.salt = salt1; + ctx.pass_len = 8; + ctx.salt_len = 4; + ctx.key_len = 32; + ctx.iterations = 1; + ft_pbkdf2_sha256(&ctx); + + i = 0; + while(i < 32) + { + _is(ctx.key[i] == expected1[i]); + i++; + } + + unsigned char expected2[32] = { + 0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3, + 0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0, + 0x2a, 0x30, 0x3f, 0x8e, 0xf3, 0xc2, 0x51, 0xdf, + 0xd6, 0xe2, 0xd8, 0x5a, 0x95, 0x47, 0x4c, 0x43, + }; + + ft_pbkdf2_sha256_init_ctx(&ctx); + ctx.key = key1; + ctx.pass = pass1; + ctx.salt = salt1; + ctx.pass_len = 8; + ctx.salt_len = 4; + ctx.key_len = 32; + ctx.iterations = 2; + ft_pbkdf2_sha256(&ctx); + + i = 0; + while(i < 32) + { + _is(ctx.key[i] == expected2[i]); + i++; + } + + unsigned char expected3[32] = { + 0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41, + 0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d, + 0x96, 0x28, 0x93, 0xa0, 0x01, 0xce, 0x4e, 0x11, + 0xa4, 0x96, 0x38, 0x73, 0xaa, 0x98, 0x13, 0x4a, + }; + + ft_pbkdf2_sha256_init_ctx(&ctx); + ctx.key = key1; + ctx.pass = pass1; + ctx.salt = salt1; + ctx.pass_len = 8; + ctx.salt_len = 4; + ctx.key_len = 32; + ctx.iterations = 4096; + ft_pbkdf2_sha256(&ctx); + + i = 0; + while(i < 32) + { + _is(ctx.key[i] == expected3[i]); + i++; + } + + unsigned char password4[24] = "passwordPASSWORDpassword"; + unsigned char salt4[36] = "saltSALTsaltSALTsaltSALTsaltSALTsalt"; + unsigned char expected4[40] = { + 0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f, + 0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf, + 0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18, + 0x1c, 0x4e, 0x2a, 0x1f, 0xb8, 0xdd, 0x53, 0xe1, + 0xc6, 0x35, 0x51, 0x8c, 0x7d, 0xac, 0x47, 0xe9, + }; + unsigned char key4[40]; + + ft_pbkdf2_sha256_init_ctx(&ctx); + ctx.key = key4; + ctx.pass = password4; + ctx.salt = salt4; + ctx.pass_len = 24; + ctx.salt_len = 36; + ctx.key_len = 40; + ctx.iterations = 4096; + ft_pbkdf2_sha256(&ctx); + + i = 0; + while(i < 40) + { + _is(ctx.key[i] == expected4[i]); + i++; + } + _end("perform pbkdf2 sha256"); +} + int pbkdf2_tests() { _should(init_hmac_sha256_ctx); _should(perform_hmac_256_computation_short_key); _should(perform_hmac_256_computation_long_key); + _should(init_pbkdf2_sha256_ctx); + _should(perform_pbkdf2_sha256); return 0; } \ No newline at end of file