heimdal: add missing heimdal/lib/hcrypto/{evp-aes-cts.c,evp-hcrypto.c}, sorry...
[Samba.git] / source4 / heimdal / lib / hcrypto / evp-aes-cts.c
blob60a538b7de1e1dfd44c4ee3c097987b1140f80b0
1 /*
2 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
38 RCSID("$Id$");
40 #define HC_DEPRECATED
42 #include <sys/types.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <assert.h>
49 #include <krb5-types.h>
51 #if defined(BUILD_KRB5_LIB) && defined(HAVE_OPENSSL)
52 #include <openssl/evp.h>
53 #include <openssl/aes.h>
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
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);
63 #else
64 #include <evp.h>
65 #include <aes.h>
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
71 #endif
77 static int
78 aes_cts_init(EVP_CIPHER_CTX *ctx,
79 const unsigned char * key,
80 const unsigned char * iv,
81 int encp)
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;
91 static void
92 _krb5_aes_cts_encrypt(const unsigned char *in, unsigned char *out,
93 size_t len, const AES_KEY *key,
94 unsigned char *ivec, const int encryptp)
96 unsigned char tmp[AES_BLOCK_SIZE];
97 int i;
100 * In the framework of kerberos, the length can never be shorter
101 * then at least one blocksize.
104 if (encryptp) {
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;
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];
121 AES_encrypt(tmp, out - AES_BLOCK_SIZE, key);
123 memcpy(out, ivec, len);
124 memcpy(ivec, out - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
126 } else {
127 unsigned char tmp2[AES_BLOCK_SIZE];
128 unsigned char tmp3[AES_BLOCK_SIZE];
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;
141 len -= AES_BLOCK_SIZE;
143 memcpy(tmp, in, AES_BLOCK_SIZE); /* save last iv */
144 AES_decrypt(in, tmp2, key);
146 memcpy(tmp3, in + AES_BLOCK_SIZE, len);
147 memcpy(tmp3 + len, tmp2 + len, AES_BLOCK_SIZE - len); /* xor 0 */
149 for (i = 0; i < len; i++)
150 out[i + AES_BLOCK_SIZE] = tmp2[i] ^ tmp3[i];
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);
159 static int
160 aes_cts_do_cipher(EVP_CIPHER_CTX *ctx,
161 unsigned char *out,
162 const unsigned char *in,
163 unsigned int len)
165 AES_KEY *k = ctx->cipher_data;
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);
178 return 1;
182 static int
183 aes_cts_cleanup(EVP_CIPHER_CTX *ctx)
185 memset(ctx->cipher_data, 0, sizeof(AES_KEY));
186 return 1;
190 * The AES-128 cts cipher type (hcrypto)
192 * @return the AES-128 EVP_CIPHER pointer.
194 * @ingroup hcrypto_evp
197 const EVP_CIPHER *
198 _hc_EVP_hcrypto_aes_128_cts(void)
200 static const EVP_CIPHER aes_128_cts = {
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
216 return &aes_128_cts;
220 * The AES-192 cts cipher type (hcrypto)
222 * @return the AES-192 EVP_CIPHER pointer.
224 * @ingroup hcrypto_evp
227 const EVP_CIPHER *
228 _hc_EVP_hcrypto_aes_192_cts(void)
230 static const EVP_CIPHER aes_192_cts = {
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
246 return &aes_192_cts;
250 * The AES-256 cts cipher type (hcrypto)
252 * @return the AES-256 EVP_CIPHER pointer.
254 * @ingroup hcrypto_evp
257 const EVP_CIPHER *
258 _hc_EVP_hcrypto_aes_256_cts(void)
260 static const EVP_CIPHER aes_256_cts = {
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
276 return &aes_256_cts;