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