2 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
38 #include <sys/types.h>
45 #include <krb5-types.h>
47 #if defined(BUILD_KRB5_LIB) && defined(HAVE_OPENSSL)
48 #include <openssl/evp.h>
49 #include <openssl/aes.h>
51 #define _hc_EVP_hcrypto_aes_128_cts _krb5_EVP_hcrypto_aes_128_cts
52 #define _hc_EVP_hcrypto_aes_192_cts _krb5_EVP_hcrypto_aes_192_cts
53 #define _hc_EVP_hcrypto_aes_256_cts _krb5_EVP_hcrypto_aes_256_cts
55 const EVP_CIPHER
* _krb5_EVP_hcrypto_aes_128_cts(void);
56 const EVP_CIPHER
* _krb5_EVP_hcrypto_aes_192_cts(void);
57 const EVP_CIPHER
* _krb5_EVP_hcrypto_aes_256_cts(void);
61 #include <evp-hcrypto.h>
64 #define _hc_EVP_hcrypto_aes_128_cts hc_EVP_hcrypto_aes_128_cts
65 #define _hc_EVP_hcrypto_aes_192_cts hc_EVP_hcrypto_aes_192_cts
66 #define _hc_EVP_hcrypto_aes_256_cts hc_EVP_hcrypto_aes_256_cts
75 aes_cts_init(EVP_CIPHER_CTX
*ctx
,
76 const unsigned char * key
,
77 const unsigned char * iv
,
80 AES_KEY
*k
= ctx
->cipher_data
;
82 AES_set_encrypt_key(key
, ctx
->cipher
->key_len
* 8, k
);
84 AES_set_decrypt_key(key
, ctx
->cipher
->key_len
* 8, k
);
89 _krb5_aes_cts_encrypt(const unsigned char *in
, unsigned char *out
,
90 size_t len
, const AES_KEY
*key
,
91 unsigned char *ivec
, const int encryptp
)
93 unsigned char tmp
[AES_BLOCK_SIZE
];
97 * In the framework of kerberos, the length can never be shorter
98 * then at least one blocksize.
103 while(len
> AES_BLOCK_SIZE
) {
104 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
105 tmp
[i
] = in
[i
] ^ ivec
[i
];
106 AES_encrypt(tmp
, out
, key
);
107 memcpy(ivec
, out
, AES_BLOCK_SIZE
);
108 len
-= AES_BLOCK_SIZE
;
109 in
+= AES_BLOCK_SIZE
;
110 out
+= AES_BLOCK_SIZE
;
113 for (i
= 0; i
< len
; i
++)
114 tmp
[i
] = in
[i
] ^ ivec
[i
];
115 for (; i
< AES_BLOCK_SIZE
; i
++)
116 tmp
[i
] = 0 ^ ivec
[i
];
118 AES_encrypt(tmp
, out
- AES_BLOCK_SIZE
, key
);
120 memcpy(out
, ivec
, len
);
121 memcpy(ivec
, out
- AES_BLOCK_SIZE
, AES_BLOCK_SIZE
);
124 unsigned char tmp2
[AES_BLOCK_SIZE
];
125 unsigned char tmp3
[AES_BLOCK_SIZE
];
127 while(len
> AES_BLOCK_SIZE
* 2) {
128 memcpy(tmp
, in
, AES_BLOCK_SIZE
);
129 AES_decrypt(in
, out
, key
);
130 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
132 memcpy(ivec
, tmp
, AES_BLOCK_SIZE
);
133 len
-= AES_BLOCK_SIZE
;
134 in
+= AES_BLOCK_SIZE
;
135 out
+= AES_BLOCK_SIZE
;
138 len
-= AES_BLOCK_SIZE
;
140 memcpy(tmp
, in
, AES_BLOCK_SIZE
); /* save last iv */
141 AES_decrypt(in
, tmp2
, key
);
143 memcpy(tmp3
, in
+ AES_BLOCK_SIZE
, len
);
144 memcpy(tmp3
+ len
, tmp2
+ len
, AES_BLOCK_SIZE
- len
); /* xor 0 */
146 for (i
= 0; i
< len
; i
++)
147 out
[i
+ AES_BLOCK_SIZE
] = tmp2
[i
] ^ tmp3
[i
];
149 AES_decrypt(tmp3
, out
, key
);
150 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
152 memcpy(ivec
, tmp
, AES_BLOCK_SIZE
);
157 aes_cts_do_cipher(EVP_CIPHER_CTX
*ctx
,
159 const unsigned char *in
,
162 AES_KEY
*k
= ctx
->cipher_data
;
164 if (len
< AES_BLOCK_SIZE
)
165 abort(); /* krb5_abortx(context, "invalid use of AES_CTS_encrypt"); */
166 if (len
== AES_BLOCK_SIZE
) {
168 AES_encrypt(in
, out
, k
);
170 AES_decrypt(in
, out
, k
);
172 _krb5_aes_cts_encrypt(in
, out
, len
, k
, ctx
->iv
, ctx
->encrypt
);
180 aes_cts_cleanup(EVP_CIPHER_CTX
*ctx
)
182 memset(ctx
->cipher_data
, 0, sizeof(AES_KEY
));
187 * The AES-128 cts cipher type (hcrypto)
189 * @return the AES-128 EVP_CIPHER pointer.
191 * @ingroup hcrypto_evp
195 _hc_EVP_hcrypto_aes_128_cts(void)
197 static const EVP_CIPHER aes_128_cts
= {
217 * The AES-192 cts cipher type (hcrypto)
219 * @return the AES-192 EVP_CIPHER pointer.
221 * @ingroup hcrypto_evp
225 _hc_EVP_hcrypto_aes_192_cts(void)
227 static const EVP_CIPHER aes_192_cts
= {
247 * The AES-256 cts cipher type (hcrypto)
249 * @return the AES-256 EVP_CIPHER pointer.
251 * @ingroup hcrypto_evp
255 _hc_EVP_hcrypto_aes_256_cts(void)
257 static const EVP_CIPHER aes_256_cts
= {