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);
63 #define _hc_EVP_hcrypto_aes_128_cts hc_EVP_hcrypto_aes_128_cts
64 #define _hc_EVP_hcrypto_aes_192_cts hc_EVP_hcrypto_aes_192_cts
65 #define _hc_EVP_hcrypto_aes_256_cts hc_EVP_hcrypto_aes_256_cts
74 aes_cts_init(EVP_CIPHER_CTX
*ctx
,
75 const unsigned char * key
,
76 const unsigned char * iv
,
79 AES_KEY
*k
= ctx
->cipher_data
;
81 AES_set_encrypt_key(key
, ctx
->cipher
->key_len
* 8, k
);
83 AES_set_decrypt_key(key
, ctx
->cipher
->key_len
* 8, k
);
88 _krb5_aes_cts_encrypt(const unsigned char *in
, unsigned char *out
,
89 size_t len
, const AES_KEY
*key
,
90 unsigned char *ivec
, const int encryptp
)
92 unsigned char tmp
[AES_BLOCK_SIZE
];
96 * In the framework of kerberos, the length can never be shorter
97 * then at least one blocksize.
102 while(len
> AES_BLOCK_SIZE
) {
103 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
104 tmp
[i
] = in
[i
] ^ ivec
[i
];
105 AES_encrypt(tmp
, out
, key
);
106 memcpy(ivec
, out
, AES_BLOCK_SIZE
);
107 len
-= AES_BLOCK_SIZE
;
108 in
+= AES_BLOCK_SIZE
;
109 out
+= AES_BLOCK_SIZE
;
112 for (i
= 0; i
< len
; i
++)
113 tmp
[i
] = in
[i
] ^ ivec
[i
];
114 for (; i
< AES_BLOCK_SIZE
; i
++)
115 tmp
[i
] = 0 ^ ivec
[i
];
117 AES_encrypt(tmp
, out
- AES_BLOCK_SIZE
, key
);
119 memcpy(out
, ivec
, len
);
120 memcpy(ivec
, out
- AES_BLOCK_SIZE
, AES_BLOCK_SIZE
);
123 unsigned char tmp2
[AES_BLOCK_SIZE
];
124 unsigned char tmp3
[AES_BLOCK_SIZE
];
126 while(len
> AES_BLOCK_SIZE
* 2) {
127 memcpy(tmp
, in
, AES_BLOCK_SIZE
);
128 AES_decrypt(in
, out
, key
);
129 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
131 memcpy(ivec
, tmp
, AES_BLOCK_SIZE
);
132 len
-= AES_BLOCK_SIZE
;
133 in
+= AES_BLOCK_SIZE
;
134 out
+= AES_BLOCK_SIZE
;
137 len
-= AES_BLOCK_SIZE
;
139 memcpy(tmp
, in
, AES_BLOCK_SIZE
); /* save last iv */
140 AES_decrypt(in
, tmp2
, key
);
142 memcpy(tmp3
, in
+ AES_BLOCK_SIZE
, len
);
143 memcpy(tmp3
+ len
, tmp2
+ len
, AES_BLOCK_SIZE
- len
); /* xor 0 */
145 for (i
= 0; i
< len
; i
++)
146 out
[i
+ AES_BLOCK_SIZE
] = tmp2
[i
] ^ tmp3
[i
];
148 AES_decrypt(tmp3
, out
, key
);
149 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
151 memcpy(ivec
, tmp
, AES_BLOCK_SIZE
);
156 aes_cts_do_cipher(EVP_CIPHER_CTX
*ctx
,
158 const unsigned char *in
,
161 AES_KEY
*k
= ctx
->cipher_data
;
163 if (len
< AES_BLOCK_SIZE
)
164 abort(); /* krb5_abortx(context, "invalid use of AES_CTS_encrypt"); */
165 if (len
== AES_BLOCK_SIZE
) {
167 AES_encrypt(in
, out
, k
);
169 AES_decrypt(in
, out
, k
);
171 _krb5_aes_cts_encrypt(in
, out
, len
, k
, ctx
->iv
, ctx
->encrypt
);
179 aes_cts_cleanup(EVP_CIPHER_CTX
*ctx
)
181 memset(ctx
->cipher_data
, 0, sizeof(AES_KEY
));
186 * The AES-128 cts cipher type (hcrypto)
188 * @return the AES-128 EVP_CIPHER pointer.
190 * @ingroup hcrypto_evp
194 _hc_EVP_hcrypto_aes_128_cts(void)
196 static const EVP_CIPHER aes_128_cts
= {
216 * The AES-192 cts cipher type (hcrypto)
218 * @return the AES-192 EVP_CIPHER pointer.
220 * @ingroup hcrypto_evp
224 _hc_EVP_hcrypto_aes_192_cts(void)
226 static const EVP_CIPHER aes_192_cts
= {
246 * The AES-256 cts cipher type (hcrypto)
248 * @return the AES-256 EVP_CIPHER pointer.
250 * @ingroup hcrypto_evp
254 _hc_EVP_hcrypto_aes_256_cts(void)
256 static const EVP_CIPHER aes_256_cts
= {