From 209fcd92eaf7666085878797f7fc0bf52897abf5 Mon Sep 17 00:00:00 2001 From: HAMANO Tsukasa Date: Wed, 5 Nov 2014 09:26:35 +0000 Subject: [PATCH] ITS#7977 Add PBKDF2 -SHA256 and -SHA512 --- contrib/slapd-modules/passwd/pbkdf2/README | 18 ++- .../slapd-modules/passwd/pbkdf2/pw-pbkdf2.c | 117 +++++++++++++----- 2 files changed, 99 insertions(+), 36 deletions(-) diff --git a/contrib/slapd-modules/passwd/pbkdf2/README b/contrib/slapd-modules/passwd/pbkdf2/README index 348580be0f..b1cced1dc8 100644 --- a/contrib/slapd-modules/passwd/pbkdf2/README +++ b/contrib/slapd-modules/passwd/pbkdf2/README @@ -1,8 +1,14 @@ PBKDF2 for OpenLDAP ======================= -pw-pbkdf2.c provides support for PBKDF2 key derivation functions in -OpenLDAP. +pw-pbkdf2.c provides PBKDF2 key derivation functions in OpenLDAP. + +Schemes: + + * {PBKDF2} - alias to {PBKDF2-SHA1} + * {PBKDF2-SHA1} + * {PBKDF2-SHA256} + * {PBKDF2-SHA512} # Requirements @@ -10,13 +16,15 @@ OpenLDAP. # Installations +First, You need to configure and build OpenLDAP. + $ cd /contrib/slapd-modules/passwd/ $ git clone https://github.com/hamano/openldap-pbkdf2.git $ cd openldap-pbkdf2/ $ make # make install -# Configuration +# Configration In slapd.conf: @@ -27,6 +35,10 @@ Password Modify Extended Operations, thanks to the password-hash option in slapd.conf. For example: password-hash {PBKDF2} +or + password-hash {PBKDF2-SHA256} +or + password-hash {PBKDF2-SHA512} # Testing diff --git a/contrib/slapd-modules/passwd/pbkdf2/pw-pbkdf2.c b/contrib/slapd-modules/passwd/pbkdf2/pw-pbkdf2.c index 6070013a58..7a962c1829 100644 --- a/contrib/slapd-modules/passwd/pbkdf2/pw-pbkdf2.c +++ b/contrib/slapd-modules/passwd/pbkdf2/pw-pbkdf2.c @@ -25,11 +25,17 @@ #include +#define PBKDF2_ITERATION 10000 #define PBKDF2_SALT_SIZE 16 -#define PBKDF2_DK_SIZE 20 -#define PBKDF2_ITERATION 60000 +#define PBKDF2_SHA1_DK_SIZE 20 +#define PBKDF2_SHA256_DK_SIZE 32 +#define PBKDF2_SHA512_DK_SIZE 64 +#define PBKDF2_MAX_DK_SIZE 64 -const struct berval pbkdf2scheme = BER_BVC("{PBKDF2}"); +const struct berval pbkdf2_scheme = BER_BVC("{PBKDF2}"); +const struct berval pbkdf2_sha1_scheme = BER_BVC("{PBKDF2-SHA1}"); +const struct berval pbkdf2_sha256_scheme = BER_BVC("{PBKDF2-SHA256}"); +const struct berval pbkdf2_sha512_scheme = BER_BVC("{PBKDF2-SHA512}"); /* * Converting base64 string to adapted base64 string. @@ -95,7 +101,7 @@ static int pbkdf2_format( int rc; char salt_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_SALT_SIZE) + 1]; - char dk_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_DK_SIZE) + 1]; + char dk_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_MAX_DK_SIZE) + 1]; rc = lutil_b64_ntop((unsigned char *)salt->bv_val, salt->bv_len, salt_b64, sizeof(salt_b64)); @@ -116,9 +122,6 @@ static int pbkdf2_format( return LUTIL_PASSWD_ERR; } -#ifdef SLAPD_PBKDF2_DEBUG - printf(" Output:\t%s\n", msg->bv_val); -#endif return LUTIL_PASSWD_OK; } @@ -130,27 +133,43 @@ static int pbkdf2_encrypt( { unsigned char salt_value[PBKDF2_SALT_SIZE]; struct berval salt; - unsigned char dk_value[PBKDF2_DK_SIZE]; + unsigned char dk_value[PBKDF2_MAX_DK_SIZE]; struct berval dk; int iteration = PBKDF2_ITERATION; + int rc; + const EVP_MD *md; - dk.bv_val = (char *)dk_value; - dk.bv_len = PBKDF2_DK_SIZE; salt.bv_val = (char *)salt_value; salt.bv_len = sizeof(salt_value); + dk.bv_val = (char *)dk_value; + if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ + dk.bv_len = PBKDF2_SHA1_DK_SIZE; + md = EVP_sha1(); + }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ + dk.bv_len = PBKDF2_SHA1_DK_SIZE; + md = EVP_sha1(); + }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ + dk.bv_len = PBKDF2_SHA256_DK_SIZE; + md = EVP_sha256(); + }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ + dk.bv_len = PBKDF2_SHA512_DK_SIZE; + md = EVP_sha512(); + }else{ + return LUTIL_PASSWD_ERR; + } if(lutil_entropy((unsigned char *)salt.bv_val, salt.bv_len) < 0){ return LUTIL_PASSWD_ERR; } - if(!PKCS5_PBKDF2_HMAC_SHA1(passwd->bv_val, passwd->bv_len, - (unsigned char *)salt.bv_val, salt.bv_len, - iteration, PBKDF2_DK_SIZE, dk_value)){ + if(!PKCS5_PBKDF2_HMAC(passwd->bv_val, passwd->bv_len, + (unsigned char *)salt.bv_val, salt.bv_len, + iteration, md, dk.bv_len, dk_value)){ return LUTIL_PASSWD_ERR; } #ifdef SLAPD_PBKDF2_DEBUG - printf("DEBUG pbkdf2_encrypt()\n"); + printf("Encrypt for %s\n", scheme->bv_val); printf(" Password:\t%s\n", passwd->bv_val); printf(" Salt:\t\t"); @@ -162,13 +181,19 @@ static int pbkdf2_encrypt( printf(" Iteration:\t%d\n", iteration); printf(" DK:\t\t"); - for(i=0; ibv_val); +#endif + + return rc; } static int pbkdf2_check( @@ -183,17 +208,35 @@ static int pbkdf2_check( /* salt_value require PBKDF2_SALT_SIZE + 1 in lutil_b64_pton. */ unsigned char salt_value[PBKDF2_SALT_SIZE + 1]; char salt_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_SALT_SIZE) + 1]; - /* dk_value require PBKDF2_DK_SIZE + 1 in lutil_b64_pton. */ - unsigned char dk_value[PBKDF2_DK_SIZE + 1]; - char dk_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_DK_SIZE) + 1]; - unsigned char input_dk_value[PBKDF2_DK_SIZE]; + /* dk_value require PBKDF2_MAX_DK_SIZE + 1 in lutil_b64_pton. */ + unsigned char dk_value[PBKDF2_MAX_DK_SIZE + 1]; + char dk_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_MAX_DK_SIZE) + 1]; + unsigned char input_dk_value[PBKDF2_MAX_DK_SIZE]; + size_t dk_len; + const EVP_MD *md; #ifdef SLAPD_PBKDF2_DEBUG - printf("DEBUG pbkdf2_check()\n"); + printf("Checking for %s\n", scheme->bv_val); printf(" Stored Value:\t%s\n", passwd->bv_val); printf(" Input Cred:\t%s\n", cred->bv_val); #endif + if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ + dk_len = PBKDF2_SHA1_DK_SIZE; + md = EVP_sha1(); + }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ + dk_len = PBKDF2_SHA1_DK_SIZE; + md = EVP_sha1(); + }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ + dk_len = PBKDF2_SHA256_DK_SIZE; + md = EVP_sha256(); + }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ + dk_len = PBKDF2_SHA512_DK_SIZE; + md = EVP_sha512(); + }else{ + return LUTIL_PASSWD_ERR; + } + iteration = atoi(passwd->bv_val); if(iteration < 1){ return LUTIL_PASSWD_ERR; @@ -231,24 +274,24 @@ static int pbkdf2_check( return LUTIL_PASSWD_ERR; } - /* The targetsize require PBKDF2_DK_SIZE + 1 in lutil_b64_pton. */ - rc = lutil_b64_pton(dk_b64, dk_value, PBKDF2_DK_SIZE + 1); + /* The targetsize require PBKDF2_MAX_DK_SIZE + 1 in lutil_b64_pton. */ + rc = lutil_b64_pton(dk_b64, dk_value, sizeof(dk_value)); if(rc < 0){ return LUTIL_PASSWD_ERR; } /* consistency check */ - if(rc != PBKDF2_DK_SIZE){ + if(rc != dk_len){ return LUTIL_PASSWD_ERR; } - if(!PKCS5_PBKDF2_HMAC_SHA1(cred->bv_val, cred->bv_len, - salt_value, PBKDF2_SALT_SIZE, - iteration, PBKDF2_DK_SIZE, input_dk_value)){ + if(!PKCS5_PBKDF2_HMAC(cred->bv_val, cred->bv_len, + salt_value, PBKDF2_SALT_SIZE, + iteration, md, dk_len, input_dk_value)){ return LUTIL_PASSWD_ERR; } - rc = memcmp(dk_value, input_dk_value, PBKDF2_DK_SIZE); + rc = memcmp(dk_value, input_dk_value, dk_len); #ifdef SLAPD_PBKDF2_DEBUG printf(" Iteration:\t%d\n", iteration); printf(" Base64 Salt:\t%s\n", salt_b64); @@ -261,13 +304,13 @@ static int pbkdf2_check( printf("\n"); printf(" Stored DK:\t"); - for(i=0; i