gss: pass GSS_C_NO_OID name type through to mechanism
[heimdal.git] / lib / hcrypto / hmac.c
blob6cdf4e97a4e90969e5d082c1fa1dfa55a27293ed
1 /*
2 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
34 #include <config.h>
35 #include <roken.h>
37 #include <hmac.h>
39 void
40 HMAC_CTX_init(HMAC_CTX *ctx)
42 memset(ctx, 0, sizeof(*ctx));
45 void
46 HMAC_CTX_cleanup(HMAC_CTX *ctx)
48 if (ctx->buf) {
49 memset(ctx->buf, 0, ctx->key_length);
50 free(ctx->buf);
51 ctx->buf = NULL;
53 if (ctx->opad) {
54 memset(ctx->opad, 0, EVP_MD_block_size(ctx->md));
55 free(ctx->opad);
56 ctx->opad = NULL;
58 if (ctx->ipad) {
59 memset(ctx->ipad, 0, EVP_MD_block_size(ctx->md));
60 free(ctx->ipad);
61 ctx->ipad = NULL;
63 if (ctx->ctx) {
64 EVP_MD_CTX_destroy(ctx->ctx);
65 ctx->ctx = NULL;
69 HMAC_CTX *
70 HMAC_CTX_new(void)
72 return calloc(1, sizeof(HMAC_CTX));
75 void
76 HMAC_CTX_free(HMAC_CTX *ctx)
78 HMAC_CTX_cleanup(ctx);
79 free(ctx);
82 size_t
83 HMAC_size(const HMAC_CTX *ctx)
85 return EVP_MD_size(ctx->md);
88 void
89 HMAC_Init_ex(HMAC_CTX *ctx,
90 const void *key,
91 size_t keylen,
92 const EVP_MD *md,
93 ENGINE *engine)
95 unsigned char *p;
96 size_t i, blockSize;
98 blockSize = EVP_MD_block_size(md);
100 if (ctx->md != md) {
101 if (ctx->md != NULL)
102 HMAC_CTX_cleanup(ctx);
104 ctx->md = md;
105 ctx->key_length = EVP_MD_size(ctx->md);
106 ctx->buf = malloc(ctx->key_length);
107 ctx->opad = malloc(blockSize);
108 ctx->ipad = malloc(blockSize);
109 ctx->ctx = EVP_MD_CTX_create();
111 #if 0
112 ctx->engine = engine;
113 #endif
115 if (keylen > blockSize) {
116 EVP_Digest(key, keylen, ctx->buf, NULL, ctx->md, engine);
117 key = ctx->buf;
118 keylen = EVP_MD_size(ctx->md);
121 memset(ctx->ipad, 0x36, blockSize);
122 memset(ctx->opad, 0x5c, blockSize);
124 for (i = 0, p = ctx->ipad; i < keylen; i++)
125 p[i] ^= ((const unsigned char *)key)[i];
126 for (i = 0, p = ctx->opad; i < keylen; i++)
127 p[i] ^= ((const unsigned char *)key)[i];
129 EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
130 EVP_DigestUpdate(ctx->ctx, ctx->ipad, EVP_MD_block_size(ctx->md));
133 void
134 HMAC_Update(HMAC_CTX *ctx, const void *data, size_t len)
136 EVP_DigestUpdate(ctx->ctx, data, len);
139 void
140 HMAC_Final(HMAC_CTX *ctx, void *md, unsigned int *len)
142 EVP_DigestFinal_ex(ctx->ctx, ctx->buf, NULL);
144 EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
145 EVP_DigestUpdate(ctx->ctx, ctx->opad, EVP_MD_block_size(ctx->md));
146 EVP_DigestUpdate(ctx->ctx, ctx->buf, ctx->key_length);
147 EVP_DigestFinal_ex(ctx->ctx, md, len);
150 void *
151 HMAC(const EVP_MD *md,
152 const void *key, size_t key_size,
153 const void *data, size_t data_size,
154 void *hash, unsigned int *hash_len)
156 HMAC_CTX ctx;
158 HMAC_CTX_init(&ctx);
159 HMAC_Init_ex(&ctx, key, key_size, md, NULL);
160 HMAC_Update(&ctx, data, data_size);
161 HMAC_Final(&ctx, hash, hash_len);
162 HMAC_CTX_cleanup(&ctx);
163 return hash;