1/*
2 * Copyright (c) 1997 - 2008 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#include "krb5_locl.h"
35
36/*
37 * AES
38 */
39
40static struct _krb5_key_type keytype_aes128 = {
41    ENCTYPE_AES128_CTS_HMAC_SHA1_96,
42    "aes-128",
43    128,
44    16,
45    sizeof(struct _krb5_evp_schedule),
46    NULL,
47    _krb5_evp_schedule,
48    _krb5_AES_salt,
49    NULL,
50    _krb5_evp_cleanup,
51    EVP_aes_128_cbc
52};
53
54static struct _krb5_key_type keytype_aes256 = {
55    ENCTYPE_AES256_CTS_HMAC_SHA1_96,
56    "aes-256",
57    256,
58    32,
59    sizeof(struct _krb5_evp_schedule),
60    NULL,
61    _krb5_evp_schedule,
62    _krb5_AES_salt,
63    NULL,
64    _krb5_evp_cleanup,
65    EVP_aes_256_cbc
66};
67
68struct _krb5_checksum_type _krb5_checksum_hmac_sha1_aes128 = {
69    CKSUMTYPE_HMAC_SHA1_96_AES_128,
70    "hmac-sha1-96-aes128",
71    64,
72    12,
73    F_KEYED | F_CPROOF | F_DERIVED,
74    _krb5_SP_HMAC_SHA1_checksum,
75    NULL
76};
77
78struct _krb5_checksum_type _krb5_checksum_hmac_sha1_aes256 = {
79    CKSUMTYPE_HMAC_SHA1_96_AES_256,
80    "hmac-sha1-96-aes256",
81    64,
82    12,
83    F_KEYED | F_CPROOF | F_DERIVED,
84    _krb5_SP_HMAC_SHA1_checksum,
85    NULL
86};
87
88static krb5_error_code
89AES_PRF(krb5_context context,
90	krb5_crypto crypto,
91	const krb5_data *in,
92	krb5_data *out)
93{
94    struct _krb5_checksum_type *ct = crypto->et->checksum;
95    krb5_error_code ret;
96    Checksum result;
97    krb5_keyblock *derived;
98
99    result.cksumtype = ct->type;
100    ret = krb5_data_alloc(&result.checksum, ct->checksumsize);
101    if (ret) {
102	krb5_set_error_message(context, ret, N_("malloc: out memory", ""));
103	return ret;
104    }
105
106    ret = (*ct->checksum)(context, NULL, in->data, in->length, 0, &result);
107    if (ret) {
108	krb5_data_free(&result.checksum);
109	return ret;
110    }
111
112    if (result.checksum.length < crypto->et->blocksize)
113	krb5_abortx(context, "internal prf error");
114
115    derived = NULL;
116    ret = krb5_derive_key(context, crypto->key.key,
117			  crypto->et->type, "prf", 3, &derived);
118    if (ret)
119	krb5_abortx(context, "krb5_derive_key");
120
121    ret = krb5_data_alloc(out, crypto->et->blocksize);
122    if (ret)
123	krb5_abortx(context, "malloc failed");
124
125    {
126	const EVP_CIPHER *c = (*crypto->et->keytype->evp)();
127	EVP_CIPHER_CTX ctx;
128
129	EVP_CIPHER_CTX_init(&ctx); /* ivec all zero */
130	EVP_CipherInit_ex(&ctx, c, NULL, derived->keyvalue.data, NULL, 1);
131	EVP_Cipher(&ctx, out->data, result.checksum.data,
132		   crypto->et->blocksize);
133	EVP_CIPHER_CTX_cleanup(&ctx);
134    }
135
136    krb5_data_free(&result.checksum);
137    krb5_free_keyblock(context, derived);
138
139    return ret;
140}
141
142struct _krb5_encryption_type _krb5_enctype_aes128_cts_hmac_sha1 = {
143    ETYPE_AES128_CTS_HMAC_SHA1_96,
144    "aes128-cts-hmac-sha1-96",
145    16,
146    1,
147    16,
148    &keytype_aes128,
149    &_krb5_checksum_sha1,
150    &_krb5_checksum_hmac_sha1_aes128,
151    F_DERIVED,
152    _krb5_evp_encrypt_cts,
153    16,
154    AES_PRF
155};
156
157struct _krb5_encryption_type _krb5_enctype_aes256_cts_hmac_sha1 = {
158    ETYPE_AES256_CTS_HMAC_SHA1_96,
159    "aes256-cts-hmac-sha1-96",
160    16,
161    1,
162    16,
163    &keytype_aes256,
164    &_krb5_checksum_sha1,
165    &_krb5_checksum_hmac_sha1_aes256,
166    F_DERIVED,
167    _krb5_evp_encrypt_cts,
168    16,
169    AES_PRF
170};
171