crypto_hkdf.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /* Copyright (c) 2001, Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file crypto_hkdf.c
  8. * \brief Block of functions related with HKDF utilities and operations.
  9. **/
  10. #include "lib/crypt_ops/crypto_hkdf.h"
  11. #include "lib/crypt_ops/crypto_util.h"
  12. #include "lib/crypt_ops/crypto_digest.h"
  13. #include "lib/crypt_ops/crypto_openssl_mgt.h"
  14. #include "lib/intmath/cmp.h"
  15. #include "lib/log/util_bug.h"
  16. #ifdef ENABLE_OPENSSL
  17. #include <openssl/evp.h>
  18. #include <openssl/opensslv.h>
  19. #if defined(HAVE_ERR_LOAD_KDF_STRINGS)
  20. #include <openssl/kdf.h>
  21. #define HAVE_OPENSSL_HKDF 1
  22. #endif
  23. #endif
  24. #include <string.h>
  25. /** Given <b>key_in_len</b> bytes of negotiated randomness in <b>key_in</b>
  26. * ("K"), expand it into <b>key_out_len</b> bytes of negotiated key material in
  27. * <b>key_out</b> by taking the first <b>key_out_len</b> bytes of
  28. * H(K | [00]) | H(K | [01]) | ....
  29. *
  30. * This is the key expansion algorithm used in the "TAP" circuit extension
  31. * mechanism; it shouldn't be used for new protocols.
  32. *
  33. * Return 0 on success, -1 on failure.
  34. */
  35. int
  36. crypto_expand_key_material_TAP(const uint8_t *key_in, size_t key_in_len,
  37. uint8_t *key_out, size_t key_out_len)
  38. {
  39. int i, r = -1;
  40. uint8_t *cp, *tmp = tor_malloc(key_in_len+1);
  41. uint8_t digest[DIGEST_LEN];
  42. /* If we try to get more than this amount of key data, we'll repeat blocks.*/
  43. tor_assert(key_out_len <= DIGEST_LEN*256);
  44. memcpy(tmp, key_in, key_in_len);
  45. for (cp = key_out, i=0; cp < key_out+key_out_len;
  46. ++i, cp += DIGEST_LEN) {
  47. tmp[key_in_len] = i;
  48. if (crypto_digest((char*)digest, (const char *)tmp, key_in_len+1) < 0)
  49. goto exit;
  50. memcpy(cp, digest, MIN(DIGEST_LEN, key_out_len-(cp-key_out)));
  51. }
  52. r = 0;
  53. exit:
  54. memwipe(tmp, 0, key_in_len+1);
  55. tor_free(tmp);
  56. memwipe(digest, 0, sizeof(digest));
  57. return r;
  58. }
  59. #ifdef HAVE_OPENSSL_HKDF
  60. /**
  61. * Perform RFC5869 HKDF computation using OpenSSL (only to be called from
  62. * crypto_expand_key_material_rfc5869_sha256_openssl). Note that OpenSSL
  63. * requires input key to be nonempty and salt length to be equal or less
  64. * than 1024.
  65. */
  66. static int
  67. crypto_expand_key_material_rfc5869_sha256_openssl(
  68. const uint8_t *key_in, size_t key_in_len,
  69. const uint8_t *salt_in, size_t salt_in_len,
  70. const uint8_t *info_in, size_t info_in_len,
  71. uint8_t *key_out, size_t key_out_len)
  72. {
  73. int r;
  74. EVP_PKEY_CTX *evp_pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
  75. tor_assert(evp_pkey_ctx);
  76. tor_assert(key_in_len != 0);
  77. tor_assert(salt_in_len <= 1024);
  78. r = EVP_PKEY_derive_init(evp_pkey_ctx);
  79. tor_assert(r == 1);
  80. r = EVP_PKEY_CTX_set_hkdf_md(evp_pkey_ctx, EVP_sha256());
  81. tor_assert(r == 1);
  82. r = EVP_PKEY_CTX_set1_hkdf_salt(evp_pkey_ctx, salt_in, (int)salt_in_len);
  83. tor_assert(r == 1);
  84. r = EVP_PKEY_CTX_set1_hkdf_key(evp_pkey_ctx, key_in, (int)key_in_len);
  85. tor_assert(r == 1);
  86. r = EVP_PKEY_CTX_add1_hkdf_info(evp_pkey_ctx, info_in, (int)info_in_len);
  87. tor_assert(r == 1);
  88. r = EVP_PKEY_derive(evp_pkey_ctx, key_out, &key_out_len);
  89. tor_assert(r == 1);
  90. EVP_PKEY_CTX_free(evp_pkey_ctx);
  91. return 0;
  92. }
  93. #else
  94. /**
  95. * Perform RFC5869 HKDF computation using our own legacy implementation.
  96. * Only to be called from crypto_expand_key_material_rfc5869_sha256_openssl.
  97. */
  98. static int
  99. crypto_expand_key_material_rfc5869_sha256_legacy(
  100. const uint8_t *key_in, size_t key_in_len,
  101. const uint8_t *salt_in, size_t salt_in_len,
  102. const uint8_t *info_in, size_t info_in_len,
  103. uint8_t *key_out, size_t key_out_len)
  104. {
  105. uint8_t prk[DIGEST256_LEN];
  106. uint8_t tmp[DIGEST256_LEN + 128 + 1];
  107. uint8_t mac[DIGEST256_LEN];
  108. int i;
  109. uint8_t *outp;
  110. size_t tmp_len;
  111. crypto_hmac_sha256((char*)prk,
  112. (const char*)salt_in, salt_in_len,
  113. (const char*)key_in, key_in_len);
  114. /* If we try to get more than this amount of key data, we'll repeat blocks.*/
  115. tor_assert(key_out_len <= DIGEST256_LEN * 256);
  116. tor_assert(info_in_len <= 128);
  117. memset(tmp, 0, sizeof(tmp));
  118. outp = key_out;
  119. i = 1;
  120. while (key_out_len) {
  121. size_t n;
  122. if (i > 1) {
  123. memcpy(tmp, mac, DIGEST256_LEN);
  124. memcpy(tmp+DIGEST256_LEN, info_in, info_in_len);
  125. tmp[DIGEST256_LEN+info_in_len] = i;
  126. tmp_len = DIGEST256_LEN + info_in_len + 1;
  127. } else {
  128. memcpy(tmp, info_in, info_in_len);
  129. tmp[info_in_len] = i;
  130. tmp_len = info_in_len + 1;
  131. }
  132. crypto_hmac_sha256((char*)mac,
  133. (const char*)prk, DIGEST256_LEN,
  134. (const char*)tmp, tmp_len);
  135. n = key_out_len < DIGEST256_LEN ? key_out_len : DIGEST256_LEN;
  136. memcpy(outp, mac, n);
  137. key_out_len -= n;
  138. outp += n;
  139. ++i;
  140. }
  141. memwipe(tmp, 0, sizeof(tmp));
  142. memwipe(mac, 0, sizeof(mac));
  143. return 0;
  144. }
  145. #endif
  146. /** Expand some secret key material according to RFC5869, using SHA256 as the
  147. * underlying hash. The <b>key_in_len</b> bytes at <b>key_in</b> are the
  148. * secret key material; the <b>salt_in_len</b> bytes at <b>salt_in</b> and the
  149. * <b>info_in_len</b> bytes in <b>info_in_len</b> are the algorithm's "salt"
  150. * and "info" parameters respectively. On success, write <b>key_out_len</b>
  151. * bytes to <b>key_out</b> and return 0. Assert on failure.
  152. */
  153. int
  154. crypto_expand_key_material_rfc5869_sha256(
  155. const uint8_t *key_in, size_t key_in_len,
  156. const uint8_t *salt_in, size_t salt_in_len,
  157. const uint8_t *info_in, size_t info_in_len,
  158. uint8_t *key_out, size_t key_out_len)
  159. {
  160. tor_assert(key_in);
  161. tor_assert(key_in_len > 0);
  162. #ifdef HAVE_OPENSSL_HKDF
  163. return crypto_expand_key_material_rfc5869_sha256_openssl(key_in,
  164. key_in_len, salt_in,
  165. salt_in_len, info_in,
  166. info_in_len,
  167. key_out, key_out_len);
  168. #else
  169. return crypto_expand_key_material_rfc5869_sha256_legacy(key_in,
  170. key_in_len, salt_in,
  171. salt_in_len, info_in,
  172. info_in_len,
  173. key_out, key_out_len);
  174. #endif
  175. }