commoncrypto_hmac.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/cal/hmac.h>
  6. #include <CommonCrypto/CommonHMAC.h>
  7. static void s_destroy(struct aws_hmac *hmac);
  8. static int s_update(struct aws_hmac *hmac, const struct aws_byte_cursor *to_hmac);
  9. static int s_finalize(struct aws_hmac *hmac, struct aws_byte_buf *output);
  10. static struct aws_hmac_vtable s_sha256_hmac_vtable = {
  11. .destroy = s_destroy,
  12. .update = s_update,
  13. .finalize = s_finalize,
  14. .alg_name = "SHA256 HMAC",
  15. .provider = "CommonCrypto",
  16. };
  17. struct cc_hmac {
  18. struct aws_hmac hmac;
  19. CCHmacContext cc_hmac_ctx;
  20. };
  21. struct aws_hmac *aws_sha256_hmac_default_new(struct aws_allocator *allocator, const struct aws_byte_cursor *secret) {
  22. AWS_ASSERT(secret->ptr);
  23. struct cc_hmac *cc_hmac = aws_mem_acquire(allocator, sizeof(struct cc_hmac));
  24. if (!cc_hmac) {
  25. return NULL;
  26. }
  27. cc_hmac->hmac.allocator = allocator;
  28. cc_hmac->hmac.vtable = &s_sha256_hmac_vtable;
  29. cc_hmac->hmac.impl = cc_hmac;
  30. cc_hmac->hmac.digest_size = AWS_SHA256_HMAC_LEN;
  31. cc_hmac->hmac.good = true;
  32. CCHmacInit(&cc_hmac->cc_hmac_ctx, kCCHmacAlgSHA256, secret->ptr, (CC_LONG)secret->len);
  33. return &cc_hmac->hmac;
  34. }
  35. static void s_destroy(struct aws_hmac *hmac) {
  36. struct cc_hmac *ctx = hmac->impl;
  37. aws_mem_release(hmac->allocator, ctx);
  38. }
  39. static int s_update(struct aws_hmac *hmac, const struct aws_byte_cursor *to_hmac) {
  40. if (!hmac->good) {
  41. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  42. }
  43. struct cc_hmac *ctx = hmac->impl;
  44. CCHmacUpdate(&ctx->cc_hmac_ctx, to_hmac->ptr, (CC_LONG)to_hmac->len);
  45. return AWS_OP_SUCCESS;
  46. }
  47. static int s_finalize(struct aws_hmac *hmac, struct aws_byte_buf *output) {
  48. if (!hmac->good) {
  49. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  50. }
  51. struct cc_hmac *ctx = hmac->impl;
  52. size_t buffer_len = output->capacity - output->len;
  53. if (buffer_len < hmac->digest_size) {
  54. return aws_raise_error(AWS_ERROR_SHORT_BUFFER);
  55. }
  56. CCHmacFinal(&ctx->cc_hmac_ctx, output->buffer + output->len);
  57. hmac->good = false;
  58. output->len += hmac->digest_size;
  59. return AWS_OP_SUCCESS;
  60. }