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
|
#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
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++) {
|
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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user