1/*	$NetBSD: crypto-aes-sha1.c,v 1.5 2023/06/19 21:41:44 christos Exp $	*/
2
3/*
4 * Copyright (c) 1997 - 2008 Kungliga Tekniska H��gskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the Institute nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include "krb5_locl.h"
37
38/*
39 * AES
40 */
41
42static struct _krb5_key_type keytype_aes128_sha1 = {
43    KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96,
44    "aes-128",
45    128,
46    16,
47    sizeof(struct _krb5_evp_schedule),
48    NULL,
49    _krb5_evp_schedule,
50    _krb5_AES_SHA1_salt,
51    NULL,
52    _krb5_evp_cleanup,
53    EVP_aes_128_cbc
54};
55
56static struct _krb5_key_type keytype_aes256_sha1 = {
57    KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96,
58    "aes-256",
59    256,
60    32,
61    sizeof(struct _krb5_evp_schedule),
62    NULL,
63    _krb5_evp_schedule,
64    _krb5_AES_SHA1_salt,
65    NULL,
66    _krb5_evp_cleanup,
67    EVP_aes_256_cbc
68};
69
70struct _krb5_checksum_type _krb5_checksum_hmac_sha1_aes128 = {
71    CKSUMTYPE_HMAC_SHA1_96_AES_128,
72    "hmac-sha1-96-aes128",
73    64,
74    12,
75    F_KEYED | F_CPROOF | F_DERIVED,
76    _krb5_SP_HMAC_SHA1_checksum,
77    NULL
78};
79
80struct _krb5_checksum_type _krb5_checksum_hmac_sha1_aes256 = {
81    CKSUMTYPE_HMAC_SHA1_96_AES_256,
82    "hmac-sha1-96-aes256",
83    64,
84    12,
85    F_KEYED | F_CPROOF | F_DERIVED,
86    _krb5_SP_HMAC_SHA1_checksum,
87    NULL
88};
89
90static krb5_error_code
91AES_SHA1_PRF(krb5_context context,
92	     krb5_crypto crypto,
93	     const krb5_data *in,
94	     krb5_data *out)
95{
96    struct _krb5_checksum_type *ct = crypto->et->checksum;
97    krb5_error_code ret;
98    Checksum result;
99    krb5_keyblock *derived;
100
101    result.cksumtype = ct->type;
102    ret = krb5_data_alloc(&result.checksum, ct->checksumsize);
103    if (ret) {
104	krb5_set_error_message(context, ret, N_("malloc: out memory", ""));
105	return ret;
106    }
107
108    ret = (*ct->checksum)(context, NULL, in->data, in->length, 0, &result);
109    if (ret) {
110	krb5_data_free(&result.checksum);
111	return ret;
112    }
113
114    if (result.checksum.length < crypto->et->blocksize)
115	krb5_abortx(context, "internal prf error");
116
117    derived = NULL;
118    ret = krb5_derive_key(context, crypto->key.key,
119			  crypto->et->type, "prf", 3, &derived);
120    if (ret)
121	krb5_abortx(context, "krb5_derive_key");
122
123    ret = krb5_data_alloc(out, crypto->et->blocksize);
124    if (ret)
125	krb5_abortx(context, "malloc failed");
126
127    {
128	const EVP_CIPHER *c = (*crypto->et->keytype->evp)();
129	EVP_CIPHER_CTX *ctx;
130#if OPENSSL_VERSION_NUMBER < 0x10100000UL
131	EVP_CIPHER_CTX ctxst;
132	ctx = &ctxst;
133	EVP_CIPHER_CTX_init(ctx); /* ivec all zero */
134#else
135	ctx = EVP_CIPHER_CTX_new(); /* ivec all zero */
136#endif
137	if (EVP_CipherInit_ex(ctx, c, NULL, derived->keyvalue.data, NULL, 1)) {
138	    EVP_Cipher(ctx, out->data, result.checksum.data,
139		       crypto->et->blocksize);
140	    ret = EINVAL;
141	    krb5_set_error_message(context, ret, "Cannot initialize cipher");
142	}
143#if OPENSSL_VERSION_NUMBER < 0x10100000UL
144	EVP_CIPHER_CTX_cleanup(ctx);
145#else
146	EVP_CIPHER_CTX_free(ctx);
147#endif
148    }
149
150    krb5_data_free(&result.checksum);
151    krb5_free_keyblock(context, derived);
152
153    return ret;
154}
155
156struct _krb5_encryption_type _krb5_enctype_aes128_cts_hmac_sha1 = {
157    ETYPE_AES128_CTS_HMAC_SHA1_96,
158    "aes128-cts-hmac-sha1-96",
159    "aes128-cts",
160    16,
161    1,
162    16,
163    &keytype_aes128_sha1,
164    &_krb5_checksum_sha1,
165    &_krb5_checksum_hmac_sha1_aes128,
166    F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF,
167    _krb5_evp_encrypt_cts,
168    16,
169    AES_SHA1_PRF
170};
171
172struct _krb5_encryption_type _krb5_enctype_aes256_cts_hmac_sha1 = {
173    ETYPE_AES256_CTS_HMAC_SHA1_96,
174    "aes256-cts-hmac-sha1-96",
175    "aes256-cts",
176    16,
177    1,
178    16,
179    &keytype_aes256_sha1,
180    &_krb5_checksum_sha1,
181    &_krb5_checksum_hmac_sha1_aes256,
182    F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF,
183    _krb5_evp_encrypt_cts,
184    16,
185    AES_SHA1_PRF
186};
187