hmac-nettle.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * QEMU Crypto hmac algorithms (based on nettle)
  3. *
  4. * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
  5. *
  6. * Authors:
  7. * Longpeng(Mike) <longpeng2@huawei.com>
  8. *
  9. * This work is licensed under the terms of the GNU GPL, version 2 or
  10. * (at your option) any later version. See the COPYING file in the
  11. * top-level directory.
  12. *
  13. */
  14. #include "qemu/osdep.h"
  15. #include "qapi/error.h"
  16. #include "crypto/hmac.h"
  17. #include "hmacpriv.h"
  18. #include <nettle/hmac.h>
  19. typedef void (*qcrypto_nettle_hmac_setkey)(void *ctx,
  20. size_t key_length,
  21. const uint8_t *key);
  22. typedef void (*qcrypto_nettle_hmac_update)(void *ctx,
  23. size_t length,
  24. const uint8_t *data);
  25. typedef void (*qcrypto_nettle_hmac_digest)(void *ctx,
  26. size_t length,
  27. uint8_t *digest);
  28. typedef struct QCryptoHmacNettle QCryptoHmacNettle;
  29. struct QCryptoHmacNettle {
  30. union qcrypto_nettle_hmac_ctx {
  31. struct hmac_md5_ctx md5_ctx;
  32. struct hmac_sha1_ctx sha1_ctx;
  33. struct hmac_sha256_ctx sha256_ctx; /* equals hmac_sha224_ctx */
  34. struct hmac_sha512_ctx sha512_ctx; /* equals hmac_sha384_ctx */
  35. struct hmac_ripemd160_ctx ripemd160_ctx;
  36. } u;
  37. };
  38. struct qcrypto_nettle_hmac_alg {
  39. qcrypto_nettle_hmac_setkey setkey;
  40. qcrypto_nettle_hmac_update update;
  41. qcrypto_nettle_hmac_digest digest;
  42. size_t len;
  43. } qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = {
  44. [QCRYPTO_HASH_ALG_MD5] = {
  45. .setkey = (qcrypto_nettle_hmac_setkey)hmac_md5_set_key,
  46. .update = (qcrypto_nettle_hmac_update)hmac_md5_update,
  47. .digest = (qcrypto_nettle_hmac_digest)hmac_md5_digest,
  48. .len = MD5_DIGEST_SIZE,
  49. },
  50. [QCRYPTO_HASH_ALG_SHA1] = {
  51. .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha1_set_key,
  52. .update = (qcrypto_nettle_hmac_update)hmac_sha1_update,
  53. .digest = (qcrypto_nettle_hmac_digest)hmac_sha1_digest,
  54. .len = SHA1_DIGEST_SIZE,
  55. },
  56. [QCRYPTO_HASH_ALG_SHA224] = {
  57. .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha224_set_key,
  58. .update = (qcrypto_nettle_hmac_update)hmac_sha224_update,
  59. .digest = (qcrypto_nettle_hmac_digest)hmac_sha224_digest,
  60. .len = SHA224_DIGEST_SIZE,
  61. },
  62. [QCRYPTO_HASH_ALG_SHA256] = {
  63. .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha256_set_key,
  64. .update = (qcrypto_nettle_hmac_update)hmac_sha256_update,
  65. .digest = (qcrypto_nettle_hmac_digest)hmac_sha256_digest,
  66. .len = SHA256_DIGEST_SIZE,
  67. },
  68. [QCRYPTO_HASH_ALG_SHA384] = {
  69. .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha384_set_key,
  70. .update = (qcrypto_nettle_hmac_update)hmac_sha384_update,
  71. .digest = (qcrypto_nettle_hmac_digest)hmac_sha384_digest,
  72. .len = SHA384_DIGEST_SIZE,
  73. },
  74. [QCRYPTO_HASH_ALG_SHA512] = {
  75. .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha512_set_key,
  76. .update = (qcrypto_nettle_hmac_update)hmac_sha512_update,
  77. .digest = (qcrypto_nettle_hmac_digest)hmac_sha512_digest,
  78. .len = SHA512_DIGEST_SIZE,
  79. },
  80. [QCRYPTO_HASH_ALG_RIPEMD160] = {
  81. .setkey = (qcrypto_nettle_hmac_setkey)hmac_ripemd160_set_key,
  82. .update = (qcrypto_nettle_hmac_update)hmac_ripemd160_update,
  83. .digest = (qcrypto_nettle_hmac_digest)hmac_ripemd160_digest,
  84. .len = RIPEMD160_DIGEST_SIZE,
  85. },
  86. };
  87. bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
  88. {
  89. if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) &&
  90. qcrypto_hmac_alg_map[alg].setkey != NULL) {
  91. return true;
  92. }
  93. return false;
  94. }
  95. void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
  96. const uint8_t *key, size_t nkey,
  97. Error **errp)
  98. {
  99. QCryptoHmacNettle *ctx;
  100. if (!qcrypto_hmac_supports(alg)) {
  101. error_setg(errp, "Unsupported hmac algorithm %s",
  102. QCryptoHashAlgorithm_str(alg));
  103. return NULL;
  104. }
  105. ctx = g_new0(QCryptoHmacNettle, 1);
  106. qcrypto_hmac_alg_map[alg].setkey(&ctx->u, nkey, key);
  107. return ctx;
  108. }
  109. static void
  110. qcrypto_nettle_hmac_ctx_free(QCryptoHmac *hmac)
  111. {
  112. QCryptoHmacNettle *ctx;
  113. ctx = hmac->opaque;
  114. g_free(ctx);
  115. }
  116. static int
  117. qcrypto_nettle_hmac_bytesv(QCryptoHmac *hmac,
  118. const struct iovec *iov,
  119. size_t niov,
  120. uint8_t **result,
  121. size_t *resultlen,
  122. Error **errp)
  123. {
  124. QCryptoHmacNettle *ctx;
  125. size_t i;
  126. ctx = (QCryptoHmacNettle *)hmac->opaque;
  127. for (i = 0; i < niov; ++i) {
  128. size_t len = iov[i].iov_len;
  129. uint8_t *base = iov[i].iov_base;
  130. while (len) {
  131. size_t shortlen = MIN(len, UINT_MAX);
  132. qcrypto_hmac_alg_map[hmac->alg].update(&ctx->u, len, base);
  133. len -= shortlen;
  134. base += len;
  135. }
  136. }
  137. if (*resultlen == 0) {
  138. *resultlen = qcrypto_hmac_alg_map[hmac->alg].len;
  139. *result = g_new0(uint8_t, *resultlen);
  140. } else if (*resultlen != qcrypto_hmac_alg_map[hmac->alg].len) {
  141. error_setg(errp,
  142. "Result buffer size %zu is smaller than hash %zu",
  143. *resultlen, qcrypto_hmac_alg_map[hmac->alg].len);
  144. return -1;
  145. }
  146. qcrypto_hmac_alg_map[hmac->alg].digest(&ctx->u, *resultlen, *result);
  147. return 0;
  148. }
  149. QCryptoHmacDriver qcrypto_hmac_lib_driver = {
  150. .hmac_bytesv = qcrypto_nettle_hmac_bytesv,
  151. .hmac_free = qcrypto_nettle_hmac_ctx_free,
  152. };