crypto_pwbox.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /* Copyright (c) 2014-2019, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file crypto_pwbox.c
  5. *
  6. * \brief Code for encrypting secrets in a password-protected form and saving
  7. * them to disk.
  8. */
  9. #include <string.h>
  10. #include "lib/arch/bytes.h"
  11. #include "lib/crypt_ops/crypto_cipher.h"
  12. #include "lib/crypt_ops/crypto_digest.h"
  13. #include "lib/crypt_ops/crypto_pwbox.h"
  14. #include "lib/crypt_ops/crypto_rand.h"
  15. #include "lib/crypt_ops/crypto_s2k.h"
  16. #include "lib/crypt_ops/crypto_util.h"
  17. #include "lib/ctime/di_ops.h"
  18. #include "lib/intmath/muldiv.h"
  19. #include "trunnel/pwbox.h"
  20. #include "lib/log/util_bug.h"
  21. /* 8 bytes "TORBOX00"
  22. 1 byte: header len (H)
  23. H bytes: header, denoting secret key algorithm.
  24. 16 bytes: IV
  25. Round up to multiple of 128 bytes, then encrypt:
  26. 4 bytes: data len
  27. data
  28. zeros
  29. 32 bytes: HMAC-SHA256 of all previous bytes.
  30. */
  31. #define MAX_OVERHEAD (S2K_MAXLEN + 8 + 1 + 32 + CIPHER_IV_LEN)
  32. /**
  33. * Make an authenticated passphrase-encrypted blob to encode the
  34. * <b>input_len</b> bytes in <b>input</b> using the passphrase
  35. * <b>secret</b> of <b>secret_len</b> bytes. Allocate a new chunk of memory
  36. * to hold the encrypted data, and store a pointer to that memory in
  37. * *<b>out</b>, and its size in <b>outlen_out</b>. Use <b>s2k_flags</b> as an
  38. * argument to the passphrase-hashing function.
  39. */
  40. int
  41. crypto_pwbox(uint8_t **out, size_t *outlen_out,
  42. const uint8_t *input, size_t input_len,
  43. const char *secret, size_t secret_len,
  44. unsigned s2k_flags)
  45. {
  46. uint8_t *result = NULL, *encrypted_portion;
  47. size_t encrypted_len = 128 * CEIL_DIV(input_len+4, 128);
  48. ssize_t result_len;
  49. int spec_len;
  50. uint8_t keys[CIPHER_KEY_LEN + DIGEST256_LEN];
  51. pwbox_encoded_t *enc = NULL;
  52. ssize_t enc_len;
  53. crypto_cipher_t *cipher;
  54. int rv;
  55. enc = pwbox_encoded_new();
  56. tor_assert(enc);
  57. pwbox_encoded_setlen_skey_header(enc, S2K_MAXLEN);
  58. spec_len = secret_to_key_make_specifier(
  59. pwbox_encoded_getarray_skey_header(enc),
  60. S2K_MAXLEN,
  61. s2k_flags);
  62. if (BUG(spec_len < 0 || spec_len > S2K_MAXLEN))
  63. goto err;
  64. pwbox_encoded_setlen_skey_header(enc, spec_len);
  65. enc->header_len = spec_len;
  66. crypto_rand((char*)enc->iv, sizeof(enc->iv));
  67. pwbox_encoded_setlen_data(enc, encrypted_len);
  68. encrypted_portion = pwbox_encoded_getarray_data(enc);
  69. set_uint32(encrypted_portion, tor_htonl((uint32_t)input_len));
  70. memcpy(encrypted_portion+4, input, input_len);
  71. /* Now that all the data is in position, derive some keys, encrypt, and
  72. * digest */
  73. const int s2k_rv = secret_to_key_derivekey(keys, sizeof(keys),
  74. pwbox_encoded_getarray_skey_header(enc),
  75. spec_len,
  76. secret, secret_len);
  77. if (BUG(s2k_rv < 0))
  78. goto err;
  79. cipher = crypto_cipher_new_with_iv((char*)keys, (char*)enc->iv);
  80. crypto_cipher_crypt_inplace(cipher, (char*)encrypted_portion, encrypted_len);
  81. crypto_cipher_free(cipher);
  82. result_len = pwbox_encoded_encoded_len(enc);
  83. if (BUG(result_len < 0))
  84. goto err;
  85. result = tor_malloc(result_len);
  86. enc_len = pwbox_encoded_encode(result, result_len, enc);
  87. if (BUG(enc_len < 0))
  88. goto err;
  89. tor_assert(enc_len == result_len);
  90. crypto_hmac_sha256((char*) result + result_len - 32,
  91. (const char*)keys + CIPHER_KEY_LEN,
  92. DIGEST256_LEN,
  93. (const char*)result,
  94. result_len - 32);
  95. *out = result;
  96. *outlen_out = result_len;
  97. rv = 0;
  98. goto out;
  99. /* LCOV_EXCL_START
  100. This error case is often unreachable if we're correctly coded, unless
  101. somebody adds a new error case somewhere, or unless you're building
  102. without scrypto support.
  103. - make_specifier can't fail, unless S2K_MAX_LEN is too short.
  104. - secret_to_key_derivekey can't really fail unless we're missing
  105. scrypt, or the underlying function fails, or we pass it a bogus
  106. algorithm or parameters.
  107. - pwbox_encoded_encoded_len can't fail unless we're using trunnel
  108. incorrectly.
  109. - pwbox_encoded_encode can't fail unless we're using trunnel wrong,
  110. or it's buggy.
  111. */
  112. err:
  113. tor_free(result);
  114. rv = -1;
  115. /* LCOV_EXCL_STOP */
  116. out:
  117. pwbox_encoded_free(enc);
  118. memwipe(keys, 0, sizeof(keys));
  119. return rv;
  120. }
  121. /**
  122. * Try to decrypt the passphrase-encrypted blob of <b>input_len</b> bytes in
  123. * <b>input</b> using the passphrase <b>secret</b> of <b>secret_len</b> bytes.
  124. * On success, return 0 and allocate a new chunk of memory to hold the
  125. * decrypted data, and store a pointer to that memory in *<b>out</b>, and its
  126. * size in <b>outlen_out</b>. On failure, return UNPWBOX_BAD_SECRET if
  127. * the passphrase might have been wrong, and UNPWBOX_CORRUPT if the object is
  128. * definitely corrupt.
  129. */
  130. int
  131. crypto_unpwbox(uint8_t **out, size_t *outlen_out,
  132. const uint8_t *inp, size_t input_len,
  133. const char *secret, size_t secret_len)
  134. {
  135. uint8_t *result = NULL;
  136. const uint8_t *encrypted;
  137. uint8_t keys[CIPHER_KEY_LEN + DIGEST256_LEN];
  138. uint8_t hmac[DIGEST256_LEN];
  139. uint32_t result_len;
  140. size_t encrypted_len;
  141. crypto_cipher_t *cipher = NULL;
  142. int rv = UNPWBOX_CORRUPTED;
  143. ssize_t got_len;
  144. pwbox_encoded_t *enc = NULL;
  145. got_len = pwbox_encoded_parse(&enc, inp, input_len);
  146. if (got_len < 0 || (size_t)got_len != input_len)
  147. goto err;
  148. /* Now derive the keys and check the hmac. */
  149. if (secret_to_key_derivekey(keys, sizeof(keys),
  150. pwbox_encoded_getarray_skey_header(enc),
  151. pwbox_encoded_getlen_skey_header(enc),
  152. secret, secret_len) < 0)
  153. goto err;
  154. crypto_hmac_sha256((char *)hmac,
  155. (const char*)keys + CIPHER_KEY_LEN, DIGEST256_LEN,
  156. (const char*)inp, input_len - DIGEST256_LEN);
  157. if (tor_memneq(hmac, enc->hmac, DIGEST256_LEN)) {
  158. rv = UNPWBOX_BAD_SECRET;
  159. goto err;
  160. }
  161. /* How long is the plaintext? */
  162. encrypted = pwbox_encoded_getarray_data(enc);
  163. encrypted_len = pwbox_encoded_getlen_data(enc);
  164. if (encrypted_len < 4)
  165. goto err;
  166. cipher = crypto_cipher_new_with_iv((char*)keys, (char*)enc->iv);
  167. crypto_cipher_decrypt(cipher, (char*)&result_len, (char*)encrypted, 4);
  168. result_len = tor_ntohl(result_len);
  169. if (encrypted_len < result_len + 4)
  170. goto err;
  171. /* Allocate a buffer and decrypt */
  172. result = tor_malloc_zero(result_len);
  173. crypto_cipher_decrypt(cipher, (char*)result, (char*)encrypted+4, result_len);
  174. *out = result;
  175. *outlen_out = result_len;
  176. rv = UNPWBOX_OKAY;
  177. goto out;
  178. err:
  179. tor_free(result);
  180. out:
  181. crypto_cipher_free(cipher);
  182. pwbox_encoded_free(enc);
  183. memwipe(keys, 0, sizeof(keys));
  184. return rv;
  185. }