LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/nettle/backport - cfb.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 92 92 100.0 %
Date: 2020-10-30 04:50:48 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* cfb.c
       2             : 
       3             :    Cipher feedback mode.
       4             : 
       5             :    Copyright (C) 2015, 2017 Dmitry Eremin-Solenikov
       6             :    Copyright (C) 2001, 2011 Niels Möller
       7             : 
       8             :    This file is part of GNU Nettle.
       9             : 
      10             :    GNU Nettle is free software: you can redistribute it and/or
      11             :    modify it under the terms of either:
      12             : 
      13             :      * the GNU Lesser General Public License as published by the Free
      14             :        Software Foundation; either version 3 of the License, or (at your
      15             :        option) any later version.
      16             : 
      17             :    or
      18             : 
      19             :      * the GNU General Public License as published by the Free
      20             :        Software Foundation; either version 2 of the License, or (at your
      21             :        option) any later version.
      22             : 
      23             :    or both in parallel, as here.
      24             : 
      25             :    GNU Nettle is distributed in the hope that it will be useful,
      26             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      27             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      28             :    General Public License for more details.
      29             : 
      30             :    You should have received copies of the GNU General Public License and
      31             :    the GNU Lesser General Public License along with this program.  If
      32             :    not, see http://www.gnu.org/licenses/.
      33             : */
      34             : 
      35             : #if HAVE_CONFIG_H
      36             : # include "config.h"
      37             : #endif
      38             : 
      39             : #include <stdlib.h>
      40             : #include <string.h>
      41             : 
      42             : #include "cfb.h"
      43             : 
      44             : #include <nettle/memxor.h>
      45             : #include "nettle-alloca.h"
      46             : 
      47             : void
      48          56 : cfb_encrypt(const void *ctx, nettle_cipher_func *f,
      49             :             size_t block_size, uint8_t *iv,
      50             :             size_t length, uint8_t *dst,
      51             :             const uint8_t *src)
      52             : {
      53          56 :   uint8_t *p;
      54          56 :   TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
      55             : 
      56          56 :   TMP_ALLOC(buffer, block_size);
      57             : 
      58          56 :   if (src != dst)
      59             :     {
      60          85 :       for (p = iv; length >= block_size; p = dst, dst += block_size, src += block_size, length -= block_size)
      61             :         {
      62          60 :           f(ctx, block_size, dst, p);
      63          60 :           memxor(dst, src, block_size);
      64             :         }
      65             :     }
      66             :   else
      67             :     {
      68         493 :       for (p = iv; length >= block_size; p = dst, dst += block_size, src += block_size, length -= block_size)
      69             :         {
      70         462 :           f(ctx, block_size, buffer, p);
      71         462 :           memxor(dst, buffer, block_size);
      72             :         }
      73             :     }
      74             : 
      75          56 :   if (p != iv)
      76          46 :     memcpy(iv, p, block_size);
      77             : 
      78          56 :   if (length)
      79             :     {
      80          36 :       f(ctx, block_size, buffer, iv);
      81          36 :       memxor3(dst, buffer, src, length);
      82             :       /* We do not care about updating IV here. This is the last call in
      83             :        * message sequence and one has to set IV afterwards anyway */
      84             :     }
      85          56 : }
      86             : 
      87             : /* Don't allocate any more space than this on the stack */
      88             : #define CFB_BUFFER_LIMIT 512
      89             : 
      90             : void
      91          66 : cfb_decrypt(const void *ctx, nettle_cipher_func *f,
      92             :             size_t block_size, uint8_t *iv,
      93             :             size_t length, uint8_t *dst,
      94             :             const uint8_t *src)
      95             : {
      96          66 :   if (src != dst)
      97             :     {
      98          25 :       size_t left = length % block_size;
      99             : 
     100          25 :       length -= left;
     101          25 :       if (length > 0)
     102             :         {
     103             :           /* Decrypt in ECB mode */
     104          20 :           f(ctx, block_size, dst, iv);
     105          20 :           f(ctx, length - block_size, dst + block_size, src);
     106          20 :           memcpy(iv, src + length - block_size, block_size);
     107          20 :           memxor(dst, src, length);
     108             :         }
     109             : 
     110          25 :       if (left > 0)
     111             :         {
     112          15 :           TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
     113          15 :           TMP_ALLOC(buffer, block_size);
     114             : 
     115          15 :           f(ctx, block_size, buffer, iv);
     116          15 :           memxor3(dst + length, src + length, buffer, left);
     117             :         }
     118             :     }
     119             :   else
     120             :     {
     121             :       /* For in-place CFB, we decrypt into a temporary buffer of size
     122             :        * at most CFB_BUFFER_LIMIT, and process that amount of data at
     123             :        * a time. */
     124             : 
     125             :       /* NOTE: We assume that block_size <= CFB_BUFFER_LIMIT */
     126             : 
     127          41 :       TMP_DECL(buffer, uint8_t, CFB_BUFFER_LIMIT);
     128          41 :       TMP_DECL(initial_iv, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
     129             : 
     130          41 :       size_t buffer_size;
     131          41 :       size_t left;
     132             : 
     133          41 :       buffer_size = CFB_BUFFER_LIMIT - (CFB_BUFFER_LIMIT % block_size);
     134             : 
     135          41 :       TMP_ALLOC(buffer, buffer_size);
     136          41 :       TMP_ALLOC(initial_iv, block_size);
     137             : 
     138          41 :       left = length % block_size;
     139          41 :       length -= left;
     140             : 
     141          85 :       while (length > 0)
     142             :         {
     143          44 :           size_t part = length > buffer_size ? buffer_size : length;
     144             : 
     145             :           /* length is greater that zero and is divided by block_size, so it is
     146             :            * not less than block_size. So does part */
     147             : 
     148          44 :           f(ctx, block_size, buffer, iv);
     149          44 :           f(ctx, part - block_size, buffer + block_size, dst);
     150          44 :           memcpy(iv, dst + part - block_size, block_size);
     151          44 :           memxor(dst, buffer, part);
     152             : 
     153          44 :           length -= part;
     154          44 :           dst += part;
     155             :         }
     156             : 
     157          41 :       if (left > 0)
     158             :         {
     159          27 :           f(ctx, block_size, buffer, iv);
     160          27 :           memxor(dst, buffer, left);
     161             :         }
     162             :     }
     163          66 : }
     164             : 
     165             : /* CFB-8 uses slight optimization: it encrypts or decrypts up to block_size
     166             :  * bytes and does memcpy/memxor afterwards */
     167             : void
     168        1080 : cfb8_encrypt(const void *ctx, nettle_cipher_func *f,
     169             :              size_t block_size, uint8_t *iv,
     170             :              size_t length, uint8_t *dst,
     171             :              const uint8_t *src)
     172             : {
     173        1080 :   TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
     174        1080 :   TMP_DECL(outbuf, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
     175        1080 :   TMP_ALLOC(buffer, block_size * 2);
     176        1080 :   TMP_ALLOC(outbuf, block_size);
     177        1080 :   uint8_t pos;
     178             : 
     179        1080 :   memcpy(buffer, iv, block_size);
     180        1080 :   pos = 0;
     181        6480 :   while (length)
     182             :     {
     183        5400 :       uint8_t t;
     184             : 
     185        5400 :       if (pos == block_size)
     186             :         {
     187          60 :           memcpy(buffer, buffer + block_size, block_size);
     188          60 :           pos = 0;
     189             :         }
     190             : 
     191        5400 :       f(ctx, block_size, outbuf, buffer + pos);
     192        5400 :       t = *(dst++) = *(src++) ^ outbuf[0];
     193        5400 :       buffer[pos + block_size] = t;
     194        5400 :       length--;
     195        5400 :       pos ++;
     196             :     }
     197        1080 :   memcpy(iv, buffer + pos, block_size);
     198        1080 : }
     199             : 
     200             : void
     201         900 : cfb8_decrypt(const void *ctx, nettle_cipher_func *f,
     202             :              size_t block_size, uint8_t *iv,
     203             :              size_t length, uint8_t *dst,
     204             :              const uint8_t *src)
     205             : {
     206         900 :   TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
     207         900 :   TMP_DECL(outbuf, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
     208         900 :   TMP_ALLOC(buffer, block_size * 2);
     209         900 :   TMP_ALLOC(outbuf, block_size * 2);
     210         900 :   uint8_t i = 0;
     211             : 
     212         900 :   memcpy(buffer, iv, block_size);
     213         900 :   memcpy(buffer + block_size, src,
     214             :          length < block_size ? length : block_size);
     215             : 
     216        1860 :   while (length)
     217             :     {
     218             : 
     219        5655 :       for (i = 0; i < length && i < block_size; i++)
     220        4695 :         f(ctx, block_size, outbuf + i, buffer + i);
     221             : 
     222         960 :       memxor3(dst, src, outbuf, i);
     223             : 
     224         960 :       length -= i;
     225         960 :       src += i;
     226         960 :       dst += i;
     227             : 
     228         960 :       if (i == block_size)
     229             :         {
     230          75 :           memcpy(buffer, buffer + block_size, block_size);
     231          75 :           memcpy(buffer + block_size, src,
     232             :                  length < block_size ? length : block_size);
     233             :         }
     234             :     }
     235             : 
     236         900 :   memcpy(iv, buffer + i, block_size);
     237         900 : }

Generated by: LCOV version 1.14