crypto_cipher.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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_cipher.c
  8. * \brief Symmetric cryptography (low-level) with AES.
  9. **/
  10. #include "orconfig.h"
  11. #include "lib/crypt_ops/crypto_cipher.h"
  12. #include "lib/crypt_ops/crypto_rand.h"
  13. #include "lib/crypt_ops/crypto_util.h"
  14. #include "lib/log/log.h"
  15. #include "lib/log/util_bug.h"
  16. #include "lib/cc/torint.h"
  17. #include "lib/crypt_ops/aes.h"
  18. #include <string.h>
  19. /** Allocate and return a new symmetric cipher using the provided key and iv.
  20. * The key is <b>bits</b> bits long; the IV is CIPHER_IV_LEN bytes. Both
  21. * must be provided. Key length must be 128, 192, or 256 */
  22. crypto_cipher_t *
  23. crypto_cipher_new_with_iv_and_bits(const uint8_t *key,
  24. const uint8_t *iv,
  25. int bits)
  26. {
  27. tor_assert(key);
  28. tor_assert(iv);
  29. return aes_new_cipher((const uint8_t*)key, (const uint8_t*)iv, bits);
  30. }
  31. /** Allocate and return a new symmetric cipher using the provided key and iv.
  32. * The key is CIPHER_KEY_LEN bytes; the IV is CIPHER_IV_LEN bytes. Both
  33. * must be provided.
  34. */
  35. crypto_cipher_t *
  36. crypto_cipher_new_with_iv(const char *key, const char *iv)
  37. {
  38. return crypto_cipher_new_with_iv_and_bits((uint8_t*)key, (uint8_t*)iv,
  39. 128);
  40. }
  41. /** Return a new crypto_cipher_t with the provided <b>key</b> and an IV of all
  42. * zero bytes and key length <b>bits</b>. Key length must be 128, 192, or
  43. * 256. */
  44. crypto_cipher_t *
  45. crypto_cipher_new_with_bits(const char *key, int bits)
  46. {
  47. char zeroiv[CIPHER_IV_LEN];
  48. memset(zeroiv, 0, sizeof(zeroiv));
  49. return crypto_cipher_new_with_iv_and_bits((uint8_t*)key, (uint8_t*)zeroiv,
  50. bits);
  51. }
  52. /** Return a new crypto_cipher_t with the provided <b>key</b> (of
  53. * CIPHER_KEY_LEN bytes) and an IV of all zero bytes. */
  54. crypto_cipher_t *
  55. crypto_cipher_new(const char *key)
  56. {
  57. return crypto_cipher_new_with_bits(key, 128);
  58. }
  59. /** Free a symmetric cipher.
  60. */
  61. void
  62. crypto_cipher_free_(crypto_cipher_t *env)
  63. {
  64. if (!env)
  65. return;
  66. aes_cipher_free(env);
  67. }
  68. /* symmetric crypto */
  69. /** Encrypt <b>fromlen</b> bytes from <b>from</b> using the cipher
  70. * <b>env</b>; on success, store the result to <b>to</b> and return 0.
  71. * Does not check for failure.
  72. */
  73. int
  74. crypto_cipher_encrypt(crypto_cipher_t *env, char *to,
  75. const char *from, size_t fromlen)
  76. {
  77. tor_assert(env);
  78. tor_assert(env);
  79. tor_assert(from);
  80. tor_assert(fromlen);
  81. tor_assert(to);
  82. tor_assert(fromlen < SIZE_T_CEILING);
  83. memcpy(to, from, fromlen);
  84. aes_crypt_inplace(env, to, fromlen);
  85. return 0;
  86. }
  87. /** Decrypt <b>fromlen</b> bytes from <b>from</b> using the cipher
  88. * <b>env</b>; on success, store the result to <b>to</b> and return 0.
  89. * Does not check for failure.
  90. */
  91. int
  92. crypto_cipher_decrypt(crypto_cipher_t *env, char *to,
  93. const char *from, size_t fromlen)
  94. {
  95. tor_assert(env);
  96. tor_assert(from);
  97. tor_assert(to);
  98. tor_assert(fromlen < SIZE_T_CEILING);
  99. memcpy(to, from, fromlen);
  100. aes_crypt_inplace(env, to, fromlen);
  101. return 0;
  102. }
  103. /** Encrypt <b>len</b> bytes on <b>from</b> using the cipher in <b>env</b>;
  104. * on success. Does not check for failure.
  105. */
  106. void
  107. crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *buf, size_t len)
  108. {
  109. tor_assert(len < SIZE_T_CEILING);
  110. aes_crypt_inplace(env, buf, len);
  111. }
  112. /** Encrypt <b>fromlen</b> bytes (at least 1) from <b>from</b> with the key in
  113. * <b>key</b> to the buffer in <b>to</b> of length
  114. * <b>tolen</b>. <b>tolen</b> must be at least <b>fromlen</b> plus
  115. * CIPHER_IV_LEN bytes for the initialization vector. On success, return the
  116. * number of bytes written, on failure, return -1.
  117. */
  118. int
  119. crypto_cipher_encrypt_with_iv(const char *key,
  120. char *to, size_t tolen,
  121. const char *from, size_t fromlen)
  122. {
  123. crypto_cipher_t *cipher;
  124. tor_assert(from);
  125. tor_assert(to);
  126. tor_assert(fromlen < INT_MAX);
  127. if (fromlen < 1)
  128. return -1;
  129. if (tolen < fromlen + CIPHER_IV_LEN)
  130. return -1;
  131. char iv[CIPHER_IV_LEN];
  132. crypto_rand(iv, sizeof(iv));
  133. cipher = crypto_cipher_new_with_iv(key, iv);
  134. memcpy(to, iv, CIPHER_IV_LEN);
  135. crypto_cipher_encrypt(cipher, to+CIPHER_IV_LEN, from, fromlen);
  136. crypto_cipher_free(cipher);
  137. memwipe(iv, 0, sizeof(iv));
  138. return (int)(fromlen + CIPHER_IV_LEN);
  139. }
  140. /** Decrypt <b>fromlen</b> bytes (at least 1+CIPHER_IV_LEN) from <b>from</b>
  141. * with the key in <b>key</b> to the buffer in <b>to</b> of length
  142. * <b>tolen</b>. <b>tolen</b> must be at least <b>fromlen</b> minus
  143. * CIPHER_IV_LEN bytes for the initialization vector. On success, return the
  144. * number of bytes written, on failure, return -1.
  145. */
  146. int
  147. crypto_cipher_decrypt_with_iv(const char *key,
  148. char *to, size_t tolen,
  149. const char *from, size_t fromlen)
  150. {
  151. crypto_cipher_t *cipher;
  152. tor_assert(key);
  153. tor_assert(from);
  154. tor_assert(to);
  155. tor_assert(fromlen < INT_MAX);
  156. if (fromlen <= CIPHER_IV_LEN)
  157. return -1;
  158. if (tolen < fromlen - CIPHER_IV_LEN)
  159. return -1;
  160. cipher = crypto_cipher_new_with_iv(key, from);
  161. crypto_cipher_encrypt(cipher, to, from+CIPHER_IV_LEN, fromlen-CIPHER_IV_LEN);
  162. crypto_cipher_free(cipher);
  163. return (int)(fromlen - CIPHER_IV_LEN);
  164. }