opensslcrypto_hash.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/cal/hash.h>
  6. #include <aws/cal/private/opensslcrypto_common.h>
  7. #include <openssl/evp.h>
  8. #include <openssl/sha.h>
  9. static void s_destroy(struct aws_hash *hash);
  10. static int s_update(struct aws_hash *hash, const struct aws_byte_cursor *to_hash);
  11. static int s_finalize(struct aws_hash *hash, struct aws_byte_buf *output);
  12. static struct aws_hash_vtable s_md5_vtable = {
  13. .destroy = s_destroy,
  14. .update = s_update,
  15. .finalize = s_finalize,
  16. .alg_name = "MD5",
  17. .provider = "OpenSSL Compatible libcrypto",
  18. };
  19. static struct aws_hash_vtable s_sha256_vtable = {
  20. .destroy = s_destroy,
  21. .update = s_update,
  22. .finalize = s_finalize,
  23. .alg_name = "SHA256",
  24. .provider = "OpenSSL Compatible libcrypto",
  25. };
  26. static struct aws_hash_vtable s_sha1_vtable = {
  27. .destroy = s_destroy,
  28. .update = s_update,
  29. .finalize = s_finalize,
  30. .alg_name = "SHA1",
  31. .provider = "OpenSSL Compatible libcrypto",
  32. };
  33. static void s_destroy(struct aws_hash *hash) {
  34. if (hash == NULL) {
  35. return;
  36. }
  37. EVP_MD_CTX *ctx = hash->impl;
  38. if (ctx != NULL) {
  39. g_aws_openssl_evp_md_ctx_table->free_fn(ctx);
  40. }
  41. aws_mem_release(hash->allocator, hash);
  42. }
  43. struct aws_hash *aws_md5_default_new(struct aws_allocator *allocator) {
  44. struct aws_hash *hash = aws_mem_acquire(allocator, sizeof(struct aws_hash));
  45. if (!hash) {
  46. return NULL;
  47. }
  48. hash->allocator = allocator;
  49. hash->vtable = &s_md5_vtable;
  50. hash->digest_size = AWS_MD5_LEN;
  51. EVP_MD_CTX *ctx = g_aws_openssl_evp_md_ctx_table->new_fn();
  52. hash->impl = ctx;
  53. hash->good = true;
  54. if (!hash->impl) {
  55. s_destroy(hash);
  56. aws_raise_error(AWS_ERROR_OOM);
  57. return NULL;
  58. }
  59. if (!g_aws_openssl_evp_md_ctx_table->init_ex_fn(ctx, EVP_md5(), NULL)) {
  60. s_destroy(hash);
  61. aws_raise_error(AWS_ERROR_UNKNOWN);
  62. return NULL;
  63. }
  64. return hash;
  65. }
  66. struct aws_hash *aws_sha256_default_new(struct aws_allocator *allocator) {
  67. struct aws_hash *hash = aws_mem_acquire(allocator, sizeof(struct aws_hash));
  68. if (!hash) {
  69. return NULL;
  70. }
  71. hash->allocator = allocator;
  72. hash->vtable = &s_sha256_vtable;
  73. hash->digest_size = AWS_SHA256_LEN;
  74. EVP_MD_CTX *ctx = g_aws_openssl_evp_md_ctx_table->new_fn();
  75. hash->impl = ctx;
  76. hash->good = true;
  77. if (!hash->impl) {
  78. s_destroy(hash);
  79. aws_raise_error(AWS_ERROR_OOM);
  80. return NULL;
  81. }
  82. if (!g_aws_openssl_evp_md_ctx_table->init_ex_fn(ctx, EVP_sha256(), NULL)) {
  83. s_destroy(hash);
  84. aws_raise_error(AWS_ERROR_UNKNOWN);
  85. return NULL;
  86. }
  87. return hash;
  88. }
  89. struct aws_hash *aws_sha1_default_new(struct aws_allocator *allocator) {
  90. struct aws_hash *hash = aws_mem_acquire(allocator, sizeof(struct aws_hash));
  91. if (!hash) {
  92. return NULL;
  93. }
  94. hash->allocator = allocator;
  95. hash->vtable = &s_sha1_vtable;
  96. hash->digest_size = AWS_SHA1_LEN;
  97. EVP_MD_CTX *ctx = g_aws_openssl_evp_md_ctx_table->new_fn();
  98. hash->impl = ctx;
  99. hash->good = true;
  100. if (!hash->impl) {
  101. s_destroy(hash);
  102. aws_raise_error(AWS_ERROR_OOM);
  103. return NULL;
  104. }
  105. if (!g_aws_openssl_evp_md_ctx_table->init_ex_fn(ctx, EVP_sha1(), NULL)) {
  106. s_destroy(hash);
  107. aws_raise_error(AWS_ERROR_UNKNOWN);
  108. return NULL;
  109. }
  110. return hash;
  111. }
  112. static int s_update(struct aws_hash *hash, const struct aws_byte_cursor *to_hash) {
  113. if (!hash->good) {
  114. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  115. }
  116. EVP_MD_CTX *ctx = hash->impl;
  117. if (AWS_LIKELY(g_aws_openssl_evp_md_ctx_table->update_fn(ctx, to_hash->ptr, to_hash->len))) {
  118. return AWS_OP_SUCCESS;
  119. }
  120. hash->good = false;
  121. return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
  122. }
  123. static int s_finalize(struct aws_hash *hash, struct aws_byte_buf *output) {
  124. if (!hash->good) {
  125. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  126. }
  127. EVP_MD_CTX *ctx = hash->impl;
  128. size_t buffer_len = output->capacity - output->len;
  129. if (buffer_len < hash->digest_size) {
  130. return aws_raise_error(AWS_ERROR_SHORT_BUFFER);
  131. }
  132. if (AWS_LIKELY(g_aws_openssl_evp_md_ctx_table->final_ex_fn(
  133. ctx, output->buffer + output->len, (unsigned int *)&buffer_len))) {
  134. output->len += hash->digest_size;
  135. hash->good = false;
  136. return AWS_OP_SUCCESS;
  137. }
  138. hash->good = false;
  139. return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
  140. }