LCOV - code coverage report
Current view: top level - modes - ccm128.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 99 227 43.6 %
Date: 2014-08-02 Functions: 6 10 60.0 %
Branches: 28 92 30.4 %

           Branch data     Line data    Source code
       1                 :            : /* ====================================================================
       2                 :            :  * Copyright (c) 2011 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                 :            : #include <openssl/crypto.h>
      51                 :            : #include "modes_lcl.h"
      52                 :            : #include <string.h>
      53                 :            : 
      54                 :            : #ifndef MODES_DEBUG
      55                 :            : # ifndef NDEBUG
      56                 :            : #  define NDEBUG
      57                 :            : # endif
      58                 :            : #endif
      59                 :            : #include <assert.h>
      60                 :            : 
      61                 :            : /* First you setup M and L parameters and pass the key schedule.
      62                 :            :  * This is called once per session setup... */
      63                 :          2 : void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
      64                 :            :         unsigned int M,unsigned int L,void *key,block128_f block)
      65                 :            : {
      66                 :          2 :         memset(ctx->nonce.c,0,sizeof(ctx->nonce.c));
      67                 :          2 :         ctx->nonce.c[0] = ((u8)(L-1)&7) | (u8)(((M-2)/2)&7)<<3;
      68                 :          2 :         ctx->blocks = 0;
      69                 :          2 :         ctx->block = block;
      70                 :          2 :         ctx->key = key;
      71                 :          2 : }
      72                 :            : 
      73                 :            : /* !!! Following interfaces are to be called *once* per packet !!! */
      74                 :            : 
      75                 :            : /* Then you setup per-message nonce and pass the length of the message */
      76                 :          2 : int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
      77                 :            :         const unsigned char *nonce,size_t nlen,size_t mlen)
      78                 :            : {
      79                 :          2 :         unsigned int L = ctx->nonce.c[0]&7;      /* the L parameter */
      80                 :            : 
      81         [ +  - ]:          2 :         if (nlen<(14-L)) return -1;          /* nonce is too short */
      82                 :            : 
      83         [ -  + ]:          2 :         if (sizeof(mlen)==8 && L>=3) {
      84                 :          0 :                 ctx->nonce.c[8]  = (u8)(mlen>>(56%(sizeof(mlen)*8)));
      85                 :          0 :                 ctx->nonce.c[9]  = (u8)(mlen>>(48%(sizeof(mlen)*8)));
      86                 :          0 :                 ctx->nonce.c[10] = (u8)(mlen>>(40%(sizeof(mlen)*8)));
      87                 :          0 :                 ctx->nonce.c[11] = (u8)(mlen>>(32%(sizeof(mlen)*8)));
      88                 :            :         }
      89                 :            :         else
      90                 :          2 :                 ctx->nonce.u[1] = 0;
      91                 :            : 
      92                 :          2 :         ctx->nonce.c[12] = (u8)(mlen>>24);
      93                 :          2 :         ctx->nonce.c[13] = (u8)(mlen>>16);
      94                 :          2 :         ctx->nonce.c[14] = (u8)(mlen>>8);
      95                 :          2 :         ctx->nonce.c[15] = (u8)mlen;
      96                 :            : 
      97                 :          2 :         ctx->nonce.c[0] &= ~0x40;        /* clear Adata flag */
      98                 :          2 :         memcpy(&ctx->nonce.c[1],nonce,14-L);
      99                 :            : 
     100                 :          2 :         return 0;
     101                 :            : }
     102                 :            : 
     103                 :            : /* Then you pass additional authentication data, this is optional */
     104                 :          2 : void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
     105                 :            :         const unsigned char *aad,size_t alen)
     106                 :            : {       unsigned int i;
     107                 :          2 :         block128_f block = ctx->block;
     108                 :            : 
     109         [ +  - ]:          2 :         if (alen==0) return;
     110                 :            : 
     111                 :          2 :         ctx->nonce.c[0] |= 0x40;     /* set Adata flag */
     112                 :          2 :         (*block)(ctx->nonce.c,ctx->cmac.c,ctx->key),
     113                 :          2 :         ctx->blocks++;
     114                 :            : 
     115         [ +  - ]:          2 :         if (alen<(0x10000-0x100)) {
     116                 :          2 :                 ctx->cmac.c[0] ^= (u8)(alen>>8);
     117                 :          2 :                 ctx->cmac.c[1] ^= (u8)alen;
     118                 :          2 :                 i=2;
     119                 :            :         }
     120         [ #  # ]:          0 :         else if (sizeof(alen)==8 && alen>=(size_t)1<<(32%(sizeof(alen)*8))) {
     121                 :          0 :                 ctx->cmac.c[0] ^= 0xFF;
     122                 :          0 :                 ctx->cmac.c[1] ^= 0xFF;
     123                 :          0 :                 ctx->cmac.c[2] ^= (u8)(alen>>(56%(sizeof(alen)*8)));
     124                 :          0 :                 ctx->cmac.c[3] ^= (u8)(alen>>(48%(sizeof(alen)*8)));
     125                 :          0 :                 ctx->cmac.c[4] ^= (u8)(alen>>(40%(sizeof(alen)*8)));
     126                 :          0 :                 ctx->cmac.c[5] ^= (u8)(alen>>(32%(sizeof(alen)*8)));
     127                 :          0 :                 ctx->cmac.c[6] ^= (u8)(alen>>24);
     128                 :          0 :                 ctx->cmac.c[7] ^= (u8)(alen>>16);
     129                 :          0 :                 ctx->cmac.c[8] ^= (u8)(alen>>8);
     130                 :          0 :                 ctx->cmac.c[9] ^= (u8)alen;
     131                 :          0 :                 i=10;
     132                 :            :         }
     133                 :            :         else {
     134                 :          0 :                 ctx->cmac.c[0] ^= 0xFF;
     135                 :          0 :                 ctx->cmac.c[1] ^= 0xFE;
     136                 :          0 :                 ctx->cmac.c[2] ^= (u8)(alen>>24);
     137                 :          0 :                 ctx->cmac.c[3] ^= (u8)(alen>>16);
     138                 :          0 :                 ctx->cmac.c[4] ^= (u8)(alen>>8);
     139                 :          0 :                 ctx->cmac.c[5] ^= (u8)alen;
     140                 :          0 :                 i=6;
     141                 :            :         }
     142                 :            : 
     143                 :            :         do {
     144         [ +  + ]:         70 :                 for(;i<16 && alen;++i,++aad,--alen)
     145                 :         64 :                         ctx->cmac.c[i] ^= *aad;
     146                 :          6 :                 (*block)(ctx->cmac.c,ctx->cmac.c,ctx->key),
     147                 :          6 :                 ctx->blocks++;
     148                 :          6 :                 i=0;
     149         [ +  + ]:          6 :         } while (alen);
     150                 :            : }
     151                 :            : 
     152                 :            : /* Finally you encrypt or decrypt the message */
     153                 :            : 
     154                 :            : /* counter part of nonce may not be larger than L*8 bits,
     155                 :            :  * L is not larger than 8, therefore 64-bit counter... */
     156                 :          0 : static void ctr64_inc(unsigned char *counter) {
     157                 :          0 :         unsigned int n=8;
     158                 :            :         u8  c;
     159                 :            : 
     160                 :          0 :         counter += 8;
     161                 :            :         do {
     162                 :          0 :                 --n;
     163                 :          0 :                 c = counter[n];
     164                 :          0 :                 ++c;
     165                 :          0 :                 counter[n] = c;
     166         [ #  # ]:          0 :                 if (c) return;
     167         [ #  # ]:          0 :         } while (n);
     168                 :            : }
     169                 :            : 
     170                 :          0 : int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
     171                 :            :         const unsigned char *inp, unsigned char *out,
     172                 :            :         size_t len)
     173                 :            : {
     174                 :            :         size_t          n;
     175                 :            :         unsigned int    i,L;
     176                 :          0 :         unsigned char   flags0  = ctx->nonce.c[0];
     177                 :          0 :         block128_f      block   = ctx->block;
     178                 :          0 :         void *          key     = ctx->key;
     179                 :            :         union { u64 u[2]; u8 c[16]; } scratch;
     180                 :            : 
     181         [ #  # ]:          0 :         if (!(flags0&0x40))
     182                 :          0 :                 (*block)(ctx->nonce.c,ctx->cmac.c,key),
     183                 :          0 :                 ctx->blocks++;
     184                 :            : 
     185                 :          0 :         ctx->nonce.c[0] = L = flags0&7;
     186         [ #  # ]:          0 :         for (n=0,i=15-L;i<15;++i) {
     187                 :          0 :                 n |= ctx->nonce.c[i];
     188                 :          0 :                 ctx->nonce.c[i]=0;
     189                 :          0 :                 n <<= 8;
     190                 :            :         }
     191                 :          0 :         n |= ctx->nonce.c[15];       /* reconstructed length */
     192                 :          0 :         ctx->nonce.c[15]=1;
     193                 :            : 
     194         [ #  # ]:          0 :         if (n!=len) return -1;  /* length mismatch */
     195                 :            : 
     196                 :          0 :         ctx->blocks += ((len+15)>>3)|1;
     197         [ #  # ]:          0 :         if (ctx->blocks > (U64(1)<<61))     return -2; /* too much data */
     198                 :            : 
     199         [ #  # ]:          0 :         while (len>=16) {
     200                 :            : #if defined(STRICT_ALIGNMENT)
     201                 :            :                 union { u64 u[2]; u8 c[16]; } temp;
     202                 :            : 
     203                 :            :                 memcpy (temp.c,inp,16);
     204                 :            :                 ctx->cmac.u[0] ^= temp.u[0];
     205                 :            :                 ctx->cmac.u[1] ^= temp.u[1];
     206                 :            : #else
     207                 :          0 :                 ctx->cmac.u[0] ^= ((u64*)inp)[0];
     208                 :          0 :                 ctx->cmac.u[1] ^= ((u64*)inp)[1];
     209                 :            : #endif
     210                 :          0 :                 (*block)(ctx->cmac.c,ctx->cmac.c,key);
     211                 :          0 :                 (*block)(ctx->nonce.c,scratch.c,key);
     212                 :          0 :                 ctr64_inc(ctx->nonce.c);
     213                 :            : #if defined(STRICT_ALIGNMENT)
     214                 :            :                 temp.u[0] ^= scratch.u[0];
     215                 :            :                 temp.u[1] ^= scratch.u[1];
     216                 :            :                 memcpy(out,temp.c,16);
     217                 :            : #else
     218                 :          0 :                 ((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0];
     219                 :          0 :                 ((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1];
     220                 :            : #endif
     221                 :          0 :                 inp += 16;
     222                 :          0 :                 out += 16;
     223                 :          0 :                 len -= 16;
     224                 :            :         }
     225                 :            : 
     226         [ #  # ]:          0 :         if (len) {
     227         [ #  # ]:          0 :                 for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i];
     228                 :          0 :                 (*block)(ctx->cmac.c,ctx->cmac.c,key);
     229                 :          0 :                 (*block)(ctx->nonce.c,scratch.c,key);
     230         [ #  # ]:          0 :                 for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i];
     231                 :            :         }
     232                 :            : 
     233         [ #  # ]:          0 :         for (i=15-L;i<16;++i)
     234                 :          0 :                 ctx->nonce.c[i]=0;
     235                 :            : 
     236                 :          0 :         (*block)(ctx->nonce.c,scratch.c,key);
     237                 :          0 :         ctx->cmac.u[0] ^= scratch.u[0];
     238                 :          0 :         ctx->cmac.u[1] ^= scratch.u[1];
     239                 :            : 
     240                 :          0 :         ctx->nonce.c[0] = flags0;
     241                 :            : 
     242                 :          0 :         return 0;
     243                 :            : }
     244                 :            : 
     245                 :          0 : int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
     246                 :            :         const unsigned char *inp, unsigned char *out,
     247                 :            :         size_t len)
     248                 :            : {
     249                 :            :         size_t          n;
     250                 :            :         unsigned int    i,L;
     251                 :          0 :         unsigned char   flags0  = ctx->nonce.c[0];
     252                 :          0 :         block128_f      block   = ctx->block;
     253                 :          0 :         void *          key     = ctx->key;
     254                 :            :         union { u64 u[2]; u8 c[16]; } scratch;
     255                 :            : 
     256         [ #  # ]:          0 :         if (!(flags0&0x40))
     257                 :          0 :                 (*block)(ctx->nonce.c,ctx->cmac.c,key);
     258                 :            : 
     259                 :          0 :         ctx->nonce.c[0] = L = flags0&7;
     260         [ #  # ]:          0 :         for (n=0,i=15-L;i<15;++i) {
     261                 :          0 :                 n |= ctx->nonce.c[i];
     262                 :          0 :                 ctx->nonce.c[i]=0;
     263                 :          0 :                 n <<= 8;
     264                 :            :         }
     265                 :          0 :         n |= ctx->nonce.c[15];       /* reconstructed length */
     266                 :          0 :         ctx->nonce.c[15]=1;
     267                 :            : 
     268         [ #  # ]:          0 :         if (n!=len) return -1;
     269                 :            : 
     270         [ #  # ]:          0 :         while (len>=16) {
     271                 :            : #if defined(STRICT_ALIGNMENT)
     272                 :            :                 union { u64 u[2]; u8 c[16]; } temp;
     273                 :            : #endif
     274                 :          0 :                 (*block)(ctx->nonce.c,scratch.c,key);
     275                 :          0 :                 ctr64_inc(ctx->nonce.c);
     276                 :            : #if defined(STRICT_ALIGNMENT)
     277                 :            :                 memcpy (temp.c,inp,16);
     278                 :            :                 ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]);
     279                 :            :                 ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]);
     280                 :            :                 memcpy (out,scratch.c,16);
     281                 :            : #else
     282                 :          0 :                 ctx->cmac.u[0] ^= (((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0]);
     283                 :          0 :                 ctx->cmac.u[1] ^= (((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1]);
     284                 :            : #endif
     285                 :          0 :                 (*block)(ctx->cmac.c,ctx->cmac.c,key);
     286                 :            : 
     287                 :          0 :                 inp += 16;
     288                 :          0 :                 out += 16;
     289                 :          0 :                 len -= 16;
     290                 :            :         }
     291                 :            : 
     292         [ #  # ]:          0 :         if (len) {
     293                 :          0 :                 (*block)(ctx->nonce.c,scratch.c,key);
     294         [ #  # ]:          0 :                 for (i=0; i<len; ++i)
     295                 :          0 :                         ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]);
     296                 :          0 :                 (*block)(ctx->cmac.c,ctx->cmac.c,key);
     297                 :            :         }
     298                 :            : 
     299         [ #  # ]:          0 :         for (i=15-L;i<16;++i)
     300                 :          0 :                 ctx->nonce.c[i]=0;
     301                 :            : 
     302                 :          0 :         (*block)(ctx->nonce.c,scratch.c,key);
     303                 :          0 :         ctx->cmac.u[0] ^= scratch.u[0];
     304                 :          0 :         ctx->cmac.u[1] ^= scratch.u[1];
     305                 :            : 
     306                 :          0 :         ctx->nonce.c[0] = flags0;
     307                 :            : 
     308                 :          0 :         return 0;
     309                 :            : }
     310                 :            : 
     311                 :          0 : static void ctr64_add (unsigned char *counter,size_t inc)
     312                 :          0 : {       size_t n=8, val=0;
     313                 :            : 
     314                 :          0 :         counter += 8;
     315                 :            :         do {
     316                 :          0 :                 --n;
     317                 :          0 :                 val += counter[n] + (inc&0xff);
     318                 :          0 :                 counter[n] = (unsigned char)val;
     319                 :          0 :                 val >>= 8;        /* carry bit */
     320                 :          0 :                 inc >>= 8;
     321 [ #  # ][ #  # ]:          0 :         } while(n && (inc || val));
     322                 :          0 : }
     323                 :            : 
     324                 :          1 : int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
     325                 :            :         const unsigned char *inp, unsigned char *out,
     326                 :            :         size_t len,ccm128_f stream)
     327                 :            : {
     328                 :            :         size_t          n;
     329                 :            :         unsigned int    i,L;
     330                 :          1 :         unsigned char   flags0  = ctx->nonce.c[0];
     331                 :          1 :         block128_f      block   = ctx->block;
     332                 :          1 :         void *          key     = ctx->key;
     333                 :            :         union { u64 u[2]; u8 c[16]; } scratch;
     334                 :            : 
     335         [ -  + ]:          1 :         if (!(flags0&0x40))
     336                 :          0 :                 (*block)(ctx->nonce.c,ctx->cmac.c,key),
     337                 :          0 :                 ctx->blocks++;
     338                 :            : 
     339                 :          1 :         ctx->nonce.c[0] = L = flags0&7;
     340         [ +  + ]:          2 :         for (n=0,i=15-L;i<15;++i) {
     341                 :          1 :                 n |= ctx->nonce.c[i];
     342                 :          1 :                 ctx->nonce.c[i]=0;
     343                 :          1 :                 n <<= 8;
     344                 :            :         }
     345                 :          1 :         n |= ctx->nonce.c[15];       /* reconstructed length */
     346                 :          1 :         ctx->nonce.c[15]=1;
     347                 :            : 
     348         [ +  - ]:          1 :         if (n!=len) return -1;  /* length mismatch */
     349                 :            : 
     350                 :          1 :         ctx->blocks += ((len+15)>>3)|1;
     351         [ +  - ]:          1 :         if (ctx->blocks > (U64(1)<<61))     return -2; /* too much data */
     352                 :            : 
     353         [ +  - ]:          1 :         if ((n=len/16)) {
     354                 :          1 :                 (*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c);
     355                 :          1 :                 n   *= 16;
     356                 :          1 :                 inp += n;
     357                 :          1 :                 out += n;
     358                 :          1 :                 len -= n;
     359         [ -  + ]:          1 :                 if (len) ctr64_add(ctx->nonce.c,n/16);
     360                 :            :         }
     361                 :            : 
     362         [ -  + ]:          1 :         if (len) {
     363         [ #  # ]:          0 :                 for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i];
     364                 :          0 :                 (*block)(ctx->cmac.c,ctx->cmac.c,key);
     365                 :          0 :                 (*block)(ctx->nonce.c,scratch.c,key);
     366         [ #  # ]:          0 :                 for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i];
     367                 :            :         }
     368                 :            : 
     369         [ +  + ]:          3 :         for (i=15-L;i<16;++i)
     370                 :          2 :                 ctx->nonce.c[i]=0;
     371                 :            : 
     372                 :          1 :         (*block)(ctx->nonce.c,scratch.c,key);
     373                 :          1 :         ctx->cmac.u[0] ^= scratch.u[0];
     374                 :          1 :         ctx->cmac.u[1] ^= scratch.u[1];
     375                 :            : 
     376                 :          1 :         ctx->nonce.c[0] = flags0;
     377                 :            : 
     378                 :          1 :         return 0;
     379                 :            : }
     380                 :            : 
     381                 :          1 : int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
     382                 :            :         const unsigned char *inp, unsigned char *out,
     383                 :            :         size_t len,ccm128_f stream)
     384                 :            : {
     385                 :            :         size_t          n;
     386                 :            :         unsigned int    i,L;
     387                 :          1 :         unsigned char   flags0  = ctx->nonce.c[0];
     388                 :          1 :         block128_f      block   = ctx->block;
     389                 :          1 :         void *          key     = ctx->key;
     390                 :            :         union { u64 u[2]; u8 c[16]; } scratch;
     391                 :            : 
     392         [ -  + ]:          1 :         if (!(flags0&0x40))
     393                 :          0 :                 (*block)(ctx->nonce.c,ctx->cmac.c,key);
     394                 :            : 
     395                 :          1 :         ctx->nonce.c[0] = L = flags0&7;
     396         [ +  + ]:          2 :         for (n=0,i=15-L;i<15;++i) {
     397                 :          1 :                 n |= ctx->nonce.c[i];
     398                 :          1 :                 ctx->nonce.c[i]=0;
     399                 :          1 :                 n <<= 8;
     400                 :            :         }
     401                 :          1 :         n |= ctx->nonce.c[15];       /* reconstructed length */
     402                 :          1 :         ctx->nonce.c[15]=1;
     403                 :            : 
     404         [ +  - ]:          1 :         if (n!=len) return -1;
     405                 :            : 
     406         [ +  - ]:          1 :         if ((n=len/16)) {
     407                 :          1 :                 (*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c);
     408                 :          1 :                 n   *= 16;
     409                 :          1 :                 inp += n;
     410                 :          1 :                 out += n;
     411                 :          1 :                 len -= n;
     412         [ -  + ]:          1 :                 if (len) ctr64_add(ctx->nonce.c,n/16);
     413                 :            :         }
     414                 :            : 
     415         [ -  + ]:          1 :         if (len) {
     416                 :          0 :                 (*block)(ctx->nonce.c,scratch.c,key);
     417         [ #  # ]:          0 :                 for (i=0; i<len; ++i)
     418                 :          0 :                         ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]);
     419                 :          0 :                 (*block)(ctx->cmac.c,ctx->cmac.c,key);
     420                 :            :         }
     421                 :            : 
     422         [ +  + ]:          3 :         for (i=15-L;i<16;++i)
     423                 :          2 :                 ctx->nonce.c[i]=0;
     424                 :            : 
     425                 :          1 :         (*block)(ctx->nonce.c,scratch.c,key);
     426                 :          1 :         ctx->cmac.u[0] ^= scratch.u[0];
     427                 :          1 :         ctx->cmac.u[1] ^= scratch.u[1];
     428                 :            : 
     429                 :          1 :         ctx->nonce.c[0] = flags0;
     430                 :            : 
     431                 :          1 :         return 0;
     432                 :            : }
     433                 :            : 
     434                 :          2 : size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx,unsigned char *tag,size_t len)
     435                 :          2 : {       unsigned int M = (ctx->nonce.c[0]>>3)&7;   /* the M parameter */
     436                 :            : 
     437                 :          2 :         M *= 2; M += 2;
     438         [ +  - ]:          2 :         if (len<M)   return 0;
     439                 :          2 :         memcpy(tag,ctx->cmac.c,M);
     440                 :          2 :         return M;
     441                 :            : }

Generated by: LCOV version 1.9