• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  *
24  *  lws_genhash provides a hash / hmac abstraction api in lws that works the
25  *  same whether you are using openssl or mbedtls hash functions underneath.
26  */
27 #include "libwebsockets.h"
28 #include <mbedtls/version.h>
29 
30 #if defined(MBEDTLS_VERSION_NUMBER) && (MBEDTLS_VERSION_NUMBER >= 0x03000000)
31 #define mbedtls_md5_starts_ret mbedtls_md5_starts
32 #define mbedtls_md5_update_ret mbedtls_md5_update
33 #define mbedtls_md5_finish_ret mbedtls_md5_finish
34 #define mbedtls_sha1_finish_ret mbedtls_sha1_finish
35 #define mbedtls_sha1_update_ret mbedtls_sha1_update
36 #define mbedtls_sha1_starts_ret mbedtls_sha1_starts
37 #define mbedtls_sha256_starts_ret mbedtls_sha256_starts
38 #define mbedtls_sha256_update_ret mbedtls_sha256_update
39 #define mbedtls_sha256_finish_ret mbedtls_sha256_finish
40 #define mbedtls_sha512_starts_ret mbedtls_sha512_starts
41 #define mbedtls_sha512_update_ret mbedtls_sha512_update
42 #define mbedtls_sha512_finish_ret mbedtls_sha512_finish
43 #endif
44 
45 #if defined(MBEDTLS_VERSION_NUMBER) && (MBEDTLS_VERSION_NUMBER >= 0x02070000)
46 
47 /*
48  * We have the _ret variants available, check the return codes on everything
49  */
50 
51 int
lws_genhash_init(struct lws_genhash_ctx * ctx,enum lws_genhash_types type)52 lws_genhash_init(struct lws_genhash_ctx *ctx, enum lws_genhash_types type)
53 {
54 	ctx->type = (uint8_t)type;
55 
56 	switch (ctx->type) {
57 	case LWS_GENHASH_TYPE_MD5:
58 		mbedtls_md5_init(&ctx->u.md5);
59 		if (mbedtls_md5_starts_ret(&ctx->u.md5))
60 			return 1;
61 		break;
62 	case LWS_GENHASH_TYPE_SHA1:
63 		mbedtls_sha1_init(&ctx->u.sha1);
64 		if (mbedtls_sha1_starts_ret(&ctx->u.sha1))
65 			return 1;
66 		break;
67 	case LWS_GENHASH_TYPE_SHA256:
68 		mbedtls_sha256_init(&ctx->u.sha256);
69 		if (mbedtls_sha256_starts_ret(&ctx->u.sha256, 0))
70 			return 1;
71 		break;
72 	case LWS_GENHASH_TYPE_SHA384:
73 		mbedtls_sha512_init(&ctx->u.sha512);
74 		if (mbedtls_sha512_starts_ret(&ctx->u.sha512, 1 /* is384 */))
75 			return 1;
76 		break;
77 	case LWS_GENHASH_TYPE_SHA512:
78 		mbedtls_sha512_init(&ctx->u.sha512);
79 		if (mbedtls_sha512_starts_ret(&ctx->u.sha512, 0))
80 			return 1;
81 		break;
82 	default:
83 		return 1;
84 	}
85 
86 	return 0;
87 }
88 
89 int
lws_genhash_update(struct lws_genhash_ctx * ctx,const void * in,size_t len)90 lws_genhash_update(struct lws_genhash_ctx *ctx, const void *in, size_t len)
91 {
92 	if (!len)
93 		return 0;
94 
95 	switch (ctx->type) {
96 	case LWS_GENHASH_TYPE_MD5:
97 		if (mbedtls_md5_update_ret(&ctx->u.md5, in, len))
98 			return 1;
99 		break;
100 	case LWS_GENHASH_TYPE_SHA1:
101 		if (mbedtls_sha1_update_ret(&ctx->u.sha1, in, len))
102 			return 1;
103 		break;
104 	case LWS_GENHASH_TYPE_SHA256:
105 		if (mbedtls_sha256_update_ret(&ctx->u.sha256, in, len))
106 			return 1;
107 		break;
108 	case LWS_GENHASH_TYPE_SHA384:
109 		if (mbedtls_sha512_update_ret(&ctx->u.sha512, in, len))
110 			return 1;
111 		break;
112 	case LWS_GENHASH_TYPE_SHA512:
113 		if (mbedtls_sha512_update_ret(&ctx->u.sha512, in, len))
114 			return 1;
115 		break;
116 	}
117 
118 	return 0;
119 }
120 
121 int
lws_genhash_destroy(struct lws_genhash_ctx * ctx,void * result)122 lws_genhash_destroy(struct lws_genhash_ctx *ctx, void *result)
123 {
124 	switch (ctx->type) {
125 	case LWS_GENHASH_TYPE_MD5:
126 		if (mbedtls_md5_finish_ret(&ctx->u.md5, result))
127 			return 1;
128 		mbedtls_md5_free(&ctx->u.md5);
129 		break;
130 	case LWS_GENHASH_TYPE_SHA1:
131 		if (mbedtls_sha1_finish_ret(&ctx->u.sha1, result))
132 			return 1;
133 		mbedtls_sha1_free(&ctx->u.sha1);
134 		break;
135 	case LWS_GENHASH_TYPE_SHA256:
136 		if (mbedtls_sha256_finish_ret(&ctx->u.sha256, result))
137 			return 1;
138 		mbedtls_sha256_free(&ctx->u.sha256);
139 		break;
140 	case LWS_GENHASH_TYPE_SHA384:
141 		if (mbedtls_sha512_finish_ret(&ctx->u.sha512, result))
142 			return 1;
143 		mbedtls_sha512_free(&ctx->u.sha512);
144 		break;
145 	case LWS_GENHASH_TYPE_SHA512:
146 		if (mbedtls_sha512_finish_ret(&ctx->u.sha512, result))
147 			return 1;
148 		mbedtls_sha512_free(&ctx->u.sha512);
149 		break;
150 	}
151 
152 	return 0;
153 }
154 
155 #else
156 
157 /*
158  * mbedtls is too old to have the _ret variants
159  */
160 
161 int
lws_genhash_init(struct lws_genhash_ctx * ctx,enum lws_genhash_types type)162 lws_genhash_init(struct lws_genhash_ctx *ctx, enum lws_genhash_types type)
163 {
164 	ctx->type = type;
165 
166 	switch (ctx->type) {
167 	case LWS_GENHASH_TYPE_MD5:
168 		mbedtls_md5_init(&ctx->u.md5);
169 		mbedtls_md5_starts(&ctx->u.md5);
170 		break;
171 	case LWS_GENHASH_TYPE_SHA1:
172 		mbedtls_sha1_init(&ctx->u.sha1);
173 		mbedtls_sha1_starts(&ctx->u.sha1);
174 		break;
175 	case LWS_GENHASH_TYPE_SHA256:
176 		mbedtls_sha256_init(&ctx->u.sha256);
177 		mbedtls_sha256_starts(&ctx->u.sha256, 0);
178 		break;
179 	case LWS_GENHASH_TYPE_SHA384:
180 		mbedtls_sha512_init(&ctx->u.sha512);
181 		mbedtls_sha512_starts(&ctx->u.sha512, 1 /* is384 */);
182 		break;
183 	case LWS_GENHASH_TYPE_SHA512:
184 		mbedtls_sha512_init(&ctx->u.sha512);
185 		mbedtls_sha512_starts(&ctx->u.sha512, 0);
186 		break;
187 	default:
188 		return 1;
189 	}
190 
191 	return 0;
192 }
193 
194 int
lws_genhash_update(struct lws_genhash_ctx * ctx,const void * in,size_t len)195 lws_genhash_update(struct lws_genhash_ctx *ctx, const void *in, size_t len)
196 {
197 	if (!len)
198 		return 0;
199 
200 	switch (ctx->type) {
201 	case LWS_GENHASH_TYPE_MD5:
202 		mbedtls_md5_update(&ctx->u.md5, in, len);
203 		break;
204 	case LWS_GENHASH_TYPE_SHA1:
205 		mbedtls_sha1_update(&ctx->u.sha1, in, len);
206 		break;
207 	case LWS_GENHASH_TYPE_SHA256:
208 		mbedtls_sha256_update(&ctx->u.sha256, in, len);
209 		break;
210 	case LWS_GENHASH_TYPE_SHA384:
211 		mbedtls_sha512_update(&ctx->u.sha512, in, len);
212 		break;
213 	case LWS_GENHASH_TYPE_SHA512:
214 		mbedtls_sha512_update(&ctx->u.sha512, in, len);
215 		break;
216 	}
217 
218 	return 0;
219 }
220 
221 int
lws_genhash_destroy(struct lws_genhash_ctx * ctx,void * result)222 lws_genhash_destroy(struct lws_genhash_ctx *ctx, void *result)
223 {
224 	switch (ctx->type) {
225 	case LWS_GENHASH_TYPE_MD5:
226 		mbedtls_md5_finish(&ctx->u.md5, result);
227 		mbedtls_md5_free(&ctx->u.md5);
228 		break;
229 	case LWS_GENHASH_TYPE_SHA1:
230 		mbedtls_sha1_finish(&ctx->u.sha1, result);
231 		mbedtls_sha1_free(&ctx->u.sha1);
232 		break;
233 	case LWS_GENHASH_TYPE_SHA256:
234 		mbedtls_sha256_finish(&ctx->u.sha256, result);
235 		mbedtls_sha256_free(&ctx->u.sha256);
236 		break;
237 	case LWS_GENHASH_TYPE_SHA384:
238 		mbedtls_sha512_finish(&ctx->u.sha512, result);
239 		mbedtls_sha512_free(&ctx->u.sha512);
240 		break;
241 	case LWS_GENHASH_TYPE_SHA512:
242 		mbedtls_sha512_finish(&ctx->u.sha512, result);
243 		mbedtls_sha512_free(&ctx->u.sha512);
244 		break;
245 	}
246 
247 	return 0;
248 }
249 
250 #endif
251 
252 int
lws_genhmac_init(struct lws_genhmac_ctx * ctx,enum lws_genhmac_types type,const uint8_t * key,size_t key_len)253 lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type,
254 		 const uint8_t *key, size_t key_len)
255 {
256 	int t;
257 
258 	ctx->type = (uint8_t)type;
259 
260 	switch (type) {
261 	case LWS_GENHMAC_TYPE_SHA256:
262 		t = MBEDTLS_MD_SHA256;
263 		break;
264 	case LWS_GENHMAC_TYPE_SHA384:
265 		t = MBEDTLS_MD_SHA384;
266 		break;
267 	case LWS_GENHMAC_TYPE_SHA512:
268 		t = MBEDTLS_MD_SHA512;
269 		break;
270 	default:
271 		return -1;
272 	}
273 
274 	ctx->hmac = mbedtls_md_info_from_type((mbedtls_md_type_t)t);
275 	if (!ctx->hmac)
276 		return -1;
277 
278 #if !defined(LWS_HAVE_mbedtls_md_setup)
279 	if (mbedtls_md_init_ctx(&ctx->ctx, ctx->hmac))
280 		return -1;
281 #else
282 	if (mbedtls_md_setup(&ctx->ctx, ctx->hmac, 1))
283 		return -1;
284 #endif
285 
286 	if (mbedtls_md_hmac_starts(&ctx->ctx, key, key_len)) {
287 		mbedtls_md_free(&ctx->ctx);
288 		ctx->hmac = NULL;
289 
290 		return -1;
291 	}
292 
293 	return 0;
294 }
295 
296 int
lws_genhmac_update(struct lws_genhmac_ctx * ctx,const void * in,size_t len)297 lws_genhmac_update(struct lws_genhmac_ctx *ctx, const void *in, size_t len)
298 {
299 	if (!len)
300 		return 0;
301 
302 	if (mbedtls_md_hmac_update(&ctx->ctx, in, len))
303 		return -1;
304 
305 	return 0;
306 }
307 
308 int
lws_genhmac_destroy(struct lws_genhmac_ctx * ctx,void * result)309 lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result)
310 {
311 	int n = 0;
312 
313 	if (result)
314 		n = mbedtls_md_hmac_finish(&ctx->ctx, result);
315 
316 	mbedtls_md_free(&ctx->ctx);
317 	ctx->hmac = NULL;
318 	if (n)
319 		return -1;
320 
321 	return 0;
322 }
323