Imported Upstream version 3.2.0
[platform/upstream/libwebsockets.git] / lib / tls / openssl / lws-genhash.c
1 /*
2  * libwebsockets - generic hash and HMAC api hiding the backend
3  *
4  * Copyright (C) 2017 Andy Green <andy@warmcat.com>
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public
8  *  License as published by the Free Software Foundation:
9  *  version 2.1 of the License.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  *  MA  02110-1301  USA
20  *
21  *  lws_genhash provides a hash / hmac abstraction api in lws that works the
22  *  same whether you are using openssl or mbedtls hash functions underneath.
23  */
24 #include "libwebsockets.h"
25 #include <openssl/obj_mac.h>
26 /*
27  * Care: many openssl apis return 1 for success.  These are translated to the
28  * lws convention of 0 for success.
29  */
30
31 int
32 lws_genhash_init(struct lws_genhash_ctx *ctx, enum lws_genhash_types type)
33 {
34         ctx->type = type;
35         ctx->mdctx = EVP_MD_CTX_create();
36         if (!ctx->mdctx)
37                 return 1;
38
39         switch (ctx->type) {
40         case LWS_GENHASH_TYPE_MD5:
41                 ctx->evp_type = EVP_md5();
42                 break;
43         case LWS_GENHASH_TYPE_SHA1:
44                 ctx->evp_type = EVP_sha1();
45                 break;
46         case LWS_GENHASH_TYPE_SHA256:
47                 ctx->evp_type = EVP_sha256();
48                 break;
49         case LWS_GENHASH_TYPE_SHA384:
50                 ctx->evp_type = EVP_sha384();
51                 break;
52         case LWS_GENHASH_TYPE_SHA512:
53                 ctx->evp_type = EVP_sha512();
54                 break;
55         default:
56                 return 1;
57         }
58
59         if (EVP_DigestInit_ex(ctx->mdctx, ctx->evp_type, NULL) != 1) {
60                 EVP_MD_CTX_destroy(ctx->mdctx);
61
62                 return 1;
63         }
64
65         return 0;
66 }
67
68 int
69 lws_genhash_update(struct lws_genhash_ctx *ctx, const void *in, size_t len)
70 {
71         if (!len)
72                 return 0;
73
74         return EVP_DigestUpdate(ctx->mdctx, in, len) != 1;
75 }
76
77 int
78 lws_genhash_destroy(struct lws_genhash_ctx *ctx, void *result)
79 {
80         unsigned int len;
81         int ret = 0;
82
83         if (result)
84                 ret = EVP_DigestFinal_ex(ctx->mdctx, result, &len) != 1;
85
86         (void)len;
87
88         EVP_MD_CTX_destroy(ctx->mdctx);
89
90         return ret;
91 }
92
93
94 int
95 lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type,
96                  const uint8_t *key, size_t key_len)
97 {
98 #if defined(LWS_HAVE_HMAC_CTX_new)
99         ctx->ctx = HMAC_CTX_new();
100         if (!ctx->ctx)
101                 return -1;
102 #else
103         HMAC_CTX_init(&ctx->ctx);
104 #endif
105
106         switch (type) {
107         case LWS_GENHMAC_TYPE_SHA256:
108                 ctx->evp_type = EVP_sha256();
109                 break;
110         case LWS_GENHMAC_TYPE_SHA384:
111                 ctx->evp_type = EVP_sha384();
112                 break;
113         case LWS_GENHMAC_TYPE_SHA512:
114                 ctx->evp_type = EVP_sha512();
115                 break;
116         default:
117                 lwsl_err("%s: unknown HMAC type %d\n", __func__, type);
118                 goto bail;
119         }
120
121 #if defined(LWS_HAVE_HMAC_CTX_new)
122         if (HMAC_Init_ex(ctx->ctx, key, key_len, ctx->evp_type, NULL) != 1)
123 #else
124         if (HMAC_Init_ex(&ctx->ctx, key, key_len, ctx->evp_type, NULL) != 1)
125 #endif
126                 goto bail;
127
128         return 0;
129
130 bail:
131 #if defined(LWS_HAVE_HMAC_CTX_new)
132         HMAC_CTX_free(ctx->ctx);
133 #endif
134
135         return -1;
136 }
137
138 int
139 lws_genhmac_update(struct lws_genhmac_ctx *ctx, const void *in, size_t len)
140 {
141 #if defined(LWS_HAVE_HMAC_CTX_new)
142         if (HMAC_Update(ctx->ctx, in, len) != 1)
143 #else
144         if (HMAC_Update(&ctx->ctx, in, len) != 1)
145 #endif
146                 return -1;
147
148         return 0;
149 }
150
151 int
152 lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result)
153 {
154         unsigned int size = lws_genhmac_size(ctx->type);
155 #if defined(LWS_HAVE_HMAC_CTX_new)
156         int n = HMAC_Final(ctx->ctx, result, &size);
157
158         HMAC_CTX_free(ctx->ctx);
159 #else
160         int n = HMAC_Final(&ctx->ctx, result, &size);
161 #endif
162
163         if (n != 1)
164                 return -1;
165
166         return 0;
167 }
168