xref: /xnu-10002.61.3/bsd/netinet6/esp_core.c (revision 0f4c859e951fba394238ab619495c4e1d54d0f34)
1 /*
2  * Copyright (c) 2008-2023 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 /*	$FreeBSD: src/sys/netinet6/esp_core.c,v 1.1.2.4 2002/03/26 10:12:29 ume Exp $	*/
30 /*	$KAME: esp_core.c,v 1.50 2000/11/02 12:27:38 itojun Exp $	*/
31 
32 /*
33  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34  * All rights reserved.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  * 2. Redistributions in binary form must reproduce the above copyright
42  *    notice, this list of conditions and the following disclaimer in the
43  *    documentation and/or other materials provided with the distribution.
44  * 3. Neither the name of the project nor the names of its contributors
45  *    may be used to endorse or promote products derived from this software
46  *    without specific prior written permission.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58  * SUCH DAMAGE.
59  */
60 
61 #define _IP_VHL
62 
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/malloc.h>
66 #include <sys/mbuf.h>
67 #include <sys/domain.h>
68 #include <sys/protosw.h>
69 #include <sys/socket.h>
70 #include <sys/errno.h>
71 #include <sys/time.h>
72 #include <sys/kernel.h>
73 #include <sys/syslog.h>
74 
75 #include <kern/locks.h>
76 
77 #include <net/if.h>
78 #include <net/multi_layer_pkt_log.h>
79 #include <net/route.h>
80 
81 #include <netinet/in.h>
82 #include <netinet/in_var.h>
83 #include <netinet/ip6.h>
84 #include <netinet6/ip6_var.h>
85 #include <netinet/icmp6.h>
86 
87 #include <netinet6/ipsec.h>
88 #include <netinet6/ipsec6.h>
89 #include <netinet6/ah.h>
90 #include <netinet6/ah6.h>
91 #include <netinet6/esp.h>
92 #include <netinet6/esp6.h>
93 #include <netinet6/esp_rijndael.h>
94 #include <netinet6/esp_chachapoly.h>
95 #include <net/pfkeyv2.h>
96 #include <netkey/keydb.h>
97 #include <netkey/key.h>
98 #include <libkern/crypto/des.h>
99 
100 #include <net/net_osdep.h>
101 
102 #include <sys/kdebug.h>
103 #define DBG_LAYER_BEG           NETDBG_CODE(DBG_NETIPSEC, 1)
104 #define DBG_LAYER_END           NETDBG_CODE(DBG_NETIPSEC, 3)
105 #define DBG_FNC_ESPAUTH         NETDBG_CODE(DBG_NETIPSEC, (8 << 8))
106 #define MAX_SBUF_LEN            2000
107 
108 os_log_t esp_mpkl_log_object = NULL;
109 
110 static int esp_null_mature(struct secasvar *);
111 static int esp_null_decrypt(struct mbuf *, size_t,
112     struct secasvar *, const struct esp_algorithm *, int);
113 static int esp_null_encrypt(struct mbuf *, size_t, size_t,
114     struct secasvar *, const struct esp_algorithm *, int);
115 static int esp_descbc_mature(struct secasvar *);
116 static int esp_descbc_ivlen(const struct esp_algorithm *,
117     struct secasvar *);
118 static int esp_des_schedule(const struct esp_algorithm *,
119     struct secasvar *);
120 static size_t esp_des_schedlen(const struct esp_algorithm *);
121 static int esp_des_blockdecrypt(const struct esp_algorithm *,
122     struct secasvar *, u_int8_t *, u_int8_t *);
123 static int esp_des_blockencrypt(const struct esp_algorithm *,
124     struct secasvar *, u_int8_t *, u_int8_t *);
125 static int esp_cbc_mature(struct secasvar *);
126 static int esp_3des_schedule(const struct esp_algorithm *,
127     struct secasvar *);
128 static size_t esp_3des_schedlen(const struct esp_algorithm *);
129 static int esp_3des_blockdecrypt(const struct esp_algorithm *,
130     struct secasvar *, u_int8_t *, u_int8_t *);
131 static int esp_3des_blockencrypt(const struct esp_algorithm *,
132     struct secasvar *, u_int8_t *, u_int8_t *);
133 static int esp_common_ivlen(const struct esp_algorithm *,
134     struct secasvar *);
135 static int esp_cbc_decrypt(struct mbuf *, size_t,
136     struct secasvar *, const struct esp_algorithm *, int);
137 static int esp_cbc_encrypt(struct mbuf *, size_t, size_t,
138     struct secasvar *, const struct esp_algorithm *, int);
139 static int esp_gcm_mature(struct secasvar *);
140 static int esp_cbc_des_encrypt_data(struct secasvar *, uint8_t *,
141     size_t, struct newesp *, uint8_t *, size_t, uint8_t *, size_t);
142 static int esp_cbc_des_decrypt_data(struct secasvar *, uint8_t *,
143     size_t, struct newesp *, uint8_t *, size_t, uint8_t *, size_t);
144 static int esp_cbc_3des_encrypt_data(struct secasvar *, uint8_t *,
145     size_t, struct newesp *, uint8_t *, size_t, uint8_t *, size_t);
146 static int esp_cbc_3des_decrypt_data(struct secasvar *, uint8_t *,
147     size_t, struct newesp *, uint8_t *, size_t, uint8_t *, size_t);
148 static int esp_null_encrypt_data(struct secasvar *, uint8_t *,
149     size_t, struct newesp *, uint8_t *, size_t, uint8_t *, size_t);
150 static int esp_null_decrypt_data(struct secasvar *, uint8_t *,
151     size_t, struct newesp *, uint8_t *, size_t, uint8_t *, size_t);
152 
153 #define MAXIVLEN        16
154 
155 #define ESP_AESGCM_KEYLEN128 160 // 16-bytes key + 4 bytes salt
156 #define ESP_AESGCM_KEYLEN192 224 // 24-bytes key + 4 bytes salt
157 #define ESP_AESGCM_KEYLEN256 288 // 32-bytes key + 4 bytes salt
158 
159 static const struct esp_algorithm des_cbc = {
160 	.padbound = 8,
161 	.ivlenval = -1,
162 	.mature = esp_descbc_mature,
163 	.keymin = 64,
164 	.keymax = 64,
165 	.schedlen = esp_des_schedlen,
166 	.name = "des-cbc",
167 	.ivlen = esp_descbc_ivlen,
168 	.decrypt = esp_cbc_decrypt,
169 	.encrypt = esp_cbc_encrypt,
170 	.schedule = esp_des_schedule,
171 	.blockdecrypt = esp_des_blockdecrypt,
172 	.blockencrypt = esp_des_blockencrypt,
173 	.icvlen = 0,
174 	.finalizedecrypt = NULL,
175 	.finalizeencrypt = NULL,
176 	.encrypt_pkt = esp_cbc_des_encrypt_data,
177 	.decrypt_pkt = esp_cbc_des_decrypt_data
178 };
179 
180 static const struct esp_algorithm des3_cbc = {
181 	.padbound = 8,
182 	.ivlenval = 8,
183 	.mature = esp_cbc_mature,
184 	.keymin = 192,
185 	.keymax = 192,
186 	.schedlen = esp_3des_schedlen,
187 	.name = "3des-cbc",
188 	.ivlen = esp_common_ivlen,
189 	.decrypt = esp_cbc_decrypt,
190 	.encrypt = esp_cbc_encrypt,
191 	.schedule = esp_3des_schedule,
192 	.blockdecrypt = esp_3des_blockdecrypt,
193 	.blockencrypt = esp_3des_blockencrypt,
194 	.icvlen = 0,
195 	.finalizedecrypt = NULL,
196 	.finalizeencrypt = NULL,
197 	.encrypt_pkt = esp_cbc_3des_encrypt_data,
198 	.decrypt_pkt = esp_cbc_3des_decrypt_data
199 };
200 
201 static const struct esp_algorithm null_esp = {
202 	.padbound = 1,
203 	.ivlenval = 0,
204 	.mature = esp_null_mature,
205 	.keymin = 0,
206 	.keymax = 2048,
207 	.schedlen = NULL,
208 	.name = "null",
209 	.ivlen = esp_common_ivlen,
210 	.decrypt = esp_null_decrypt,
211 	.encrypt = esp_null_encrypt,
212 	.schedule = NULL,
213 	.blockdecrypt = NULL,
214 	.blockencrypt = NULL,
215 	.icvlen = 0,
216 	.finalizedecrypt = NULL,
217 	.finalizeencrypt = NULL,
218 	.encrypt_pkt = esp_null_encrypt_data,
219 	.decrypt_pkt = esp_null_decrypt_data
220 };
221 
222 static const struct esp_algorithm aes_cbc = {
223 	.padbound = 16,
224 	.ivlenval = 16,
225 	.mature = esp_cbc_mature,
226 	.keymin = 128,
227 	.keymax = 256,
228 	.schedlen = esp_aes_schedlen,
229 	.name = "aes-cbc",
230 	.ivlen = esp_common_ivlen,
231 	.decrypt = esp_cbc_decrypt_aes,
232 	.encrypt = esp_cbc_encrypt_aes,
233 	.schedule = esp_aes_schedule,
234 	.blockdecrypt = NULL,
235 	.blockencrypt = NULL,
236 	.icvlen = 0,
237 	.finalizedecrypt = NULL,
238 	.finalizeencrypt = NULL,
239 	.encrypt_pkt = esp_aes_cbc_encrypt_data,
240 	.decrypt_pkt = esp_aes_cbc_decrypt_data
241 };
242 
243 static const struct esp_algorithm aes_gcm = {
244 	.padbound = 4,
245 	.ivlenval = 8,
246 	.mature = esp_gcm_mature,
247 	.keymin = ESP_AESGCM_KEYLEN128,
248 	.keymax = ESP_AESGCM_KEYLEN256,
249 	.schedlen = esp_gcm_schedlen,
250 	.name = "aes-gcm",
251 	.ivlen = esp_gcm_ivlen,
252 	.decrypt = esp_gcm_decrypt_aes,
253 	.encrypt = esp_gcm_encrypt_aes,
254 	.schedule = esp_gcm_schedule,
255 	.blockdecrypt = NULL,
256 	.blockencrypt = NULL,
257 	.icvlen = 16,
258 	.finalizedecrypt = esp_gcm_decrypt_finalize,
259 	.finalizeencrypt = esp_gcm_encrypt_finalize,
260 	.encrypt_pkt = esp_aes_gcm_encrypt_data,
261 	.decrypt_pkt = esp_aes_gcm_decrypt_data
262 };
263 
264 static const struct esp_algorithm chacha_poly = {
265 	.padbound = ESP_CHACHAPOLY_PAD_BOUND,
266 	.ivlenval = ESP_CHACHAPOLY_IV_LEN,
267 	.mature = esp_chachapoly_mature,
268 	.keymin = ESP_CHACHAPOLY_KEYBITS_WITH_SALT,
269 	.keymax = ESP_CHACHAPOLY_KEYBITS_WITH_SALT,
270 	.schedlen = esp_chachapoly_schedlen,
271 	.name = "chacha-poly",
272 	.ivlen = esp_chachapoly_ivlen,
273 	.decrypt = esp_chachapoly_decrypt,
274 	.encrypt = esp_chachapoly_encrypt,
275 	.schedule = esp_chachapoly_schedule,
276 	.blockdecrypt = NULL,
277 	.blockencrypt = NULL,
278 	.icvlen = ESP_CHACHAPOLY_ICV_LEN,
279 	.finalizedecrypt = esp_chachapoly_decrypt_finalize,
280 	.finalizeencrypt = esp_chachapoly_encrypt_finalize,
281 	.encrypt_pkt = esp_chachapoly_encrypt_data,
282 	.decrypt_pkt = esp_chachapoly_decrypt_data
283 };
284 
285 /*
286  * If any algorithm requires more than 2048 bits (256 bytes) of key material,
287  * update IPSEC_KEY_ENCRYPT_MAX_BYTES in ipsec.h
288  */
289 static const struct esp_algorithm *esp_algorithms[] = {
290 	&des_cbc,
291 	&des3_cbc,
292 	&null_esp,
293 	&aes_cbc,
294 	&aes_gcm,
295 	&chacha_poly,
296 };
297 
298 const struct esp_algorithm *
esp_algorithm_lookup(int idx)299 esp_algorithm_lookup(int idx)
300 {
301 	switch (idx) {
302 	case SADB_EALG_DESCBC:
303 		return &des_cbc;
304 	case SADB_EALG_3DESCBC:
305 		return &des3_cbc;
306 	case SADB_EALG_NULL:
307 		return &null_esp;
308 	case SADB_X_EALG_RIJNDAELCBC:
309 		return &aes_cbc;
310 	case SADB_X_EALG_AES_GCM:
311 	case SADB_X_EALG_AES_GMAC:
312 		return &aes_gcm;
313 	case SADB_X_EALG_CHACHA20POLY1305:
314 		return &chacha_poly;
315 	default:
316 		return NULL;
317 	}
318 }
319 
320 int
esp_max_ivlen(void)321 esp_max_ivlen(void)
322 {
323 	int idx;
324 	int ivlen;
325 
326 	ivlen = 0;
327 	for (idx = 0; idx < sizeof(esp_algorithms) / sizeof(esp_algorithms[0]);
328 	    idx++) {
329 		if (esp_algorithms[idx]->ivlenval > ivlen) {
330 			ivlen = esp_algorithms[idx]->ivlenval;
331 		}
332 	}
333 
334 	return ivlen;
335 }
336 
337 int
esp_schedule(const struct esp_algorithm * algo,struct secasvar * sav)338 esp_schedule(const struct esp_algorithm *algo, struct secasvar *sav)
339 {
340 	int error;
341 
342 	/* check for key length */
343 	if (_KEYBITS(sav->key_enc) < algo->keymin ||
344 	    _KEYBITS(sav->key_enc) > algo->keymax) {
345 		ipseclog((LOG_ERR,
346 		    "esp_schedule %s: unsupported key length %d: "
347 		    "needs %d to %d bits\n", algo->name, _KEYBITS(sav->key_enc),
348 		    algo->keymin, algo->keymax));
349 		return EINVAL;
350 	}
351 
352 	lck_mtx_lock(sadb_mutex);
353 	/* already allocated */
354 	if (sav->sched && sav->schedlen != 0) {
355 		lck_mtx_unlock(sadb_mutex);
356 		return 0;
357 	}
358 
359 	/* prevent disallowed implicit IV */
360 	if (((sav->flags & SADB_X_EXT_IIV) != 0) &&
361 	    (sav->alg_enc != SADB_X_EALG_AES_GCM) &&
362 	    (sav->alg_enc != SADB_X_EALG_CHACHA20POLY1305)) {
363 		ipseclog((LOG_ERR,
364 		    "esp_schedule %s: implicit IV not allowed\n",
365 		    algo->name));
366 		lck_mtx_unlock(sadb_mutex);
367 		return EINVAL;
368 	}
369 
370 	/* no schedule necessary */
371 	if (!algo->schedule || !algo->schedlen) {
372 		lck_mtx_unlock(sadb_mutex);
373 		return 0;
374 	}
375 
376 	sav->schedlen = (*algo->schedlen)(algo);
377 	if ((signed) sav->schedlen < 0) {
378 		lck_mtx_unlock(sadb_mutex);
379 		return EINVAL;
380 	}
381 
382 //#### that malloc should be replaced by a saved buffer...
383 	sav->sched = kalloc_data(sav->schedlen, Z_NOWAIT);
384 	if (!sav->sched) {
385 		sav->schedlen = 0;
386 		lck_mtx_unlock(sadb_mutex);
387 		return ENOBUFS;
388 	}
389 
390 	error = (*algo->schedule)(algo, sav);
391 	if (error) {
392 		ipseclog((LOG_ERR, "esp_schedule %s: error %d\n",
393 		    algo->name, error));
394 		bzero(sav->sched, sav->schedlen);
395 		kfree_data(sav->sched, sav->schedlen);
396 		sav->sched = NULL;
397 		sav->schedlen = 0;
398 	}
399 	lck_mtx_unlock(sadb_mutex);
400 	return error;
401 }
402 
403 static int
esp_null_mature(__unused struct secasvar * sav)404 esp_null_mature(
405 	__unused struct secasvar *sav)
406 {
407 	/* anything is okay */
408 	return 0;
409 }
410 
411 static int
esp_null_decrypt(__unused struct mbuf * m,__unused size_t off,__unused struct secasvar * sav,__unused const struct esp_algorithm * algo,__unused int ivlen)412 esp_null_decrypt(
413 	__unused struct mbuf *m,
414 	__unused size_t off,            /* offset to ESP header */
415 	__unused struct secasvar *sav,
416 	__unused const struct esp_algorithm *algo,
417 	__unused int ivlen)
418 {
419 	return 0; /* do nothing */
420 }
421 
422 static int
esp_null_encrypt(__unused struct mbuf * m,__unused size_t off,__unused size_t plen,__unused struct secasvar * sav,__unused const struct esp_algorithm * algo,__unused int ivlen)423 esp_null_encrypt(
424 	__unused struct mbuf *m,
425 	__unused size_t off,    /* offset to ESP header */
426 	__unused size_t plen,   /* payload length (to be encrypted) */
427 	__unused struct secasvar *sav,
428 	__unused const struct esp_algorithm *algo,
429 	__unused int ivlen)
430 {
431 	return 0; /* do nothing */
432 }
433 
434 static int
esp_null_encrypt_data(__unused struct secasvar * sav,__unused uint8_t * input_data,__unused size_t input_data_len,__unused struct newesp * esp_hdr,__unused uint8_t * out_iv,__unused size_t out_ivlen,__unused uint8_t * output_data,__unused size_t output_data_len)435 esp_null_encrypt_data(__unused struct secasvar *sav,
436     __unused uint8_t *input_data, __unused size_t input_data_len,
437     __unused struct newesp *esp_hdr, __unused uint8_t *out_iv,
438     __unused size_t out_ivlen, __unused uint8_t *output_data,
439     __unused size_t output_data_len)
440 {
441 	return 0; /* do nothing */
442 }
443 
444 static int
esp_null_decrypt_data(__unused struct secasvar * sav,__unused uint8_t * input_data,__unused size_t input_data_len,__unused struct newesp * esp_hdr,__unused uint8_t * iv,__unused size_t ivlen,__unused uint8_t * output_data,__unused size_t output_data_len)445 esp_null_decrypt_data(__unused struct secasvar *sav,
446     __unused uint8_t *input_data, __unused size_t input_data_len,
447     __unused struct newesp *esp_hdr, __unused uint8_t *iv,
448     __unused size_t ivlen, __unused uint8_t *output_data,
449     __unused size_t output_data_len)
450 {
451 	return 0; /* do nothing */
452 }
453 
454 static int
esp_descbc_mature(struct secasvar * sav)455 esp_descbc_mature(struct secasvar *sav)
456 {
457 	const struct esp_algorithm *algo;
458 
459 	if (!(sav->flags & SADB_X_EXT_OLD) && (sav->flags & SADB_X_EXT_IV4B)) {
460 		ipseclog((LOG_ERR, "esp_cbc_mature: "
461 		    "algorithm incompatible with 4 octets IV length\n"));
462 		return 1;
463 	}
464 
465 	if (!sav->key_enc) {
466 		ipseclog((LOG_ERR, "esp_descbc_mature: no key is given.\n"));
467 		return 1;
468 	}
469 
470 	algo = esp_algorithm_lookup(sav->alg_enc);
471 	if (!algo) {
472 		ipseclog((LOG_ERR,
473 		    "esp_descbc_mature: unsupported algorithm.\n"));
474 		return 1;
475 	}
476 
477 	if (_KEYBITS(sav->key_enc) < algo->keymin ||
478 	    _KEYBITS(sav->key_enc) > algo->keymax) {
479 		ipseclog((LOG_ERR,
480 		    "esp_descbc_mature: invalid key length %d.\n",
481 		    _KEYBITS(sav->key_enc)));
482 		return 1;
483 	}
484 
485 	/* weak key check */
486 	if (des_is_weak_key((des_cblock *)_KEYBUF(sav->key_enc))) {
487 		ipseclog((LOG_ERR,
488 		    "esp_descbc_mature: weak key was passed.\n"));
489 		return 1;
490 	}
491 
492 	return 0;
493 }
494 
495 static int
esp_descbc_ivlen(__unused const struct esp_algorithm * algo,struct secasvar * sav)496 esp_descbc_ivlen(
497 	__unused const struct esp_algorithm *algo,
498 	struct secasvar *sav)
499 {
500 	if (!sav) {
501 		return 8;
502 	}
503 	if ((sav->flags & SADB_X_EXT_OLD) && (sav->flags & SADB_X_EXT_IV4B)) {
504 		return 4;
505 	}
506 	if (!(sav->flags & SADB_X_EXT_OLD) && (sav->flags & SADB_X_EXT_DERIV)) {
507 		return 4;
508 	}
509 	return 8;
510 }
511 
512 static size_t
esp_des_schedlen(__unused const struct esp_algorithm * algo)513 esp_des_schedlen(
514 	__unused const struct esp_algorithm *algo)
515 {
516 	return sizeof(des_ecb_key_schedule);
517 }
518 
519 static int
esp_des_schedule(__unused const struct esp_algorithm * algo,struct secasvar * sav)520 esp_des_schedule(
521 	__unused const struct esp_algorithm *algo,
522 	struct secasvar *sav)
523 {
524 	LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
525 	if (des_ecb_key_sched((des_cblock *)_KEYBUF(sav->key_enc),
526 	    (des_ecb_key_schedule *)sav->sched)) {
527 		return EINVAL;
528 	} else {
529 		return 0;
530 	}
531 }
532 
533 static int
esp_des_blockdecrypt(__unused const struct esp_algorithm * algo,struct secasvar * sav,u_int8_t * s,u_int8_t * d)534 esp_des_blockdecrypt(
535 	__unused const struct esp_algorithm *algo,
536 	struct secasvar *sav,
537 	u_int8_t *s,
538 	u_int8_t *d)
539 {
540 	/* assumption: d has a good alignment */
541 	bcopy(s, d, sizeof(DES_LONG) * 2);
542 	return des_ecb_encrypt((des_cblock *)d, (des_cblock *)d,
543 	           (des_ecb_key_schedule *)sav->sched, DES_DECRYPT);
544 }
545 
546 static int
esp_des_blockencrypt(__unused const struct esp_algorithm * algo,struct secasvar * sav,u_int8_t * s,u_int8_t * d)547 esp_des_blockencrypt(
548 	__unused const struct esp_algorithm *algo,
549 	struct secasvar *sav,
550 	u_int8_t *s,
551 	u_int8_t *d)
552 {
553 	/* assumption: d has a good alignment */
554 	bcopy(s, d, sizeof(DES_LONG) * 2);
555 	return des_ecb_encrypt((des_cblock *)d, (des_cblock *)d,
556 	           (des_ecb_key_schedule *)sav->sched, DES_ENCRYPT);
557 }
558 
559 static int
esp_cbc_mature(struct secasvar * sav)560 esp_cbc_mature(struct secasvar *sav)
561 {
562 	int keylen;
563 	const struct esp_algorithm *algo;
564 
565 	if (sav->flags & SADB_X_EXT_OLD) {
566 		ipseclog((LOG_ERR,
567 		    "esp_cbc_mature: algorithm incompatible with esp-old\n"));
568 		return 1;
569 	}
570 	if (sav->flags & SADB_X_EXT_DERIV) {
571 		ipseclog((LOG_ERR,
572 		    "esp_cbc_mature: algorithm incompatible with derived\n"));
573 		return 1;
574 	}
575 
576 	if (!sav->key_enc) {
577 		ipseclog((LOG_ERR, "esp_cbc_mature: no key is given.\n"));
578 		return 1;
579 	}
580 
581 	algo = esp_algorithm_lookup(sav->alg_enc);
582 	if (!algo) {
583 		ipseclog((LOG_ERR,
584 		    "esp_cbc_mature: unsupported algorithm.\n"));
585 		return 1;
586 	}
587 
588 	keylen = sav->key_enc->sadb_key_bits;
589 	if (keylen < algo->keymin || algo->keymax < keylen) {
590 		ipseclog((LOG_ERR,
591 		    "esp_cbc_mature %s: invalid key length %d.\n",
592 		    algo->name, sav->key_enc->sadb_key_bits));
593 		return 1;
594 	}
595 	switch (sav->alg_enc) {
596 	case SADB_EALG_3DESCBC:
597 		/* weak key check */
598 		if (des_is_weak_key((des_cblock *)_KEYBUF(sav->key_enc)) ||
599 		    des_is_weak_key((des_cblock *)(_KEYBUF(sav->key_enc) + 8)) ||
600 		    des_is_weak_key((des_cblock *)(_KEYBUF(sav->key_enc) + 16))) {
601 			ipseclog((LOG_ERR,
602 			    "esp_cbc_mature %s: weak key was passed.\n",
603 			    algo->name));
604 			return 1;
605 		}
606 		break;
607 	case SADB_X_EALG_RIJNDAELCBC:
608 		/* allows specific key sizes only */
609 		if (!(keylen == 128 || keylen == 192 || keylen == 256)) {
610 			ipseclog((LOG_ERR,
611 			    "esp_cbc_mature %s: invalid key length %d.\n",
612 			    algo->name, keylen));
613 			return 1;
614 		}
615 		break;
616 	}
617 
618 	return 0;
619 }
620 
621 static int
esp_gcm_mature(struct secasvar * sav)622 esp_gcm_mature(struct secasvar *sav)
623 {
624 	int keylen;
625 	const struct esp_algorithm *algo;
626 
627 	if (sav->flags & SADB_X_EXT_OLD) {
628 		ipseclog((LOG_ERR,
629 		    "esp_gcm_mature: algorithm incompatible with esp-old\n"));
630 		return 1;
631 	}
632 	if (sav->flags & SADB_X_EXT_DERIV) {
633 		ipseclog((LOG_ERR,
634 		    "esp_gcm_mature: algorithm incompatible with derived\n"));
635 		return 1;
636 	}
637 
638 	if (!sav->key_enc) {
639 		ipseclog((LOG_ERR, "esp_gcm_mature: no key is given.\n"));
640 		return 1;
641 	}
642 
643 	algo = esp_algorithm_lookup(sav->alg_enc);
644 	if (!algo) {
645 		ipseclog((LOG_ERR,
646 		    "esp_gcm_mature: unsupported algorithm.\n"));
647 		return 1;
648 	}
649 
650 	keylen = sav->key_enc->sadb_key_bits;
651 	if (keylen < algo->keymin || algo->keymax < keylen) {
652 		ipseclog((LOG_ERR,
653 		    "esp_gcm_mature %s: invalid key length %d.\n",
654 		    algo->name, sav->key_enc->sadb_key_bits));
655 		return 1;
656 	}
657 	switch (sav->alg_enc) {
658 	case SADB_X_EALG_AES_GCM:
659 	case SADB_X_EALG_AES_GMAC:
660 		/* allows specific key sizes only */
661 		if (!(keylen == ESP_AESGCM_KEYLEN128 || keylen == ESP_AESGCM_KEYLEN192 || keylen == ESP_AESGCM_KEYLEN256)) {
662 			ipseclog((LOG_ERR,
663 			    "esp_gcm_mature %s: invalid key length %d.\n",
664 			    algo->name, keylen));
665 			return 1;
666 		}
667 		break;
668 	default:
669 		ipseclog((LOG_ERR,
670 		    "esp_gcm_mature %s: invalid algo %d.\n", algo->name, sav->alg_enc));
671 		return 1;
672 	}
673 
674 	return 0;
675 }
676 
677 static size_t
esp_3des_schedlen(__unused const struct esp_algorithm * algo)678 esp_3des_schedlen(
679 	__unused const struct esp_algorithm *algo)
680 {
681 	return sizeof(des3_ecb_key_schedule);
682 }
683 
684 static int
esp_3des_schedule(__unused const struct esp_algorithm * algo,struct secasvar * sav)685 esp_3des_schedule(
686 	__unused const struct esp_algorithm *algo,
687 	struct secasvar *sav)
688 {
689 	LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
690 
691 	if (des3_ecb_key_sched((des_cblock *)_KEYBUF(sav->key_enc),
692 	    (des3_ecb_key_schedule *)sav->sched)) {
693 		return EINVAL;
694 	} else {
695 		return 0;
696 	}
697 }
698 
699 static int
esp_3des_blockdecrypt(__unused const struct esp_algorithm * algo,struct secasvar * sav,u_int8_t * s,u_int8_t * d)700 esp_3des_blockdecrypt(
701 	__unused const struct esp_algorithm *algo,
702 	struct secasvar *sav,
703 	u_int8_t *s,
704 	u_int8_t *d)
705 {
706 	/* assumption: d has a good alignment */
707 	bcopy(s, d, sizeof(DES_LONG) * 2);
708 	return des3_ecb_encrypt((des_cblock *)d, (des_cblock *)d,
709 	           (des3_ecb_key_schedule *)sav->sched, DES_DECRYPT);
710 }
711 
712 static int
esp_3des_blockencrypt(__unused const struct esp_algorithm * algo,struct secasvar * sav,u_int8_t * s,u_int8_t * d)713 esp_3des_blockencrypt(
714 	__unused const struct esp_algorithm *algo,
715 	struct secasvar *sav,
716 	u_int8_t *s,
717 	u_int8_t *d)
718 {
719 	/* assumption: d has a good alignment */
720 	bcopy(s, d, sizeof(DES_LONG) * 2);
721 	return des3_ecb_encrypt((des_cblock *)d, (des_cblock *)d,
722 	           (des3_ecb_key_schedule *)sav->sched, DES_ENCRYPT);
723 }
724 
725 static int
esp_common_ivlen(const struct esp_algorithm * algo,__unused struct secasvar * sav)726 esp_common_ivlen(
727 	const struct esp_algorithm *algo,
728 	__unused struct secasvar *sav)
729 {
730 	if (!algo) {
731 		panic("esp_common_ivlen: unknown algorithm");
732 	}
733 	return algo->ivlenval;
734 }
735 
736 static int
esp_cbc_decrypt(struct mbuf * m,size_t off,struct secasvar * sav,const struct esp_algorithm * algo,int ivlen)737 esp_cbc_decrypt(struct mbuf *m, size_t off, struct secasvar *sav,
738     const struct esp_algorithm *algo, int ivlen)
739 {
740 	struct mbuf *s;
741 	struct mbuf *d, *d0, *dp;
742 	int soff, doff; /* offset from the head of chain, to head of this mbuf */
743 	int sn, dn;     /* offset from the head of the mbuf, to meat */
744 	size_t ivoff, bodyoff;
745 	u_int8_t iv[MAXIVLEN] __attribute__((aligned(4))), *ivp;
746 	u_int8_t *sbuf = NULL, *sp, *sp_unaligned;
747 	u_int8_t *p, *q;
748 	struct mbuf *scut;
749 	int scutoff;
750 	int i, result = 0;
751 	int blocklen;
752 	int derived;
753 
754 	if (ivlen != sav->ivlen || ivlen > sizeof(iv)) {
755 		ipseclog((LOG_ERR, "esp_cbc_decrypt %s: "
756 		    "unsupported ivlen %d\n", algo->name, ivlen));
757 		m_freem(m);
758 		return EINVAL;
759 	}
760 
761 	/* assumes blocklen == padbound */
762 	blocklen = algo->padbound;
763 
764 #if DIAGNOSTIC
765 	if (blocklen > sizeof(iv)) {
766 		ipseclog((LOG_ERR, "esp_cbc_decrypt %s: "
767 		    "unsupported blocklen %d\n", algo->name, blocklen));
768 		m_freem(m);
769 		return EINVAL;
770 	}
771 #endif
772 
773 	if (sav->flags & SADB_X_EXT_OLD) {
774 		/* RFC 1827 */
775 		ivoff = off + sizeof(struct esp);
776 		bodyoff = off + sizeof(struct esp) + ivlen;
777 		derived = 0;
778 	} else {
779 		/* RFC 2406 */
780 		if (sav->flags & SADB_X_EXT_DERIV) {
781 			/*
782 			 * draft-ietf-ipsec-ciph-des-derived-00.txt
783 			 * uses sequence number field as IV field.
784 			 */
785 			ivoff = off + sizeof(struct esp);
786 			bodyoff = off + sizeof(struct esp) + sizeof(u_int32_t);
787 			ivlen = sizeof(u_int32_t);
788 			derived = 1;
789 		} else {
790 			ivoff = off + sizeof(struct newesp);
791 			bodyoff = off + sizeof(struct newesp) + ivlen;
792 			derived = 0;
793 		}
794 	}
795 
796 	VERIFY(ivoff <= INT_MAX);
797 	/* grab iv */
798 	m_copydata(m, (int)ivoff, ivlen, (caddr_t) iv);
799 
800 	/* extend iv */
801 	if (ivlen == blocklen) {
802 		;
803 	} else if (ivlen == 4 && blocklen == 8) {
804 		bcopy(&iv[0], &iv[4], 4);
805 		iv[4] ^= 0xff;
806 		iv[5] ^= 0xff;
807 		iv[6] ^= 0xff;
808 		iv[7] ^= 0xff;
809 	} else {
810 		ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
811 		    "unsupported ivlen/blocklen: %d %d\n",
812 		    algo->name, ivlen, blocklen));
813 		m_freem(m);
814 		return EINVAL;
815 	}
816 
817 	if (m->m_pkthdr.len < bodyoff) {
818 		ipseclog((LOG_ERR, "esp_cbc_decrypt %s: bad len %d/%u\n",
819 		    algo->name, m->m_pkthdr.len, (u_int32_t)bodyoff));
820 		m_freem(m);
821 		return EINVAL;
822 	}
823 	if ((m->m_pkthdr.len - bodyoff) % blocklen) {
824 		ipseclog((LOG_ERR, "esp_cbc_decrypt %s: "
825 		    "payload length must be multiple of %d\n",
826 		    algo->name, blocklen));
827 		m_freem(m);
828 		return EINVAL;
829 	}
830 
831 	s = m;
832 	d = d0 = dp = NULL;
833 	soff = doff = sn = dn = 0;
834 	ivp = sp = NULL;
835 
836 	/* skip bodyoff */
837 	while (soff < bodyoff) {
838 		if (soff + s->m_len > bodyoff) {
839 			sn = (int)(bodyoff - soff);
840 			break;
841 		}
842 
843 		soff += s->m_len;
844 		s = s->m_next;
845 	}
846 	scut = s;
847 	scutoff = sn;
848 
849 	/* skip over empty mbuf */
850 	while (s && s->m_len == 0) {
851 		s = s->m_next;
852 	}
853 
854 	// Allocate blocksized buffer for unaligned or non-contiguous access
855 	sbuf = (u_int8_t *)kalloc_data(blocklen, Z_NOWAIT);
856 	if (sbuf == NULL) {
857 		return ENOBUFS;
858 	}
859 	while (soff < m->m_pkthdr.len) {
860 		/* source */
861 		if (sn + blocklen <= s->m_len) {
862 			/* body is continuous */
863 			sp = mtod(s, u_int8_t *) + sn;
864 		} else {
865 			/* body is non-continuous */
866 			m_copydata(s, sn, blocklen, (caddr_t) sbuf);
867 			sp = sbuf;
868 		}
869 
870 		/* destination */
871 		if (!d || dn + blocklen > d->m_len) {
872 			if (d) {
873 				dp = d;
874 			}
875 			MGET(d, M_DONTWAIT, MT_DATA);
876 			i = m->m_pkthdr.len - (soff + sn);
877 			if (d && i > MLEN) {
878 				MCLGET(d, M_DONTWAIT);
879 				if ((d->m_flags & M_EXT) == 0) {
880 					m_free(d);
881 					d = NULL;
882 				}
883 			}
884 			if (!d) {
885 				m_freem(m);
886 				if (d0) {
887 					m_freem(d0);
888 				}
889 				result = ENOBUFS;
890 				goto end;
891 			}
892 			if (!d0) {
893 				d0 = d;
894 			}
895 			if (dp) {
896 				dp->m_next = d;
897 			}
898 
899 			// try to make mbuf data aligned
900 			if (!IPSEC_IS_P2ALIGNED(d->m_data)) {
901 				m_adj(d, IPSEC_GET_P2UNALIGNED_OFS(d->m_data));
902 			}
903 
904 			d->m_len = 0;
905 			d->m_len = (int)((M_TRAILINGSPACE(d) / blocklen) * blocklen);
906 			if (d->m_len > i) {
907 				d->m_len = i;
908 			}
909 			dn = 0;
910 		}
911 
912 		/* decrypt */
913 		// check input pointer alignment and use a separate aligned buffer (if sp is unaligned on 4-byte boundary).
914 		if (IPSEC_IS_P2ALIGNED(sp)) {
915 			sp_unaligned = NULL;
916 		} else {
917 			sp_unaligned = sp;
918 			sp = sbuf;
919 			memcpy(sp, sp_unaligned, blocklen);
920 		}
921 		// no need to check output pointer alignment
922 		(*algo->blockdecrypt)(algo, sav, sp, mtod(d, u_int8_t *) + dn);
923 
924 		// update unaligned pointers
925 		if (!IPSEC_IS_P2ALIGNED(sp_unaligned)) {
926 			sp = sp_unaligned;
927 		}
928 
929 		/* xor */
930 		p = ivp ? ivp : iv;
931 		q = mtod(d, u_int8_t *) + dn;
932 		for (i = 0; i < blocklen; i++) {
933 			q[i] ^= p[i];
934 		}
935 
936 		/* next iv */
937 		if (sp == sbuf) {
938 			bcopy(sbuf, iv, blocklen);
939 			ivp = NULL;
940 		} else {
941 			ivp = sp;
942 		}
943 
944 		sn += blocklen;
945 		dn += blocklen;
946 
947 		/* find the next source block */
948 		while (s && sn >= s->m_len) {
949 			sn -= s->m_len;
950 			soff += s->m_len;
951 			s = s->m_next;
952 		}
953 	}
954 
955 	m_freem(scut->m_next);
956 	scut->m_len = scutoff;
957 	scut->m_next = d0;
958 
959 	/* just in case */
960 	bzero(iv, sizeof(iv));
961 	bzero(sbuf, blocklen);
962 end:
963 	if (sbuf != NULL) {
964 		kfree_data(sbuf, blocklen);
965 	}
966 	return result;
967 }
968 
969 static int
esp_cbc_encrypt(struct mbuf * m,size_t off,__unused size_t plen,struct secasvar * sav,const struct esp_algorithm * algo,int ivlen)970 esp_cbc_encrypt(
971 	struct mbuf *m,
972 	size_t off,
973 	__unused size_t plen,
974 	struct secasvar *sav,
975 	const struct esp_algorithm *algo,
976 	int ivlen)
977 {
978 	struct mbuf *s;
979 	struct mbuf *d, *d0, *dp;
980 	int soff, doff; /* offset from the head of chain, to head of this mbuf */
981 	int sn, dn;     /* offset from the head of the mbuf, to meat */
982 	size_t ivoff, bodyoff;
983 	u_int8_t iv[MAXIVLEN] __attribute__((aligned(4))), *ivp;
984 	u_int8_t *sbuf = NULL, *sp, *sp_unaligned;
985 	u_int8_t *p, *q;
986 	struct mbuf *scut;
987 	int scutoff;
988 	int i, result = 0;
989 	int blocklen;
990 	int derived;
991 
992 	if (ivlen != sav->ivlen || ivlen > sizeof(iv)) {
993 		ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
994 		    "unsupported ivlen %d\n", algo->name, ivlen));
995 		m_freem(m);
996 		return EINVAL;
997 	}
998 
999 	/* assumes blocklen == padbound */
1000 	blocklen = algo->padbound;
1001 
1002 #if DIAGNOSTIC
1003 	if (blocklen > sizeof(iv)) {
1004 		ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
1005 		    "unsupported blocklen %d\n", algo->name, blocklen));
1006 		m_freem(m);
1007 		return EINVAL;
1008 	}
1009 #endif
1010 
1011 	if (sav->flags & SADB_X_EXT_OLD) {
1012 		/* RFC 1827 */
1013 		ivoff = off + sizeof(struct esp);
1014 		bodyoff = off + sizeof(struct esp) + ivlen;
1015 		derived = 0;
1016 	} else {
1017 		/* RFC 2406 */
1018 		if (sav->flags & SADB_X_EXT_DERIV) {
1019 			/*
1020 			 * draft-ietf-ipsec-ciph-des-derived-00.txt
1021 			 * uses sequence number field as IV field.
1022 			 */
1023 			ivoff = off + sizeof(struct esp);
1024 			bodyoff = off + sizeof(struct esp) + sizeof(u_int32_t);
1025 			ivlen = sizeof(u_int32_t);
1026 			derived = 1;
1027 		} else {
1028 			ivoff = off + sizeof(struct newesp);
1029 			bodyoff = off + sizeof(struct newesp) + ivlen;
1030 			derived = 0;
1031 		}
1032 	}
1033 
1034 	VERIFY(ivoff <= INT_MAX);
1035 
1036 	/* put iv into the packet.  if we are in derived mode, use seqno. */
1037 	if (derived) {
1038 		m_copydata(m, (int)ivoff, ivlen, (caddr_t) iv);
1039 	} else {
1040 		bcopy(sav->iv, iv, ivlen);
1041 		/* maybe it is better to overwrite dest, not source */
1042 		m_copyback(m, (int)ivoff, ivlen, (caddr_t) iv);
1043 	}
1044 
1045 	/* extend iv */
1046 	if (ivlen == blocklen) {
1047 		;
1048 	} else if (ivlen == 4 && blocklen == 8) {
1049 		bcopy(&iv[0], &iv[4], 4);
1050 		iv[4] ^= 0xff;
1051 		iv[5] ^= 0xff;
1052 		iv[6] ^= 0xff;
1053 		iv[7] ^= 0xff;
1054 	} else {
1055 		ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
1056 		    "unsupported ivlen/blocklen: %d %d\n",
1057 		    algo->name, ivlen, blocklen));
1058 		m_freem(m);
1059 		return EINVAL;
1060 	}
1061 
1062 	if (m->m_pkthdr.len < bodyoff) {
1063 		ipseclog((LOG_ERR, "esp_cbc_encrypt %s: bad len %d/%u\n",
1064 		    algo->name, m->m_pkthdr.len, (u_int32_t)bodyoff));
1065 		m_freem(m);
1066 		return EINVAL;
1067 	}
1068 	if ((m->m_pkthdr.len - bodyoff) % blocklen) {
1069 		ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
1070 		    "payload length must be multiple of %u\n",
1071 		    algo->name, (u_int32_t)algo->padbound));
1072 		m_freem(m);
1073 		return EINVAL;
1074 	}
1075 
1076 	s = m;
1077 	d = d0 = dp = NULL;
1078 	soff = doff = sn = dn = 0;
1079 	ivp = sp = NULL;
1080 
1081 	/* skip bodyoff */
1082 	while (soff < bodyoff) {
1083 		if (soff + s->m_len > bodyoff) {
1084 			sn = (int)(bodyoff - soff);
1085 			break;
1086 		}
1087 
1088 		soff += s->m_len;
1089 		s = s->m_next;
1090 	}
1091 	scut = s;
1092 	scutoff = sn;
1093 
1094 	/* skip over empty mbuf */
1095 	while (s && s->m_len == 0) {
1096 		s = s->m_next;
1097 	}
1098 
1099 	// Allocate blocksized buffer for unaligned or non-contiguous access
1100 	sbuf = (u_int8_t *)kalloc_data(blocklen, Z_NOWAIT);
1101 	if (sbuf == NULL) {
1102 		return ENOBUFS;
1103 	}
1104 	while (soff < m->m_pkthdr.len) {
1105 		/* source */
1106 		if (sn + blocklen <= s->m_len) {
1107 			/* body is continuous */
1108 			sp = mtod(s, u_int8_t *) + sn;
1109 		} else {
1110 			/* body is non-continuous */
1111 			m_copydata(s, sn, blocklen, (caddr_t) sbuf);
1112 			sp = sbuf;
1113 		}
1114 
1115 		/* destination */
1116 		if (!d || dn + blocklen > d->m_len) {
1117 			if (d) {
1118 				dp = d;
1119 			}
1120 			MGET(d, M_DONTWAIT, MT_DATA);
1121 			i = m->m_pkthdr.len - (soff + sn);
1122 			if (d && i > MLEN) {
1123 				MCLGET(d, M_DONTWAIT);
1124 				if ((d->m_flags & M_EXT) == 0) {
1125 					m_free(d);
1126 					d = NULL;
1127 				}
1128 			}
1129 			if (!d) {
1130 				m_freem(m);
1131 				if (d0) {
1132 					m_freem(d0);
1133 				}
1134 				result = ENOBUFS;
1135 				goto end;
1136 			}
1137 			if (!d0) {
1138 				d0 = d;
1139 			}
1140 			if (dp) {
1141 				dp->m_next = d;
1142 			}
1143 
1144 			// try to make mbuf data aligned
1145 			if (!IPSEC_IS_P2ALIGNED(d->m_data)) {
1146 				m_adj(d, IPSEC_GET_P2UNALIGNED_OFS(d->m_data));
1147 			}
1148 
1149 			d->m_len = 0;
1150 			d->m_len = (int)((M_TRAILINGSPACE(d) / blocklen) * blocklen);
1151 			if (d->m_len > i) {
1152 				d->m_len = i;
1153 			}
1154 			dn = 0;
1155 		}
1156 
1157 		/* xor */
1158 		p = ivp ? ivp : iv;
1159 		q = sp;
1160 		for (i = 0; i < blocklen; i++) {
1161 			q[i] ^= p[i];
1162 		}
1163 
1164 		/* encrypt */
1165 		// check input pointer alignment and use a separate aligned buffer (if sp is not aligned on 4-byte boundary).
1166 		if (IPSEC_IS_P2ALIGNED(sp)) {
1167 			sp_unaligned = NULL;
1168 		} else {
1169 			sp_unaligned = sp;
1170 			sp = sbuf;
1171 			memcpy(sp, sp_unaligned, blocklen);
1172 		}
1173 		// no need to check output pointer alignment
1174 		(*algo->blockencrypt)(algo, sav, sp, mtod(d, u_int8_t *) + dn);
1175 
1176 		// update unaligned pointers
1177 		if (!IPSEC_IS_P2ALIGNED(sp_unaligned)) {
1178 			sp = sp_unaligned;
1179 		}
1180 
1181 		/* next iv */
1182 		ivp = mtod(d, u_int8_t *) + dn;
1183 
1184 		sn += blocklen;
1185 		dn += blocklen;
1186 
1187 		/* find the next source block */
1188 		while (s && sn >= s->m_len) {
1189 			sn -= s->m_len;
1190 			soff += s->m_len;
1191 			s = s->m_next;
1192 		}
1193 	}
1194 
1195 	m_freem(scut->m_next);
1196 	scut->m_len = scutoff;
1197 	scut->m_next = d0;
1198 
1199 	/* just in case */
1200 	bzero(iv, sizeof(iv));
1201 	bzero(sbuf, blocklen);
1202 
1203 	key_sa_stir_iv(sav);
1204 end:
1205 	if (sbuf != NULL) {
1206 		kfree_data(sbuf, blocklen);
1207 	}
1208 	return result;
1209 }
1210 
1211 #define ESP_CBC_DES_BLOCKLEN 8
1212 static int
esp_cbc_des_encrypt_data(struct secasvar * sav,uint8_t * input_data,size_t input_data_len,struct newesp * esp_hdr,uint8_t * out_iv,size_t ivlen,uint8_t * output_data,size_t output_data_len)1213 esp_cbc_des_encrypt_data(struct secasvar *sav, uint8_t *input_data,
1214     size_t input_data_len, struct newesp *esp_hdr, uint8_t *out_iv,
1215     size_t ivlen, uint8_t *output_data, size_t output_data_len)
1216 {
1217 	uint8_t *ivp = NULL;
1218 	size_t soff = 0;
1219 	int rc = 0;
1220 
1221 	ESP_CHECK_ARG(sav);
1222 	ESP_CHECK_ARG(input_data);
1223 	ESP_CHECK_ARG(esp_hdr);
1224 	ESP_CHECK_ARG(output_data);
1225 
1226 	VERIFY(input_data_len > 0);
1227 	VERIFY(output_data_len >= input_data_len);
1228 	VERIFY(sav->ivlen == ivlen);
1229 	VERIFY(ivlen == ESP_CBC_DES_BLOCKLEN);
1230 
1231 	if (input_data_len % ESP_CBC_DES_BLOCKLEN) {
1232 		esp_log_err("payload length %zu must be a multiple of "
1233 		    "ESP_CBC_DES_BLOCKLEN, SPI 0x%08x", input_data_len, ntohl(sav->spi));
1234 		return EINVAL;
1235 	}
1236 
1237 	memcpy(out_iv, sav->iv, ivlen);
1238 	ivp = out_iv;
1239 
1240 	while (soff < input_data_len) {
1241 		for (int i = 0; i < ESP_CBC_DES_BLOCKLEN; i++) {
1242 			input_data[soff + i] ^= ivp[i];
1243 		}
1244 
1245 		/* encrypt */
1246 		if (__improbable((rc = des_ecb_encrypt((des_cblock *)&input_data[soff],
1247 		    (des_cblock *)&output_data[soff], (des_ecb_key_schedule *)sav->sched,
1248 		    DES_ENCRYPT)) != 0)) {
1249 			esp_log_err("encrypt failed %d, SPI 0x%08x", rc, ntohl(sav->spi));
1250 			return rc;
1251 		}
1252 
1253 		ivp = &output_data[soff];
1254 		soff += ESP_CBC_DES_BLOCKLEN;
1255 	}
1256 
1257 	key_sa_stir_iv(sav);
1258 	return 0;
1259 }
1260 
1261 static int
esp_cbc_des_decrypt_data(struct secasvar * sav,uint8_t * input_data,size_t input_data_len,struct newesp * esp_hdr,uint8_t * iv,size_t ivlen,uint8_t * output_data,size_t output_data_len)1262 esp_cbc_des_decrypt_data(struct secasvar *sav, uint8_t *input_data,
1263     size_t input_data_len, struct newesp *esp_hdr, uint8_t *iv,
1264     size_t ivlen, uint8_t *output_data, size_t output_data_len)
1265 {
1266 	uint8_t *ivp = NULL;
1267 	size_t soff = 0;
1268 	int rc = 0;
1269 
1270 	ESP_CHECK_ARG(sav);
1271 	ESP_CHECK_ARG(input_data);
1272 	ESP_CHECK_ARG(esp_hdr);
1273 	ESP_CHECK_ARG(output_data);
1274 
1275 	VERIFY(input_data_len > 0);
1276 	VERIFY(output_data_len >= input_data_len);
1277 	VERIFY(sav->ivlen == ivlen);
1278 	VERIFY(ivlen == ESP_CBC_DES_BLOCKLEN);
1279 
1280 	if (input_data_len % ESP_CBC_DES_BLOCKLEN) {
1281 		esp_packet_log_err("payload length %zu must be a multiple of "
1282 		    "ESP_CBC_DES_BLOCKLEN, SPI 0x%08x", input_data_len, ntohl(sav->spi));
1283 		return EINVAL;
1284 	}
1285 
1286 	ivp = iv;
1287 
1288 	while (soff < input_data_len) {
1289 		/* decrypt */
1290 		if (__improbable((rc = des_ecb_encrypt((des_cblock *)&input_data[soff],
1291 		    (des_cblock *)&output_data[soff], (des_ecb_key_schedule *)sav->sched,
1292 		    DES_DECRYPT)) != 0)) {
1293 			esp_log_err("decrypt failed %d, SPI 0x%08x", rc, ntohl(sav->spi));
1294 			return rc;
1295 		}
1296 
1297 		for (int i = 0; i < ESP_CBC_DES_BLOCKLEN; i++) {
1298 			output_data[soff + i] ^= ivp[i];
1299 		}
1300 
1301 		ivp = &input_data[soff];
1302 		soff += ESP_CBC_DES_BLOCKLEN;
1303 	}
1304 
1305 	return 0;
1306 }
1307 
1308 #define ESP_CBC_3DES_BLOCKLEN 8
1309 static int
esp_cbc_3des_encrypt_data(struct secasvar * sav,uint8_t * input_data,size_t input_data_len,struct newesp * esp_hdr,uint8_t * out_iv,size_t ivlen,uint8_t * output_data,size_t output_data_len)1310 esp_cbc_3des_encrypt_data(struct secasvar *sav, uint8_t *input_data,
1311     size_t input_data_len, struct newesp *esp_hdr, uint8_t *out_iv,
1312     size_t ivlen, uint8_t *output_data, size_t output_data_len)
1313 {
1314 	uint8_t *ivp = NULL;
1315 	size_t soff = 0;
1316 	int rc = 0;
1317 
1318 	ESP_CHECK_ARG(sav);
1319 	ESP_CHECK_ARG(input_data);
1320 	ESP_CHECK_ARG(esp_hdr);
1321 	ESP_CHECK_ARG(output_data);
1322 
1323 	VERIFY(input_data_len > 0);
1324 	VERIFY(output_data_len >= input_data_len);
1325 	VERIFY(sav->ivlen == ivlen);
1326 	VERIFY(ivlen == ESP_CBC_3DES_BLOCKLEN);
1327 
1328 	if (input_data_len % ESP_CBC_3DES_BLOCKLEN) {
1329 		esp_log_err("payload length %zu must be a multiple of "
1330 		    "ESP_CBC_3DES_BLOCKLEN, SPI 0x%08x", input_data_len, ntohl(sav->spi));
1331 		return EINVAL;
1332 	}
1333 
1334 	memcpy(out_iv, sav->iv, ivlen);
1335 	ivp = out_iv;
1336 
1337 	while (soff < input_data_len) {
1338 		for (int i = 0; i < ESP_CBC_3DES_BLOCKLEN; i++) {
1339 			input_data[soff + i] ^= ivp[i];
1340 		}
1341 
1342 		/* encrypt */
1343 		if (__improbable((rc = des3_ecb_encrypt((des_cblock *)&input_data[soff],
1344 		    (des_cblock *)&output_data[soff], (des3_ecb_key_schedule *)sav->sched,
1345 		    DES_ENCRYPT)) != 0)) {
1346 			esp_log_err("encrypt failed %d, SPI 0x%08x", rc, ntohl(sav->spi));
1347 			return rc;
1348 		}
1349 
1350 		ivp = &output_data[soff];
1351 		soff += ESP_CBC_3DES_BLOCKLEN;
1352 	}
1353 
1354 	key_sa_stir_iv(sav);
1355 	return 0;
1356 }
1357 
1358 static int
esp_cbc_3des_decrypt_data(struct secasvar * sav,uint8_t * input_data,size_t input_data_len,struct newesp * esp_hdr,uint8_t * iv,size_t ivlen,uint8_t * output_data,size_t output_data_len)1359 esp_cbc_3des_decrypt_data(struct secasvar *sav, uint8_t *input_data,
1360     size_t input_data_len, struct newesp *esp_hdr, uint8_t *iv,
1361     size_t ivlen, uint8_t *output_data, size_t output_data_len)
1362 {
1363 	uint8_t *ivp = NULL;
1364 	size_t soff = 0;
1365 	int rc = 0;
1366 
1367 	ESP_CHECK_ARG(sav);
1368 	ESP_CHECK_ARG(input_data);
1369 	ESP_CHECK_ARG(esp_hdr);
1370 	ESP_CHECK_ARG(output_data);
1371 
1372 	VERIFY(input_data_len > 0);
1373 	VERIFY(output_data_len >= input_data_len);
1374 	VERIFY(sav->ivlen == ivlen);
1375 	VERIFY(ivlen == ESP_CBC_3DES_BLOCKLEN);
1376 
1377 	if (input_data_len % ESP_CBC_3DES_BLOCKLEN) {
1378 		esp_packet_log_err("payload length %zu must be a multiple of "
1379 		    "ESP_CBC_3DES_BLOCKLEN, SPI 0x%08x", input_data_len, ntohl(sav->spi));
1380 		return EINVAL;
1381 	}
1382 
1383 	ivp = iv;
1384 
1385 	while (soff < input_data_len) {
1386 		/* decrypt */
1387 		if (__improbable((rc = des3_ecb_encrypt((des_cblock *)&input_data[soff],
1388 		    (des_cblock *)&output_data[soff], (des3_ecb_key_schedule *)sav->sched,
1389 		    DES_DECRYPT)) != 0)) {
1390 			esp_log_err("decrypt failed %d, SPI 0x%08x", rc, ntohl(sav->spi));
1391 			return rc;
1392 		}
1393 
1394 		for (int i = 0; i < ESP_CBC_3DES_BLOCKLEN; i++) {
1395 			output_data[soff + i] ^= ivp[i];
1396 		}
1397 
1398 		ivp = &input_data[soff];
1399 		soff += ESP_CBC_3DES_BLOCKLEN;
1400 	}
1401 
1402 	return 0;
1403 }
1404 
1405 /*------------------------------------------------------------*/
1406 
1407 /* does not free m0 on error */
1408 int
esp_auth(struct mbuf * m0,size_t skip,size_t length,struct secasvar * sav,u_char * sum)1409 esp_auth(
1410 	struct mbuf *m0,
1411 	size_t skip,    /* offset to ESP header */
1412 	size_t length,  /* payload length */
1413 	struct secasvar *sav,
1414 	u_char *sum)
1415 {
1416 	struct mbuf *m;
1417 	size_t off;
1418 	struct ah_algorithm_state s;
1419 	u_char sumbuf[AH_MAXSUMSIZE] __attribute__((aligned(4)));
1420 	const struct ah_algorithm *algo;
1421 	size_t siz;
1422 	int error;
1423 
1424 	/* sanity checks */
1425 	if (m0->m_pkthdr.len < skip) {
1426 		ipseclog((LOG_DEBUG, "esp_auth: mbuf length < skip\n"));
1427 		return EINVAL;
1428 	}
1429 	if (m0->m_pkthdr.len < skip + length) {
1430 		ipseclog((LOG_DEBUG,
1431 		    "esp_auth: mbuf length < skip + length\n"));
1432 		return EINVAL;
1433 	}
1434 
1435 	KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_START, skip, length, 0, 0, 0);
1436 	/*
1437 	 * length of esp part (excluding authentication data) must be 4n,
1438 	 * since nexthdr must be at offset 4n+3.
1439 	 */
1440 	if (length % 4) {
1441 		ipseclog((LOG_ERR, "esp_auth: length is not multiple of 4\n"));
1442 		KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 1, 0, 0, 0, 0);
1443 		return EINVAL;
1444 	}
1445 	if (!sav) {
1446 		ipseclog((LOG_DEBUG, "esp_auth: NULL SA passed\n"));
1447 		KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 2, 0, 0, 0, 0);
1448 		return EINVAL;
1449 	}
1450 	algo = ah_algorithm_lookup(sav->alg_auth);
1451 	if (!algo) {
1452 		ipseclog((LOG_ERR,
1453 		    "esp_auth: bad ESP auth algorithm passed: %d\n",
1454 		    sav->alg_auth));
1455 		KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 3, 0, 0, 0, 0);
1456 		return EINVAL;
1457 	}
1458 
1459 	m = m0;
1460 	off = 0;
1461 
1462 	siz = (((*algo->sumsiz)(sav) + 3) & ~(4 - 1));
1463 	if (sizeof(sumbuf) < siz) {
1464 		ipseclog((LOG_DEBUG,
1465 		    "esp_auth: AH_MAXSUMSIZE is too small: siz=%u\n",
1466 		    (u_int32_t)siz));
1467 		KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 4, 0, 0, 0, 0);
1468 		return EINVAL;
1469 	}
1470 
1471 	/* skip the header */
1472 	while (skip) {
1473 		if (!m) {
1474 			panic("mbuf chain?");
1475 		}
1476 		if (m->m_len <= skip) {
1477 			skip -= m->m_len;
1478 			m = m->m_next;
1479 			off = 0;
1480 		} else {
1481 			off = skip;
1482 			skip = 0;
1483 		}
1484 	}
1485 
1486 	error = (*algo->init)(&s, sav);
1487 	if (error) {
1488 		KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 5, 0, 0, 0, 0);
1489 		return error;
1490 	}
1491 	while (0 < length) {
1492 		if (!m) {
1493 			panic("mbuf chain?");
1494 		}
1495 
1496 		if (m->m_len - off < length) {
1497 			(*algo->update)(&s, (caddr_t)(mtod(m, u_char *) + off),
1498 			    m->m_len - off);
1499 			length -= m->m_len - off;
1500 			m = m->m_next;
1501 			off = 0;
1502 		} else {
1503 			(*algo->update)(&s, (caddr_t)(mtod(m, u_char *) + off), length);
1504 			break;
1505 		}
1506 	}
1507 	(*algo->result)(&s, (caddr_t) sumbuf, sizeof(sumbuf));
1508 	bcopy(sumbuf, sum, siz);        /*XXX*/
1509 	KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 6, 0, 0, 0, 0);
1510 	return 0;
1511 }
1512 
1513 int
esp_auth_data(struct secasvar * sav,uint8_t * input_data,size_t input_data_len,uint8_t * out_auth,size_t auth_size)1514 esp_auth_data(struct secasvar *sav, uint8_t *input_data, size_t input_data_len,
1515     uint8_t *out_auth, size_t auth_size)
1516 {
1517 	struct ah_algorithm_state state = {};
1518 	const struct ah_algorithm *algo = NULL;
1519 	size_t siz = 0;
1520 	int err = 0;
1521 
1522 	ESP_CHECK_ARG(sav);
1523 	ESP_CHECK_ARG(input_data);
1524 	ESP_CHECK_ARG(out_auth);
1525 
1526 	VERIFY(input_data_len > 0);
1527 
1528 	KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_START, 0, length, 0, 0, 0);
1529 
1530 	/*
1531 	 * Length of ESP part (excluding authentication data) must be 4n,
1532 	 * since nexthdr must be at offset 4n + 3.
1533 	 */
1534 	if (__improbable(input_data_len % 4)) {
1535 		esp_packet_log_err("esp auth: input data length %zu is not a multiple 4, "
1536 		    "SPI 0x%08x\n", input_data_len, ntohl(sav->spi));
1537 		KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 1, EINVAL, 0, 0, 0);
1538 		return EINVAL;
1539 	}
1540 
1541 	algo = ah_algorithm_lookup(sav->alg_auth);
1542 	VERIFY(algo != NULL);
1543 
1544 	siz = (((*algo->sumsiz)(sav) + 3) & ~(4 - 1));
1545 	if (__improbable(auth_size < siz)) {
1546 		esp_log_err("esp auth: auth size=%zu is lesser than siz=%zu "
1547 		    "SPI 0x%08x\n", input_data_len, siz, ntohl(sav->spi));
1548 		KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 2, EINVAL, 0, 0, 0);
1549 		return EINVAL;
1550 	}
1551 
1552 	err = (*algo->init)(&state, sav);
1553 	if (__improbable(err != 0)) {
1554 		esp_log_err("esp auth: algo init failed with error %d, "
1555 		    "SPI 0x%08x\n", err, ntohl(sav->spi));
1556 		KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 3, error, 0, 0, 0);
1557 		return err;
1558 	}
1559 
1560 	(*algo->update)(&state, (caddr_t)input_data, input_data_len);
1561 	(*algo->result)(&state, (caddr_t)out_auth, auth_size);
1562 	KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 4, 0, 0, 0, 0);
1563 	return 0;
1564 }
1565 
1566 void
esp_init(void)1567 esp_init(void)
1568 {
1569 	static int esp_initialized = 0;
1570 
1571 	if (esp_initialized) {
1572 		return;
1573 	}
1574 
1575 	esp_initialized = 1;
1576 
1577 	esp_mpkl_log_object = MPKL_CREATE_LOGOBJECT("com.apple.xnu.esp");
1578 	if (esp_mpkl_log_object == NULL) {
1579 		panic("MPKL_CREATE_LOGOBJECT for ESP failed");
1580 	}
1581 
1582 	return;
1583 }
1584