LCOV - code coverage report
Current view: top level - lib/crypt_ops - crypto_cipher.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 64 64 100.0 %
Date: 2021-11-24 03:28:48 Functions: 10 10 100.0 %

          Line data    Source code
       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       13555 : crypto_cipher_new_with_iv_and_bits(const uint8_t *key,
      30             :                                    const uint8_t *iv,
      31             :                                    int bits)
      32             : {
      33       13555 :   tor_assert(key);
      34       13555 :   tor_assert(iv);
      35             : 
      36       13555 :   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          50 : crypto_cipher_new_with_iv(const char *key, const char *iv)
      45             : {
      46          50 :   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         260 : crypto_cipher_new_with_bits(const char *key, int bits)
      55             : {
      56         260 :   char zeroiv[CIPHER_IV_LEN];
      57         260 :   memset(zeroiv, 0, sizeof(zeroiv));
      58         260 :   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         123 : crypto_cipher_new(const char *key)
      66             : {
      67         123 :   return crypto_cipher_new_with_bits(key, 128);
      68             : }
      69             : 
      70             : /** Free a symmetric cipher.
      71             :  */
      72             : void
      73       13736 : crypto_cipher_free_(crypto_cipher_t *env)
      74             : {
      75       13736 :   if (!env)
      76             :     return;
      77             : 
      78       13533 :   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         846 : crypto_cipher_encrypt(crypto_cipher_t *env, char *to,
      89             :                       const char *from, size_t fromlen)
      90             : {
      91         846 :   tor_assert(env);
      92         846 :   tor_assert(env);
      93         846 :   tor_assert(from);
      94         846 :   tor_assert(fromlen);
      95         846 :   tor_assert(to);
      96         846 :   tor_assert(fromlen < SIZE_T_CEILING);
      97             : 
      98         846 :   memcpy(to, from, fromlen);
      99         846 :   aes_crypt_inplace(env, to, fromlen);
     100         846 :   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         501 : crypto_cipher_decrypt(crypto_cipher_t *env, char *to,
     109             :                       const char *from, size_t fromlen)
     110             : {
     111         501 :   tor_assert(env);
     112         501 :   tor_assert(from);
     113         501 :   tor_assert(to);
     114         501 :   tor_assert(fromlen < SIZE_T_CEILING);
     115             : 
     116         501 :   memcpy(to, from, fromlen);
     117         501 :   aes_crypt_inplace(env, to, fromlen);
     118         501 :   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       76124 : crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *buf, size_t len)
     126             : {
     127       76124 :   tor_assert(len < SIZE_T_CEILING);
     128       76124 :   aes_crypt_inplace(env, buf, len);
     129       76124 : }
     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          12 : crypto_cipher_encrypt_with_iv(const char *key,
     139             :                               char *to, size_t tolen,
     140             :                               const char *from, size_t fromlen)
     141             : {
     142          12 :   crypto_cipher_t *cipher;
     143          12 :   tor_assert(from);
     144          12 :   tor_assert(to);
     145          12 :   tor_assert(fromlen < INT_MAX);
     146             : 
     147          12 :   if (fromlen < 1)
     148             :     return -1;
     149          12 :   if (tolen < fromlen + CIPHER_IV_LEN)
     150             :     return -1;
     151             : 
     152          12 :   char iv[CIPHER_IV_LEN];
     153          12 :   crypto_rand(iv, sizeof(iv));
     154          12 :   cipher = crypto_cipher_new_with_iv(key, iv);
     155             : 
     156          12 :   memcpy(to, iv, CIPHER_IV_LEN);
     157          12 :   crypto_cipher_encrypt(cipher, to+CIPHER_IV_LEN, from, fromlen);
     158          12 :   crypto_cipher_free(cipher);
     159          12 :   memwipe(iv, 0, sizeof(iv));
     160          12 :   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          16 : crypto_cipher_decrypt_with_iv(const char *key,
     171             :                               char *to, size_t tolen,
     172             :                               const char *from, size_t fromlen)
     173             : {
     174          16 :   crypto_cipher_t *cipher;
     175          16 :   tor_assert(key);
     176          16 :   tor_assert(from);
     177          16 :   tor_assert(to);
     178          16 :   tor_assert(fromlen < INT_MAX);
     179             : 
     180          16 :   if (fromlen <= CIPHER_IV_LEN)
     181             :     return -1;
     182          16 :   if (tolen < fromlen - CIPHER_IV_LEN)
     183             :     return -1;
     184             : 
     185          16 :   cipher = crypto_cipher_new_with_iv(key, from);
     186             : 
     187          16 :   crypto_cipher_encrypt(cipher, to, from+CIPHER_IV_LEN, fromlen-CIPHER_IV_LEN);
     188          16 :   crypto_cipher_free(cipher);
     189          16 :   return (int)(fromlen - CIPHER_IV_LEN);
     190             : }

Generated by: LCOV version 1.14