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
42 #include <sys/types.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);
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
78 aes_cts_init(EVP_CIPHER_CTX
*ctx
,
79 const unsigned char * key
,
80 const unsigned char * iv
,
83 AES_KEY
*k
= ctx
->cipher_data
;
85 AES_set_encrypt_key(key
, ctx
->cipher
->key_len
* 8, k
);
87 AES_set_decrypt_key(key
, ctx
->cipher
->key_len
* 8, k
);
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
];
100 * In the framework of kerberos, the length can never be shorter
101 * then at least one blocksize.
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
);
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
++)
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
++)
155 memcpy(ivec
, tmp
, AES_BLOCK_SIZE
);
160 aes_cts_do_cipher(EVP_CIPHER_CTX
*ctx
,
162 const unsigned char *in
,
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
) {
171 AES_encrypt(in
, out
, k
);
173 AES_decrypt(in
, out
, k
);
175 _krb5_aes_cts_encrypt(in
, out
, len
, k
, ctx
->iv
, ctx
->encrypt
);
183 aes_cts_cleanup(EVP_CIPHER_CTX
*ctx
)
185 memset(ctx
->cipher_data
, 0, sizeof(AES_KEY
));
190 * The AES-128 cts cipher type (hcrypto)
192 * @return the AES-128 EVP_CIPHER pointer.
194 * @ingroup hcrypto_evp
198 _hc_EVP_hcrypto_aes_128_cts(void)
200 static const EVP_CIPHER aes_128_cts
= {
220 * The AES-192 cts cipher type (hcrypto)
222 * @return the AES-192 EVP_CIPHER pointer.
224 * @ingroup hcrypto_evp
228 _hc_EVP_hcrypto_aes_192_cts(void)
230 static const EVP_CIPHER aes_192_cts
= {
250 * The AES-256 cts cipher type (hcrypto)
252 * @return the AES-256 EVP_CIPHER pointer.
254 * @ingroup hcrypto_evp
258 _hc_EVP_hcrypto_aes_256_cts(void)
260 static const EVP_CIPHER aes_256_cts
= {