LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/modes - ctr128.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 63 0.0 %
Date: 2015-10-10 Functions: 0 2 0.0 %

          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             : /*
      63             :  * NOTE: the IV/counter CTR mode is big-endian.  The code itself is
      64             :  * endian-neutral.
      65             :  */
      66             : 
      67             : /* increment counter (128-bit int) by 1 */
      68             : static void ctr128_inc(unsigned char *counter)
      69             : {
      70             :     u32 n = 16;
      71             :     u8 c;
      72             : 
      73             :     do {
      74           0 :         --n;
      75           0 :         c = counter[n];
      76           0 :         ++c;
      77           0 :         counter[n] = c;
      78           0 :         if (c)
      79             :             return;
      80           0 :     } while (n);
      81             : }
      82             : 
      83             : #if !defined(OPENSSL_SMALL_FOOTPRINT)
      84             : static void ctr128_inc_aligned(unsigned char *counter)
      85             : {
      86             :     size_t *data, c, n;
      87             :     const union {
      88             :         long one;
      89             :         char little;
      90             :     } is_endian = {
      91             :         1
      92             :     };
      93             : 
      94             :     if (is_endian.little) {
      95             :         ctr128_inc(counter);
      96             :         return;
      97             :     }
      98             : 
      99             :     data = (size_t *)counter;
     100             :     n = 16 / sizeof(size_t);
     101             :     do {
     102             :         --n;
     103             :         c = data[n];
     104             :         ++c;
     105             :         data[n] = c;
     106             :         if (c)
     107             :             return;
     108             :     } while (n);
     109             : }
     110             : #endif
     111             : 
     112             : /*
     113             :  * The input encrypted as though 128bit counter mode is being used.  The
     114             :  * extra state information to record how much of the 128bit block we have
     115             :  * used is contained in *num, and the encrypted counter is kept in
     116             :  * ecount_buf.  Both *num and ecount_buf must be initialised with zeros
     117             :  * before the first call to CRYPTO_ctr128_encrypt(). This algorithm assumes
     118             :  * that the counter is in the x lower bits of the IV (ivec), and that the
     119             :  * application has full control over overflow and the rest of the IV.  This
     120             :  * implementation takes NO responsability for checking that the counter
     121             :  * doesn't overflow into the rest of the IV when incremented.
     122             :  */
     123           0 : void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
     124             :                            size_t len, const void *key,
     125             :                            unsigned char ivec[16],
     126             :                            unsigned char ecount_buf[16], unsigned int *num,
     127             :                            block128_f block)
     128             : {
     129             :     unsigned int n;
     130             :     size_t l = 0;
     131             : 
     132             :     assert(in && out && key && ecount_buf && num);
     133             :     assert(*num < 16);
     134             : 
     135           0 :     n = *num;
     136             : 
     137             : #if !defined(OPENSSL_SMALL_FOOTPRINT)
     138             :     if (16 % sizeof(size_t) == 0) { /* always true actually */
     139             :         do {
     140           0 :             while (n && len) {
     141           0 :                 *(out++) = *(in++) ^ ecount_buf[n];
     142           0 :                 --len;
     143           0 :                 n = (n + 1) % 16;
     144             :             }
     145             : 
     146             : # if defined(STRICT_ALIGNMENT)
     147             :             if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) !=
     148             :                 0)
     149             :                 break;
     150             : # endif
     151           0 :             while (len >= 16) {
     152           0 :                 (*block) (ivec, ecount_buf, key);
     153             :                 ctr128_inc_aligned(ivec);
     154           0 :                 for (; n < 16; n += sizeof(size_t))
     155           0 :                     *(size_t *)(out + n) =
     156           0 :                         *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n);
     157           0 :                 len -= 16;
     158           0 :                 out += 16;
     159           0 :                 in += 16;
     160             :                 n = 0;
     161             :             }
     162           0 :             if (len) {
     163           0 :                 (*block) (ivec, ecount_buf, key);
     164             :                 ctr128_inc_aligned(ivec);
     165           0 :                 while (len--) {
     166           0 :                     out[n] = in[n] ^ ecount_buf[n];
     167           0 :                     ++n;
     168             :                 }
     169             :             }
     170           0 :             *num = n;
     171           0 :             return;
     172             :         } while (0);
     173             :     }
     174             :     /* the rest would be commonly eliminated by x86* compiler */
     175             : #endif
     176             :     while (l < len) {
     177             :         if (n == 0) {
     178             :             (*block) (ivec, ecount_buf, key);
     179             :             ctr128_inc(ivec);
     180             :         }
     181             :         out[l] = in[l] ^ ecount_buf[n];
     182             :         ++l;
     183             :         n = (n + 1) % 16;
     184             :     }
     185             : 
     186             :     *num = n;
     187             : }
     188             : 
     189             : /* increment upper 96 bits of 128-bit counter by 1 */
     190             : static void ctr96_inc(unsigned char *counter)
     191             : {
     192             :     u32 n = 12;
     193             :     u8 c;
     194             : 
     195             :     do {
     196           0 :         --n;
     197           0 :         c = counter[n];
     198           0 :         ++c;
     199           0 :         counter[n] = c;
     200           0 :         if (c)
     201             :             return;
     202           0 :     } while (n);
     203             : }
     204             : 
     205           0 : void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
     206             :                                  size_t len, const void *key,
     207             :                                  unsigned char ivec[16],
     208             :                                  unsigned char ecount_buf[16],
     209             :                                  unsigned int *num, ctr128_f func)
     210             : {
     211             :     unsigned int n, ctr32;
     212             : 
     213             :     assert(in && out && key && ecount_buf && num);
     214             :     assert(*num < 16);
     215             : 
     216           0 :     n = *num;
     217             : 
     218           0 :     while (n && len) {
     219           0 :         *(out++) = *(in++) ^ ecount_buf[n];
     220           0 :         --len;
     221           0 :         n = (n + 1) % 16;
     222             :     }
     223             : 
     224           0 :     ctr32 = GETU32(ivec + 12);
     225           0 :     while (len >= 16) {
     226           0 :         size_t blocks = len / 16;
     227             :         /*
     228             :          * 1<<28 is just a not-so-small yet not-so-large number...
     229             :          * Below condition is practically never met, but it has to
     230             :          * be checked for code correctness.
     231             :          */
     232           0 :         if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28))
     233             :             blocks = (1U << 28);
     234             :         /*
     235             :          * As (*func) operates on 32-bit counter, caller
     236             :          * has to handle overflow. 'if' below detects the
     237             :          * overflow, which is then handled by limiting the
     238             :          * amount of blocks to the exact overflow point...
     239             :          */
     240           0 :         ctr32 += (u32)blocks;
     241           0 :         if (ctr32 < blocks) {
     242           0 :             blocks -= ctr32;
     243             :             ctr32 = 0;
     244             :         }
     245           0 :         (*func) (in, out, blocks, key, ivec);
     246             :         /* (*ctr) does not update ivec, caller does: */
     247           0 :         PUTU32(ivec + 12, ctr32);
     248             :         /* ... overflow was detected, propogate carry. */
     249           0 :         if (ctr32 == 0)
     250             :             ctr96_inc(ivec);
     251           0 :         blocks *= 16;
     252           0 :         len -= blocks;
     253           0 :         out += blocks;
     254           0 :         in += blocks;
     255             :     }
     256           0 :     if (len) {
     257             :         memset(ecount_buf, 0, 16);
     258           0 :         (*func) (ecount_buf, ecount_buf, 1, key, ivec);
     259           0 :         ++ctr32;
     260           0 :         PUTU32(ivec + 12, ctr32);
     261           0 :         if (ctr32 == 0)
     262             :             ctr96_inc(ivec);
     263           0 :         while (len--) {
     264           0 :             out[n] = in[n] ^ ecount_buf[n];
     265           0 :             ++n;
     266             :         }
     267             :     }
     268             : 
     269           0 :     *num = n;
     270           0 : }

Generated by: LCOV version 1.10