"Fossies" - the Fresh Open Source Software Archive

Member "tor-0.4.1.6/src/lib/crypt_ops/crypto_cipher.c" (10 Jun 2019, 5512 Bytes) of package /linux/misc/tor-0.4.1.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "crypto_cipher.c" see the Fossies "Dox" file reference documentation.

    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 /**
    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 }