LCOV - code coverage report
Current view: top level - evp - e_des3.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 103 147 70.1 %
Date: 2014-08-02 Functions: 21 25 84.0 %
Branches: 26 52 50.0 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/evp/e_des3.c */
       2                 :            : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       3                 :            :  * All rights reserved.
       4                 :            :  *
       5                 :            :  * This package is an SSL implementation written
       6                 :            :  * by Eric Young (eay@cryptsoft.com).
       7                 :            :  * The implementation was written so as to conform with Netscapes SSL.
       8                 :            :  * 
       9                 :            :  * This library is free for commercial and non-commercial use as long as
      10                 :            :  * the following conditions are aheared to.  The following conditions
      11                 :            :  * apply to all code found in this distribution, be it the RC4, RSA,
      12                 :            :  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
      13                 :            :  * included with this distribution is covered by the same copyright terms
      14                 :            :  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
      15                 :            :  * 
      16                 :            :  * Copyright remains Eric Young's, and as such any Copyright notices in
      17                 :            :  * the code are not to be removed.
      18                 :            :  * If this package is used in a product, Eric Young should be given attribution
      19                 :            :  * as the author of the parts of the library used.
      20                 :            :  * This can be in the form of a textual message at program startup or
      21                 :            :  * in documentation (online or textual) provided with the package.
      22                 :            :  * 
      23                 :            :  * Redistribution and use in source and binary forms, with or without
      24                 :            :  * modification, are permitted provided that the following conditions
      25                 :            :  * are met:
      26                 :            :  * 1. Redistributions of source code must retain the copyright
      27                 :            :  *    notice, this list of conditions and the following disclaimer.
      28                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      29                 :            :  *    notice, this list of conditions and the following disclaimer in the
      30                 :            :  *    documentation and/or other materials provided with the distribution.
      31                 :            :  * 3. All advertising materials mentioning features or use of this software
      32                 :            :  *    must display the following acknowledgement:
      33                 :            :  *    "This product includes cryptographic software written by
      34                 :            :  *     Eric Young (eay@cryptsoft.com)"
      35                 :            :  *    The word 'cryptographic' can be left out if the rouines from the library
      36                 :            :  *    being used are not cryptographic related :-).
      37                 :            :  * 4. If you include any Windows specific code (or a derivative thereof) from 
      38                 :            :  *    the apps directory (application code) you must include an acknowledgement:
      39                 :            :  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
      40                 :            :  * 
      41                 :            :  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
      42                 :            :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      43                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      44                 :            :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      45                 :            :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      46                 :            :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      47                 :            :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      49                 :            :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      50                 :            :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      51                 :            :  * SUCH DAMAGE.
      52                 :            :  * 
      53                 :            :  * The licence and distribution terms for any publically available version or
      54                 :            :  * derivative of this code cannot be changed.  i.e. this code cannot simply be
      55                 :            :  * copied and put under another distribution licence
      56                 :            :  * [including the GNU Public Licence.]
      57                 :            :  */
      58                 :            : 
      59                 :            : #define OPENSSL_FIPSAPI
      60                 :            : 
      61                 :            : #include <stdio.h>
      62                 :            : #include "cryptlib.h"
      63                 :            : #ifndef OPENSSL_NO_DES
      64                 :            : #include <openssl/evp.h>
      65                 :            : #include <openssl/objects.h>
      66                 :            : #include "evp_locl.h"
      67                 :            : #include <openssl/des.h>
      68                 :            : #include <openssl/rand.h>
      69                 :            : 
      70                 :            : typedef struct
      71                 :            :         {
      72                 :            :         union { double align; DES_key_schedule ks[3]; } ks;
      73                 :            :         union {
      74                 :            :                 void (*cbc)(const void *,void *,size_t,const void *,void *);
      75                 :            :         } stream;
      76                 :            :         } DES_EDE_KEY;
      77                 :            : #define ks1 ks.ks[0]
      78                 :            : #define ks2 ks.ks[1]
      79                 :            : #define ks3 ks.ks[2]
      80                 :            : 
      81                 :            : #if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
      82                 :            : /* ---------^^^ this is not a typo, just a way to detect that
      83                 :            :  * assembler support was in general requested... */
      84                 :            : #include "sparc_arch.h"
      85                 :            : 
      86                 :            : extern unsigned int OPENSSL_sparcv9cap_P[];
      87                 :            : 
      88                 :            : #define SPARC_DES_CAPABLE       (OPENSSL_sparcv9cap_P[1] & CFR_DES)
      89                 :            : 
      90                 :            : void    des_t4_key_expand(const void *key, DES_key_schedule *ks);
      91                 :            : void    des_t4_ede3_cbc_encrypt(const void *inp,void *out,size_t len,
      92                 :            :                                 DES_key_schedule *ks,unsigned char iv[8]);
      93                 :            : void    des_t4_ede3_cbc_decrypt(const void *inp,void *out,size_t len,
      94                 :            :                                 DES_key_schedule *ks,unsigned char iv[8]);
      95                 :            : #endif
      96                 :            : 
      97                 :            : static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
      98                 :            :                             const unsigned char *iv,int enc);
      99                 :            : 
     100                 :            : static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
     101                 :            :                              const unsigned char *iv,int enc);
     102                 :            : 
     103                 :            : static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
     104                 :            : 
     105                 :            : #define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data)
     106                 :            : 
     107                 :            : /* Because of various casts and different args can't use IMPLEMENT_BLOCK_CIPHER */
     108                 :            : 
     109                 :        120 : static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     110                 :            :                               const unsigned char *in, size_t inl)
     111                 :            : {
     112 [ +  - ][ +  + ]:       1144 :         BLOCK_CIPHER_ecb_loop()
     113                 :       1024 :                 DES_ecb3_encrypt((const_DES_cblock *)(in + i),
     114                 :            :                                  (DES_cblock *)(out + i),
     115                 :            :                                  &data(ctx)->ks1, &data(ctx)->ks2,
     116                 :       1024 :                                  &data(ctx)->ks3,
     117                 :            :                                  ctx->encrypt);
     118                 :            :         return 1;
     119                 :            : }
     120                 :            : 
     121                 :         64 : static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     122                 :            :                               const unsigned char *in, size_t inl)
     123                 :            : {
     124         [ -  + ]:         64 :         while (inl>=EVP_MAXCHUNK)
     125                 :            :                 {
     126                 :          0 :                 DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
     127                 :          0 :                                &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
     128                 :          0 :                                (DES_cblock *)ctx->iv, &ctx->num);
     129                 :          0 :                 inl-=EVP_MAXCHUNK;
     130                 :          0 :                 in +=EVP_MAXCHUNK;
     131                 :          0 :                 out+=EVP_MAXCHUNK;
     132                 :            :                 }
     133         [ +  - ]:         64 :         if (inl)
     134                 :         64 :                 DES_ede3_ofb64_encrypt(in, out, (long)inl,
     135                 :         64 :                                 &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
     136                 :         64 :                                (DES_cblock *)ctx->iv, &ctx->num);
     137                 :            : 
     138                 :         64 :         return 1;
     139                 :            : }
     140                 :            : 
     141                 :        385 : static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     142                 :            :                               const unsigned char *in, size_t inl)
     143                 :            : {
     144                 :        385 :         DES_EDE_KEY *dat = data(ctx);
     145                 :            : 
     146                 :            : #ifdef KSSL_DEBUG
     147                 :            :         {
     148                 :            :         int i;
     149                 :            :         char *cp;
     150                 :            :         printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", ctx, ctx->buf_len);
     151                 :            :         printf("\t iv= ");
     152                 :            :         for(i=0;i<8;i++)
     153                 :            :                 printf("%02X",ctx->iv[i]);
     154                 :            :         printf("\n");
     155                 :            :         }
     156                 :            : #endif    /* KSSL_DEBUG */
     157         [ +  - ]:        385 :         if (dat->stream.cbc)
     158                 :            :                 {
     159                 :          0 :                 (*dat->stream.cbc)(in,out,inl,&dat->ks,ctx->iv);
     160                 :          0 :                 return 1;
     161                 :            :                 }
     162                 :            : 
     163         [ -  + ]:        385 :         while (inl>=EVP_MAXCHUNK)
     164                 :            :                 {
     165                 :          0 :                 DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
     166                 :            :                              &dat->ks1, &dat->ks2, &dat->ks3,
     167                 :          0 :                              (DES_cblock *)ctx->iv, ctx->encrypt);
     168                 :          0 :                 inl-=EVP_MAXCHUNK;
     169                 :          0 :                 in +=EVP_MAXCHUNK;
     170                 :          0 :                 out+=EVP_MAXCHUNK;
     171                 :            :                 }
     172         [ +  - ]:        385 :         if (inl)
     173                 :        385 :                 DES_ede3_cbc_encrypt(in, out, (long)inl,
     174                 :            :                              &dat->ks1, &dat->ks2, &dat->ks3,
     175                 :        385 :                              (DES_cblock *)ctx->iv, ctx->encrypt);
     176                 :            :         return 1;
     177                 :            : }
     178                 :            : 
     179                 :         64 : static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     180                 :            :                               const unsigned char *in, size_t inl)
     181                 :            : {
     182         [ -  + ]:         64 :         while (inl>=EVP_MAXCHUNK)
     183                 :            :                 {
     184                 :          0 :                 DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, 
     185                 :          0 :                                &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
     186                 :          0 :                                (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
     187                 :          0 :                 inl-=EVP_MAXCHUNK;
     188                 :          0 :                 in +=EVP_MAXCHUNK;
     189                 :          0 :                 out+=EVP_MAXCHUNK;
     190                 :            :                 }
     191         [ +  - ]:         64 :         if (inl)
     192                 :         64 :                 DES_ede3_cfb64_encrypt(in, out, (long)inl,
     193                 :         64 :                                &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
     194                 :         64 :                                (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
     195                 :         64 :         return 1;
     196                 :            : }
     197                 :            : 
     198                 :            : /* Although we have a CFB-r implementation for 3-DES, it doesn't pack the right
     199                 :            :    way, so wrap it here */
     200                 :          0 : static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     201                 :            :                                 const unsigned char *in, size_t inl)
     202                 :            :     {
     203                 :            :     size_t n;
     204                 :            :     unsigned char c[1],d[1];
     205                 :            : 
     206         [ #  # ]:          0 :     for(n=0 ; n < inl ; ++n)
     207                 :            :         {
     208         [ #  # ]:          0 :         c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
     209                 :          0 :         DES_ede3_cfb_encrypt(c,d,1,1,
     210                 :          0 :                              &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
     211                 :          0 :                              (DES_cblock *)ctx->iv,ctx->encrypt);
     212                 :          0 :         out[n/8]=(out[n/8]&~(0x80 >> (unsigned int)(n%8))) |
     213                 :          0 :                  ((d[0]&0x80) >> (unsigned int)(n%8));
     214                 :            :         }
     215                 :            : 
     216                 :          0 :     return 1;
     217                 :            :     }
     218                 :            : 
     219                 :          0 : static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     220                 :            :                                 const unsigned char *in, size_t inl)
     221                 :            :     {
     222         [ #  # ]:          0 :     while (inl>=EVP_MAXCHUNK)
     223                 :            :         {
     224                 :          0 :         DES_ede3_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK,
     225                 :          0 :                          &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
     226                 :          0 :                          (DES_cblock *)ctx->iv,ctx->encrypt);
     227                 :          0 :         inl-=EVP_MAXCHUNK;
     228                 :          0 :         in +=EVP_MAXCHUNK;
     229                 :          0 :         out+=EVP_MAXCHUNK;
     230                 :            :         }
     231         [ #  # ]:          0 :     if (inl)
     232                 :          0 :         DES_ede3_cfb_encrypt(in,out,8,(long)inl,
     233                 :          0 :                         &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
     234                 :          0 :                         (DES_cblock *)ctx->iv,ctx->encrypt);
     235                 :          0 :     return 1;
     236                 :            :     }
     237                 :            : 
     238                 :       2178 : BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
     239                 :            :                         EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_DEFAULT_ASN1,
     240                 :            :                         des_ede_init_key, NULL, NULL, NULL,
     241                 :            :                         des3_ctrl)
     242                 :            : 
     243                 :            : #define des_ede3_cfb64_cipher des_ede_cfb64_cipher
     244                 :            : #define des_ede3_ofb_cipher des_ede_ofb_cipher
     245                 :            : #define des_ede3_cbc_cipher des_ede_cbc_cipher
     246                 :            : #define des_ede3_ecb_cipher des_ede_ecb_cipher
     247                 :            : 
     248                 :       3188 : BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64,
     249                 :            :                 EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
     250                 :            :                   des_ede3_init_key, NULL, NULL, NULL,
     251                 :            :                   des3_ctrl)
     252                 :            : 
     253                 :        726 : BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1,
     254                 :            :                 EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
     255                 :            :                         des_ede3_init_key, NULL, NULL, NULL,
     256                 :            :                         des3_ctrl)
     257                 :            : 
     258                 :        726 : BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8,
     259                 :            :                 EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
     260                 :            :                         des_ede3_init_key, NULL, NULL, NULL,
     261                 :            :                         des3_ctrl)
     262                 :            : 
     263                 :         16 : static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
     264                 :            :                             const unsigned char *iv, int enc)
     265                 :            :         {
     266                 :         16 :         DES_cblock *deskey = (DES_cblock *)key;
     267                 :         16 :         DES_EDE_KEY *dat = data(ctx);
     268                 :            : 
     269                 :         16 :         dat->stream.cbc = NULL;
     270                 :            : #if defined(SPARC_DES_CAPABLE)
     271                 :            :         if (SPARC_DES_CAPABLE)
     272                 :            :                 {
     273                 :            :                 int mode = ctx->cipher->flags & EVP_CIPH_MODE;
     274                 :            : 
     275                 :            :                 if (mode == EVP_CIPH_CBC_MODE)
     276                 :            :                         {
     277                 :            :                         des_t4_key_expand(&deskey[0],&dat->ks1);
     278                 :            :                         des_t4_key_expand(&deskey[1],&dat->ks2);
     279                 :            :                         memcpy(&dat->ks3,&dat->ks1,sizeof(dat->ks1));
     280                 :            :                         dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt :
     281                 :            :                                                 des_t4_ede3_cbc_decrypt;
     282                 :            :                         return 1;
     283                 :            :                         }
     284                 :            :                 }
     285                 :            : #endif
     286                 :            : #ifdef EVP_CHECK_DES_KEY
     287                 :            :         if (DES_set_key_checked(&deskey[0],&dat->ks1)
     288                 :            :                 !! DES_set_key_checked(&deskey[1],&dat->ks2))
     289                 :            :                 return 0;
     290                 :            : #else
     291                 :         16 :         DES_set_key_unchecked(&deskey[0],&dat->ks1);
     292                 :         16 :         DES_set_key_unchecked(&deskey[1],&dat->ks2);
     293                 :            : #endif
     294                 :         16 :         memcpy(&dat->ks3,&dat->ks1,
     295                 :            :                sizeof(dat->ks1));
     296                 :         16 :         return 1;
     297                 :            :         }
     298                 :            : 
     299                 :         96 : static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
     300                 :            :                              const unsigned char *iv, int enc)
     301                 :            :         {
     302                 :         96 :         DES_cblock *deskey = (DES_cblock *)key;
     303                 :         96 :         DES_EDE_KEY *dat = data(ctx);
     304                 :            : 
     305                 :            : #ifdef KSSL_DEBUG
     306                 :            :         {
     307                 :            :         int i;
     308                 :            :         printf("des_ede3_init_key(ctx=%lx)\n", ctx);
     309                 :            :         printf("\tKEY= ");
     310                 :            :         for(i=0;i<24;i++) printf("%02X",key[i]); printf("\n");
     311                 :            :         printf("\t IV= ");
     312                 :            :         for(i=0;i<8;i++) printf("%02X",iv[i]); printf("\n");
     313                 :            :         }
     314                 :            : #endif  /* KSSL_DEBUG */
     315                 :            : 
     316                 :         96 :         dat->stream.cbc = NULL;
     317                 :            : #if defined(SPARC_DES_CAPABLE)
     318                 :            :         if (SPARC_DES_CAPABLE)
     319                 :            :                 {
     320                 :            :                 int mode = ctx->cipher->flags & EVP_CIPH_MODE;
     321                 :            : 
     322                 :            :                 if (mode == EVP_CIPH_CBC_MODE)
     323                 :            :                         {
     324                 :            :                         des_t4_key_expand(&deskey[0],&dat->ks1);
     325                 :            :                         des_t4_key_expand(&deskey[1],&dat->ks2);
     326                 :            :                         des_t4_key_expand(&deskey[2],&dat->ks3);
     327                 :            :                         dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt :
     328                 :            :                                                 des_t4_ede3_cbc_decrypt;
     329                 :            :                         return 1;
     330                 :            :                         }
     331                 :            :                 }
     332                 :            : #endif
     333                 :            : #ifdef EVP_CHECK_DES_KEY
     334                 :            :         if (DES_set_key_checked(&deskey[0],&dat->ks1)
     335                 :            :                 || DES_set_key_checked(&deskey[1],&dat->ks2)
     336                 :            :                 || DES_set_key_checked(&deskey[2],&dat->ks3))
     337                 :            :                 return 0;
     338                 :            : #else
     339                 :         96 :         DES_set_key_unchecked(&deskey[0],&dat->ks1);
     340                 :         96 :         DES_set_key_unchecked(&deskey[1],&dat->ks2);
     341                 :         96 :         DES_set_key_unchecked(&deskey[2],&dat->ks3);
     342                 :            : #endif
     343                 :         96 :         return 1;
     344                 :            :         }
     345                 :            : 
     346                 :         27 : static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
     347                 :            :         {
     348                 :            : 
     349                 :         27 :         DES_cblock *deskey = ptr;
     350                 :            : 
     351         [ +  - ]:         27 :         switch(type)
     352                 :            :                 {
     353                 :            :         case EVP_CTRL_RAND_KEY:
     354         [ +  - ]:         27 :                 if (RAND_bytes(ptr, c->key_len) <= 0)
     355                 :            :                         return 0;
     356                 :         27 :                 DES_set_odd_parity(deskey);
     357         [ +  - ]:         27 :                 if (c->key_len >= 16)
     358                 :         27 :                         DES_set_odd_parity(deskey + 1);
     359         [ +  - ]:         27 :                 if (c->key_len >= 24)
     360                 :         27 :                         DES_set_odd_parity(deskey + 2);
     361                 :            :                 return 1;
     362                 :            : 
     363                 :            :         default:
     364                 :            :                 return -1;
     365                 :            :                 }
     366                 :            :         }
     367                 :            : 
     368                 :        726 : const EVP_CIPHER *EVP_des_ede(void)
     369                 :            : {
     370                 :        726 :         return &des_ede_ecb;
     371                 :            : }
     372                 :            : 
     373                 :        726 : const EVP_CIPHER *EVP_des_ede3(void)
     374                 :            : {
     375                 :        726 :         return &des_ede3_ecb;
     376                 :            : }
     377                 :            : 
     378                 :            : #ifndef OPENSSL_NO_SHA
     379                 :            : 
     380                 :            : #include <openssl/sha.h>
     381                 :            : 
     382                 :            : static const unsigned char wrap_iv[8] = {0x4a,0xdd,0xa2,0x2c,0x79,0xe8,0x21,0x05};
     383                 :            : 
     384                 :          2 : static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out,
     385                 :            :                                 const unsigned char *in, size_t inl)
     386                 :            :         {
     387                 :            :         unsigned char icv[8], iv[8], sha1tmp[SHA_DIGEST_LENGTH];
     388                 :          2 :         int rv = -1;
     389         [ +  - ]:          2 :         if (inl < 24)
     390                 :            :                 return -1;
     391         [ +  + ]:          2 :         if (!out)
     392                 :          1 :                 return inl - 16;
     393                 :          1 :         memcpy(ctx->iv, wrap_iv, 8);
     394                 :            :         /* Decrypt first block which will end up as icv */
     395                 :          1 :         des_ede_cbc_cipher(ctx, icv, in, 8);
     396                 :            :         /* Decrypt central blocks */
     397                 :            :         /* If decrypting in place move whole output along a block
     398                 :            :          * so the next des_ede_cbc_cipher is in place.
     399                 :            :          */
     400         [ -  + ]:          1 :         if (out == in)
     401                 :            :                 {
     402                 :          0 :                 memmove(out, out + 8, inl - 8);
     403                 :          0 :                 in -= 8;
     404                 :            :                 }
     405                 :          1 :         des_ede_cbc_cipher(ctx, out, in + 8, inl - 16);
     406                 :            :         /* Decrypt final block which will be IV */
     407                 :          1 :         des_ede_cbc_cipher(ctx, iv, in + inl - 8, 8);
     408                 :            :         /* Reverse order of everything */
     409                 :          1 :         BUF_reverse(icv, NULL, 8);
     410                 :          1 :         BUF_reverse(out, NULL, inl - 16);
     411                 :          1 :         BUF_reverse(ctx->iv, iv, 8);
     412                 :            :         /* Decrypt again using new IV */
     413                 :          1 :         des_ede_cbc_cipher(ctx, out, out, inl - 16);
     414                 :          1 :         des_ede_cbc_cipher(ctx, icv, icv, 8);
     415                 :            :         /* Work out SHA1 hash of first portion */
     416                 :          1 :         SHA1(out, inl - 16, sha1tmp);
     417                 :            : 
     418         [ +  - ]:          1 :         if (!CRYPTO_memcmp(sha1tmp, icv, 8))
     419                 :          1 :                 rv = inl - 16;
     420                 :          1 :         OPENSSL_cleanse(icv, 8);
     421                 :          1 :         OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH);
     422                 :          1 :         OPENSSL_cleanse(iv, 8);
     423                 :          1 :         OPENSSL_cleanse(ctx->iv, 8);
     424         [ -  + ]:          1 :         if (rv == -1)
     425                 :          0 :                 OPENSSL_cleanse(out, inl - 16);
     426                 :            :         
     427                 :          1 :         return rv;
     428                 :            :         }
     429                 :            : 
     430                 :          2 : static int des_ede3_wrap(EVP_CIPHER_CTX *ctx, unsigned char *out,
     431                 :            :                                 const unsigned char *in, size_t inl)
     432                 :            :         {
     433                 :            :         unsigned char sha1tmp[SHA_DIGEST_LENGTH];
     434         [ +  + ]:          2 :         if (!out)
     435                 :          1 :                 return inl + 16;
     436                 :            :         /* Copy input to output buffer + 8 so we have space for IV */
     437                 :          1 :         memmove(out + 8, in, inl);
     438                 :            :         /* Work out ICV */
     439                 :          1 :         SHA1(in, inl, sha1tmp);
     440                 :          1 :         memcpy(out + inl + 8, sha1tmp, 8);
     441                 :          1 :         OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH);
     442                 :            :         /* Generate random IV */
     443                 :          1 :         RAND_bytes(ctx->iv, 8);
     444                 :          1 :         memcpy(out, ctx->iv, 8);
     445                 :            :         /* Encrypt everything after IV in place */
     446                 :          1 :         des_ede_cbc_cipher(ctx, out + 8, out + 8, inl + 8);
     447                 :          1 :         BUF_reverse(out, NULL, inl + 16);
     448                 :          1 :         memcpy(ctx->iv, wrap_iv, 8);
     449                 :          1 :         des_ede_cbc_cipher(ctx, out, out, inl + 16);
     450                 :          1 :         return inl + 16;
     451                 :            :         }
     452                 :            : 
     453                 :          4 : static int des_ede3_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     454                 :            :                                 const unsigned char *in, size_t inl)
     455                 :            :         {
     456                 :            :         /* Sanity check input length: we typically only wrap keys
     457                 :            :          * so EVP_MAXCHUNK is more than will ever be needed. Also
     458                 :            :          * input length must be a multiple of 8 bits.
     459                 :            :          */
     460 [ +  - ][ +  - ]:          4 :         if (inl >= EVP_MAXCHUNK || inl % 8)
     461                 :            :                 return -1;
     462         [ +  + ]:          4 :         if (ctx->encrypt)
     463                 :          2 :                 return des_ede3_wrap(ctx, out, in, inl);
     464                 :            :         else
     465                 :          2 :                 return des_ede3_unwrap(ctx, out, in, inl);
     466                 :            :         }
     467                 :            : 
     468                 :            : static const EVP_CIPHER des3_wrap = {
     469                 :            :         NID_id_smime_alg_CMS3DESwrap,
     470                 :            :         8, 24, 0,
     471                 :            :         EVP_CIPH_WRAP_MODE|EVP_CIPH_CUSTOM_IV|EVP_CIPH_FLAG_CUSTOM_CIPHER
     472                 :            :                 |EVP_CIPH_FLAG_DEFAULT_ASN1,
     473                 :            :         des_ede3_init_key, des_ede3_wrap_cipher,
     474                 :            :         NULL,   
     475                 :            :         sizeof(DES_EDE_KEY),
     476                 :            :         NULL,NULL,NULL,NULL };
     477                 :            : 
     478                 :            : 
     479                 :        727 : const EVP_CIPHER *EVP_des_ede3_wrap(void)
     480                 :            :         {
     481                 :        727 :         return &des3_wrap;
     482                 :            :         }
     483                 :            : 
     484                 :            : # endif
     485                 :            : #endif

Generated by: LCOV version 1.9