crypto_cipher.c (5512B)
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 14 #include "lib/crypt_ops/crypto_cipher.h" 15 #include "lib/crypt_ops/crypto_rand.h" 16 #include "lib/crypt_ops/crypto_util.h" 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 * 29 crypto_cipher_new_with_iv_and_bits(const uint8_t *key, 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 138 crypto_cipher_encrypt_with_iv(const char *key, 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 170 crypto_cipher_decrypt_with_iv(const char *key, 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 }