dirvote: Fix memleak when computing consensus
[tor.git] / src / lib / crypt_ops / crypto_cipher.c
blobcfece770a18af409b48f6a25f9d0391f8a27f323
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-2021, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
7 /**
8 * \file crypto_cipher.c
9 * \brief Symmetric cryptography (low-level) with AES.
10 **/
12 #include "orconfig.h"
14 #include "lib/crypt_ops/crypto_cipher.h"
15 #include "lib/crypt_ops/crypto_rand.h"
16 #include "lib/crypt_ops/crypto_util.h"
18 #include "lib/log/log.h"
19 #include "lib/log/util_bug.h"
20 #include "lib/cc/torint.h"
21 #include "lib/crypt_ops/aes.h"
23 #include <string.h>
25 /** Allocate and return a new symmetric cipher using the provided key and iv.
26 * The key is <b>bits</b> bits long; the IV is CIPHER_IV_LEN bytes. Both
27 * must be provided. Key length must be 128, 192, or 256 */
28 crypto_cipher_t *
29 crypto_cipher_new_with_iv_and_bits(const uint8_t *key,
30 const uint8_t *iv,
31 int bits)
33 tor_assert(key);
34 tor_assert(iv);
36 return aes_new_cipher((const uint8_t*)key, (const uint8_t*)iv, bits);
39 /** Allocate and return a new symmetric cipher using the provided key and iv.
40 * The key is CIPHER_KEY_LEN bytes; the IV is CIPHER_IV_LEN bytes. Both
41 * must be provided.
43 crypto_cipher_t *
44 crypto_cipher_new_with_iv(const char *key, const char *iv)
46 return crypto_cipher_new_with_iv_and_bits((uint8_t*)key, (uint8_t*)iv,
47 128);
50 /** Return a new crypto_cipher_t with the provided <b>key</b> and an IV of all
51 * zero bytes and key length <b>bits</b>. Key length must be 128, 192, or
52 * 256. */
53 crypto_cipher_t *
54 crypto_cipher_new_with_bits(const char *key, int bits)
56 char zeroiv[CIPHER_IV_LEN];
57 memset(zeroiv, 0, sizeof(zeroiv));
58 return crypto_cipher_new_with_iv_and_bits((uint8_t*)key, (uint8_t*)zeroiv,
59 bits);
62 /** Return a new crypto_cipher_t with the provided <b>key</b> (of
63 * CIPHER_KEY_LEN bytes) and an IV of all zero bytes. */
64 crypto_cipher_t *
65 crypto_cipher_new(const char *key)
67 return crypto_cipher_new_with_bits(key, 128);
70 /** Free a symmetric cipher.
72 void
73 crypto_cipher_free_(crypto_cipher_t *env)
75 if (!env)
76 return;
78 aes_cipher_free(env);
81 /* symmetric crypto */
83 /** Encrypt <b>fromlen</b> bytes from <b>from</b> using the cipher
84 * <b>env</b>; on success, store the result to <b>to</b> and return 0.
85 * Does not check for failure.
87 int
88 crypto_cipher_encrypt(crypto_cipher_t *env, char *to,
89 const char *from, size_t fromlen)
91 tor_assert(env);
92 tor_assert(env);
93 tor_assert(from);
94 tor_assert(fromlen);
95 tor_assert(to);
96 tor_assert(fromlen < SIZE_T_CEILING);
98 memcpy(to, from, fromlen);
99 aes_crypt_inplace(env, to, fromlen);
100 return 0;
103 /** Decrypt <b>fromlen</b> bytes from <b>from</b> using the cipher
104 * <b>env</b>; on success, store the result to <b>to</b> and return 0.
105 * Does not check for failure.
108 crypto_cipher_decrypt(crypto_cipher_t *env, char *to,
109 const char *from, size_t fromlen)
111 tor_assert(env);
112 tor_assert(from);
113 tor_assert(to);
114 tor_assert(fromlen < SIZE_T_CEILING);
116 memcpy(to, from, fromlen);
117 aes_crypt_inplace(env, to, fromlen);
118 return 0;
121 /** Encrypt <b>len</b> bytes on <b>from</b> using the cipher in <b>env</b>;
122 * on success. Does not check for failure.
124 void
125 crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *buf, size_t len)
127 tor_assert(len < SIZE_T_CEILING);
128 aes_crypt_inplace(env, buf, len);
131 /** Encrypt <b>fromlen</b> bytes (at least 1) from <b>from</b> with the key in
132 * <b>key</b> to the buffer in <b>to</b> of length
133 * <b>tolen</b>. <b>tolen</b> must be at least <b>fromlen</b> plus
134 * CIPHER_IV_LEN bytes for the initialization vector. On success, return the
135 * number of bytes written, on failure, return -1.
138 crypto_cipher_encrypt_with_iv(const char *key,
139 char *to, size_t tolen,
140 const char *from, size_t fromlen)
142 crypto_cipher_t *cipher;
143 tor_assert(from);
144 tor_assert(to);
145 tor_assert(fromlen < INT_MAX);
147 if (fromlen < 1)
148 return -1;
149 if (tolen < fromlen + CIPHER_IV_LEN)
150 return -1;
152 char iv[CIPHER_IV_LEN];
153 crypto_rand(iv, sizeof(iv));
154 cipher = crypto_cipher_new_with_iv(key, iv);
156 memcpy(to, iv, CIPHER_IV_LEN);
157 crypto_cipher_encrypt(cipher, to+CIPHER_IV_LEN, from, fromlen);
158 crypto_cipher_free(cipher);
159 memwipe(iv, 0, sizeof(iv));
160 return (int)(fromlen + CIPHER_IV_LEN);
163 /** Decrypt <b>fromlen</b> bytes (at least 1+CIPHER_IV_LEN) from <b>from</b>
164 * with the key in <b>key</b> to the buffer in <b>to</b> of length
165 * <b>tolen</b>. <b>tolen</b> must be at least <b>fromlen</b> minus
166 * CIPHER_IV_LEN bytes for the initialization vector. On success, return the
167 * number of bytes written, on failure, return -1.
170 crypto_cipher_decrypt_with_iv(const char *key,
171 char *to, size_t tolen,
172 const char *from, size_t fromlen)
174 crypto_cipher_t *cipher;
175 tor_assert(key);
176 tor_assert(from);
177 tor_assert(to);
178 tor_assert(fromlen < INT_MAX);
180 if (fromlen <= CIPHER_IV_LEN)
181 return -1;
182 if (tolen < fromlen - CIPHER_IV_LEN)
183 return -1;
185 cipher = crypto_cipher_new_with_iv(key, from);
187 crypto_cipher_encrypt(cipher, to, from+CIPHER_IV_LEN, fromlen-CIPHER_IV_LEN);
188 crypto_cipher_free(cipher);
189 return (int)(fromlen - CIPHER_IV_LEN);