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 470981305 : HMAC_CTX_init(HMAC_CTX *ctx)
41 : {
42 470981305 : memset(ctx, 0, sizeof(*ctx));
43 470981305 : }
44 :
45 : void
46 471855884 : HMAC_CTX_cleanup(HMAC_CTX *ctx)
47 : {
48 471855884 : if (ctx->buf) {
49 471855884 : memset(ctx->buf, 0, ctx->key_length);
50 471855884 : free(ctx->buf);
51 471855884 : ctx->buf = NULL;
52 : }
53 471855884 : if (ctx->opad) {
54 471855884 : memset(ctx->opad, 0, EVP_MD_block_size(ctx->md));
55 471855884 : free(ctx->opad);
56 471855884 : ctx->opad = NULL;
57 : }
58 471855884 : if (ctx->ipad) {
59 471855884 : memset(ctx->ipad, 0, EVP_MD_block_size(ctx->md));
60 471855884 : free(ctx->ipad);
61 471855884 : ctx->ipad = NULL;
62 : }
63 471855884 : if (ctx->ctx) {
64 471855884 : EVP_MD_CTX_destroy(ctx->ctx);
65 471855884 : ctx->ctx = NULL;
66 : }
67 471855884 : }
68 :
69 : HMAC_CTX *
70 874579 : HMAC_CTX_new(void)
71 : {
72 874579 : return calloc(1, sizeof(HMAC_CTX));
73 : }
74 :
75 : void
76 874579 : HMAC_CTX_free(HMAC_CTX *ctx)
77 : {
78 874579 : HMAC_CTX_cleanup(ctx);
79 874579 : free(ctx);
80 874579 : }
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 474855947 : HMAC_Init_ex(HMAC_CTX *ctx,
90 : const void *key,
91 : size_t keylen,
92 : const EVP_MD *md,
93 : ENGINE *engine)
94 : {
95 : unsigned char *p;
96 : size_t i, blockSize;
97 :
98 474855947 : blockSize = EVP_MD_block_size(md);
99 :
100 474855947 : if (ctx->md != md) {
101 471855884 : if (ctx->md != NULL)
102 0 : HMAC_CTX_cleanup(ctx);
103 :
104 471855884 : ctx->md = md;
105 471855884 : ctx->key_length = EVP_MD_size(ctx->md);
106 471855884 : ctx->opad = NULL;
107 471855884 : ctx->ipad = NULL;
108 471855884 : ctx->ctx = NULL;
109 471855884 : ctx->buf = malloc(ctx->key_length);
110 471855884 : if (ctx->buf)
111 471855884 : ctx->opad = malloc(blockSize);
112 471855884 : if (ctx->opad)
113 471855884 : ctx->ipad = malloc(blockSize);
114 471855884 : if (ctx->ipad)
115 471855884 : ctx->ctx = EVP_MD_CTX_create();
116 471855884 : if (!ctx->buf || !ctx->opad || !ctx->ipad || !ctx->ctx)
117 0 : return 0;
118 : }
119 : #if 0
120 : ctx->engine = engine;
121 : #endif
122 :
123 474855947 : if (keylen > blockSize) {
124 166207488 : if (EVP_Digest(key, keylen, ctx->buf, NULL, ctx->md, engine) == 0)
125 0 : return 0;
126 166207488 : key = ctx->buf;
127 166207488 : keylen = EVP_MD_size(ctx->md);
128 : }
129 :
130 474855947 : memset(ctx->ipad, 0x36, blockSize);
131 474855947 : memset(ctx->opad, 0x5c, blockSize);
132 :
133 8143952183 : for (i = 0, p = ctx->ipad; i < keylen; i++)
134 7669096236 : p[i] ^= ((const unsigned char *)key)[i];
135 8143952183 : for (i = 0, p = ctx->opad; i < keylen; i++)
136 7669096236 : p[i] ^= ((const unsigned char *)key)[i];
137 :
138 474855947 : if (EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine) == 0)
139 0 : return 0;
140 474855947 : EVP_DigestUpdate(ctx->ctx, ctx->ipad, EVP_MD_block_size(ctx->md));
141 474855947 : return 1;
142 : }
143 :
144 : void
145 477646132 : HMAC_Update(HMAC_CTX *ctx, const void *data, size_t len)
146 : {
147 477646132 : EVP_DigestUpdate(ctx->ctx, data, len);
148 477646132 : }
149 :
150 : void
151 474855947 : HMAC_Final(HMAC_CTX *ctx, void *md, unsigned int *len)
152 : {
153 474855947 : EVP_DigestFinal_ex(ctx->ctx, ctx->buf, NULL);
154 :
155 474855947 : EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
156 474855947 : EVP_DigestUpdate(ctx->ctx, ctx->opad, EVP_MD_block_size(ctx->md));
157 474855947 : EVP_DigestUpdate(ctx->ctx, ctx->buf, ctx->key_length);
158 474855947 : EVP_DigestFinal_ex(ctx->ctx, md, len);
159 474855947 : }
160 :
161 : void *
162 470970368 : HMAC(const EVP_MD *md,
163 : const void *key, size_t key_size,
164 : const void *data, size_t data_size,
165 : void *hash, unsigned int *hash_len)
166 : {
167 : HMAC_CTX ctx;
168 :
169 470970368 : HMAC_CTX_init(&ctx);
170 470970368 : if (HMAC_Init_ex(&ctx, key, key_size, md, NULL) == 0) {
171 0 : HMAC_CTX_cleanup(&ctx);
172 0 : return NULL;
173 : }
174 470970368 : HMAC_Update(&ctx, data, data_size);
175 470970368 : HMAC_Final(&ctx, hash, hash_len);
176 470970368 : HMAC_CTX_cleanup(&ctx);
177 470970368 : return hash;
178 : }
|