#include <openssl/evp.h>
+#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.
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));
return LUTIL_PASSWD_ERR;
}
-#ifdef SLAPD_PBKDF2_DEBUG
- printf(" Output:\t%s\n", msg->bv_val);
-#endif
return LUTIL_PASSWD_OK;
}
{
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");
printf(" Iteration:\t%d\n", iteration);
printf(" DK:\t\t");
- for(i=0; i<PBKDF2_DK_SIZE; i++){
+ for(i=0; i<dk.bv_len; i++){
printf("%02x", dk_value[i]);
}
printf("\n");
#endif
- return pbkdf2_format(scheme, iteration, &salt, &dk, msg);
+ rc = pbkdf2_format(scheme, iteration, &salt, &dk, msg);
+
+#ifdef SLAPD_PBKDF2_DEBUG
+ printf(" Output:\t%s\n", msg->bv_val);
+#endif
+
+ return rc;
}
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;
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);
printf("\n");
printf(" Stored DK:\t");
- for(i=0; i<PBKDF2_DK_SIZE; i++){
+ for(i=0; i<dk_len; i++){
printf("%02x", dk_value[i]);
}
printf("\n");
printf(" Input DK:\t");
- for(i=0; i<PBKDF2_DK_SIZE; i++){
+ for(i=0; i<dk_len; i++){
printf("%02x", input_dk_value[i]);
}
printf("\n");
int init_module(int argc, char *argv[]) {
int rc;
- rc = lutil_passwd_add((struct berval *)&pbkdf2scheme,
+ rc = lutil_passwd_add((struct berval *)&pbkdf2_scheme,
+ pbkdf2_check, pbkdf2_encrypt);
+ if(rc) return rc;
+ rc = lutil_passwd_add((struct berval *)&pbkdf2_sha1_scheme,
pbkdf2_check, pbkdf2_encrypt);
- if(!rc) return rc;
+ if(rc) return rc;
- /* TODO: add {PBKDF2-SHA256} and {PBKDF2-SHA512} schemes. */
+ rc = lutil_passwd_add((struct berval *)&pbkdf2_sha256_scheme,
+ pbkdf2_check, pbkdf2_encrypt);
+ if(rc) return rc;
+
+ rc = lutil_passwd_add((struct berval *)&pbkdf2_sha512_scheme,
+ pbkdf2_check, pbkdf2_encrypt);
return rc;
}