LCOV - code coverage report
Current view: top level - modes - cfb128.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 45 71 63.4 %
Date: 2014-08-02 Functions: 1 4 25.0 %
Branches: 22 40 55.0 %

           Branch data     Line data    Source code
       1                 :            : /* ====================================================================
       2                 :            :  * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
       3                 :            :  *
       4                 :            :  * Redistribution and use in source and binary forms, with or without
       5                 :            :  * modification, are permitted provided that the following conditions
       6                 :            :  * are met:
       7                 :            :  *
       8                 :            :  * 1. Redistributions of source code must retain the above copyright
       9                 :            :  *    notice, this list of conditions and the following disclaimer. 
      10                 :            :  *
      11                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      12                 :            :  *    notice, this list of conditions and the following disclaimer in
      13                 :            :  *    the documentation and/or other materials provided with the
      14                 :            :  *    distribution.
      15                 :            :  *
      16                 :            :  * 3. All advertising materials mentioning features or use of this
      17                 :            :  *    software must display the following acknowledgment:
      18                 :            :  *    "This product includes software developed by the OpenSSL Project
      19                 :            :  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
      20                 :            :  *
      21                 :            :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      22                 :            :  *    endorse or promote products derived from this software without
      23                 :            :  *    prior written permission. For written permission, please contact
      24                 :            :  *    openssl-core@openssl.org.
      25                 :            :  *
      26                 :            :  * 5. Products derived from this software may not be called "OpenSSL"
      27                 :            :  *    nor may "OpenSSL" appear in their names without prior written
      28                 :            :  *    permission of the OpenSSL Project.
      29                 :            :  *
      30                 :            :  * 6. Redistributions of any form whatsoever must retain the following
      31                 :            :  *    acknowledgment:
      32                 :            :  *    "This product includes software developed by the OpenSSL Project
      33                 :            :  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
      34                 :            :  *
      35                 :            :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      36                 :            :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      37                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      38                 :            :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      39                 :            :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      40                 :            :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      41                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      42                 :            :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      43                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      44                 :            :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      45                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      46                 :            :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      47                 :            :  * ====================================================================
      48                 :            :  *
      49                 :            :  */
      50                 :            : 
      51                 :            : #include <openssl/crypto.h>
      52                 :            : #include "modes_lcl.h"
      53                 :            : #include <string.h>
      54                 :            : 
      55                 :            : #ifndef MODES_DEBUG
      56                 :            : # ifndef NDEBUG
      57                 :            : #  define NDEBUG
      58                 :            : # endif
      59                 :            : #endif
      60                 :            : #include <assert.h>
      61                 :            : 
      62                 :            : /* The input and output encrypted as though 128bit cfb mode is being
      63                 :            :  * used.  The extra state information to record how much of the
      64                 :            :  * 128bit block we have used is contained in *num;
      65                 :            :  */
      66                 :         80 : void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
      67                 :            :                         size_t len, const void *key,
      68                 :            :                         unsigned char ivec[16], int *num,
      69                 :            :                         int enc, block128_f block)
      70                 :            : {
      71                 :            :     unsigned int n;
      72                 :         80 :     size_t l = 0;
      73                 :            : 
      74                 :            :     assert(in && out && key && ivec && num);
      75                 :            : 
      76                 :         80 :     n = *num;
      77                 :            : 
      78         [ +  + ]:         80 :     if (enc) {
      79                 :            : #if !defined(OPENSSL_SMALL_FOOTPRINT)
      80                 :            :         if (16%sizeof(size_t) == 0) do {        /* always true actually */
      81         [ +  + ]:        226 :                 while (n && len) {
      82                 :        184 :                         *(out++) = ivec[n] ^= *(in++);
      83                 :        184 :                         --len;
      84                 :        184 :                         n = (n+1) % 16;
      85                 :            :                 }
      86                 :            : #if defined(STRICT_ALIGNMENT)
      87                 :            :                 if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
      88                 :            :                         break;
      89                 :            : #endif
      90         [ +  + ]:        176 :                 while (len>=16) {
      91                 :        134 :                         (*block)(ivec, ivec, key);
      92         [ +  + ]:        402 :                         for (; n<16; n+=sizeof(size_t)) {
      93                 :        536 :                                 *(size_t*)(out+n) =
      94                 :        268 :                                 *(size_t*)(ivec+n) ^= *(size_t*)(in+n);
      95                 :            :                         }
      96                 :        134 :                         len -= 16;
      97                 :        134 :                         out += 16;
      98                 :        134 :                         in  += 16;
      99                 :        134 :                         n = 0;
     100                 :            :                 }
     101         [ +  + ]:         42 :                 if (len) {
     102                 :         18 :                         (*block)(ivec, ivec, key);
     103         [ +  + ]:        106 :                         while (len--) {
     104                 :         88 :                                 out[n] = ivec[n] ^= in[n];
     105                 :         88 :                                 ++n;
     106                 :            :                         }
     107                 :            :                 }
     108                 :         42 :                 *num = n;
     109                 :         42 :                 return;
     110                 :            :         } while (0);
     111                 :            :         /* the rest would be commonly eliminated by x86* compiler */
     112                 :            : #endif
     113                 :            :         while (l<len) {
     114                 :            :                 if (n == 0) {
     115                 :            :                         (*block)(ivec, ivec, key);
     116                 :            :                 }
     117                 :            :                 out[l] = ivec[n] ^= in[l];
     118                 :            :                 ++l;
     119                 :            :                 n = (n+1) % 16;
     120                 :            :         }
     121                 :            :         *num = n;
     122                 :            :     } else {
     123                 :            : #if !defined(OPENSSL_SMALL_FOOTPRINT)
     124                 :            :         if (16%sizeof(size_t) == 0) do {        /* always true actually */
     125         [ +  + ]:        132 :                 while (n && len) {
     126                 :            :                         unsigned char c;
     127                 :         94 :                         *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
     128                 :         94 :                         --len;
     129                 :         94 :                         n = (n+1) % 16;
     130                 :            :                 }
     131                 :            : #if defined(STRICT_ALIGNMENT)
     132                 :            :                 if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
     133                 :            :                         break;
     134                 :            : #endif
     135         [ +  + ]:        176 :                 while (len>=16) {
     136                 :        138 :                         (*block)(ivec, ivec, key);
     137         [ +  + ]:        414 :                         for (; n<16; n+=sizeof(size_t)) {
     138                 :        276 :                                 size_t t = *(size_t*)(in+n);
     139                 :        276 :                                 *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
     140                 :        276 :                                 *(size_t*)(ivec+n) = t;
     141                 :            :                         }
     142                 :        138 :                         len -= 16;
     143                 :        138 :                         out += 16;
     144                 :        138 :                         in  += 16;
     145                 :        138 :                         n = 0;
     146                 :            :                 }
     147         [ +  + ]:         38 :                 if (len) {
     148                 :         14 :                         (*block)(ivec, ivec, key);
     149         [ +  + ]:        128 :                         while (len--) {
     150                 :            :                                 unsigned char c;
     151                 :        114 :                                 out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
     152                 :        114 :                                 ++n;
     153                 :            :                         }
     154                 :            :                 }
     155                 :         38 :                 *num = n;
     156                 :         38 :                 return;
     157                 :            :         } while (0);
     158                 :            :         /* the rest would be commonly eliminated by x86* compiler */
     159                 :            : #endif
     160                 :            :         while (l<len) {
     161                 :            :                 unsigned char c;
     162                 :            :                 if (n == 0) {
     163                 :            :                         (*block)(ivec, ivec, key);
     164                 :            :                 }
     165                 :            :                 out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c;
     166                 :            :                 ++l;
     167                 :            :                 n = (n+1) % 16;
     168                 :            :         }
     169                 :            :         *num=n;
     170                 :            :     }
     171                 :            : }
     172                 :            : 
     173                 :            : /* This expects a single block of size nbits for both in and out. Note that
     174                 :            :    it corrupts any extra bits in the last byte of out */
     175                 :          0 : static void cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
     176                 :            :                             int nbits,const void *key,
     177                 :            :                             unsigned char ivec[16],int enc,
     178                 :            :                             block128_f block)
     179                 :            : {
     180                 :            :     int n,rem,num;
     181                 :            :     unsigned char ovec[16*2 + 1];  /* +1 because we dererefence (but don't use) one byte off the end */
     182                 :            : 
     183         [ #  # ]:          0 :     if (nbits<=0 || nbits>128) return;
     184                 :            : 
     185                 :            :         /* fill in the first half of the new IV with the current IV */
     186                 :            :         memcpy(ovec,ivec,16);
     187                 :            :         /* construct the new IV */
     188                 :          0 :         (*block)(ivec,ivec,key);
     189                 :          0 :         num = (nbits+7)/8;
     190         [ #  # ]:          0 :         if (enc)        /* encrypt the input */
     191         [ #  # ]:          0 :             for(n=0 ; n < num ; ++n)
     192                 :          0 :                 out[n] = (ovec[16+n] = in[n] ^ ivec[n]);
     193                 :            :         else            /* decrypt the input */
     194         [ #  # ]:          0 :             for(n=0 ; n < num ; ++n)
     195                 :          0 :                 out[n] = (ovec[16+n] = in[n]) ^ ivec[n];
     196                 :            :         /* shift ovec left... */
     197                 :          0 :         rem = nbits%8;
     198                 :          0 :         num = nbits/8;
     199         [ #  # ]:          0 :         if(rem==0)
     200                 :          0 :             memcpy(ivec,ovec+num,16);
     201                 :            :         else
     202         [ #  # ]:          0 :             for(n=0 ; n < 16 ; ++n)
     203                 :          0 :                 ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem);
     204                 :            : 
     205                 :            :     /* it is not necessary to cleanse ovec, since the IV is not secret */
     206                 :            : }
     207                 :            : 
     208                 :            : /* N.B. This expects the input to be packed, MS bit first */
     209                 :          0 : void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
     210                 :            :                         size_t bits, const void *key,
     211                 :            :                         unsigned char ivec[16], int *num,
     212                 :            :                         int enc, block128_f block)
     213                 :            : {
     214                 :            :     size_t n;
     215                 :            :     unsigned char c[1],d[1];
     216                 :            : 
     217                 :            :     assert(in && out && key && ivec && num);
     218                 :            :     assert(*num == 0);
     219                 :            : 
     220         [ #  # ]:          0 :     for(n=0 ; n<bits ; ++n)
     221                 :            :         {
     222         [ #  # ]:          0 :         c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
     223                 :          0 :         cfbr_encrypt_block(c,d,1,key,ivec,enc,block);
     224                 :          0 :         out[n/8]=(out[n/8]&~(1 << (unsigned int)(7-n%8))) |
     225                 :          0 :                  ((d[0]&0x80) >> (unsigned int)(n%8));
     226                 :            :         }
     227                 :          0 : }
     228                 :            : 
     229                 :          0 : void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
     230                 :            :                         size_t length, const void *key,
     231                 :            :                         unsigned char ivec[16], int *num,
     232                 :            :                         int enc, block128_f block)
     233                 :            : {
     234                 :            :     size_t n;
     235                 :            : 
     236                 :            :     assert(in && out && key && ivec && num);
     237                 :            :     assert(*num == 0);
     238                 :            : 
     239         [ #  # ]:          0 :     for(n=0 ; n<length ; ++n)
     240                 :          0 :         cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc,block);
     241                 :          0 : }
     242                 :            : 

Generated by: LCOV version 1.9