xref: /netbsd-src/crypto/external/bsd/heimdal/dist/lib/krb5/crypto-des3.c (revision afab4e300d3a9fb07dd8c80daf53d0feb3345706)
1*afab4e30Schristos /*	$NetBSD: crypto-des3.c,v 1.7 2023/06/19 21:41:44 christos Exp $	*/
2ca1c9b0cSelric 
3ca1c9b0cSelric /*
4ca1c9b0cSelric  * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
5ca1c9b0cSelric  * (Royal Institute of Technology, Stockholm, Sweden).
6ca1c9b0cSelric  * All rights reserved.
7ca1c9b0cSelric  *
8ca1c9b0cSelric  * Redistribution and use in source and binary forms, with or without
9ca1c9b0cSelric  * modification, are permitted provided that the following conditions
10ca1c9b0cSelric  * are met:
11ca1c9b0cSelric  *
12ca1c9b0cSelric  * 1. Redistributions of source code must retain the above copyright
13ca1c9b0cSelric  *    notice, this list of conditions and the following disclaimer.
14ca1c9b0cSelric  *
15ca1c9b0cSelric  * 2. Redistributions in binary form must reproduce the above copyright
16ca1c9b0cSelric  *    notice, this list of conditions and the following disclaimer in the
17ca1c9b0cSelric  *    documentation and/or other materials provided with the distribution.
18ca1c9b0cSelric  *
19ca1c9b0cSelric  * 3. Neither the name of the Institute nor the names of its contributors
20ca1c9b0cSelric  *    may be used to endorse or promote products derived from this software
21ca1c9b0cSelric  *    without specific prior written permission.
22ca1c9b0cSelric  *
23ca1c9b0cSelric  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24ca1c9b0cSelric  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ca1c9b0cSelric  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ca1c9b0cSelric  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27ca1c9b0cSelric  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28ca1c9b0cSelric  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29ca1c9b0cSelric  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30ca1c9b0cSelric  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31ca1c9b0cSelric  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32ca1c9b0cSelric  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33ca1c9b0cSelric  * SUCH DAMAGE.
34ca1c9b0cSelric  */
35ca1c9b0cSelric 
36ca1c9b0cSelric #include "krb5_locl.h"
37ca1c9b0cSelric 
38ca1c9b0cSelric /*
39ca1c9b0cSelric  *
40ca1c9b0cSelric  */
41ca1c9b0cSelric 
42ca1c9b0cSelric static void
DES3_random_key(krb5_context context,krb5_keyblock * key)43ca1c9b0cSelric DES3_random_key(krb5_context context,
44ca1c9b0cSelric 		krb5_keyblock *key)
45ca1c9b0cSelric {
46ca1c9b0cSelric     DES_cblock *k = key->keyvalue.data;
47ca1c9b0cSelric     do {
48ca1c9b0cSelric 	krb5_generate_random_block(k, 3 * sizeof(DES_cblock));
49ca1c9b0cSelric 	DES_set_odd_parity(&k[0]);
50ca1c9b0cSelric 	DES_set_odd_parity(&k[1]);
51ca1c9b0cSelric 	DES_set_odd_parity(&k[2]);
52ca1c9b0cSelric     } while(DES_is_weak_key(&k[0]) ||
53ca1c9b0cSelric 	    DES_is_weak_key(&k[1]) ||
54ca1c9b0cSelric 	    DES_is_weak_key(&k[2]));
55ca1c9b0cSelric }
56ca1c9b0cSelric 
57d3273b5bSchristos static krb5_error_code
DES3_prf(krb5_context context,krb5_crypto crypto,const krb5_data * in,krb5_data * out)58d3273b5bSchristos DES3_prf(krb5_context context,
59d3273b5bSchristos 	 krb5_crypto crypto,
60d3273b5bSchristos 	 const krb5_data *in,
61d3273b5bSchristos 	 krb5_data *out)
62d3273b5bSchristos {
63d3273b5bSchristos     struct _krb5_checksum_type *ct = crypto->et->checksum;
64d3273b5bSchristos     krb5_error_code ret;
65d3273b5bSchristos     Checksum result;
66d3273b5bSchristos     krb5_keyblock *derived;
67d3273b5bSchristos 
68d3273b5bSchristos     result.cksumtype = ct->type;
69d3273b5bSchristos     ret = krb5_data_alloc(&result.checksum, ct->checksumsize);
70d3273b5bSchristos     if (ret) {
71d3273b5bSchristos 	krb5_set_error_message(context, ret, N_("malloc: out memory", ""));
72d3273b5bSchristos 	return ret;
73d3273b5bSchristos     }
74d3273b5bSchristos 
75d3273b5bSchristos     ret = (*ct->checksum)(context, NULL, in->data, in->length, 0, &result);
76d3273b5bSchristos     if (ret) {
77d3273b5bSchristos 	krb5_data_free(&result.checksum);
78d3273b5bSchristos 	return ret;
79d3273b5bSchristos     }
80d3273b5bSchristos 
81d3273b5bSchristos     if (result.checksum.length < crypto->et->blocksize)
82d3273b5bSchristos 	krb5_abortx(context, "internal prf error");
83d3273b5bSchristos 
84d3273b5bSchristos     derived = NULL;
85d3273b5bSchristos     ret = krb5_derive_key(context, crypto->key.key,
86d3273b5bSchristos 			  crypto->et->type, "prf", 3, &derived);
87d3273b5bSchristos     if (ret)
88d3273b5bSchristos 	krb5_abortx(context, "krb5_derive_key");
89d3273b5bSchristos 
90d3273b5bSchristos     ret = krb5_data_alloc(out, crypto->et->prf_length);
91d3273b5bSchristos     if (ret)
92d3273b5bSchristos 	krb5_abortx(context, "malloc failed");
93d3273b5bSchristos 
94d3273b5bSchristos     {
95d3273b5bSchristos 	const EVP_CIPHER *c = (*crypto->et->keytype->evp)();
966680b65dSchristos 	EVP_CIPHER_CTX *ctx;
976680b65dSchristos #if OPENSSL_VERSION_NUMBER < 0x10100000UL
986680b65dSchristos 	EVP_CIPHER_CTX ctxst;
996680b65dSchristos 	ctx = &ctxst;
1006680b65dSchristos 	EVP_CIPHER_CTX_init(ctx);
1016680b65dSchristos #else
1026680b65dSchristos 	ctx = EVP_CIPHER_CTX_new();
1036680b65dSchristos #endif
1047b2118deSchristos 	if (!EVP_CipherInit_ex(ctx, c, NULL, derived->keyvalue.data, NULL, 1))
1057b2118deSchristos 	    krb5_abortx(context, "can't initialize cipher");
1066680b65dSchristos 	EVP_Cipher(ctx, out->data, result.checksum.data,
107d3273b5bSchristos 		   crypto->et->prf_length);
1086680b65dSchristos #if OPENSSL_VERSION_NUMBER < 0x10100000UL
1096680b65dSchristos 	EVP_CIPHER_CTX_cleanup(ctx);
1106680b65dSchristos #else
1116680b65dSchristos 	EVP_CIPHER_CTX_free(ctx);
1126680b65dSchristos #endif
113d3273b5bSchristos     }
114d3273b5bSchristos 
115d3273b5bSchristos     krb5_data_free(&result.checksum);
116d3273b5bSchristos     krb5_free_keyblock(context, derived);
117d3273b5bSchristos 
118d3273b5bSchristos     return ret;
119d3273b5bSchristos }
120ca1c9b0cSelric 
121ca1c9b0cSelric #ifdef DES3_OLD_ENCTYPE
122ca1c9b0cSelric static struct _krb5_key_type keytype_des3 = {
1239641b56eSpettai     ETYPE_OLD_DES3_CBC_SHA1,
124ca1c9b0cSelric     "des3",
125ca1c9b0cSelric     168,
126ca1c9b0cSelric     24,
127ca1c9b0cSelric     sizeof(struct _krb5_evp_schedule),
128ca1c9b0cSelric     DES3_random_key,
129ca1c9b0cSelric     _krb5_evp_schedule,
130ca1c9b0cSelric     _krb5_des3_salt,
131ca1c9b0cSelric     _krb5_DES3_random_to_key,
132ca1c9b0cSelric     _krb5_evp_cleanup,
133ca1c9b0cSelric     EVP_des_ede3_cbc
134ca1c9b0cSelric };
135ca1c9b0cSelric #endif
136ca1c9b0cSelric 
137ca1c9b0cSelric static struct _krb5_key_type keytype_des3_derived = {
1389641b56eSpettai     ETYPE_OLD_DES3_CBC_SHA1,
139ca1c9b0cSelric     "des3",
140ca1c9b0cSelric     168,
141ca1c9b0cSelric     24,
142ca1c9b0cSelric     sizeof(struct _krb5_evp_schedule),
143ca1c9b0cSelric     DES3_random_key,
144ca1c9b0cSelric     _krb5_evp_schedule,
145ca1c9b0cSelric     _krb5_des3_salt_derived,
146ca1c9b0cSelric     _krb5_DES3_random_to_key,
147ca1c9b0cSelric     _krb5_evp_cleanup,
148ca1c9b0cSelric     EVP_des_ede3_cbc
149ca1c9b0cSelric };
150ca1c9b0cSelric 
151ca1c9b0cSelric #ifdef DES3_OLD_ENCTYPE
152ca1c9b0cSelric static krb5_error_code
RSA_MD5_DES3_checksum(krb5_context context,struct _krb5_key_data * key,const void * data,size_t len,unsigned usage,Checksum * C)153ca1c9b0cSelric RSA_MD5_DES3_checksum(krb5_context context,
154ca1c9b0cSelric 		      struct _krb5_key_data *key,
155ca1c9b0cSelric 		      const void *data,
156ca1c9b0cSelric 		      size_t len,
157ca1c9b0cSelric 		      unsigned usage,
158ca1c9b0cSelric 		      Checksum *C)
159ca1c9b0cSelric {
160ca1c9b0cSelric     return _krb5_des_checksum(context, EVP_md5(), key, data, len, C);
161ca1c9b0cSelric }
162ca1c9b0cSelric 
163ca1c9b0cSelric static krb5_error_code
RSA_MD5_DES3_verify(krb5_context context,struct _krb5_key_data * key,const void * data,size_t len,unsigned usage,Checksum * C)164ca1c9b0cSelric RSA_MD5_DES3_verify(krb5_context context,
165ca1c9b0cSelric 		    struct _krb5_key_data *key,
166ca1c9b0cSelric 		    const void *data,
167ca1c9b0cSelric 		    size_t len,
168ca1c9b0cSelric 		    unsigned usage,
169ca1c9b0cSelric 		    Checksum *C)
170ca1c9b0cSelric {
171ca1c9b0cSelric     return _krb5_des_verify(context, EVP_md5(), key, data, len, C);
172ca1c9b0cSelric }
173ca1c9b0cSelric 
174ca1c9b0cSelric struct _krb5_checksum_type _krb5_checksum_rsa_md5_des3 = {
175ca1c9b0cSelric     CKSUMTYPE_RSA_MD5_DES3,
176ca1c9b0cSelric     "rsa-md5-des3",
177ca1c9b0cSelric     64,
178ca1c9b0cSelric     24,
179ca1c9b0cSelric     F_KEYED | F_CPROOF | F_VARIANT,
180ca1c9b0cSelric     RSA_MD5_DES3_checksum,
181ca1c9b0cSelric     RSA_MD5_DES3_verify
182ca1c9b0cSelric };
183ca1c9b0cSelric #endif
184ca1c9b0cSelric 
185ca1c9b0cSelric struct _krb5_checksum_type _krb5_checksum_hmac_sha1_des3 = {
186ca1c9b0cSelric     CKSUMTYPE_HMAC_SHA1_DES3,
187ca1c9b0cSelric     "hmac-sha1-des3",
188ca1c9b0cSelric     64,
189ca1c9b0cSelric     20,
190ca1c9b0cSelric     F_KEYED | F_CPROOF | F_DERIVED,
191ca1c9b0cSelric     _krb5_SP_HMAC_SHA1_checksum,
192ca1c9b0cSelric     NULL
193ca1c9b0cSelric };
194ca1c9b0cSelric 
195ca1c9b0cSelric #ifdef DES3_OLD_ENCTYPE
196ca1c9b0cSelric struct _krb5_encryption_type _krb5_enctype_des3_cbc_md5 = {
197ca1c9b0cSelric     ETYPE_DES3_CBC_MD5,
198ca1c9b0cSelric     "des3-cbc-md5",
199d3273b5bSchristos     NULL,
200ca1c9b0cSelric     8,
201ca1c9b0cSelric     8,
202ca1c9b0cSelric     8,
203ca1c9b0cSelric     &keytype_des3,
204ca1c9b0cSelric     &_krb5_checksum_rsa_md5,
205ca1c9b0cSelric     &_krb5_checksum_rsa_md5_des3,
206ca1c9b0cSelric     0,
207ca1c9b0cSelric     _krb5_evp_encrypt,
208ca1c9b0cSelric     0,
209ca1c9b0cSelric     NULL
210ca1c9b0cSelric };
211ca1c9b0cSelric #endif
212ca1c9b0cSelric 
213ca1c9b0cSelric struct _krb5_encryption_type _krb5_enctype_des3_cbc_sha1 = {
214ca1c9b0cSelric     ETYPE_DES3_CBC_SHA1,
215ca1c9b0cSelric     "des3-cbc-sha1",
216d3273b5bSchristos     NULL,
217ca1c9b0cSelric     8,
218ca1c9b0cSelric     8,
219ca1c9b0cSelric     8,
220ca1c9b0cSelric     &keytype_des3_derived,
221ca1c9b0cSelric     &_krb5_checksum_sha1,
222ca1c9b0cSelric     &_krb5_checksum_hmac_sha1_des3,
223d3273b5bSchristos     F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF,
224ca1c9b0cSelric     _krb5_evp_encrypt,
225d3273b5bSchristos     16,
226d3273b5bSchristos     DES3_prf
227ca1c9b0cSelric };
228ca1c9b0cSelric 
229ca1c9b0cSelric #ifdef DES3_OLD_ENCTYPE
230ca1c9b0cSelric struct _krb5_encryption_type _krb5_enctype_old_des3_cbc_sha1 = {
231ca1c9b0cSelric     ETYPE_OLD_DES3_CBC_SHA1,
232ca1c9b0cSelric     "old-des3-cbc-sha1",
233d3273b5bSchristos     NULL,
234ca1c9b0cSelric     8,
235ca1c9b0cSelric     8,
236ca1c9b0cSelric     8,
237ca1c9b0cSelric     &keytype_des3,
238ca1c9b0cSelric     &_krb5_checksum_sha1,
239ca1c9b0cSelric     &_krb5_checksum_hmac_sha1_des3,
240ca1c9b0cSelric     0,
241ca1c9b0cSelric     _krb5_evp_encrypt,
242ca1c9b0cSelric     0,
243ca1c9b0cSelric     NULL
244ca1c9b0cSelric };
245ca1c9b0cSelric #endif
246ca1c9b0cSelric 
247ca1c9b0cSelric struct _krb5_encryption_type _krb5_enctype_des3_cbc_none = {
248ca1c9b0cSelric     ETYPE_DES3_CBC_NONE,
249ca1c9b0cSelric     "des3-cbc-none",
250d3273b5bSchristos     NULL,
251ca1c9b0cSelric     8,
252ca1c9b0cSelric     8,
253ca1c9b0cSelric     0,
254ca1c9b0cSelric     &keytype_des3_derived,
255ca1c9b0cSelric     &_krb5_checksum_none,
256ca1c9b0cSelric     NULL,
257ca1c9b0cSelric     F_PSEUDO,
258ca1c9b0cSelric     _krb5_evp_encrypt,
259ca1c9b0cSelric     0,
260ca1c9b0cSelric     NULL
261ca1c9b0cSelric };
262ca1c9b0cSelric 
263ca1c9b0cSelric void
_krb5_DES3_random_to_key(krb5_context context,krb5_keyblock * key,const void * data,size_t size)264ca1c9b0cSelric _krb5_DES3_random_to_key(krb5_context context,
265ca1c9b0cSelric 			 krb5_keyblock *key,
266ca1c9b0cSelric 			 const void *data,
267ca1c9b0cSelric 			 size_t size)
268ca1c9b0cSelric {
269ca1c9b0cSelric     unsigned char *x = key->keyvalue.data;
270ca1c9b0cSelric     const u_char *q = data;
271ca1c9b0cSelric     DES_cblock *k;
272ca1c9b0cSelric     int i, j;
273ca1c9b0cSelric 
2749641b56eSpettai     memset(key->keyvalue.data, 0, key->keyvalue.length);
275ca1c9b0cSelric     for (i = 0; i < 3; ++i) {
276ca1c9b0cSelric 	unsigned char foo;
277ca1c9b0cSelric 	for (j = 0; j < 7; ++j) {
278ca1c9b0cSelric 	    unsigned char b = q[7 * i + j];
279ca1c9b0cSelric 
280ca1c9b0cSelric 	    x[8 * i + j] = b;
281ca1c9b0cSelric 	}
282ca1c9b0cSelric 	foo = 0;
283ca1c9b0cSelric 	for (j = 6; j >= 0; --j) {
284ca1c9b0cSelric 	    foo |= q[7 * i + j] & 1;
285ca1c9b0cSelric 	    foo <<= 1;
286ca1c9b0cSelric 	}
287ca1c9b0cSelric 	x[8 * i + 7] = foo;
288ca1c9b0cSelric     }
289ca1c9b0cSelric     k = key->keyvalue.data;
290ca1c9b0cSelric     for (i = 0; i < 3; i++) {
291ca1c9b0cSelric 	DES_set_odd_parity(&k[i]);
292ca1c9b0cSelric 	if(DES_is_weak_key(&k[i]))
293d3273b5bSchristos 	    _krb5_xor8(k[i], (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
294ca1c9b0cSelric     }
295ca1c9b0cSelric }
296