LCOV - code coverage report
Current view: top level - aes - aes_ige.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 135 135 100.0 %
Date: 2014-08-02 Functions: 2 2 100.0 %
Branches: 64 72 88.9 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/aes/aes_ige.c -*- mode:C; c-file-style: "eay" -*- */
       2                 :            : /* ====================================================================
       3                 :            :  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
       4                 :            :  *
       5                 :            :  * Redistribution and use in source and binary forms, with or without
       6                 :            :  * modification, are permitted provided that the following conditions
       7                 :            :  * are met:
       8                 :            :  *
       9                 :            :  * 1. Redistributions of source code must retain the above copyright
      10                 :            :  *    notice, this list of conditions and the following disclaimer. 
      11                 :            :  *
      12                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      13                 :            :  *    notice, this list of conditions and the following disclaimer in
      14                 :            :  *    the documentation and/or other materials provided with the
      15                 :            :  *    distribution.
      16                 :            :  *
      17                 :            :  * 3. All advertising materials mentioning features or use of this
      18                 :            :  *    software must display the following acknowledgment:
      19                 :            :  *    "This product includes software developed by the OpenSSL Project
      20                 :            :  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
      21                 :            :  *
      22                 :            :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      23                 :            :  *    endorse or promote products derived from this software without
      24                 :            :  *    prior written permission. For written permission, please contact
      25                 :            :  *    openssl-core@openssl.org.
      26                 :            :  *
      27                 :            :  * 5. Products derived from this software may not be called "OpenSSL"
      28                 :            :  *    nor may "OpenSSL" appear in their names without prior written
      29                 :            :  *    permission of the OpenSSL Project.
      30                 :            :  *
      31                 :            :  * 6. Redistributions of any form whatsoever must retain the following
      32                 :            :  *    acknowledgment:
      33                 :            :  *    "This product includes software developed by the OpenSSL Project
      34                 :            :  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
      35                 :            :  *
      36                 :            :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      37                 :            :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      38                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      39                 :            :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      40                 :            :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      41                 :            :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      42                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      43                 :            :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      44                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      45                 :            :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      46                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      47                 :            :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      48                 :            :  * ====================================================================
      49                 :            :  *
      50                 :            :  */
      51                 :            : 
      52                 :            : #include "cryptlib.h"
      53                 :            : 
      54                 :            : #include <openssl/aes.h>
      55                 :            : #include "aes_locl.h"
      56                 :            : 
      57                 :            : #define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
      58                 :            : typedef struct {
      59                 :            :         unsigned long data[N_WORDS];
      60                 :            : } aes_block_t;
      61                 :            : 
      62                 :            : /* XXX: probably some better way to do this */
      63                 :            : #if defined(__i386__) || defined(__x86_64__)
      64                 :            : #define UNALIGNED_MEMOPS_ARE_FAST 1
      65                 :            : #else
      66                 :            : #define UNALIGNED_MEMOPS_ARE_FAST 0
      67                 :            : #endif
      68                 :            : 
      69                 :            : #if UNALIGNED_MEMOPS_ARE_FAST
      70                 :            : #define load_block(d, s)        (d) = *(const aes_block_t *)(s)
      71                 :            : #define store_block(d, s)       *(aes_block_t *)(d) = (s)
      72                 :            : #else
      73                 :            : #define load_block(d, s)        memcpy((d).data, (s), AES_BLOCK_SIZE)
      74                 :            : #define store_block(d, s)       memcpy((d), (s).data, AES_BLOCK_SIZE)
      75                 :            : #endif
      76                 :            : 
      77                 :            : /* N.B. The IV for this mode is _twice_ the block size */
      78                 :            : 
      79                 :         21 : void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
      80                 :            :                                          size_t length, const AES_KEY *key,
      81                 :            :                                          unsigned char *ivec, const int enc)
      82                 :            :         {
      83                 :            :         size_t n;
      84                 :         21 :         size_t len = length;
      85                 :            : 
      86 [ +  - ][ -  + ]:         21 :         OPENSSL_assert(in && out && key && ivec);
      87         [ -  + ]:         21 :         OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
      88         [ -  + ]:         21 :         OPENSSL_assert((length%AES_BLOCK_SIZE) == 0);
      89                 :            : 
      90                 :         21 :         len = length / AES_BLOCK_SIZE;
      91                 :            : 
      92         [ +  + ]:         21 :         if (AES_ENCRYPT == enc)
      93                 :            :                 {
      94         [ +  + ]:         11 :                 if (in != out &&
      95                 :            :                     (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0))
      96                 :            :                         {
      97                 :         10 :                         aes_block_t *ivp = (aes_block_t *)ivec;
      98                 :         10 :                         aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
      99                 :            : 
     100         [ +  + ]:       2596 :                         while (len)
     101                 :            :                                 {
     102                 :            :                                 aes_block_t *inp = (aes_block_t *)in;
     103                 :            :                                 aes_block_t *outp = (aes_block_t *)out;
     104                 :            : 
     105         [ +  + ]:       7758 :                                 for(n=0 ; n < N_WORDS; ++n)
     106                 :       5172 :                                         outp->data[n] = inp->data[n] ^ ivp->data[n];
     107                 :       2586 :                                 AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key);
     108         [ +  + ]:       7758 :                                 for(n=0 ; n < N_WORDS; ++n)
     109                 :       5172 :                                         outp->data[n] ^= iv2p->data[n];
     110                 :       2586 :                                 ivp = outp;
     111                 :       2586 :                                 iv2p = inp;
     112                 :       2586 :                                 --len;
     113                 :       2586 :                                 in += AES_BLOCK_SIZE;
     114                 :       2586 :                                 out += AES_BLOCK_SIZE;
     115                 :            :                                 }
     116                 :         10 :                         memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
     117                 :         10 :                         memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
     118                 :            :                         }
     119                 :            :                 else
     120                 :            :                         {
     121                 :            :                         aes_block_t tmp, tmp2;
     122                 :            :                         aes_block_t iv;
     123                 :            :                         aes_block_t iv2;
     124                 :            : 
     125                 :          1 :                         load_block(iv, ivec);
     126                 :          1 :                         load_block(iv2, ivec + AES_BLOCK_SIZE);
     127                 :            : 
     128         [ +  + ]:          3 :                         while (len)
     129                 :            :                                 {
     130                 :          2 :                                 load_block(tmp, in);
     131         [ +  + ]:          6 :                                 for(n=0 ; n < N_WORDS; ++n)
     132                 :          4 :                                         tmp2.data[n] = tmp.data[n] ^ iv.data[n];
     133                 :          2 :                                 AES_encrypt((unsigned char *)tmp2.data, (unsigned char *)tmp2.data, key);
     134         [ +  + ]:          6 :                                 for(n=0 ; n < N_WORDS; ++n)
     135                 :          4 :                                         tmp2.data[n] ^= iv2.data[n];
     136                 :          2 :                                 store_block(out, tmp2);
     137                 :          2 :                                 iv = tmp2;
     138                 :          2 :                                 iv2 = tmp;
     139                 :          2 :                                 --len;
     140                 :          2 :                                 in += AES_BLOCK_SIZE;
     141                 :          2 :                                 out += AES_BLOCK_SIZE;
     142                 :            :                                 }
     143                 :            :                         memcpy(ivec, iv.data, AES_BLOCK_SIZE);
     144                 :          1 :                         memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
     145                 :            :                         }
     146                 :            :                 }
     147                 :            :         else
     148                 :            :                 {
     149         [ +  + ]:         10 :                 if (in != out &&
     150                 :            :                     (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0))
     151                 :            :                         {
     152                 :          9 :                         aes_block_t *ivp = (aes_block_t *)ivec;
     153                 :          9 :                         aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
     154                 :            : 
     155         [ +  + ]:       2595 :                         while (len)
     156                 :            :                                 {
     157                 :            :                                 aes_block_t tmp;
     158                 :            :                                 aes_block_t *inp = (aes_block_t *)in;
     159                 :            :                                 aes_block_t *outp = (aes_block_t *)out;
     160                 :            : 
     161         [ +  + ]:       7758 :                                 for(n=0 ; n < N_WORDS; ++n)
     162                 :       5172 :                                         tmp.data[n] = inp->data[n] ^ iv2p->data[n];
     163                 :       2586 :                                 AES_decrypt((unsigned char *)tmp.data, (unsigned char *)outp->data, key);
     164         [ +  + ]:       7758 :                                 for(n=0 ; n < N_WORDS; ++n)
     165                 :       5172 :                                         outp->data[n] ^= ivp->data[n];
     166                 :       2586 :                                 ivp = inp;
     167                 :       2586 :                                 iv2p = outp;
     168                 :       2586 :                                 --len;
     169                 :       2586 :                                 in += AES_BLOCK_SIZE;
     170                 :       2586 :                                 out += AES_BLOCK_SIZE;
     171                 :            :                                 }
     172                 :          9 :                         memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
     173                 :          9 :                         memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
     174                 :            :                         }
     175                 :            :                 else
     176                 :            :                         {
     177                 :            :                         aes_block_t tmp, tmp2;
     178                 :            :                         aes_block_t iv;
     179                 :            :                         aes_block_t iv2;
     180                 :            : 
     181                 :          1 :                         load_block(iv, ivec);
     182                 :          1 :                         load_block(iv2, ivec + AES_BLOCK_SIZE);
     183                 :            : 
     184         [ +  + ]:          3 :                         while (len)
     185                 :            :                                 {
     186                 :          2 :                                 load_block(tmp, in);
     187                 :          2 :                                 tmp2 = tmp;
     188         [ +  + ]:          6 :                                 for(n=0 ; n < N_WORDS; ++n)
     189                 :          4 :                                         tmp.data[n] ^= iv2.data[n];
     190                 :          2 :                                 AES_decrypt((unsigned char *)tmp.data, (unsigned char *)tmp.data, key);
     191         [ +  + ]:          6 :                                 for(n=0 ; n < N_WORDS; ++n)
     192                 :          4 :                                         tmp.data[n] ^= iv.data[n];
     193                 :          2 :                                 store_block(out, tmp);
     194                 :          2 :                                 iv = tmp2;
     195                 :          2 :                                 iv2 = tmp;
     196                 :          2 :                                 --len;
     197                 :          2 :                                 in += AES_BLOCK_SIZE;
     198                 :          2 :                                 out += AES_BLOCK_SIZE;
     199                 :            :                                 }
     200                 :            :                         memcpy(ivec, iv.data, AES_BLOCK_SIZE);
     201                 :          1 :                         memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
     202                 :            :                         }
     203                 :            :                 }
     204                 :         21 :         }
     205                 :            : 
     206                 :            : /*
     207                 :            :  * Note that its effectively impossible to do biIGE in anything other
     208                 :            :  * than a single pass, so no provision is made for chaining.
     209                 :            :  */
     210                 :            : 
     211                 :            : /* N.B. The IV for this mode is _four times_ the block size */
     212                 :            : 
     213                 :          4 : void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
     214                 :            :                                                 size_t length, const AES_KEY *key,
     215                 :            :                                                 const AES_KEY *key2, const unsigned char *ivec,
     216                 :            :                                                 const int enc)
     217                 :            :         {
     218                 :            :         size_t n;
     219                 :          4 :         size_t len = length;
     220                 :            :         unsigned char tmp[AES_BLOCK_SIZE];
     221                 :            :         unsigned char tmp2[AES_BLOCK_SIZE];
     222                 :            :         unsigned char tmp3[AES_BLOCK_SIZE];
     223                 :            :         unsigned char prev[AES_BLOCK_SIZE];
     224                 :            :         const unsigned char *iv;
     225                 :            :         const unsigned char *iv2;
     226                 :            : 
     227 [ +  - ][ -  + ]:          4 :         OPENSSL_assert(in && out && key && ivec);
     228         [ -  + ]:          4 :         OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
     229         [ -  + ]:          4 :         OPENSSL_assert((length%AES_BLOCK_SIZE) == 0);
     230                 :            : 
     231         [ +  + ]:          4 :         if (AES_ENCRYPT == enc)
     232                 :            :                 {
     233                 :            :                 /* XXX: Do a separate case for when in != out (strictly should
     234                 :            :                    check for overlap, too) */
     235                 :            : 
     236                 :            :                 /* First the forward pass */ 
     237                 :          3 :                 iv = ivec;
     238                 :          3 :                 iv2 = ivec + AES_BLOCK_SIZE;
     239         [ +  + ]:         17 :                 while (len >= AES_BLOCK_SIZE)
     240                 :            :                         {
     241         [ +  + ]:        238 :                         for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
     242                 :        224 :                                 out[n] = in[n] ^ iv[n];
     243                 :         14 :                         AES_encrypt(out, out, key);
     244         [ +  + ]:        238 :                         for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
     245                 :        224 :                                 out[n] ^= iv2[n];
     246                 :         14 :                         iv = out;
     247                 :            :                         memcpy(prev, in, AES_BLOCK_SIZE);
     248                 :         14 :                         iv2 = prev;
     249                 :         14 :                         len -= AES_BLOCK_SIZE;
     250                 :         14 :                         in += AES_BLOCK_SIZE;
     251                 :         14 :                         out += AES_BLOCK_SIZE;
     252                 :            :                         }
     253                 :            : 
     254                 :            :                 /* And now backwards */
     255                 :          3 :                 iv = ivec + AES_BLOCK_SIZE*2;
     256                 :          3 :                 iv2 = ivec + AES_BLOCK_SIZE*3;
     257                 :          3 :                 len = length;
     258         [ +  + ]:         17 :                 while(len >= AES_BLOCK_SIZE)
     259                 :            :                         {
     260                 :         14 :                         out -= AES_BLOCK_SIZE;
     261                 :            :                         /* XXX: reduce copies by alternating between buffers */
     262                 :            :                         memcpy(tmp, out, AES_BLOCK_SIZE);
     263         [ +  + ]:        238 :                         for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
     264                 :        224 :                                 out[n] ^= iv[n];
     265                 :            :                         /*                      hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); */
     266                 :         14 :                         AES_encrypt(out, out, key);
     267                 :            :                         /*                      hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */
     268                 :            :                         /*                      hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */
     269         [ +  + ]:        238 :                         for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
     270                 :        224 :                                 out[n] ^= iv2[n];
     271                 :            :                         /*                      hexdump(stdout,"out", out, AES_BLOCK_SIZE); */
     272                 :         14 :                         iv = out;
     273                 :            :                         memcpy(prev, tmp, AES_BLOCK_SIZE);
     274                 :         14 :                         iv2 = prev;
     275                 :         14 :                         len -= AES_BLOCK_SIZE;
     276                 :            :                         }
     277                 :            :                 }
     278                 :            :         else
     279                 :            :                 {
     280                 :            :                 /* First backwards */
     281                 :          1 :                 iv = ivec + AES_BLOCK_SIZE*2;
     282                 :          1 :                 iv2 = ivec + AES_BLOCK_SIZE*3;
     283                 :          1 :                 in += length;
     284                 :          1 :                 out += length;
     285         [ +  + ]:          9 :                 while (len >= AES_BLOCK_SIZE)
     286                 :            :                         {
     287                 :          8 :                         in -= AES_BLOCK_SIZE;
     288                 :          8 :                         out -= AES_BLOCK_SIZE;
     289                 :            :                         memcpy(tmp, in, AES_BLOCK_SIZE);
     290                 :            :                         memcpy(tmp2, in, AES_BLOCK_SIZE);
     291         [ +  + ]:        136 :                         for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
     292                 :        128 :                                 tmp[n] ^= iv2[n];
     293                 :          8 :                         AES_decrypt(tmp, out, key);
     294         [ +  + ]:        136 :                         for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
     295                 :        128 :                                 out[n] ^= iv[n];
     296                 :            :                         memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
     297                 :          8 :                         iv = tmp3;
     298                 :          8 :                         iv2 = out;
     299                 :          8 :                         len -= AES_BLOCK_SIZE;
     300                 :            :                         }
     301                 :            : 
     302                 :            :                 /* And now forwards */
     303                 :          1 :                 iv = ivec;
     304                 :          1 :                 iv2 = ivec + AES_BLOCK_SIZE;
     305                 :          1 :                 len = length;
     306         [ +  + ]:          9 :                 while (len >= AES_BLOCK_SIZE)
     307                 :            :                         {
     308                 :            :                         memcpy(tmp, out, AES_BLOCK_SIZE);
     309                 :            :                         memcpy(tmp2, out, AES_BLOCK_SIZE);
     310         [ +  + ]:        136 :                         for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
     311                 :        128 :                                 tmp[n] ^= iv2[n];
     312                 :          8 :                         AES_decrypt(tmp, out, key);
     313         [ +  + ]:        136 :                         for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
     314                 :        128 :                                 out[n] ^= iv[n];
     315                 :            :                         memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
     316                 :          8 :                         iv = tmp3;
     317                 :          8 :                         iv2 = out;
     318                 :          8 :                         len -= AES_BLOCK_SIZE;
     319                 :          8 :                         in += AES_BLOCK_SIZE;
     320                 :          8 :                         out += AES_BLOCK_SIZE;
     321                 :            :                         }
     322                 :            :                 }
     323                 :          4 :         }

Generated by: LCOV version 1.9