• 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 (MBEDTLS_VERSION_NUMBER >= 0x02070000)
31 #define MBA(fn) fn##_ret
32 #else
33 #define MBA(fn) fn
34 #endif
35 
36 int
lws_genhash_init(struct lws_genhash_ctx * ctx,enum lws_genhash_types type)37 lws_genhash_init(struct lws_genhash_ctx *ctx, enum lws_genhash_types type)
38 {
39 	ctx->type = type;
40 
41 	switch (ctx->type) {
42 	case LWS_GENHASH_TYPE_MD5:
43 		mbedtls_md5_init(&ctx->u.md5);
44 		MBA(mbedtls_md5_starts)(&ctx->u.md5);
45 		break;
46 	case LWS_GENHASH_TYPE_SHA1:
47 		mbedtls_sha1_init(&ctx->u.sha1);
48 		MBA(mbedtls_sha1_starts)(&ctx->u.sha1);
49 		break;
50 	case LWS_GENHASH_TYPE_SHA256:
51 		mbedtls_sha256_init(&ctx->u.sha256);
52 		MBA(mbedtls_sha256_starts)(&ctx->u.sha256, 0);
53 		break;
54 	case LWS_GENHASH_TYPE_SHA384:
55 		mbedtls_sha512_init(&ctx->u.sha512);
56 		MBA(mbedtls_sha512_starts)(&ctx->u.sha512, 1 /* is384 */);
57 		break;
58 	case LWS_GENHASH_TYPE_SHA512:
59 		mbedtls_sha512_init(&ctx->u.sha512);
60 		MBA(mbedtls_sha512_starts)(&ctx->u.sha512, 0);
61 		break;
62 	default:
63 		return 1;
64 	}
65 
66 	return 0;
67 }
68 
69 int
lws_genhash_update(struct lws_genhash_ctx * ctx,const void * in,size_t len)70 lws_genhash_update(struct lws_genhash_ctx *ctx, const void *in, size_t len)
71 {
72 	if (!len)
73 		return 0;
74 
75 	switch (ctx->type) {
76 	case LWS_GENHASH_TYPE_MD5:
77 		MBA(mbedtls_md5_update)(&ctx->u.md5, in, len);
78 		break;
79 	case LWS_GENHASH_TYPE_SHA1:
80 		MBA(mbedtls_sha1_update)(&ctx->u.sha1, in, len);
81 		break;
82 	case LWS_GENHASH_TYPE_SHA256:
83 		MBA(mbedtls_sha256_update)(&ctx->u.sha256, in, len);
84 		break;
85 	case LWS_GENHASH_TYPE_SHA384:
86 		MBA(mbedtls_sha512_update)(&ctx->u.sha512, in, len);
87 		break;
88 	case LWS_GENHASH_TYPE_SHA512:
89 		MBA(mbedtls_sha512_update)(&ctx->u.sha512, in, len);
90 		break;
91 	}
92 
93 	return 0;
94 }
95 
96 int
lws_genhash_destroy(struct lws_genhash_ctx * ctx,void * result)97 lws_genhash_destroy(struct lws_genhash_ctx *ctx, void *result)
98 {
99 	switch (ctx->type) {
100 	case LWS_GENHASH_TYPE_MD5:
101 		MBA(mbedtls_md5_finish)(&ctx->u.md5, result);
102 		mbedtls_md5_free(&ctx->u.md5);
103 		break;
104 	case LWS_GENHASH_TYPE_SHA1:
105 		MBA(mbedtls_sha1_finish)(&ctx->u.sha1, result);
106 		mbedtls_sha1_free(&ctx->u.sha1);
107 		break;
108 	case LWS_GENHASH_TYPE_SHA256:
109 		MBA(mbedtls_sha256_finish)(&ctx->u.sha256, result);
110 		mbedtls_sha256_free(&ctx->u.sha256);
111 		break;
112 	case LWS_GENHASH_TYPE_SHA384:
113 		MBA(mbedtls_sha512_finish)(&ctx->u.sha512, result);
114 		mbedtls_sha512_free(&ctx->u.sha512);
115 		break;
116 	case LWS_GENHASH_TYPE_SHA512:
117 		MBA(mbedtls_sha512_finish)(&ctx->u.sha512, result);
118 		mbedtls_sha512_free(&ctx->u.sha512);
119 		break;
120 	}
121 
122 	return 0;
123 }
124 
125 int
lws_genhmac_init(struct lws_genhmac_ctx * ctx,enum lws_genhmac_types type,const uint8_t * key,size_t key_len)126 lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type,
127 		 const uint8_t *key, size_t key_len)
128 {
129 	int t;
130 
131 	ctx->type = type;
132 
133 	switch (type) {
134 	case LWS_GENHMAC_TYPE_SHA256:
135 		t = MBEDTLS_MD_SHA256;
136 		break;
137 	case LWS_GENHMAC_TYPE_SHA384:
138 		t = MBEDTLS_MD_SHA384;
139 		break;
140 	case LWS_GENHMAC_TYPE_SHA512:
141 		t = MBEDTLS_MD_SHA512;
142 		break;
143 	default:
144 		return -1;
145 	}
146 
147 	ctx->hmac = mbedtls_md_info_from_type(t);
148 	if (!ctx->hmac)
149 		return -1;
150 
151 	if (mbedtls_md_init_ctx(&ctx->ctx, ctx->hmac))
152 		return -1;
153 
154 	if (mbedtls_md_hmac_starts(&ctx->ctx, key, key_len)) {
155 		mbedtls_md_free(&ctx->ctx);
156 		ctx->hmac = NULL;
157 
158 		return -1;
159 	}
160 
161 	return 0;
162 }
163 
164 int
lws_genhmac_update(struct lws_genhmac_ctx * ctx,const void * in,size_t len)165 lws_genhmac_update(struct lws_genhmac_ctx *ctx, const void *in, size_t len)
166 {
167 	if (!len)
168 		return 0;
169 
170 	if (mbedtls_md_hmac_update(&ctx->ctx, in, len))
171 		return -1;
172 
173 	return 0;
174 }
175 
176 int
lws_genhmac_destroy(struct lws_genhmac_ctx * ctx,void * result)177 lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result)
178 {
179 	int n = 0;
180 
181 	if (result)
182 		n = mbedtls_md_hmac_finish(&ctx->ctx, result);
183 
184 	mbedtls_md_free(&ctx->ctx);
185 	ctx->hmac = NULL;
186 	if (n)
187 		return -1;
188 
189 	return 0;
190 }
191