24 #include "exceptions.h"
29 cx_err_t cx_pbkdf2_hmac(cx_md_t md_type,
38 cx_hmac_t *hmac_ctx = &
G_cx.pbkdf2.hmac_ctx;
45 cx_err_t error = CX_OK;
47 if (password == NULL || salt == NULL || key == NULL) {
48 return CX_INVALID_PARAMETER;
51 const cx_hash_info_t *info = cx_hash_get_info(md_type);
52 digest_size = info->output_size;
54 memset(counter, 0,
sizeof(counter));
55 counter[
sizeof(counter) - 1] = 1;
58 CX_CHECK(cx_hmac_init(hmac_ctx, md_type, password, password_len));
59 CX_CHECK(cx_hmac_update(hmac_ctx, salt, salt_len));
60 CX_CHECK(cx_hmac_update(hmac_ctx, counter, 4));
62 work_size = digest_size;
63 CX_CHECK(cx_hmac_final(hmac_ctx, work, &work_size));
65 memcpy(md1, work, digest_size);
66 for (uint32_t i = 1; i < iterations; i++) {
67 CX_CHECK(cx_hmac_init(hmac_ctx, md_type, password, password_len));
68 CX_CHECK(cx_hmac_update(hmac_ctx, md1, digest_size));
69 work_size = digest_size;
70 CX_CHECK(cx_hmac_final(hmac_ctx, md1, &work_size));
72 for (
unsigned int j = 0; j < digest_size; j++) {
77 if (key_len < digest_size) {
81 copy_len = digest_size;
83 memcpy(key, work, copy_len);
88 for (
int i = 3; i >= 0; i--) {
89 if (++counter[i] != 0) {
98 cx_err_t cx_pbkdf2_no_throw(cx_md_t md_type,
107 return cx_pbkdf2_hmac(
108 md_type, password, password_len, salt, salt_len, iterations, out, out_len);