2
0

hmac-nettle.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. #if CONFIG_NETTLE_VERSION_MAJOR < 3
  20. typedef unsigned int hmac_length_t;
  21. #else
  22. typedef size_t hmac_length_t;
  23. #endif
  24. typedef void (*qcrypto_nettle_hmac_setkey)(void *ctx,
  25. hmac_length_t key_length,
  26. const uint8_t *key);
  27. typedef void (*qcrypto_nettle_hmac_update)(void *ctx,
  28. hmac_length_t length,
  29. const uint8_t *data);
  30. typedef void (*qcrypto_nettle_hmac_digest)(void *ctx,
  31. hmac_length_t length,
  32. uint8_t *digest);
  33. typedef struct QCryptoHmacNettle QCryptoHmacNettle;
  34. struct QCryptoHmacNettle {
  35. union qcrypto_nettle_hmac_ctx {
  36. struct hmac_md5_ctx md5_ctx;
  37. struct hmac_sha1_ctx sha1_ctx;
  38. struct hmac_sha256_ctx sha256_ctx; /* equals hmac_sha224_ctx */
  39. struct hmac_sha512_ctx sha512_ctx; /* equals hmac_sha384_ctx */
  40. struct hmac_ripemd160_ctx ripemd160_ctx;
  41. } u;
  42. };
  43. struct qcrypto_nettle_hmac_alg {
  44. qcrypto_nettle_hmac_setkey setkey;
  45. qcrypto_nettle_hmac_update update;
  46. qcrypto_nettle_hmac_digest digest;
  47. size_t len;
  48. } qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = {
  49. [QCRYPTO_HASH_ALG_MD5] = {
  50. .setkey = (qcrypto_nettle_hmac_setkey)hmac_md5_set_key,
  51. .update = (qcrypto_nettle_hmac_update)hmac_md5_update,
  52. .digest = (qcrypto_nettle_hmac_digest)hmac_md5_digest,
  53. .len = MD5_DIGEST_SIZE,
  54. },
  55. [QCRYPTO_HASH_ALG_SHA1] = {
  56. .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha1_set_key,
  57. .update = (qcrypto_nettle_hmac_update)hmac_sha1_update,
  58. .digest = (qcrypto_nettle_hmac_digest)hmac_sha1_digest,
  59. .len = SHA1_DIGEST_SIZE,
  60. },
  61. [QCRYPTO_HASH_ALG_SHA224] = {
  62. .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha224_set_key,
  63. .update = (qcrypto_nettle_hmac_update)hmac_sha224_update,
  64. .digest = (qcrypto_nettle_hmac_digest)hmac_sha224_digest,
  65. .len = SHA224_DIGEST_SIZE,
  66. },
  67. [QCRYPTO_HASH_ALG_SHA256] = {
  68. .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha256_set_key,
  69. .update = (qcrypto_nettle_hmac_update)hmac_sha256_update,
  70. .digest = (qcrypto_nettle_hmac_digest)hmac_sha256_digest,
  71. .len = SHA256_DIGEST_SIZE,
  72. },
  73. [QCRYPTO_HASH_ALG_SHA384] = {
  74. .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha384_set_key,
  75. .update = (qcrypto_nettle_hmac_update)hmac_sha384_update,
  76. .digest = (qcrypto_nettle_hmac_digest)hmac_sha384_digest,
  77. .len = SHA384_DIGEST_SIZE,
  78. },
  79. [QCRYPTO_HASH_ALG_SHA512] = {
  80. .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha512_set_key,
  81. .update = (qcrypto_nettle_hmac_update)hmac_sha512_update,
  82. .digest = (qcrypto_nettle_hmac_digest)hmac_sha512_digest,
  83. .len = SHA512_DIGEST_SIZE,
  84. },
  85. [QCRYPTO_HASH_ALG_RIPEMD160] = {
  86. .setkey = (qcrypto_nettle_hmac_setkey)hmac_ripemd160_set_key,
  87. .update = (qcrypto_nettle_hmac_update)hmac_ripemd160_update,
  88. .digest = (qcrypto_nettle_hmac_digest)hmac_ripemd160_digest,
  89. .len = RIPEMD160_DIGEST_SIZE,
  90. },
  91. };
  92. bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
  93. {
  94. if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) &&
  95. qcrypto_hmac_alg_map[alg].setkey != NULL) {
  96. return true;
  97. }
  98. return false;
  99. }
  100. void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
  101. const uint8_t *key, size_t nkey,
  102. Error **errp)
  103. {
  104. QCryptoHmacNettle *ctx;
  105. if (!qcrypto_hmac_supports(alg)) {
  106. error_setg(errp, "Unsupported hmac algorithm %s",
  107. QCryptoHashAlgorithm_str(alg));
  108. return NULL;
  109. }
  110. ctx = g_new0(QCryptoHmacNettle, 1);
  111. qcrypto_hmac_alg_map[alg].setkey(&ctx->u, nkey, key);
  112. return ctx;
  113. }
  114. static void
  115. qcrypto_nettle_hmac_ctx_free(QCryptoHmac *hmac)
  116. {
  117. QCryptoHmacNettle *ctx;
  118. ctx = hmac->opaque;
  119. g_free(ctx);
  120. }
  121. static int
  122. qcrypto_nettle_hmac_bytesv(QCryptoHmac *hmac,
  123. const struct iovec *iov,
  124. size_t niov,
  125. uint8_t **result,
  126. size_t *resultlen,
  127. Error **errp)
  128. {
  129. QCryptoHmacNettle *ctx;
  130. size_t i;
  131. ctx = (QCryptoHmacNettle *)hmac->opaque;
  132. for (i = 0; i < niov; ++i) {
  133. size_t len = iov[i].iov_len;
  134. uint8_t *base = iov[i].iov_base;
  135. while (len) {
  136. size_t shortlen = MIN(len, UINT_MAX);
  137. qcrypto_hmac_alg_map[hmac->alg].update(&ctx->u, len, base);
  138. len -= shortlen;
  139. base += len;
  140. }
  141. }
  142. if (*resultlen == 0) {
  143. *resultlen = qcrypto_hmac_alg_map[hmac->alg].len;
  144. *result = g_new0(uint8_t, *resultlen);
  145. } else if (*resultlen != qcrypto_hmac_alg_map[hmac->alg].len) {
  146. error_setg(errp,
  147. "Result buffer size %zu is smaller than hash %zu",
  148. *resultlen, qcrypto_hmac_alg_map[hmac->alg].len);
  149. return -1;
  150. }
  151. qcrypto_hmac_alg_map[hmac->alg].digest(&ctx->u, *resultlen, *result);
  152. return 0;
  153. }
  154. QCryptoHmacDriver qcrypto_hmac_lib_driver = {
  155. .hmac_bytesv = qcrypto_nettle_hmac_bytesv,
  156. .hmac_free = qcrypto_nettle_hmac_ctx_free,
  157. };