1 /* $NetBSD: hmac.c,v 1.1.1.1 2011/04/13 18:14:50 elric Exp $ */
4 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <sys/types.h>
43 HMAC_CTX_init(HMAC_CTX
*ctx
)
45 memset(ctx
, 0, sizeof(*ctx
));
49 HMAC_CTX_cleanup(HMAC_CTX
*ctx
)
52 memset(ctx
->buf
, 0, ctx
->key_length
);
57 memset(ctx
->opad
, 0, EVP_MD_block_size(ctx
->md
));
62 memset(ctx
->ipad
, 0, EVP_MD_block_size(ctx
->md
));
67 EVP_MD_CTX_destroy(ctx
->ctx
);
73 HMAC_size(const HMAC_CTX
*ctx
)
75 return EVP_MD_size(ctx
->md
);
79 HMAC_Init_ex(HMAC_CTX
*ctx
,
91 memset(ctx
->buf
, 0, ctx
->key_length
);
94 ctx
->key_length
= EVP_MD_size(ctx
->md
);
95 ctx
->buf
= malloc(ctx
->key_length
);
101 if (keylen
> EVP_MD_block_size(ctx
->md
)) {
102 EVP_Digest(key
, keylen
, ctx
->buf
, NULL
, ctx
->md
, engine
);
104 keylen
= EVP_MD_size(ctx
->md
);
108 memset(ctx
->opad
, 0, ctx
->key_length
);
112 memset(ctx
->ipad
, 0, ctx
->key_length
);
116 ctx
->opad
= malloc(EVP_MD_block_size(ctx
->md
));
117 ctx
->ipad
= malloc(EVP_MD_block_size(ctx
->md
));
118 memset(ctx
->ipad
, 0x36, EVP_MD_block_size(ctx
->md
));
119 memset(ctx
->opad
, 0x5c, EVP_MD_block_size(ctx
->md
));
121 for (i
= 0, p
= ctx
->ipad
; i
< keylen
; i
++)
122 p
[i
] ^= ((const unsigned char *)key
)[i
];
123 for (i
= 0, p
= ctx
->opad
; i
< keylen
; i
++)
124 p
[i
] ^= ((const unsigned char *)key
)[i
];
126 if (ctx
->ctx
== NULL
)
127 ctx
->ctx
= EVP_MD_CTX_create();
129 EVP_DigestInit_ex(ctx
->ctx
, ctx
->md
, ctx
->engine
);
130 EVP_DigestUpdate(ctx
->ctx
, ctx
->ipad
, EVP_MD_block_size(ctx
->md
));
134 HMAC_Update(HMAC_CTX
*ctx
, const void *data
, size_t len
)
136 EVP_DigestUpdate(ctx
->ctx
, data
, len
);
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
);
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
)
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
);