Line data Source code
1 : /*
2 : * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * 3. Neither the name of the Institute nor the names of its contributors
18 : * may be used to endorse or promote products derived from this software
19 : * without specific prior written permission.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 : * SUCH DAMAGE.
32 : */
33 :
34 : #include <config.h>
35 : #include <roken.h>
36 :
37 : #include <hmac.h>
38 :
39 : void
40 607881779 : HMAC_CTX_init(HMAC_CTX *ctx)
41 : {
42 607881779 : memset(ctx, 0, sizeof(*ctx));
43 607881779 : }
44 :
45 : void
46 609075343 : HMAC_CTX_cleanup(HMAC_CTX *ctx)
47 : {
48 609075343 : if (ctx->buf) {
49 609075343 : memset_s(ctx->buf, ctx->key_length, 0, ctx->key_length);
50 609075343 : free(ctx->buf);
51 609075343 : ctx->buf = NULL;
52 : }
53 609075343 : if (ctx->opad) {
54 609075343 : memset_s(ctx->opad, EVP_MD_block_size(ctx->md), 0, EVP_MD_block_size(ctx->md));
55 609075343 : free(ctx->opad);
56 609075343 : ctx->opad = NULL;
57 : }
58 609075343 : if (ctx->ipad) {
59 609075343 : memset_s(ctx->ipad, EVP_MD_block_size(ctx->md), 0, EVP_MD_block_size(ctx->md));
60 609075343 : free(ctx->ipad);
61 609075343 : ctx->ipad = NULL;
62 : }
63 609075343 : if (ctx->ctx) {
64 609075343 : EVP_MD_CTX_destroy(ctx->ctx);
65 609075343 : ctx->ctx = NULL;
66 : }
67 609075343 : }
68 :
69 : HMAC_CTX *
70 1193564 : HMAC_CTX_new(void)
71 : {
72 1193564 : return calloc(1, sizeof(HMAC_CTX));
73 : }
74 :
75 : void
76 1193564 : HMAC_CTX_free(HMAC_CTX *ctx)
77 : {
78 1193564 : HMAC_CTX_cleanup(ctx);
79 1193564 : free(ctx);
80 1193564 : }
81 :
82 : size_t
83 0 : HMAC_size(const HMAC_CTX *ctx)
84 : {
85 0 : return EVP_MD_size(ctx->md);
86 : }
87 :
88 : int
89 612706065 : HMAC_Init_ex(HMAC_CTX *ctx,
90 : const void *key,
91 : size_t keylen,
92 : const EVP_MD *md,
93 : ENGINE *engine)
94 : {
95 12566258 : unsigned char *p;
96 12566258 : size_t i, blockSize;
97 :
98 612706065 : blockSize = EVP_MD_block_size(md);
99 :
100 612706065 : if (ctx->md != md) {
101 609075343 : if (ctx->md != NULL)
102 0 : HMAC_CTX_cleanup(ctx);
103 :
104 609075343 : ctx->md = md;
105 609075343 : ctx->key_length = EVP_MD_size(ctx->md);
106 609075343 : ctx->opad = NULL;
107 609075343 : ctx->ipad = NULL;
108 609075343 : ctx->ctx = NULL;
109 609075343 : ctx->buf = malloc(ctx->key_length);
110 609075343 : if (ctx->buf)
111 609075343 : ctx->opad = malloc(blockSize);
112 609075343 : if (ctx->opad)
113 609075343 : ctx->ipad = malloc(blockSize);
114 609075343 : if (ctx->ipad)
115 609075343 : ctx->ctx = EVP_MD_CTX_create();
116 : }
117 : /* We do this check here to quiet scan-build */
118 612706065 : if (!ctx->buf || !ctx->opad || !ctx->ipad || !ctx->ctx)
119 0 : return 0;
120 : #if 0
121 : ctx->engine = engine;
122 : #endif
123 :
124 612706065 : if (keylen > blockSize) {
125 178147328 : if (EVP_Digest(key, keylen, ctx->buf, NULL, ctx->md, engine) == 0)
126 0 : return 0;
127 178147328 : key = ctx->buf;
128 178147328 : keylen = EVP_MD_size(ctx->md);
129 : }
130 :
131 612706065 : memset(ctx->ipad, 0x36, blockSize);
132 612706065 : memset(ctx->opad, 0x5c, blockSize);
133 :
134 10032097157 : for (i = 0, p = ctx->ipad; i < keylen; i++)
135 9419391092 : p[i] ^= ((const unsigned char *)key)[i];
136 10032097157 : for (i = 0, p = ctx->opad; i < keylen; i++)
137 9419391092 : p[i] ^= ((const unsigned char *)key)[i];
138 :
139 612706065 : if (EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine) == 0)
140 0 : return 0;
141 612706065 : EVP_DigestUpdate(ctx->ctx, ctx->ipad, EVP_MD_block_size(ctx->md));
142 612706065 : return 1;
143 : }
144 :
145 : void
146 615841777 : HMAC_Update(HMAC_CTX *ctx, const void *data, size_t len)
147 : {
148 615841777 : EVP_DigestUpdate(ctx->ctx, data, len);
149 615841777 : }
150 :
151 : void
152 612706065 : HMAC_Final(HMAC_CTX *ctx, void *md, unsigned int *len)
153 : {
154 612706065 : EVP_DigestFinal_ex(ctx->ctx, ctx->buf, NULL);
155 :
156 612706065 : EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
157 612706065 : EVP_DigestUpdate(ctx->ctx, ctx->opad, EVP_MD_block_size(ctx->md));
158 612706065 : EVP_DigestUpdate(ctx->ctx, ctx->buf, ctx->key_length);
159 612706065 : EVP_DigestFinal_ex(ctx->ctx, md, len);
160 612706065 : }
161 :
162 : void *
163 607866880 : HMAC(const EVP_MD *md,
164 : const void *key, size_t key_size,
165 : const void *data, size_t data_size,
166 : void *hash, unsigned int *hash_len)
167 : {
168 12513280 : HMAC_CTX ctx;
169 :
170 607866880 : HMAC_CTX_init(&ctx);
171 607866880 : if (HMAC_Init_ex(&ctx, key, key_size, md, NULL) == 0) {
172 0 : HMAC_CTX_cleanup(&ctx);
173 0 : return NULL;
174 : }
175 607866880 : HMAC_Update(&ctx, data, data_size);
176 607866880 : HMAC_Final(&ctx, hash, hash_len);
177 607866880 : HMAC_CTX_cleanup(&ctx);
178 607866880 : return hash;
179 : }
|