Update PBKDF2

This commit is contained in:
Zhi Guan
2026-06-09 17:17:12 +08:00
parent 3c72b5bce8
commit d001ead11e
3 changed files with 114 additions and 6 deletions

View File

@@ -29,11 +29,7 @@ extern "C" {
#define PBKDF2_DEFAULT_SALT_SIZE 8 #define PBKDF2_DEFAULT_SALT_SIZE 8
int pbkdf2_genkey(const DIGEST *digest, int pbkdf2_hmac_genkey(const DIGEST *digest,
const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, size_t iter,
size_t outlen, uint8_t *out);
int pbkdf2_hmac_sm3_genkey(
const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, size_t iter, const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, size_t iter,
size_t outlen, uint8_t *out); size_t outlen, uint8_t *out);

112
src/pbkdf2.c Normal file
View File

@@ -0,0 +1,112 @@
/*
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <stdint.h>
#include <string.h>
#include <gmssl/pbkdf2.h>
#include <gmssl/error.h>
#include <gmssl/endian.h>
#include <gmssl/mem.h>
int pbkdf2_hmac_genkey(const DIGEST *digest,
const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen,
size_t iter, size_t outlen, uint8_t *out)
{
int ret = -1;
HMAC_CTX ctx;
HMAC_CTX ctx_tmpl;
uint8_t iter_be[4];
uint8_t tmp_block[DIGEST_MAX_SIZE];
uint8_t key_block[DIGEST_MAX_SIZE];
uint32_t block_index = 1;
size_t digest_size;
size_t block_count;
if (!digest || !iter || !outlen || !out) {
error_print();
return -1;
}
if (digest->digest_size > HMAC_MAX_SIZE
|| !digest->digest_size) {
error_print();
return -1;
}
if (!pass && passlen) {
error_print();
return -1;
}
if (!salt && saltlen) {
error_print();
return -1;
}
digest_size = digest->digest_size;
block_count = outlen / digest_size;
if (outlen % digest_size) {
block_count++;
}
if (block_count > UINT32_MAX) {
error_print();
return -1;
}
if (hmac_init(&ctx_tmpl, digest, (const uint8_t *)pass, passlen) != 1) {
error_print();
return -1;
}
while (outlen) {
size_t maclen;
size_t i;
PUTU32(iter_be, block_index);
block_index++;
ctx = ctx_tmpl;
if (hmac_update(&ctx, salt, saltlen) < 0
|| hmac_update(&ctx, iter_be, sizeof(iter_be)) != 1
|| hmac_finish(&ctx, tmp_block, &maclen) != 1) {
error_print();
goto end;
}
memcpy(key_block, tmp_block, digest_size);
for (i = 1; i < iter; i++) {
ctx = ctx_tmpl;
if (hmac_update(&ctx, tmp_block, digest_size) != 1
|| hmac_finish(&ctx, tmp_block, &maclen) != 1) {
error_print();
goto end;
}
memxor(key_block, tmp_block, digest_size);
}
if (outlen < digest_size) {
memcpy(out, key_block, outlen);
out += outlen;
outlen = 0;
} else {
memcpy(out, key_block, digest_size);
out += digest_size;
outlen -= digest_size;
}
}
ret = 1;
end:
gmssl_secure_clear(&ctx, sizeof(ctx));
gmssl_secure_clear(&ctx_tmpl, sizeof(ctx_tmpl));
gmssl_secure_clear(key_block, sizeof(key_block));
gmssl_secure_clear(tmp_block, sizeof(tmp_block));
return ret;
}

View File

@@ -111,7 +111,7 @@ static int test_pbkdf2_genkey(void)
for (i = 0; i < sizeof(pbkdf2_hmac_sha1_tests)/sizeof(pbkdf2_hmac_sha1_tests[0]); i++) { for (i = 0; i < sizeof(pbkdf2_hmac_sha1_tests)/sizeof(pbkdf2_hmac_sha1_tests[0]); i++) {
hex_to_bytes(pbkdf2_hmac_sha1_tests[i].dk, strlen(pbkdf2_hmac_sha1_tests[i].dk), buf, &len); hex_to_bytes(pbkdf2_hmac_sha1_tests[i].dk, strlen(pbkdf2_hmac_sha1_tests[i].dk), buf, &len);
if (pbkdf2_genkey(DIGEST_sha1(), if (pbkdf2_hmac_genkey(DIGEST_sha1(),
pbkdf2_hmac_sha1_tests[i].pass, strlen(pbkdf2_hmac_sha1_tests[i].pass), pbkdf2_hmac_sha1_tests[i].pass, strlen(pbkdf2_hmac_sha1_tests[i].pass),
(uint8_t *)pbkdf2_hmac_sha1_tests[i].salt, strlen(pbkdf2_hmac_sha1_tests[i].salt), (uint8_t *)pbkdf2_hmac_sha1_tests[i].salt, strlen(pbkdf2_hmac_sha1_tests[i].salt),
pbkdf2_hmac_sha1_tests[i].iter, pbkdf2_hmac_sha1_tests[i].dklen, key) != 1) { pbkdf2_hmac_sha1_tests[i].iter, pbkdf2_hmac_sha1_tests[i].dklen, key) != 1) {