hash.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. #ifndef BYO_CRYPTO
  7. extern struct aws_hash *aws_sha256_default_new(struct aws_allocator *allocator);
  8. extern struct aws_hash *aws_sha1_default_new(struct aws_allocator *allocator);
  9. extern struct aws_hash *aws_md5_default_new(struct aws_allocator *allocator);
  10. static aws_hash_new_fn *s_sha256_new_fn = aws_sha256_default_new;
  11. static aws_hash_new_fn *s_sha1_new_fn = aws_sha1_default_new;
  12. static aws_hash_new_fn *s_md5_new_fn = aws_md5_default_new;
  13. #else
  14. static struct aws_hash *aws_hash_new_abort(struct aws_allocator *allocator) {
  15. (void)allocator;
  16. abort();
  17. }
  18. static aws_hash_new_fn *s_sha256_new_fn = aws_hash_new_abort;
  19. static aws_hash_new_fn *s_sha1_new_fn = aws_hash_new_abort;
  20. static aws_hash_new_fn *s_md5_new_fn = aws_hash_new_abort;
  21. #endif
  22. struct aws_hash *aws_sha1_new(struct aws_allocator *allocator) {
  23. return s_sha1_new_fn(allocator);
  24. }
  25. struct aws_hash *aws_sha256_new(struct aws_allocator *allocator) {
  26. return s_sha256_new_fn(allocator);
  27. }
  28. struct aws_hash *aws_md5_new(struct aws_allocator *allocator) {
  29. return s_md5_new_fn(allocator);
  30. }
  31. void aws_set_md5_new_fn(aws_hash_new_fn *fn) {
  32. s_md5_new_fn = fn;
  33. }
  34. void aws_set_sha256_new_fn(aws_hash_new_fn *fn) {
  35. s_sha256_new_fn = fn;
  36. }
  37. void aws_set_sha1_new_fn(aws_hash_new_fn *fn) {
  38. s_sha1_new_fn = fn;
  39. }
  40. void aws_hash_destroy(struct aws_hash *hash) {
  41. hash->vtable->destroy(hash);
  42. }
  43. int aws_hash_update(struct aws_hash *hash, const struct aws_byte_cursor *to_hash) {
  44. return hash->vtable->update(hash, to_hash);
  45. }
  46. int aws_hash_finalize(struct aws_hash *hash, struct aws_byte_buf *output, size_t truncate_to) {
  47. if (truncate_to && truncate_to < hash->digest_size) {
  48. size_t available_buffer = output->capacity - output->len;
  49. if (available_buffer < truncate_to) {
  50. return aws_raise_error(AWS_ERROR_SHORT_BUFFER);
  51. }
  52. uint8_t tmp_output[128] = {0};
  53. AWS_ASSERT(sizeof(tmp_output) >= hash->digest_size);
  54. struct aws_byte_buf tmp_out_buf = aws_byte_buf_from_array(tmp_output, sizeof(tmp_output));
  55. tmp_out_buf.len = 0;
  56. if (hash->vtable->finalize(hash, &tmp_out_buf)) {
  57. return AWS_OP_ERR;
  58. }
  59. memcpy(output->buffer + output->len, tmp_output, truncate_to);
  60. output->len += truncate_to;
  61. return AWS_OP_SUCCESS;
  62. }
  63. return hash->vtable->finalize(hash, output);
  64. }
  65. static inline int compute_hash(
  66. struct aws_hash *hash,
  67. const struct aws_byte_cursor *input,
  68. struct aws_byte_buf *output,
  69. size_t truncate_to) {
  70. if (!hash) {
  71. return AWS_OP_ERR;
  72. }
  73. if (aws_hash_update(hash, input)) {
  74. aws_hash_destroy(hash);
  75. return AWS_OP_ERR;
  76. }
  77. if (aws_hash_finalize(hash, output, truncate_to)) {
  78. aws_hash_destroy(hash);
  79. return AWS_OP_ERR;
  80. }
  81. aws_hash_destroy(hash);
  82. return AWS_OP_SUCCESS;
  83. }
  84. int aws_md5_compute(
  85. struct aws_allocator *allocator,
  86. const struct aws_byte_cursor *input,
  87. struct aws_byte_buf *output,
  88. size_t truncate_to) {
  89. return compute_hash(aws_md5_new(allocator), input, output, truncate_to);
  90. }
  91. int aws_sha256_compute(
  92. struct aws_allocator *allocator,
  93. const struct aws_byte_cursor *input,
  94. struct aws_byte_buf *output,
  95. size_t truncate_to) {
  96. return compute_hash(aws_sha256_new(allocator), input, output, truncate_to);
  97. }
  98. int aws_sha1_compute(
  99. struct aws_allocator *allocator,
  100. const struct aws_byte_cursor *input,
  101. struct aws_byte_buf *output,
  102. size_t truncate_to) {
  103. return compute_hash(aws_sha1_new(allocator), input, output, truncate_to);
  104. }