LCOV - code coverage report
Current view: top level - source4/heimdal/lib/krb5 - crypto-evp.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 59 83 71.1 %
Date: 2021-09-23 10:06:22 Functions: 3 4 75.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
       3             :  * (Royal Institute of Technology, Stockholm, Sweden).
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  *
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  *
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * 3. Neither the name of the Institute nor the names of its contributors
      18             :  *    may be used to endorse or promote products derived from this software
      19             :  *    without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include "krb5_locl.h"
      35             : 
      36             : void
      37     3306830 : _krb5_evp_schedule(krb5_context context,
      38             :                    struct _krb5_key_type *kt,
      39             :                    struct _krb5_key_data *kd)
      40             : {
      41     3306830 :     struct _krb5_evp_schedule *key = kd->schedule->data;
      42     3306830 :     const EVP_CIPHER *c = (*kt->evp)();
      43             : 
      44     3306830 :     EVP_CIPHER_CTX_init(&key->ectx);
      45     3306830 :     EVP_CIPHER_CTX_init(&key->dctx);
      46             : 
      47     3306830 :     EVP_CipherInit_ex(&key->ectx, c, NULL, kd->key->keyvalue.data, NULL, 1);
      48     3306830 :     EVP_CipherInit_ex(&key->dctx, c, NULL, kd->key->keyvalue.data, NULL, 0);
      49     3306830 : }
      50             : 
      51             : void
      52     3306796 : _krb5_evp_cleanup(krb5_context context, struct _krb5_key_data *kd)
      53             : {
      54     3306796 :     struct _krb5_evp_schedule *key = kd->schedule->data;
      55     3306796 :     EVP_CIPHER_CTX_cleanup(&key->ectx);
      56     3306796 :     EVP_CIPHER_CTX_cleanup(&key->dctx);
      57     3306796 : }
      58             : 
      59             : krb5_error_code
      60           0 : _krb5_evp_encrypt(krb5_context context,
      61             :                 struct _krb5_key_data *key,
      62             :                 void *data,
      63             :                 size_t len,
      64             :                 krb5_boolean encryptp,
      65             :                 int usage,
      66             :                 void *ivec)
      67             : {
      68           0 :     struct _krb5_evp_schedule *ctx = key->schedule->data;
      69             :     EVP_CIPHER_CTX *c;
      70           0 :     c = encryptp ? &ctx->ectx : &ctx->dctx;
      71           0 :     if (ivec == NULL) {
      72             :         /* alloca ? */
      73           0 :         size_t len2 = EVP_CIPHER_CTX_iv_length(c);
      74           0 :         void *loiv = malloc(len2);
      75           0 :         if (loiv == NULL) {
      76           0 :             krb5_clear_error_message(context);
      77           0 :             return ENOMEM;
      78             :         }
      79           0 :         memset(loiv, 0, len2);
      80           0 :         EVP_CipherInit_ex(c, NULL, NULL, NULL, loiv, -1);
      81           0 :         free(loiv);
      82             :     } else
      83           0 :         EVP_CipherInit_ex(c, NULL, NULL, NULL, ivec, -1);
      84           0 :     EVP_Cipher(c, data, data, len);
      85           0 :     return 0;
      86             : }
      87             : 
      88             : static const unsigned char zero_ivec[EVP_MAX_BLOCK_LENGTH] = { 0 };
      89             : 
      90             : krb5_error_code
      91     5391111 : _krb5_evp_encrypt_cts(krb5_context context,
      92             :                       struct _krb5_key_data *key,
      93             :                       void *data,
      94             :                       size_t len,
      95             :                       krb5_boolean encryptp,
      96             :                       int usage,
      97             :                       void *ivec)
      98             : {
      99             :     size_t i, blocksize;
     100     5391111 :     struct _krb5_evp_schedule *ctx = key->schedule->data;
     101             :     unsigned char tmp[EVP_MAX_BLOCK_LENGTH], ivec2[EVP_MAX_BLOCK_LENGTH];
     102             :     EVP_CIPHER_CTX *c;
     103             :     unsigned char *p;
     104             : 
     105     5391111 :     c = encryptp ? &ctx->ectx : &ctx->dctx;
     106             : 
     107     5391111 :     blocksize = EVP_CIPHER_CTX_block_size(c);
     108             : 
     109     5391111 :     if (len < blocksize) {
     110           0 :         krb5_set_error_message(context, EINVAL,
     111             :                                "message block too short");
     112           0 :         return EINVAL;
     113     5391111 :     } else if (len == blocksize) {
     114     3217031 :         EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
     115     3217031 :         EVP_Cipher(c, data, data, len);
     116     3217031 :         return 0;
     117             :     }
     118             : 
     119     2174080 :     if (ivec)
     120           0 :         EVP_CipherInit_ex(c, NULL, NULL, NULL, ivec, -1);
     121             :     else
     122     2174080 :         EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
     123             : 
     124     2174080 :     if (encryptp) {
     125             : 
     126     1362616 :         p = data;
     127     1362616 :         i = ((len - 1) / blocksize) * blocksize;
     128     1362616 :         EVP_Cipher(c, p, p, i);
     129     1362616 :         p += i - blocksize;
     130     1362616 :         len -= i;
     131     1362616 :         memcpy(ivec2, p, blocksize);
     132             : 
     133    19702389 :         for (i = 0; i < len; i++)
     134    18339773 :             tmp[i] = p[i + blocksize] ^ ivec2[i];
     135     4817362 :         for (; i < blocksize; i++)
     136     3462083 :             tmp[i] = 0 ^ ivec2[i];
     137             : 
     138     1362616 :         EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
     139     1362616 :         EVP_Cipher(c, p, tmp, blocksize);
     140             : 
     141     1369953 :         memcpy(p + blocksize, ivec2, len);
     142     1362616 :         if (ivec)
     143           0 :             memcpy(ivec, p, blocksize);
     144             :     } else {
     145             :         unsigned char tmp2[EVP_MAX_BLOCK_LENGTH], tmp3[EVP_MAX_BLOCK_LENGTH];
     146             : 
     147      811464 :         p = data;
     148      811464 :         if (len > blocksize * 2) {
     149             :             /* remove last two blocks and round up, decrypt this with cbc, then do cts dance */
     150      811464 :             i = ((((len - blocksize * 2) + blocksize - 1) / blocksize) * blocksize);
     151      818940 :             memcpy(ivec2, p + i - blocksize, blocksize);
     152      811464 :             EVP_Cipher(c, p, p, i);
     153      811464 :             p += i;
     154      811464 :             len -= i + blocksize;
     155             :         } else {
     156           0 :             if (ivec)
     157           0 :                 memcpy(ivec2, ivec, blocksize);
     158             :             else
     159           0 :                 memcpy(ivec2, zero_ivec, blocksize);
     160           0 :             len -= blocksize;
     161             :         }
     162             : 
     163      811464 :         memcpy(tmp, p, blocksize);
     164      811464 :         EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
     165      811464 :         EVP_Cipher(c, tmp2, p, blocksize);
     166             : 
     167      818940 :         memcpy(tmp3, p + blocksize, len);
     168      818940 :         memcpy(tmp3 + len, tmp2 + len, blocksize - len); /* xor 0 */
     169             : 
     170    10196651 :         for (i = 0; i < len; i++)
     171     9385187 :             p[i + blocksize] = tmp2[i] ^ tmp3[i];
     172             : 
     173      811464 :         EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
     174      811464 :         EVP_Cipher(c, p, tmp3, blocksize);
     175             : 
     176    13794888 :         for (i = 0; i < blocksize; i++)
     177    12983424 :             p[i] ^= ivec2[i];
     178      811464 :         if (ivec)
     179           0 :             memcpy(ivec, tmp, blocksize);
     180             :     }
     181     2159267 :     return 0;
     182             : }

Generated by: LCOV version 1.13