lws-genhash.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
  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. int
  34. lws_genhash_init(struct lws_genhash_ctx *ctx, enum lws_genhash_types type)
  35. {
  36. ctx->type = type;
  37. ctx->mdctx = EVP_MD_CTX_create();
  38. if (!ctx->mdctx)
  39. return 1;
  40. switch (ctx->type) {
  41. case LWS_GENHASH_TYPE_MD5:
  42. ctx->evp_type = EVP_md5();
  43. break;
  44. case LWS_GENHASH_TYPE_SHA1:
  45. ctx->evp_type = EVP_sha1();
  46. break;
  47. case LWS_GENHASH_TYPE_SHA256:
  48. ctx->evp_type = EVP_sha256();
  49. break;
  50. case LWS_GENHASH_TYPE_SHA384:
  51. ctx->evp_type = EVP_sha384();
  52. break;
  53. case LWS_GENHASH_TYPE_SHA512:
  54. ctx->evp_type = EVP_sha512();
  55. break;
  56. default:
  57. return 1;
  58. }
  59. if (EVP_DigestInit_ex(ctx->mdctx, ctx->evp_type, NULL) != 1) {
  60. EVP_MD_CTX_destroy(ctx->mdctx);
  61. return 1;
  62. }
  63. return 0;
  64. }
  65. int
  66. lws_genhash_update(struct lws_genhash_ctx *ctx, const void *in, size_t len)
  67. {
  68. if (!len)
  69. return 0;
  70. return EVP_DigestUpdate(ctx->mdctx, in, len) != 1;
  71. }
  72. int
  73. lws_genhash_destroy(struct lws_genhash_ctx *ctx, void *result)
  74. {
  75. unsigned int len;
  76. int ret = 0;
  77. if (result)
  78. ret = EVP_DigestFinal_ex(ctx->mdctx, result, &len) != 1;
  79. (void)len;
  80. EVP_MD_CTX_destroy(ctx->mdctx);
  81. return ret;
  82. }
  83. #if defined(LWS_HAVE_EVP_PKEY_new_raw_private_key)
  84. int
  85. lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type,
  86. const uint8_t *key, size_t key_len)
  87. {
  88. ctx->ctx = EVP_MD_CTX_create();
  89. if (!ctx->ctx)
  90. return -1;
  91. ctx->evp_type = 0;
  92. ctx->type = type;
  93. switch (type) {
  94. case LWS_GENHMAC_TYPE_SHA256:
  95. ctx->evp_type = EVP_sha256();
  96. break;
  97. case LWS_GENHMAC_TYPE_SHA384:
  98. ctx->evp_type = EVP_sha384();
  99. break;
  100. case LWS_GENHMAC_TYPE_SHA512:
  101. ctx->evp_type = EVP_sha512();
  102. break;
  103. default:
  104. lwsl_err("%s: unknown HMAC type %d\n", __func__, type);
  105. goto bail;
  106. }
  107. ctx->key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, key, key_len);
  108. if (!ctx->key)
  109. goto bail;
  110. if (EVP_DigestSignInit(ctx->ctx, NULL, ctx->evp_type, NULL, ctx->key) != 1)
  111. goto bail1;
  112. return 0;
  113. bail1:
  114. EVP_PKEY_free(ctx->key);
  115. bail:
  116. EVP_MD_CTX_free(ctx->ctx);
  117. return -1;
  118. }
  119. int
  120. lws_genhmac_update(struct lws_genhmac_ctx *ctx, const void *in, size_t len)
  121. {
  122. if (EVP_DigestSignUpdate(ctx->ctx, in, len) != 1)
  123. return -1;
  124. return 0;
  125. }
  126. int
  127. lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result)
  128. {
  129. size_t size = (size_t)lws_genhmac_size(ctx->type);
  130. int n;
  131. n = EVP_DigestSignFinal(ctx->ctx, result, &size);
  132. EVP_MD_CTX_free(ctx->ctx);
  133. EVP_PKEY_free(ctx->key);
  134. if (n != 1)
  135. return -1;
  136. return 0;
  137. }
  138. #else
  139. int
  140. lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type,
  141. const uint8_t *key, size_t key_len)
  142. {
  143. #if defined(LWS_HAVE_HMAC_CTX_new)
  144. ctx->ctx = HMAC_CTX_new();
  145. if (!ctx->ctx)
  146. return -1;
  147. #else
  148. HMAC_CTX_init(&ctx->ctx);
  149. #endif
  150. ctx->evp_type = 0;
  151. ctx->type = type;
  152. switch (type) {
  153. case LWS_GENHMAC_TYPE_SHA256:
  154. ctx->evp_type = EVP_sha256();
  155. break;
  156. case LWS_GENHMAC_TYPE_SHA384:
  157. ctx->evp_type = EVP_sha384();
  158. break;
  159. case LWS_GENHMAC_TYPE_SHA512:
  160. ctx->evp_type = EVP_sha512();
  161. break;
  162. default:
  163. lwsl_err("%s: unknown HMAC type %d\n", __func__, type);
  164. goto bail;
  165. }
  166. #if defined(LWS_HAVE_HMAC_CTX_new)
  167. if (HMAC_Init_ex(ctx->ctx, key, (int)key_len, ctx->evp_type, NULL) != 1)
  168. #else
  169. if (HMAC_Init_ex(&ctx->ctx, key, (int)key_len, ctx->evp_type, NULL) != 1)
  170. #endif
  171. goto bail;
  172. return 0;
  173. bail:
  174. #if defined(LWS_HAVE_HMAC_CTX_new)
  175. HMAC_CTX_free(ctx->ctx);
  176. #endif
  177. return -1;
  178. }
  179. int
  180. lws_genhmac_update(struct lws_genhmac_ctx *ctx, const void *in, size_t len)
  181. {
  182. #if defined(LWS_HAVE_HMAC_CTX_new)
  183. if (HMAC_Update(ctx->ctx, in, len) != 1)
  184. #else
  185. if (HMAC_Update(&ctx->ctx, in, len) != 1)
  186. #endif
  187. return -1;
  188. return 0;
  189. }
  190. int
  191. lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result)
  192. {
  193. unsigned int size = (unsigned int)lws_genhmac_size(ctx->type);
  194. #if defined(LWS_HAVE_HMAC_CTX_new)
  195. int n = HMAC_Final(ctx->ctx, result, &size);
  196. HMAC_CTX_free(ctx->ctx);
  197. #else
  198. int n = HMAC_Final(&ctx->ctx, result, &size);
  199. #endif
  200. if (n != 1)
  201. return -1;
  202. return 0;
  203. }
  204. #endif