1/*	$NetBSD: crypto-aes-sha2.c,v 1.2 2017/01/28 21:31:49 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 HMAC-SHA2
40 */
41
42krb5_error_code
43_krb5_aes_sha2_md_for_enctype(krb5_context context,
44			      krb5_enctype enctype,
45			      const EVP_MD **md)
46{
47    switch (enctype) {
48    case ETYPE_AES128_CTS_HMAC_SHA256_128:
49	*md = EVP_sha256();
50	break;
51    case ETYPE_AES256_CTS_HMAC_SHA384_192:
52	*md = EVP_sha384();
53	break;
54    default:
55	return KRB5_PROG_ETYPE_NOSUPP;
56	break;
57    }
58    return 0;
59}
60
61static krb5_error_code
62SP_HMAC_SHA2_checksum(krb5_context context,
63		      struct _krb5_key_data *key,
64		      const void *data,
65		      size_t len,
66		      unsigned usage,
67		      Checksum *result)
68{
69    krb5_error_code ret;
70    const EVP_MD *md;
71    unsigned char hmac[EVP_MAX_MD_SIZE];
72    unsigned int hmaclen = sizeof(hmac);
73
74    ret = _krb5_aes_sha2_md_for_enctype(context, key->key->keytype, &md);
75    if (ret)
76	return ret;
77
78    HMAC(md, key->key->keyvalue.data, key->key->keyvalue.length,
79	 data, len, hmac, &hmaclen);
80
81    heim_assert(result->checksum.length <= hmaclen, "SHA2 internal error");
82
83    memcpy(result->checksum.data, hmac, result->checksum.length);
84
85    return 0;
86}
87
88static struct _krb5_key_type keytype_aes128_sha2 = {
89    KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128,
90    "aes-128-sha2",
91    128,
92    16,
93    sizeof(struct _krb5_evp_schedule),
94    NULL,
95    _krb5_evp_schedule,
96    _krb5_AES_SHA2_salt,
97    NULL,
98    _krb5_evp_cleanup,
99    EVP_aes_128_cbc
100};
101
102static struct _krb5_key_type keytype_aes256_sha2 = {
103    KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192,
104    "aes-256-sha2",
105    256,
106    32,
107    sizeof(struct _krb5_evp_schedule),
108    NULL,
109    _krb5_evp_schedule,
110    _krb5_AES_SHA2_salt,
111    NULL,
112    _krb5_evp_cleanup,
113    EVP_aes_256_cbc
114};
115
116struct _krb5_checksum_type _krb5_checksum_hmac_sha256_128_aes128 = {
117    CKSUMTYPE_HMAC_SHA256_128_AES128,
118    "hmac-sha256-128-aes128",
119    64,
120    16,
121    F_KEYED | F_CPROOF | F_DERIVED,
122    SP_HMAC_SHA2_checksum,
123    NULL
124};
125
126struct _krb5_checksum_type _krb5_checksum_hmac_sha384_192_aes256 = {
127    CKSUMTYPE_HMAC_SHA384_192_AES256,
128    "hmac-sha384-192-aes256",
129    128,
130    24,
131    F_KEYED | F_CPROOF | F_DERIVED,
132    SP_HMAC_SHA2_checksum,
133    NULL
134};
135
136static krb5_error_code
137AES_SHA2_PRF(krb5_context context,
138	     krb5_crypto crypto,
139	     const krb5_data *in,
140	     krb5_data *out)
141{
142    krb5_error_code ret;
143    krb5_data label;
144    const EVP_MD *md = NULL;
145
146    ret = _krb5_aes_sha2_md_for_enctype(context, crypto->et->type, &md);
147    if (ret)
148	return ret;
149
150    label.data = "prf";
151    label.length = 3;
152
153    ret = krb5_data_alloc(out, EVP_MD_size(md));
154    if (ret)
155	return ret;
156
157    ret = _krb5_SP800_108_HMAC_KDF(context, &crypto->key.key->keyvalue,
158				   &label, in, md, out);
159
160    if (ret)
161	krb5_data_free(out);
162
163    return ret;
164}
165
166struct _krb5_encryption_type _krb5_enctype_aes128_cts_hmac_sha256_128 = {
167    ETYPE_AES128_CTS_HMAC_SHA256_128,
168    "aes128-cts-hmac-sha256-128",
169    "aes128-cts-sha256",
170    16,
171    1,
172    16,
173    &keytype_aes128_sha2,
174    NULL, /* should never be called */
175    &_krb5_checksum_hmac_sha256_128_aes128,
176    F_DERIVED | F_ENC_THEN_CKSUM | F_SP800_108_HMAC_KDF,
177    _krb5_evp_encrypt_cts,
178    16,
179    AES_SHA2_PRF
180};
181
182struct _krb5_encryption_type _krb5_enctype_aes256_cts_hmac_sha384_192 = {
183    ETYPE_AES256_CTS_HMAC_SHA384_192,
184    "aes256-cts-hmac-sha384-192",
185    "aes256-cts-sha384",
186    16,
187    1,
188    16,
189    &keytype_aes256_sha2,
190    NULL, /* should never be called */
191    &_krb5_checksum_hmac_sha384_192_aes256,
192    F_DERIVED | F_ENC_THEN_CKSUM | F_SP800_108_HMAC_KDF,
193    _krb5_evp_encrypt_cts,
194    16,
195    AES_SHA2_PRF
196};
197