diff --git a/Makefile b/Makefile index 409b230c..b9df8265 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ MD5_DIR := $(SRC_DIR)/md5/ SHA_DIR := $(SRC_DIR)/sha/ B64_DIR := $(SRC_DIR)/base64/ DES_DIR := $(SRC_DIR)/des/ +KD2_DIR := $(SRC_DIR)/pbkdf2/ OBJ_DIR := $(ROOT)/obj/ INC_DIR := $(ROOT)/inc/ LIB_DIR := $(ROOT)/lib/ @@ -34,11 +35,13 @@ SHA_HEADER := $(INC_DIR)/ft_sha.h SSL_HEADER := $(INC_DIR)/ft_ssl.h B64_HEADER := $(INC_DIR)/ft_base64.h DES_HEADER := $(INC_DIR)/ft_des.h +KD2_HEADER := $(INC_DIR)/ft_pbkdf2.h HEADERS := $(MD5_HEADER) \ $(SHA_HEADER) \ $(SSL_HEADER) \ $(B64_HEADER) \ - $(DES_HEADER) + $(DES_HEADER) \ + $(PBKDF2_HEADER) # libraries LIBFT_DIR := $(LIB_DIR)libft/ @@ -137,7 +140,9 @@ DES_SRC = ft_des_initial_permutation.c \ ft_des_ecb_encode_process_chunk.c \ ft_des_hex_to_bit_key.c \ ft_des_ecb_finish_encrypt.c - # ft_des_ecb_finish_decrypt.c + +KD2_SRC = ft_hmac_sha256_init_ctx.c \ + ft_hmac_sha256.c SRC = main.c \ ft_ssl_usage.c @@ -145,7 +150,8 @@ SRC = main.c \ SRC += $(MD5_SRC) \ $(SHA_SRC) \ $(BASE64_SRC) \ - $(DES_SRC) + $(DES_SRC) \ + $(KD2_SRC) # project object files OBJ = $(addprefix $(OBJ_DIR), $(SRC:.c=.o)) @@ -167,11 +173,15 @@ BASE64_TESTS += $(BASE64_SRC) DES_TESTS = des_tests.c DES_TESTS += $(DES_SRC) +KD2_TESTS = pbkdf2_tests.c +KD2_TESTS += $(KD2_SRC) + TEST_SRC = tests.c TEST_SRC += $(MD5_TESTS) \ $(SHA_TESTS) \ $(BASE64_TESTS) \ - $(DES_TESTS) + $(DES_TESTS) \ + $(KD2_TESTS) TEST_OBJ = $(addprefix $(OBJ_DIR), $(TEST_SRC:.c=.o)) @@ -261,6 +271,7 @@ vpath %.c $(SRC_DIR) \ $(SHA_DIR) \ $(B64_DIR) \ $(DES_DIR) \ + $(KD2_DIR) \ $(TST_DIR) .PHONY: all check clean fclean re multi diff --git a/inc/ft_pbkdf2.h b/inc/ft_pbkdf2.h new file mode 100644 index 00000000..f2f1ab36 --- /dev/null +++ b/inc/ft_pbkdf2.h @@ -0,0 +1,20 @@ +#include "ft_sha.h" + +typedef struct s_hmac_sha256_ctx +{ + unsigned char *key; + unsigned char *msg; + unsigned char out[FT_SHA256_DIGEST_LENGTH_BYTE]; + unsigned int key_size; + unsigned int msg_size; +} t_hmac_sha256_ctx; + +void ft_hmac_sha256_init_ctx +( + t_hmac_sha256_ctx *ctx +); + +void ft_hmac_sha256 +( + t_hmac_sha256_ctx *ctx +); \ No newline at end of file diff --git a/inc/tests.h b/inc/tests.h index 4a1f5d83..c31fb63f 100644 --- a/inc/tests.h +++ b/inc/tests.h @@ -17,5 +17,6 @@ int md5_tests(void); int sha_tests(void); int base64_tests(void); int des_tests(void); +int pbkdf2_tests(void); #endif diff --git a/src/pbkdf2/ft_hmac_sha256.c b/src/pbkdf2/ft_hmac_sha256.c new file mode 100644 index 00000000..d99eebf6 --- /dev/null +++ b/src/pbkdf2/ft_hmac_sha256.c @@ -0,0 +1,61 @@ +#include "ft_pbkdf2.h" +#include "libft.h" + +static void set_padding +( + unsigned char ipad[FT_SHA256_BLOCK_SIZE], + unsigned char opad[FT_SHA256_BLOCK_SIZE], + unsigned char key[FT_SHA256_BLOCK_SIZE] +) +{ + int i; + + i = 0; + while(i < FT_SHA256_BLOCK_SIZE) + { + ipad[i] = key[i] ^ 0x36; + opad[i] = key[i] ^ 0x5c; + i++; + } +} + +static void 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] +) +{ + 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); +} + +void ft_hmac_sha256 +( + 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); + } + else + ft_memcpy(key, ctx->key, ctx->key_size); + set_padding(ipad, opad, key); + finish(ctx, &sha256_ctx, ipad, opad); +} \ 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 new file mode 100644 index 00000000..42cb3491 --- /dev/null +++ b/src/pbkdf2/ft_hmac_sha256_init_ctx.c @@ -0,0 +1,16 @@ +#include +#include "ft_pbkdf2.h" +#include "ft_sha.h" +#include "libft.h" + +void ft_hmac_sha256_init_ctx +( + t_hmac_sha256_ctx *ctx +) +{ + ctx->key = NULL; + ctx->msg = NULL; + ctx->key_size = 0; + ctx->msg_size = 0; + ft_bzero(ctx->out, FT_SHA256_DIGEST_LENGTH_BYTE); +} \ No newline at end of file diff --git a/t/des_tests.c b/t/des_tests.c index c21e042b..f4554568 100644 --- a/t/des_tests.c +++ b/t/des_tests.c @@ -658,7 +658,7 @@ int init_ctx() _is(ctx.input_fd == STDIN_FILENO); _is(ctx.output_fd == STDOUT_FILENO); _is(ctx.decode == 0); - _is(ctx.output_in_base64 == 0); + _is(ctx.b64 == 0); _end("shoud init ctx"); } diff --git a/t/pbkdf2_tests.c b/t/pbkdf2_tests.c new file mode 100644 index 00000000..8473ff31 --- /dev/null +++ b/t/pbkdf2_tests.c @@ -0,0 +1,128 @@ +#include "t.h" +#include "tests.h" +#include "ft_pbkdf2.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) + { + _is(ctx.out[i] == 0); + i++; + } + _end("init hmac sha256 ctx"); +} + +static int perform_hmac_256_computation_short_key() +{ + t_hmac_sha256_ctx ctx; + unsigned char key[20] = { + 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, + }; + unsigned char msg[8] = { + 'H', 'i', ' ', 'T', 'h', 'e', 'r', 'e' + }; + unsigned char expected_result[FT_SHA256_DIGEST_LENGTH_BYTE] = { + 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, + 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, + 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, + 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7, + }; + ft_hmac_sha256_init_ctx(&ctx); + ctx.key = key; + ctx.msg = msg; + ctx.key_size = 20; + ctx.msg_size = 8; + ft_hmac_sha256(&ctx); + + int i = 0; + while(i < FT_SHA256_DIGEST_LENGTH_BYTE) + { + _is(ctx.out[i] == expected_result[i]); + i++; + } + _end("perform hamc sha256 computation with short key"); +} + +static int perform_hmac_256_computation_long_key() +{ + t_hmac_sha256_ctx ctx; + unsigned char key[131] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, + }; + unsigned char msg[152] = { + 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x75, + 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c, + 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68, + 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6b, 0x65, + 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20, + 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65, + 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6e, 0x65, 0x65, + 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, + 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, + 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62, + 0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x61, 0x6c, + 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e, + }; + unsigned char expected_result[FT_SHA256_DIGEST_LENGTH_BYTE] = { + 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, + 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, + 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, + 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2, + }; + ft_hmac_sha256_init_ctx(&ctx); + ctx.key = key; + ctx.msg = msg; + ctx.key_size = 131; + ctx.msg_size = 152; + ft_hmac_sha256(&ctx); + + int i = 0; + while(i < FT_SHA256_DIGEST_LENGTH_BYTE) + { + _is(ctx.out[i] == expected_result[i]); + i++; + } + _end("perform hamc sha256 computation with long key"); +} + +int pbkdf2_tests() +{ + _should(init_hmac_sha256_ctx); + _should(perform_hmac_256_computation_short_key); + _should(perform_hmac_256_computation_long_key); + return 0; +} \ No newline at end of file diff --git a/t/tests.c b/t/tests.c index f2d4f867..93c9f13d 100644 --- a/t/tests.c +++ b/t/tests.c @@ -19,6 +19,7 @@ int all_tests() _verify("sha:", sha_tests); _verify("base64:", base64_tests); _verify("des:", des_tests); + _verify("pbkdf2:", pbkdf2_tests); return 0; }