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