mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-20 03:44:15 +08:00
Update PBKDF2
This commit is contained in:
@@ -29,11 +29,7 @@ extern "C" {
|
||||
#define PBKDF2_DEFAULT_SALT_SIZE 8
|
||||
|
||||
|
||||
int pbkdf2_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(
|
||||
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);
|
||||
|
||||
|
||||
112
src/pbkdf2.c
Normal file
112
src/pbkdf2.c
Normal 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;
|
||||
}
|
||||
@@ -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++) {
|
||||
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),
|
||||
(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) {
|
||||
|
||||
Reference in New Issue
Block a user