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