• 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 <openssl/obj_mac.h>
29 /*
30  * Care: many openssl apis return 1 for success.  These are translated to the
31  * lws convention of 0 for success.
32  */
33 
34 int
lws_genhash_init(struct lws_genhash_ctx * ctx,enum lws_genhash_types type)35 lws_genhash_init(struct lws_genhash_ctx *ctx, enum lws_genhash_types type)
36 {
37 	ctx->type = type;
38 	ctx->mdctx = EVP_MD_CTX_create();
39 	if (!ctx->mdctx)
40 		return 1;
41 
42 	switch (ctx->type) {
43 	case LWS_GENHASH_TYPE_MD5:
44 		ctx->evp_type = EVP_md5();
45 		break;
46 	case LWS_GENHASH_TYPE_SHA1:
47 		ctx->evp_type = EVP_sha1();
48 		break;
49 	case LWS_GENHASH_TYPE_SHA256:
50 		ctx->evp_type = EVP_sha256();
51 		break;
52 	case LWS_GENHASH_TYPE_SHA384:
53 		ctx->evp_type = EVP_sha384();
54 		break;
55 	case LWS_GENHASH_TYPE_SHA512:
56 		ctx->evp_type = EVP_sha512();
57 		break;
58 	default:
59 		return 1;
60 	}
61 
62 	if (EVP_DigestInit_ex(ctx->mdctx, ctx->evp_type, NULL) != 1) {
63 		EVP_MD_CTX_destroy(ctx->mdctx);
64 
65 		return 1;
66 	}
67 
68 	return 0;
69 }
70 
71 int
lws_genhash_update(struct lws_genhash_ctx * ctx,const void * in,size_t len)72 lws_genhash_update(struct lws_genhash_ctx *ctx, const void *in, size_t len)
73 {
74 	if (!len)
75 		return 0;
76 
77 	return EVP_DigestUpdate(ctx->mdctx, in, len) != 1;
78 }
79 
80 int
lws_genhash_destroy(struct lws_genhash_ctx * ctx,void * result)81 lws_genhash_destroy(struct lws_genhash_ctx *ctx, void *result)
82 {
83 	unsigned int len;
84 	int ret = 0;
85 
86 	if (result)
87 		ret = EVP_DigestFinal_ex(ctx->mdctx, result, &len) != 1;
88 
89 	(void)len;
90 
91 	EVP_MD_CTX_destroy(ctx->mdctx);
92 
93 	return ret;
94 }
95 
96 
97 int
lws_genhmac_init(struct lws_genhmac_ctx * ctx,enum lws_genhmac_types type,const uint8_t * key,size_t key_len)98 lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type,
99 		 const uint8_t *key, size_t key_len)
100 {
101 #if defined(LWS_HAVE_HMAC_CTX_new)
102 	ctx->ctx = HMAC_CTX_new();
103 	if (!ctx->ctx)
104 		return -1;
105 #else
106 	HMAC_CTX_init(&ctx->ctx);
107 #endif
108 
109 	ctx->evp_type = 0;
110 	ctx->type = type;
111 
112 	switch (type) {
113 	case LWS_GENHMAC_TYPE_SHA256:
114 		ctx->evp_type = EVP_sha256();
115 		break;
116 	case LWS_GENHMAC_TYPE_SHA384:
117 		ctx->evp_type = EVP_sha384();
118 		break;
119 	case LWS_GENHMAC_TYPE_SHA512:
120 		ctx->evp_type = EVP_sha512();
121 		break;
122 	default:
123 		lwsl_err("%s: unknown HMAC type %d\n", __func__, type);
124 		goto bail;
125 	}
126 
127 #if defined(LWS_HAVE_HMAC_CTX_new)
128         if (HMAC_Init_ex(ctx->ctx, key, (int)key_len, ctx->evp_type, NULL) != 1)
129 #else
130         if (HMAC_Init_ex(&ctx->ctx, key, (int)key_len, ctx->evp_type, NULL) != 1)
131 #endif
132         	goto bail;
133 
134 	return 0;
135 
136 bail:
137 #if defined(LWS_HAVE_HMAC_CTX_new)
138 	HMAC_CTX_free(ctx->ctx);
139 #endif
140 
141 	return -1;
142 }
143 
144 int
lws_genhmac_update(struct lws_genhmac_ctx * ctx,const void * in,size_t len)145 lws_genhmac_update(struct lws_genhmac_ctx *ctx, const void *in, size_t len)
146 {
147 #if defined(LWS_HAVE_HMAC_CTX_new)
148 	if (HMAC_Update(ctx->ctx, in, len) != 1)
149 #else
150 	if (HMAC_Update(&ctx->ctx, in, len) != 1)
151 #endif
152 		return -1;
153 
154 	return 0;
155 }
156 
157 int
lws_genhmac_destroy(struct lws_genhmac_ctx * ctx,void * result)158 lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result)
159 {
160 	unsigned int size = (unsigned int)lws_genhmac_size(ctx->type);
161 #if defined(LWS_HAVE_HMAC_CTX_new)
162 	int n = HMAC_Final(ctx->ctx, result, &size);
163 
164 	HMAC_CTX_free(ctx->ctx);
165 #else
166 	int n = HMAC_Final(&ctx->ctx, result, &size);
167 #endif
168 
169 	if (n != 1)
170 		return -1;
171 
172 	return 0;
173 }
174 
175