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 471354048 : HMAC_CTX_init(HMAC_CTX *ctx)
41 : {
42 471354048 : memset(ctx, 0, sizeof(*ctx));
43 471354048 : }
44 :
45 : void
46 472229223 : HMAC_CTX_cleanup(HMAC_CTX *ctx)
47 : {
48 472229223 : if (ctx->buf) {
49 472229223 : memset(ctx->buf, 0, ctx->key_length);
50 472229223 : free(ctx->buf);
51 472229223 : ctx->buf = NULL;
52 : }
53 472229223 : if (ctx->opad) {
54 472229223 : memset(ctx->opad, 0, EVP_MD_block_size(ctx->md));
55 472229223 : free(ctx->opad);
56 472229223 : ctx->opad = NULL;
57 : }
58 472229223 : if (ctx->ipad) {
59 472229223 : memset(ctx->ipad, 0, EVP_MD_block_size(ctx->md));
60 472229223 : free(ctx->ipad);
61 472229223 : ctx->ipad = NULL;
62 : }
63 472229223 : if (ctx->ctx) {
64 472229223 : EVP_MD_CTX_destroy(ctx->ctx);
65 472229223 : ctx->ctx = NULL;
66 : }
67 472229223 : }
68 :
69 : HMAC_CTX *
70 875175 : HMAC_CTX_new(void)
71 : {
72 875175 : return calloc(1, sizeof(HMAC_CTX));
73 : }
74 :
75 : void
76 875175 : HMAC_CTX_free(HMAC_CTX *ctx)
77 : {
78 875175 : HMAC_CTX_cleanup(ctx);
79 875175 : free(ctx);
80 875175 : }
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 475243131 : 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 475243131 : blockSize = EVP_MD_block_size(md);
99 :
100 475243131 : if (ctx->md != md) {
101 472229223 : if (ctx->md != NULL)
102 0 : HMAC_CTX_cleanup(ctx);
103 :
104 472229223 : ctx->md = md;
105 472229223 : ctx->key_length = EVP_MD_size(ctx->md);
106 472229223 : ctx->opad = NULL;
107 472229223 : ctx->ipad = NULL;
108 472229223 : ctx->ctx = NULL;
109 472229223 : ctx->buf = malloc(ctx->key_length);
110 472229223 : if (ctx->buf)
111 472229223 : ctx->opad = malloc(blockSize);
112 472229223 : if (ctx->opad)
113 472229223 : ctx->ipad = malloc(blockSize);
114 472229223 : if (ctx->ipad)
115 472229223 : ctx->ctx = EVP_MD_CTX_create();
116 472229223 : 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 475243131 : if (keylen > blockSize) {
124 165335040 : if (EVP_Digest(key, keylen, ctx->buf, NULL, ctx->md, engine) == 0)
125 0 : return 0;
126 165335040 : key = ctx->buf;
127 165335040 : keylen = EVP_MD_size(ctx->md);
128 : }
129 :
130 475243131 : memset(ctx->ipad, 0x36, blockSize);
131 475243131 : memset(ctx->opad, 0x5c, blockSize);
132 :
133 8195989275 : for (i = 0, p = ctx->ipad; i < keylen; i++)
134 7720746144 : p[i] ^= ((const unsigned char *)key)[i];
135 8195989275 : for (i = 0, p = ctx->opad; i < keylen; i++)
136 7720746144 : p[i] ^= ((const unsigned char *)key)[i];
137 :
138 475243131 : if (EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine) == 0)
139 0 : return 0;
140 475243131 : EVP_DigestUpdate(ctx->ctx, ctx->ipad, EVP_MD_block_size(ctx->md));
141 475243131 : return 1;
142 : }
143 :
144 : void
145 478054658 : HMAC_Update(HMAC_CTX *ctx, const void *data, size_t len)
146 : {
147 478054658 : EVP_DigestUpdate(ctx->ctx, data, len);
148 478054658 : }
149 :
150 : void
151 475243131 : HMAC_Final(HMAC_CTX *ctx, void *md, unsigned int *len)
152 : {
153 475243131 : EVP_DigestFinal_ex(ctx->ctx, ctx->buf, NULL);
154 :
155 475243131 : EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
156 475243131 : EVP_DigestUpdate(ctx->ctx, ctx->opad, EVP_MD_block_size(ctx->md));
157 475243131 : EVP_DigestUpdate(ctx->ctx, ctx->buf, ctx->key_length);
158 475243131 : EVP_DigestFinal_ex(ctx->ctx, md, len);
159 475243131 : }
160 :
161 : void *
162 471343104 : 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 471343104 : HMAC_CTX_init(&ctx);
170 471343104 : if (HMAC_Init_ex(&ctx, key, key_size, md, NULL) == 0) {
171 0 : HMAC_CTX_cleanup(&ctx);
172 0 : return NULL;
173 : }
174 471343104 : HMAC_Update(&ctx, data, data_size);
175 471343104 : HMAC_Final(&ctx, hash, hash_len);
176 471343104 : HMAC_CTX_cleanup(&ctx);
177 471343104 : return hash;
178 : }
|