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