Tor  0.4.7.0-alpha-dev
crypto_cipher.c
Go to the documentation of this file.
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 */
6 
7 /**
8  * \file crypto_cipher.c
9  * \brief Symmetric cryptography (low-level) with AES.
10  **/
11 
12 #include "orconfig.h"
13 
17 
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"
22 
23 #include <string.h>
24 
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 *
30  const uint8_t *iv,
31  int bits)
32 {
33  tor_assert(key);
34  tor_assert(iv);
35 
36  return aes_new_cipher((const uint8_t*)key, (const uint8_t*)iv, bits);
37 }
38 
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.
42  */
43 crypto_cipher_t *
44 crypto_cipher_new_with_iv(const char *key, const char *iv)
45 {
46  return crypto_cipher_new_with_iv_and_bits((uint8_t*)key, (uint8_t*)iv,
47  128);
48 }
49 
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)
55 {
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);
60 }
61 
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)
66 {
67  return crypto_cipher_new_with_bits(key, 128);
68 }
69 
70 /** Free a symmetric cipher.
71  */
72 void
73 crypto_cipher_free_(crypto_cipher_t *env)
74 {
75  if (!env)
76  return;
77 
78  aes_cipher_free(env);
79 }
80 
81 /* symmetric crypto */
82 
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.
86  */
87 int
88 crypto_cipher_encrypt(crypto_cipher_t *env, char *to,
89  const char *from, size_t fromlen)
90 {
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);
97 
98  memcpy(to, from, fromlen);
99  aes_crypt_inplace(env, to, fromlen);
100  return 0;
101 }
102 
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.
106  */
107 int
108 crypto_cipher_decrypt(crypto_cipher_t *env, char *to,
109  const char *from, size_t fromlen)
110 {
111  tor_assert(env);
112  tor_assert(from);
113  tor_assert(to);
114  tor_assert(fromlen < SIZE_T_CEILING);
115 
116  memcpy(to, from, fromlen);
117  aes_crypt_inplace(env, to, fromlen);
118  return 0;
119 }
120 
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.
123  */
124 void
125 crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *buf, size_t len)
126 {
127  tor_assert(len < SIZE_T_CEILING);
128  aes_crypt_inplace(env, buf, len);
129 }
130 
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.
136  */
137 int
139  char *to, size_t tolen,
140  const char *from, size_t fromlen)
141 {
142  crypto_cipher_t *cipher;
143  tor_assert(from);
144  tor_assert(to);
145  tor_assert(fromlen < INT_MAX);
146 
147  if (fromlen < 1)
148  return -1;
149  if (tolen < fromlen + CIPHER_IV_LEN)
150  return -1;
151 
152  char iv[CIPHER_IV_LEN];
153  crypto_rand(iv, sizeof(iv));
154  cipher = crypto_cipher_new_with_iv(key, iv);
155 
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);
161 }
162 
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.
168  */
169 int
171  char *to, size_t tolen,
172  const char *from, size_t fromlen)
173 {
174  crypto_cipher_t *cipher;
175  tor_assert(key);
176  tor_assert(from);
177  tor_assert(to);
178  tor_assert(fromlen < INT_MAX);
179 
180  if (fromlen <= CIPHER_IV_LEN)
181  return -1;
182  if (tolen < fromlen - CIPHER_IV_LEN)
183  return -1;
184 
185  cipher = crypto_cipher_new_with_iv(key, from);
186 
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);
190 }
Headers for aes.c.
int crypto_cipher_decrypt_with_iv(const char *key, char *to, size_t tolen, const char *from, size_t fromlen)
crypto_cipher_t * crypto_cipher_new(const char *key)
Definition: crypto_cipher.c:65
void crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *buf, size_t len)
crypto_cipher_t * crypto_cipher_new_with_bits(const char *key, int bits)
Definition: crypto_cipher.c:54
int crypto_cipher_decrypt(crypto_cipher_t *env, char *to, const char *from, size_t fromlen)
int crypto_cipher_encrypt_with_iv(const char *key, char *to, size_t tolen, const char *from, size_t fromlen)
crypto_cipher_t * crypto_cipher_new_with_iv_and_bits(const uint8_t *key, const uint8_t *iv, int bits)
Definition: crypto_cipher.c:29
int crypto_cipher_encrypt(crypto_cipher_t *env, char *to, const char *from, size_t fromlen)
Definition: crypto_cipher.c:88
void crypto_cipher_free_(crypto_cipher_t *env)
Definition: crypto_cipher.c:73
crypto_cipher_t * crypto_cipher_new_with_iv(const char *key, const char *iv)
Definition: crypto_cipher.c:44
Headers for crypto_cipher.c.
#define CIPHER_IV_LEN
Definition: crypto_cipher.h:24
void crypto_rand(char *to, size_t n)
Definition: crypto_rand.c:477
Common functions for using (pseudo-)random number generators.
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
Common functions for cryptographic routines.
Headers for log.c.
Integer definitions used throughout Tor.
#define SIZE_T_CEILING
Definition: torint.h:126
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:102