root/source4/heimdal/lib/hcrypto/evp-aes-cts.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. aes_cts_init
  2. _krb5_aes_cts_encrypt
  3. aes_cts_do_cipher
  4. aes_cts_cleanup
  5. _hc_EVP_hcrypto_aes_128_cts
  6. _hc_EVP_hcrypto_aes_192_cts
  7. _hc_EVP_hcrypto_aes_256_cts

   1 /*
   2  * Copyright (c) 2006 - 2007 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 #ifdef HAVE_CONFIG_H
  35 #include <config.h>
  36 #endif
  37 
  38 RCSID("$Id$");
  39 
  40 #define HC_DEPRECATED
  41 
  42 #include <sys/types.h>
  43 #include <stdio.h>
  44 #include <stdlib.h>
  45 #include <string.h>
  46 #include <assert.h>
  47 
  48 
  49 #include <krb5-types.h>
  50 
  51 #if defined(BUILD_KRB5_LIB) && defined(HAVE_OPENSSL)
  52 #include <openssl/evp.h>
  53 #include <openssl/aes.h>
  54 
  55 #define _hc_EVP_hcrypto_aes_128_cts _krb5_EVP_hcrypto_aes_128_cts
  56 #define _hc_EVP_hcrypto_aes_192_cts _krb5_EVP_hcrypto_aes_192_cts
  57 #define _hc_EVP_hcrypto_aes_256_cts _krb5_EVP_hcrypto_aes_256_cts
  58 
  59 const EVP_CIPHER * _krb5_EVP_hcrypto_aes_128_cts(void);
  60 const EVP_CIPHER * _krb5_EVP_hcrypto_aes_192_cts(void);
  61 const EVP_CIPHER * _krb5_EVP_hcrypto_aes_256_cts(void);
  62 
  63 #else
  64 #include <evp.h>
  65 #include <aes.h>
  66 
  67 #define _hc_EVP_hcrypto_aes_128_cts hc_EVP_hcrypto_aes_128_cts
  68 #define _hc_EVP_hcrypto_aes_192_cts hc_EVP_hcrypto_aes_192_cts
  69 #define _hc_EVP_hcrypto_aes_256_cts hc_EVP_hcrypto_aes_256_cts
  70 
  71 #endif
  72 
  73 /*
  74  *
  75  */
  76 
  77 static int
  78 aes_cts_init(EVP_CIPHER_CTX *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  79              const unsigned char * key,
  80              const unsigned char * iv,
  81              int encp)
  82 {
  83     AES_KEY *k = ctx->cipher_data;
  84     if (ctx->encrypt)
  85         AES_set_encrypt_key(key, ctx->cipher->key_len * 8, k);
  86     else
  87         AES_set_decrypt_key(key, ctx->cipher->key_len * 8, k);
  88     return 1;
  89 }
  90 
  91 static void
  92 _krb5_aes_cts_encrypt(const unsigned char *in, unsigned char *out,
     /* [<][>][^][v][top][bottom][index][help] */
  93                       size_t len, const AES_KEY *key,
  94                       unsigned char *ivec, const int encryptp)
  95 {
  96     unsigned char tmp[AES_BLOCK_SIZE];
  97     int i;
  98 
  99     /*
 100      * In the framework of kerberos, the length can never be shorter
 101      * then at least one blocksize.
 102      */
 103 
 104     if (encryptp) {
 105 
 106         while(len > AES_BLOCK_SIZE) {
 107             for (i = 0; i < AES_BLOCK_SIZE; i++)
 108                 tmp[i] = in[i] ^ ivec[i];
 109             AES_encrypt(tmp, out, key);
 110             memcpy(ivec, out, AES_BLOCK_SIZE);
 111             len -= AES_BLOCK_SIZE;
 112             in += AES_BLOCK_SIZE;
 113             out += AES_BLOCK_SIZE;
 114         }
 115 
 116         for (i = 0; i < len; i++)
 117             tmp[i] = in[i] ^ ivec[i];
 118         for (; i < AES_BLOCK_SIZE; i++)
 119             tmp[i] = 0 ^ ivec[i];
 120 
 121         AES_encrypt(tmp, out - AES_BLOCK_SIZE, key);
 122 
 123         memcpy(out, ivec, len);
 124         memcpy(ivec, out - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
 125 
 126     } else {
 127         unsigned char tmp2[AES_BLOCK_SIZE];
 128         unsigned char tmp3[AES_BLOCK_SIZE];
 129 
 130         while(len > AES_BLOCK_SIZE * 2) {
 131             memcpy(tmp, in, AES_BLOCK_SIZE);
 132             AES_decrypt(in, out, key);
 133             for (i = 0; i < AES_BLOCK_SIZE; i++)
 134                 out[i] ^= ivec[i];
 135             memcpy(ivec, tmp, AES_BLOCK_SIZE);
 136             len -= AES_BLOCK_SIZE;
 137             in += AES_BLOCK_SIZE;
 138             out += AES_BLOCK_SIZE;
 139         }
 140 
 141         len -= AES_BLOCK_SIZE;
 142 
 143         memcpy(tmp, in, AES_BLOCK_SIZE); /* save last iv */
 144         AES_decrypt(in, tmp2, key);
 145 
 146         memcpy(tmp3, in + AES_BLOCK_SIZE, len);
 147         memcpy(tmp3 + len, tmp2 + len, AES_BLOCK_SIZE - len); /* xor 0 */
 148 
 149         for (i = 0; i < len; i++)
 150             out[i + AES_BLOCK_SIZE] = tmp2[i] ^ tmp3[i];
 151 
 152         AES_decrypt(tmp3, out, key);
 153         for (i = 0; i < AES_BLOCK_SIZE; i++)
 154             out[i] ^= ivec[i];
 155         memcpy(ivec, tmp, AES_BLOCK_SIZE);
 156     }
 157 }
 158 
 159 static int
 160 aes_cts_do_cipher(EVP_CIPHER_CTX *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 161                   unsigned char *out,
 162                   const unsigned char *in,
 163                   unsigned int len)
 164 {
 165     AES_KEY *k = ctx->cipher_data;
 166 
 167     if (len < AES_BLOCK_SIZE)
 168         abort();  /* krb5_abortx(context, "invalid use of AES_CTS_encrypt"); */
 169     if (len == AES_BLOCK_SIZE) {
 170         if (ctx->encrypt)
 171             AES_encrypt(in, out, k);
 172         else
 173             AES_decrypt(in, out, k);
 174     } else {
 175         _krb5_aes_cts_encrypt(in, out, len, k, ctx->iv, ctx->encrypt);
 176     }
 177 
 178     return 1;
 179 }
 180 
 181 
 182 static int
 183 aes_cts_cleanup(EVP_CIPHER_CTX *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 184 {
 185     memset(ctx->cipher_data, 0, sizeof(AES_KEY));
 186     return 1;
 187 }
 188 
 189 /**
 190  * The AES-128 cts cipher type (hcrypto)
 191  *
 192  * @return the AES-128 EVP_CIPHER pointer.
 193  *
 194  * @ingroup hcrypto_evp
 195  */
 196 
 197 const EVP_CIPHER *
 198 _hc_EVP_hcrypto_aes_128_cts(void)
     /* [<][>][^][v][top][bottom][index][help] */
 199 {
 200     static const EVP_CIPHER aes_128_cts = {
 201         0,
 202         1,
 203         16,
 204         16,
 205         EVP_CIPH_CBC_MODE,
 206         aes_cts_init,
 207         aes_cts_do_cipher,
 208         aes_cts_cleanup,
 209         sizeof(AES_KEY),
 210         NULL,
 211         NULL,
 212         NULL,
 213         NULL
 214     };
 215 
 216     return &aes_128_cts;
 217 }
 218 
 219 /**
 220  * The AES-192 cts cipher type (hcrypto)
 221  *
 222  * @return the AES-192 EVP_CIPHER pointer.
 223  *
 224  * @ingroup hcrypto_evp
 225  */
 226 
 227 const EVP_CIPHER *
 228 _hc_EVP_hcrypto_aes_192_cts(void)
     /* [<][>][^][v][top][bottom][index][help] */
 229 {
 230     static const EVP_CIPHER aes_192_cts = {
 231         0,
 232         1,
 233         24,
 234         16,
 235         EVP_CIPH_CBC_MODE,
 236         aes_cts_init,
 237         aes_cts_do_cipher,
 238         aes_cts_cleanup,
 239         sizeof(AES_KEY),
 240         NULL,
 241         NULL,
 242         NULL,
 243         NULL
 244     };
 245 
 246     return &aes_192_cts;
 247 }
 248 
 249 /**
 250  * The AES-256 cts cipher type (hcrypto)
 251  *
 252  * @return the AES-256 EVP_CIPHER pointer.
 253  *
 254  * @ingroup hcrypto_evp
 255  */
 256 
 257 const EVP_CIPHER *
 258 _hc_EVP_hcrypto_aes_256_cts(void)
     /* [<][>][^][v][top][bottom][index][help] */
 259 {
 260     static const EVP_CIPHER aes_256_cts = {
 261         0,
 262         1,
 263         32,
 264         16,
 265         EVP_CIPH_CBC_MODE,
 266         aes_cts_init,
 267         aes_cts_do_cipher,
 268         aes_cts_cleanup,
 269         sizeof(AES_KEY),
 270         NULL,
 271         NULL,
 272         NULL,
 273         NULL
 274     };
 275 
 276     return &aes_256_cts;
 277 }

/* [<][>][^][v][top][bottom][index][help] */