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 */
8 * \file crypto_cipher.c
9 * \brief Symmetric cryptography (low-level) with AES.
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"
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 */
29 crypto_cipher_new_with_iv_and_bits(const uint8_t *key
,
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
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
,
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
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
,
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. */
65 crypto_cipher_new(const char *key
)
67 return crypto_cipher_new_with_bits(key
, 128);
70 /** Free a symmetric cipher.
73 crypto_cipher_free_(crypto_cipher_t
*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.
88 crypto_cipher_encrypt(crypto_cipher_t
*env
, char *to
,
89 const char *from
, size_t fromlen
)
96 tor_assert(fromlen
< SIZE_T_CEILING
);
98 memcpy(to
, from
, fromlen
);
99 aes_crypt_inplace(env
, to
, fromlen
);
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
)
114 tor_assert(fromlen
< SIZE_T_CEILING
);
116 memcpy(to
, from
, fromlen
);
117 aes_crypt_inplace(env
, to
, fromlen
);
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.
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
;
145 tor_assert(fromlen
< INT_MAX
);
149 if (tolen
< fromlen
+ CIPHER_IV_LEN
)
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
;
178 tor_assert(fromlen
< INT_MAX
);
180 if (fromlen
<= CIPHER_IV_LEN
)
182 if (tolen
< fromlen
- CIPHER_IV_LEN
)
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
);