25 #include "exceptions.h"
33 static size_t cx_get_block_size(cx_md_t md)
35 const cx_hash_info_t *info = cx_hash_get_info(md);
39 return info->block_size;
42 static cx_md_t cx_get_algorithm(cx_hmac_t *ctx)
44 return ctx->hash_ctx.info->md_type;
47 static bool cx_is_allowed_digest(cx_md_t md_type)
49 const cx_md_t allowed_algorithms[] = {
66 for (
unsigned int i = 0; i <
sizeof(allowed_algorithms) /
sizeof(allowed_algorithms[0]); i++) {
67 if (allowed_algorithms[i] == md_type) {
74 cx_err_t cx_hmac_init(cx_hmac_t *ctx, cx_md_t hash_id,
const uint8_t *key,
size_t key_len)
79 if ((ctx == NULL) || (!cx_is_allowed_digest(hash_id)) || (key == NULL && key_len != 0)) {
80 return CX_INVALID_PARAMETER;
83 hash_ctx = &ctx->hash_ctx;
84 memset(ctx, 0,
sizeof(cx_hmac_t));
85 size_t block_size = cx_get_block_size(hash_id);
88 if (key_len > block_size) {
89 CX_CHECK(cx_hash_init(hash_ctx, hash_id));
90 CX_CHECK(cx_hash_update(hash_ctx, key, key_len));
91 CX_CHECK(cx_hash_final(hash_ctx, ctx->key));
94 memcpy(ctx->key, key, key_len);
97 for (
unsigned int i = 0; i < block_size; i++) {
102 CX_CHECK(cx_hash_init(hash_ctx, hash_id));
103 CX_CHECK(cx_hash_update(hash_ctx, ctx->key, block_size));
108 cx_err_t cx_hmac_update(cx_hmac_t *ctx,
const uint8_t *data,
size_t data_len)
113 return cx_hash_update(&ctx->hash_ctx, data, data_len);
116 cx_err_t cx_hmac_final(cx_hmac_t *ctx,
uint8_t *out,
size_t *out_len)
120 uint8_t inner_hash[MAX_HASH_SIZE];
121 uint8_t hkey[MAX_HASH_BLOCK_SIZE];
123 cx_hash_t *hash_ctx = &ctx->hash_ctx;
125 cx_md_t hash_algorithm = cx_get_algorithm(ctx);
126 size_t block_size = cx_get_block_size(hash_algorithm);
127 size_t hash_output_size = cx_hash_get_size(hash_ctx);
129 CX_CHECK(cx_hash_final(hash_ctx, inner_hash));
132 memcpy(hkey, ctx->key, block_size);
133 for (
unsigned int i = 0; i < block_size; i++) {
134 hkey[i] ^= OPAD ^ IPAD;
137 CX_CHECK(cx_hash_init(hash_ctx, hash_algorithm));
138 CX_CHECK(cx_hash_update(hash_ctx, hkey, block_size));
139 CX_CHECK(cx_hash_update(hash_ctx, inner_hash, hash_output_size));
140 CX_CHECK(cx_hash_final(hash_ctx, hkey));
143 if (*out_len >= hash_output_size) {
144 *out_len = hash_output_size;
146 memcpy(out, hkey, *out_len);
152 cx_err_t cx_hmac_sha224_init(cx_hmac_sha256_t *hmac,
const uint8_t *key,
unsigned int key_len)
154 return cx_hmac_init((cx_hmac_t *) hmac, CX_SHA224, key, key_len);
158 cx_err_t cx_hmac_sha256_init_no_throw(cx_hmac_sha256_t *hmac,
const uint8_t *key,
size_t key_len)
160 return cx_hmac_init((cx_hmac_t *) hmac, CX_SHA256, key, key_len);
165 cx_err_t cx_hmac_sha384_init(cx_hmac_sha512_t *hmac,
const uint8_t *key,
unsigned int key_len)
167 return cx_hmac_init((cx_hmac_t *) hmac, CX_SHA384, key, key_len);
171 cx_err_t cx_hmac_sha512_init_no_throw(cx_hmac_sha512_t *hmac,
const uint8_t *key,
size_t key_len)
173 return cx_hmac_init((cx_hmac_t *) hmac, CX_SHA512, key, key_len);
177 #ifdef HAVE_RIPEMD160
178 cx_err_t cx_hmac_ripemd160_init_no_throw(cx_hmac_ripemd160_t *hmac,
182 return cx_hmac_init((cx_hmac_t *) hmac, CX_RIPEMD160, key, key_len);
186 cx_err_t cx_hmac_no_throw(cx_hmac_t *hmac,
193 size_t output_size = 0;
194 cx_err_t error = CX_OK;
196 if (in == NULL && len != 0) {
197 return CX_INVALID_PARAMETER;
199 if (out == NULL && out_len != 0) {
200 return CX_INVALID_PARAMETER;
204 CX_CHECK(cx_hmac_update(hmac, in, len));
208 output_size = out_len;
209 CX_CHECK(cx_hmac_final(hmac, out, &output_size));
212 CX_CHECK(cx_hmac_init(hmac, cx_get_algorithm(hmac), NULL, 0));
221 size_t cx_hmac_sha256(
const uint8_t *key,
228 size_t mac_len = out_len;
229 if (cx_hmac_init(&
G_cx.hmac, CX_SHA256, key, key_len) != CX_OK
230 || cx_hmac_update(&
G_cx.hmac, in, len) != CX_OK
231 || cx_hmac_final(&
G_cx.hmac, out, &mac_len) != CX_OK) {
234 explicit_bzero(&
G_cx.hmac,
sizeof(cx_hmac_sha256_t));
240 size_t cx_hmac_sha512(
const uint8_t *key,
247 size_t mac_len = out_len;
248 if (cx_hmac_init(&
G_cx.hmac, CX_SHA512, key, key_len) != CX_OK
249 || cx_hmac_update(&
G_cx.hmac, in, len) != CX_OK
250 || cx_hmac_final(&
G_cx.hmac, out, &mac_len) != CX_OK) {
253 explicit_bzero(&
G_cx.hmac,
sizeof(cx_hmac_sha512_t));