Mercurial > dovecot > core-2.2
annotate src/lib/hmac.c @ 23007:36e01285b5b8
lib: buffer - Improve header comment for buffer_insert() and buffer_delete().
author | Stephan Bosch <stephan.bosch@dovecot.fi> |
---|---|
date | Mon, 18 Mar 2019 00:52:37 +0100 |
parents | b861c0860dd2 |
children |
rev | line source |
---|---|
15172
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
1 /* |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
2 * HMAC (RFC-2104) implementation. |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
3 * |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
4 * Copyright (c) 2004 Andrey Panin <pazke@donpac.ru> |
19552
0f22db71df7a
global: freshen copyright
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
18137
diff
changeset
|
5 * Copyright (c) 2011-2016 Florian Zeitz <florob@babelmonkeys.de> |
15172
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
6 * |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
7 * This software is released under the MIT license. |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
8 */ |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
9 |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
10 #include "lib.h" |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
11 #include "hmac.h" |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
12 #include "safe-memset.h" |
21266 | 13 #include "buffer.h" |
15172
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
14 |
16718
92a54bb2ee00
hmac: Fixed crashes on CPUs that don't allow unaligned memory access.
Timo Sirainen <tss@iki.fi>
parents:
15172
diff
changeset
|
15 void hmac_init(struct hmac_context *_ctx, const unsigned char *key, |
15172
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
16 size_t key_len, const struct hash_method *meth) |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
17 { |
16718
92a54bb2ee00
hmac: Fixed crashes on CPUs that don't allow unaligned memory access.
Timo Sirainen <tss@iki.fi>
parents:
15172
diff
changeset
|
18 struct hmac_context_priv *ctx = &_ctx->u.priv; |
15172
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
19 int i; |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
20 unsigned char k_ipad[64]; |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
21 unsigned char k_opad[64]; |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
22 unsigned char hashedkey[meth->digest_size]; |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
23 |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
24 i_assert(meth->context_size <= HMAC_MAX_CONTEXT_SIZE); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
25 |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
26 ctx->hash = meth; |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
27 |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
28 if (key_len > 64) { |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
29 meth->init(ctx->ctx); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
30 meth->loop(ctx->ctx, key, key_len); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
31 meth->result(ctx->ctx, hashedkey); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
32 key = hashedkey; |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
33 key_len = meth->digest_size; |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
34 } |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
35 |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
36 memcpy(k_ipad, key, key_len); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
37 memset(k_ipad + key_len, 0, 64 - key_len); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
38 memcpy(k_opad, k_ipad, 64); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
39 |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
40 for (i = 0; i < 64; i++) { |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
41 k_ipad[i] ^= 0x36; |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
42 k_opad[i] ^= 0x5c; |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
43 } |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
44 |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
45 meth->init(ctx->ctx); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
46 meth->loop(ctx->ctx, k_ipad, 64); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
47 meth->init(ctx->ctxo); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
48 meth->loop(ctx->ctxo, k_opad, 64); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
49 |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
50 safe_memset(k_ipad, 0, 64); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
51 safe_memset(k_opad, 0, 64); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
52 } |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
53 |
16718
92a54bb2ee00
hmac: Fixed crashes on CPUs that don't allow unaligned memory access.
Timo Sirainen <tss@iki.fi>
parents:
15172
diff
changeset
|
54 void hmac_final(struct hmac_context *_ctx, unsigned char *digest) |
15172
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
55 { |
16718
92a54bb2ee00
hmac: Fixed crashes on CPUs that don't allow unaligned memory access.
Timo Sirainen <tss@iki.fi>
parents:
15172
diff
changeset
|
56 struct hmac_context_priv *ctx = &_ctx->u.priv; |
92a54bb2ee00
hmac: Fixed crashes on CPUs that don't allow unaligned memory access.
Timo Sirainen <tss@iki.fi>
parents:
15172
diff
changeset
|
57 |
15172
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
58 ctx->hash->result(ctx->ctx, digest); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
59 |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
60 ctx->hash->loop(ctx->ctxo, digest, ctx->hash->digest_size); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
61 ctx->hash->result(ctx->ctxo, digest); |
8802322d7257
lib: Generalize hmac to be hash independent
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
62 } |
21266 | 63 |
64 buffer_t *t_hmac_data(const struct hash_method *meth, | |
65 const unsigned char *key, size_t key_len, | |
66 const void *data, size_t data_len) | |
67 { | |
68 struct hmac_context ctx; | |
69 i_assert(meth != NULL); | |
70 i_assert(key != NULL && key_len > 0); | |
71 i_assert(data != NULL || data_len == 0); | |
72 | |
73 buffer_t *res = buffer_create_dynamic(pool_datastack_create(), meth->digest_size); | |
74 hmac_init(&ctx, key, key_len, meth); | |
75 if (data_len > 0) | |
76 hmac_update(&ctx, data, data_len); | |
77 unsigned char *buf = buffer_get_space_unsafe(res, 0, meth->digest_size); | |
78 hmac_final(&ctx, buf); | |
79 return res; | |
80 } | |
81 | |
82 buffer_t *t_hmac_buffer(const struct hash_method *meth, | |
83 const unsigned char *key, size_t key_len, | |
84 const buffer_t *data) | |
85 { | |
86 return t_hmac_data(meth, key, key_len, data->data, data->used); | |
87 } | |
88 | |
89 buffer_t *t_hmac_str(const struct hash_method *meth, | |
90 const unsigned char *key, size_t key_len, | |
91 const char *data) | |
92 { | |
93 return t_hmac_data(meth, key, key_len, data, strlen(data)); | |
94 } | |
95 |