1 /*
2 * Copyright (c) 2008-2021 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
141 #define MAXIVLEN 16
142
143 #define ESP_AESGCM_KEYLEN128 160 // 16-bytes key + 4 bytes salt
144 #define ESP_AESGCM_KEYLEN192 224 // 24-bytes key + 4 bytes salt
145 #define ESP_AESGCM_KEYLEN256 288 // 32-bytes key + 4 bytes salt
146
147 static const struct esp_algorithm des_cbc = {
148 .padbound = 8,
149 .ivlenval = -1,
150 .mature = esp_descbc_mature,
151 .keymin = 64,
152 .keymax = 64,
153 .schedlen = esp_des_schedlen,
154 .name = "des-cbc",
155 .ivlen = esp_descbc_ivlen,
156 .decrypt = esp_cbc_decrypt,
157 .encrypt = esp_cbc_encrypt,
158 .schedule = esp_des_schedule,
159 .blockdecrypt = esp_des_blockdecrypt,
160 .blockencrypt = esp_des_blockencrypt,
161 .icvlen = 0,
162 .finalizedecrypt = NULL,
163 .finalizeencrypt = NULL
164 };
165
166 static const struct esp_algorithm des3_cbc = {
167 .padbound = 8,
168 .ivlenval = 8,
169 .mature = esp_cbc_mature,
170 .keymin = 192,
171 .keymax = 192,
172 .schedlen = esp_3des_schedlen,
173 .name = "3des-cbc",
174 .ivlen = esp_common_ivlen,
175 .decrypt = esp_cbc_decrypt,
176 .encrypt = esp_cbc_encrypt,
177 .schedule = esp_3des_schedule,
178 .blockdecrypt = esp_3des_blockdecrypt,
179 .blockencrypt = esp_3des_blockencrypt,
180 .icvlen = 0,
181 .finalizedecrypt = NULL,
182 .finalizeencrypt = NULL
183 };
184
185 static const struct esp_algorithm null_esp = {
186 .padbound = 1,
187 .ivlenval = 0,
188 .mature = esp_null_mature,
189 .keymin = 0,
190 .keymax = 2048,
191 .schedlen = NULL,
192 .name = "null",
193 .ivlen = esp_common_ivlen,
194 .decrypt = esp_null_decrypt,
195 .encrypt = esp_null_encrypt,
196 .schedule = NULL,
197 .blockdecrypt = NULL,
198 .blockencrypt = NULL,
199 .icvlen = 0,
200 .finalizedecrypt = NULL,
201 .finalizeencrypt = NULL
202 };
203
204 static const struct esp_algorithm aes_cbc = {
205 .padbound = 16,
206 .ivlenval = 16,
207 .mature = esp_cbc_mature,
208 .keymin = 128,
209 .keymax = 256,
210 .schedlen = esp_aes_schedlen,
211 .name = "aes-cbc",
212 .ivlen = esp_common_ivlen,
213 .decrypt = esp_cbc_decrypt_aes,
214 .encrypt = esp_cbc_encrypt_aes,
215 .schedule = esp_aes_schedule,
216 .blockdecrypt = NULL,
217 .blockencrypt = NULL,
218 .icvlen = 0,
219 .finalizedecrypt = NULL,
220 .finalizeencrypt = NULL
221 };
222
223 static const struct esp_algorithm aes_gcm = {
224 .padbound = 4,
225 .ivlenval = 8,
226 .mature = esp_gcm_mature,
227 .keymin = ESP_AESGCM_KEYLEN128,
228 .keymax = ESP_AESGCM_KEYLEN256,
229 .schedlen = esp_gcm_schedlen,
230 .name = "aes-gcm",
231 .ivlen = esp_gcm_ivlen,
232 .decrypt = esp_gcm_decrypt_aes,
233 .encrypt = esp_gcm_encrypt_aes,
234 .schedule = esp_gcm_schedule,
235 .blockdecrypt = NULL,
236 .blockencrypt = NULL,
237 .icvlen = 16,
238 .finalizedecrypt = esp_gcm_decrypt_finalize,
239 .finalizeencrypt = esp_gcm_encrypt_finalize
240 };
241
242 static const struct esp_algorithm chacha_poly = {
243 .padbound = ESP_CHACHAPOLY_PAD_BOUND,
244 .ivlenval = ESP_CHACHAPOLY_IV_LEN,
245 .mature = esp_chachapoly_mature,
246 .keymin = ESP_CHACHAPOLY_KEYBITS_WITH_SALT,
247 .keymax = ESP_CHACHAPOLY_KEYBITS_WITH_SALT,
248 .schedlen = esp_chachapoly_schedlen,
249 .name = "chacha-poly",
250 .ivlen = esp_chachapoly_ivlen,
251 .decrypt = esp_chachapoly_decrypt,
252 .encrypt = esp_chachapoly_encrypt,
253 .schedule = esp_chachapoly_schedule,
254 .blockdecrypt = NULL,
255 .blockencrypt = NULL,
256 .icvlen = ESP_CHACHAPOLY_ICV_LEN,
257 .finalizedecrypt = esp_chachapoly_decrypt_finalize,
258 .finalizeencrypt = esp_chachapoly_encrypt_finalize
259 };
260
261 static const struct esp_algorithm *esp_algorithms[] = {
262 &des_cbc,
263 &des3_cbc,
264 &null_esp,
265 &aes_cbc,
266 &aes_gcm,
267 &chacha_poly,
268 };
269
270 const struct esp_algorithm *
esp_algorithm_lookup(int idx)271 esp_algorithm_lookup(int idx)
272 {
273 switch (idx) {
274 case SADB_EALG_DESCBC:
275 return &des_cbc;
276 case SADB_EALG_3DESCBC:
277 return &des3_cbc;
278 case SADB_EALG_NULL:
279 return &null_esp;
280 case SADB_X_EALG_RIJNDAELCBC:
281 return &aes_cbc;
282 case SADB_X_EALG_AES_GCM:
283 return &aes_gcm;
284 case SADB_X_EALG_CHACHA20POLY1305:
285 return &chacha_poly;
286 default:
287 return NULL;
288 }
289 }
290
291 int
esp_max_ivlen(void)292 esp_max_ivlen(void)
293 {
294 int idx;
295 int ivlen;
296
297 ivlen = 0;
298 for (idx = 0; idx < sizeof(esp_algorithms) / sizeof(esp_algorithms[0]);
299 idx++) {
300 if (esp_algorithms[idx]->ivlenval > ivlen) {
301 ivlen = esp_algorithms[idx]->ivlenval;
302 }
303 }
304
305 return ivlen;
306 }
307
308 int
esp_schedule(const struct esp_algorithm * algo,struct secasvar * sav)309 esp_schedule(const struct esp_algorithm *algo, struct secasvar *sav)
310 {
311 int error;
312
313 /* check for key length */
314 if (_KEYBITS(sav->key_enc) < algo->keymin ||
315 _KEYBITS(sav->key_enc) > algo->keymax) {
316 ipseclog((LOG_ERR,
317 "esp_schedule %s: unsupported key length %d: "
318 "needs %d to %d bits\n", algo->name, _KEYBITS(sav->key_enc),
319 algo->keymin, algo->keymax));
320 return EINVAL;
321 }
322
323 lck_mtx_lock(sadb_mutex);
324 /* already allocated */
325 if (sav->sched && sav->schedlen != 0) {
326 lck_mtx_unlock(sadb_mutex);
327 return 0;
328 }
329
330 /* prevent disallowed implicit IV */
331 if (((sav->flags & SADB_X_EXT_IIV) != 0) &&
332 (sav->alg_enc != SADB_X_EALG_AES_GCM) &&
333 (sav->alg_enc != SADB_X_EALG_CHACHA20POLY1305)) {
334 ipseclog((LOG_ERR,
335 "esp_schedule %s: implicit IV not allowed\n",
336 algo->name));
337 lck_mtx_unlock(sadb_mutex);
338 return EINVAL;
339 }
340
341 /* no schedule necessary */
342 if (!algo->schedule || !algo->schedlen) {
343 lck_mtx_unlock(sadb_mutex);
344 return 0;
345 }
346
347 sav->schedlen = (*algo->schedlen)(algo);
348 if ((signed) sav->schedlen < 0) {
349 lck_mtx_unlock(sadb_mutex);
350 return EINVAL;
351 }
352
353 //#### that malloc should be replaced by a saved buffer...
354 sav->sched = kalloc_data(sav->schedlen, Z_NOWAIT);
355 if (!sav->sched) {
356 sav->schedlen = 0;
357 lck_mtx_unlock(sadb_mutex);
358 return ENOBUFS;
359 }
360
361 error = (*algo->schedule)(algo, sav);
362 if (error) {
363 ipseclog((LOG_ERR, "esp_schedule %s: error %d\n",
364 algo->name, error));
365 bzero(sav->sched, sav->schedlen);
366 kfree_data(sav->sched, sav->schedlen);
367 sav->sched = NULL;
368 sav->schedlen = 0;
369 }
370 lck_mtx_unlock(sadb_mutex);
371 return error;
372 }
373
374 static int
esp_null_mature(__unused struct secasvar * sav)375 esp_null_mature(
376 __unused struct secasvar *sav)
377 {
378 /* anything is okay */
379 return 0;
380 }
381
382 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)383 esp_null_decrypt(
384 __unused struct mbuf *m,
385 __unused size_t off, /* offset to ESP header */
386 __unused struct secasvar *sav,
387 __unused const struct esp_algorithm *algo,
388 __unused int ivlen)
389 {
390 return 0; /* do nothing */
391 }
392
393 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)394 esp_null_encrypt(
395 __unused struct mbuf *m,
396 __unused size_t off, /* offset to ESP header */
397 __unused size_t plen, /* payload length (to be encrypted) */
398 __unused struct secasvar *sav,
399 __unused const struct esp_algorithm *algo,
400 __unused int ivlen)
401 {
402 return 0; /* do nothing */
403 }
404
405 static int
esp_descbc_mature(struct secasvar * sav)406 esp_descbc_mature(struct secasvar *sav)
407 {
408 const struct esp_algorithm *algo;
409
410 if (!(sav->flags & SADB_X_EXT_OLD) && (sav->flags & SADB_X_EXT_IV4B)) {
411 ipseclog((LOG_ERR, "esp_cbc_mature: "
412 "algorithm incompatible with 4 octets IV length\n"));
413 return 1;
414 }
415
416 if (!sav->key_enc) {
417 ipseclog((LOG_ERR, "esp_descbc_mature: no key is given.\n"));
418 return 1;
419 }
420
421 algo = esp_algorithm_lookup(sav->alg_enc);
422 if (!algo) {
423 ipseclog((LOG_ERR,
424 "esp_descbc_mature: unsupported algorithm.\n"));
425 return 1;
426 }
427
428 if (_KEYBITS(sav->key_enc) < algo->keymin ||
429 _KEYBITS(sav->key_enc) > algo->keymax) {
430 ipseclog((LOG_ERR,
431 "esp_descbc_mature: invalid key length %d.\n",
432 _KEYBITS(sav->key_enc)));
433 return 1;
434 }
435
436 /* weak key check */
437 if (des_is_weak_key((des_cblock *)_KEYBUF(sav->key_enc))) {
438 ipseclog((LOG_ERR,
439 "esp_descbc_mature: weak key was passed.\n"));
440 return 1;
441 }
442
443 return 0;
444 }
445
446 static int
esp_descbc_ivlen(__unused const struct esp_algorithm * algo,struct secasvar * sav)447 esp_descbc_ivlen(
448 __unused const struct esp_algorithm *algo,
449 struct secasvar *sav)
450 {
451 if (!sav) {
452 return 8;
453 }
454 if ((sav->flags & SADB_X_EXT_OLD) && (sav->flags & SADB_X_EXT_IV4B)) {
455 return 4;
456 }
457 if (!(sav->flags & SADB_X_EXT_OLD) && (sav->flags & SADB_X_EXT_DERIV)) {
458 return 4;
459 }
460 return 8;
461 }
462
463 static size_t
esp_des_schedlen(__unused const struct esp_algorithm * algo)464 esp_des_schedlen(
465 __unused const struct esp_algorithm *algo)
466 {
467 return sizeof(des_ecb_key_schedule);
468 }
469
470 static int
esp_des_schedule(__unused const struct esp_algorithm * algo,struct secasvar * sav)471 esp_des_schedule(
472 __unused const struct esp_algorithm *algo,
473 struct secasvar *sav)
474 {
475 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
476 if (des_ecb_key_sched((des_cblock *)_KEYBUF(sav->key_enc),
477 (des_ecb_key_schedule *)sav->sched)) {
478 return EINVAL;
479 } else {
480 return 0;
481 }
482 }
483
484 static int
esp_des_blockdecrypt(__unused const struct esp_algorithm * algo,struct secasvar * sav,u_int8_t * s,u_int8_t * d)485 esp_des_blockdecrypt(
486 __unused const struct esp_algorithm *algo,
487 struct secasvar *sav,
488 u_int8_t *s,
489 u_int8_t *d)
490 {
491 /* assumption: d has a good alignment */
492 bcopy(s, d, sizeof(DES_LONG) * 2);
493 return des_ecb_encrypt((des_cblock *)d, (des_cblock *)d,
494 (des_ecb_key_schedule *)sav->sched, DES_DECRYPT);
495 }
496
497 static int
esp_des_blockencrypt(__unused const struct esp_algorithm * algo,struct secasvar * sav,u_int8_t * s,u_int8_t * d)498 esp_des_blockencrypt(
499 __unused const struct esp_algorithm *algo,
500 struct secasvar *sav,
501 u_int8_t *s,
502 u_int8_t *d)
503 {
504 /* assumption: d has a good alignment */
505 bcopy(s, d, sizeof(DES_LONG) * 2);
506 return des_ecb_encrypt((des_cblock *)d, (des_cblock *)d,
507 (des_ecb_key_schedule *)sav->sched, DES_ENCRYPT);
508 }
509
510 static int
esp_cbc_mature(struct secasvar * sav)511 esp_cbc_mature(struct secasvar *sav)
512 {
513 int keylen;
514 const struct esp_algorithm *algo;
515
516 if (sav->flags & SADB_X_EXT_OLD) {
517 ipseclog((LOG_ERR,
518 "esp_cbc_mature: algorithm incompatible with esp-old\n"));
519 return 1;
520 }
521 if (sav->flags & SADB_X_EXT_DERIV) {
522 ipseclog((LOG_ERR,
523 "esp_cbc_mature: algorithm incompatible with derived\n"));
524 return 1;
525 }
526
527 if (!sav->key_enc) {
528 ipseclog((LOG_ERR, "esp_cbc_mature: no key is given.\n"));
529 return 1;
530 }
531
532 algo = esp_algorithm_lookup(sav->alg_enc);
533 if (!algo) {
534 ipseclog((LOG_ERR,
535 "esp_cbc_mature: unsupported algorithm.\n"));
536 return 1;
537 }
538
539 keylen = sav->key_enc->sadb_key_bits;
540 if (keylen < algo->keymin || algo->keymax < keylen) {
541 ipseclog((LOG_ERR,
542 "esp_cbc_mature %s: invalid key length %d.\n",
543 algo->name, sav->key_enc->sadb_key_bits));
544 return 1;
545 }
546 switch (sav->alg_enc) {
547 case SADB_EALG_3DESCBC:
548 /* weak key check */
549 if (des_is_weak_key((des_cblock *)_KEYBUF(sav->key_enc)) ||
550 des_is_weak_key((des_cblock *)(_KEYBUF(sav->key_enc) + 8)) ||
551 des_is_weak_key((des_cblock *)(_KEYBUF(sav->key_enc) + 16))) {
552 ipseclog((LOG_ERR,
553 "esp_cbc_mature %s: weak key was passed.\n",
554 algo->name));
555 return 1;
556 }
557 break;
558 case SADB_X_EALG_RIJNDAELCBC:
559 /* allows specific key sizes only */
560 if (!(keylen == 128 || keylen == 192 || keylen == 256)) {
561 ipseclog((LOG_ERR,
562 "esp_cbc_mature %s: invalid key length %d.\n",
563 algo->name, keylen));
564 return 1;
565 }
566 break;
567 }
568
569 return 0;
570 }
571
572 static int
esp_gcm_mature(struct secasvar * sav)573 esp_gcm_mature(struct secasvar *sav)
574 {
575 int keylen;
576 const struct esp_algorithm *algo;
577
578 if (sav->flags & SADB_X_EXT_OLD) {
579 ipseclog((LOG_ERR,
580 "esp_gcm_mature: algorithm incompatible with esp-old\n"));
581 return 1;
582 }
583 if (sav->flags & SADB_X_EXT_DERIV) {
584 ipseclog((LOG_ERR,
585 "esp_gcm_mature: algorithm incompatible with derived\n"));
586 return 1;
587 }
588
589 if (!sav->key_enc) {
590 ipseclog((LOG_ERR, "esp_gcm_mature: no key is given.\n"));
591 return 1;
592 }
593
594 algo = esp_algorithm_lookup(sav->alg_enc);
595 if (!algo) {
596 ipseclog((LOG_ERR,
597 "esp_gcm_mature: unsupported algorithm.\n"));
598 return 1;
599 }
600
601 keylen = sav->key_enc->sadb_key_bits;
602 if (keylen < algo->keymin || algo->keymax < keylen) {
603 ipseclog((LOG_ERR,
604 "esp_gcm_mature %s: invalid key length %d.\n",
605 algo->name, sav->key_enc->sadb_key_bits));
606 return 1;
607 }
608 switch (sav->alg_enc) {
609 case SADB_X_EALG_AES_GCM:
610 /* allows specific key sizes only */
611 if (!(keylen == ESP_AESGCM_KEYLEN128 || keylen == ESP_AESGCM_KEYLEN192 || keylen == ESP_AESGCM_KEYLEN256)) {
612 ipseclog((LOG_ERR,
613 "esp_gcm_mature %s: invalid key length %d.\n",
614 algo->name, keylen));
615 return 1;
616 }
617 break;
618 default:
619 ipseclog((LOG_ERR,
620 "esp_gcm_mature %s: invalid algo %d.\n", algo->name, sav->alg_enc));
621 return 1;
622 }
623
624 return 0;
625 }
626
627 static size_t
esp_3des_schedlen(__unused const struct esp_algorithm * algo)628 esp_3des_schedlen(
629 __unused const struct esp_algorithm *algo)
630 {
631 return sizeof(des3_ecb_key_schedule);
632 }
633
634 static int
esp_3des_schedule(__unused const struct esp_algorithm * algo,struct secasvar * sav)635 esp_3des_schedule(
636 __unused const struct esp_algorithm *algo,
637 struct secasvar *sav)
638 {
639 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_OWNED);
640
641 if (des3_ecb_key_sched((des_cblock *)_KEYBUF(sav->key_enc),
642 (des3_ecb_key_schedule *)sav->sched)) {
643 return EINVAL;
644 } else {
645 return 0;
646 }
647 }
648
649 static int
esp_3des_blockdecrypt(__unused const struct esp_algorithm * algo,struct secasvar * sav,u_int8_t * s,u_int8_t * d)650 esp_3des_blockdecrypt(
651 __unused const struct esp_algorithm *algo,
652 struct secasvar *sav,
653 u_int8_t *s,
654 u_int8_t *d)
655 {
656 /* assumption: d has a good alignment */
657 bcopy(s, d, sizeof(DES_LONG) * 2);
658 return des3_ecb_encrypt((des_cblock *)d, (des_cblock *)d,
659 (des3_ecb_key_schedule *)sav->sched, DES_DECRYPT);
660 }
661
662 static int
esp_3des_blockencrypt(__unused const struct esp_algorithm * algo,struct secasvar * sav,u_int8_t * s,u_int8_t * d)663 esp_3des_blockencrypt(
664 __unused const struct esp_algorithm *algo,
665 struct secasvar *sav,
666 u_int8_t *s,
667 u_int8_t *d)
668 {
669 /* assumption: d has a good alignment */
670 bcopy(s, d, sizeof(DES_LONG) * 2);
671 return des3_ecb_encrypt((des_cblock *)d, (des_cblock *)d,
672 (des3_ecb_key_schedule *)sav->sched, DES_ENCRYPT);
673 }
674
675 static int
esp_common_ivlen(const struct esp_algorithm * algo,__unused struct secasvar * sav)676 esp_common_ivlen(
677 const struct esp_algorithm *algo,
678 __unused struct secasvar *sav)
679 {
680 if (!algo) {
681 panic("esp_common_ivlen: unknown algorithm");
682 }
683 return algo->ivlenval;
684 }
685
686 static int
esp_cbc_decrypt(struct mbuf * m,size_t off,struct secasvar * sav,const struct esp_algorithm * algo,int ivlen)687 esp_cbc_decrypt(struct mbuf *m, size_t off, struct secasvar *sav,
688 const struct esp_algorithm *algo, int ivlen)
689 {
690 struct mbuf *s;
691 struct mbuf *d, *d0, *dp;
692 int soff, doff; /* offset from the head of chain, to head of this mbuf */
693 int sn, dn; /* offset from the head of the mbuf, to meat */
694 size_t ivoff, bodyoff;
695 u_int8_t iv[MAXIVLEN] __attribute__((aligned(4))), *ivp;
696 u_int8_t *sbuf = NULL, *sp, *sp_unaligned;
697 u_int8_t *p, *q;
698 struct mbuf *scut;
699 int scutoff;
700 int i, result = 0;
701 int blocklen;
702 int derived;
703
704 if (ivlen != sav->ivlen || ivlen > sizeof(iv)) {
705 ipseclog((LOG_ERR, "esp_cbc_decrypt %s: "
706 "unsupported ivlen %d\n", algo->name, ivlen));
707 m_freem(m);
708 return EINVAL;
709 }
710
711 /* assumes blocklen == padbound */
712 blocklen = algo->padbound;
713
714 #if DIAGNOSTIC
715 if (blocklen > sizeof(iv)) {
716 ipseclog((LOG_ERR, "esp_cbc_decrypt %s: "
717 "unsupported blocklen %d\n", algo->name, blocklen));
718 m_freem(m);
719 return EINVAL;
720 }
721 #endif
722
723 if (sav->flags & SADB_X_EXT_OLD) {
724 /* RFC 1827 */
725 ivoff = off + sizeof(struct esp);
726 bodyoff = off + sizeof(struct esp) + ivlen;
727 derived = 0;
728 } else {
729 /* RFC 2406 */
730 if (sav->flags & SADB_X_EXT_DERIV) {
731 /*
732 * draft-ietf-ipsec-ciph-des-derived-00.txt
733 * uses sequence number field as IV field.
734 */
735 ivoff = off + sizeof(struct esp);
736 bodyoff = off + sizeof(struct esp) + sizeof(u_int32_t);
737 ivlen = sizeof(u_int32_t);
738 derived = 1;
739 } else {
740 ivoff = off + sizeof(struct newesp);
741 bodyoff = off + sizeof(struct newesp) + ivlen;
742 derived = 0;
743 }
744 }
745
746 VERIFY(ivoff <= INT_MAX);
747 /* grab iv */
748 m_copydata(m, (int)ivoff, ivlen, (caddr_t) iv);
749
750 /* extend iv */
751 if (ivlen == blocklen) {
752 ;
753 } else if (ivlen == 4 && blocklen == 8) {
754 bcopy(&iv[0], &iv[4], 4);
755 iv[4] ^= 0xff;
756 iv[5] ^= 0xff;
757 iv[6] ^= 0xff;
758 iv[7] ^= 0xff;
759 } else {
760 ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
761 "unsupported ivlen/blocklen: %d %d\n",
762 algo->name, ivlen, blocklen));
763 m_freem(m);
764 return EINVAL;
765 }
766
767 if (m->m_pkthdr.len < bodyoff) {
768 ipseclog((LOG_ERR, "esp_cbc_decrypt %s: bad len %d/%u\n",
769 algo->name, m->m_pkthdr.len, (u_int32_t)bodyoff));
770 m_freem(m);
771 return EINVAL;
772 }
773 if ((m->m_pkthdr.len - bodyoff) % blocklen) {
774 ipseclog((LOG_ERR, "esp_cbc_decrypt %s: "
775 "payload length must be multiple of %d\n",
776 algo->name, blocklen));
777 m_freem(m);
778 return EINVAL;
779 }
780
781 s = m;
782 d = d0 = dp = NULL;
783 soff = doff = sn = dn = 0;
784 ivp = sp = NULL;
785
786 /* skip bodyoff */
787 while (soff < bodyoff) {
788 if (soff + s->m_len > bodyoff) {
789 sn = (int)(bodyoff - soff);
790 break;
791 }
792
793 soff += s->m_len;
794 s = s->m_next;
795 }
796 scut = s;
797 scutoff = sn;
798
799 /* skip over empty mbuf */
800 while (s && s->m_len == 0) {
801 s = s->m_next;
802 }
803
804 // Allocate blocksized buffer for unaligned or non-contiguous access
805 sbuf = (u_int8_t *)kalloc_data(blocklen, Z_NOWAIT);
806 if (sbuf == NULL) {
807 return ENOBUFS;
808 }
809 while (soff < m->m_pkthdr.len) {
810 /* source */
811 if (sn + blocklen <= s->m_len) {
812 /* body is continuous */
813 sp = mtod(s, u_int8_t *) + sn;
814 } else {
815 /* body is non-continuous */
816 m_copydata(s, sn, blocklen, (caddr_t) sbuf);
817 sp = sbuf;
818 }
819
820 /* destination */
821 if (!d || dn + blocklen > d->m_len) {
822 if (d) {
823 dp = d;
824 }
825 MGET(d, M_DONTWAIT, MT_DATA);
826 i = m->m_pkthdr.len - (soff + sn);
827 if (d && i > MLEN) {
828 MCLGET(d, M_DONTWAIT);
829 if ((d->m_flags & M_EXT) == 0) {
830 m_free(d);
831 d = NULL;
832 }
833 }
834 if (!d) {
835 m_freem(m);
836 if (d0) {
837 m_freem(d0);
838 }
839 result = ENOBUFS;
840 goto end;
841 }
842 if (!d0) {
843 d0 = d;
844 }
845 if (dp) {
846 dp->m_next = d;
847 }
848
849 // try to make mbuf data aligned
850 if (!IPSEC_IS_P2ALIGNED(d->m_data)) {
851 m_adj(d, IPSEC_GET_P2UNALIGNED_OFS(d->m_data));
852 }
853
854 d->m_len = 0;
855 d->m_len = (int)((M_TRAILINGSPACE(d) / blocklen) * blocklen);
856 if (d->m_len > i) {
857 d->m_len = i;
858 }
859 dn = 0;
860 }
861
862 /* decrypt */
863 // check input pointer alignment and use a separate aligned buffer (if sp is unaligned on 4-byte boundary).
864 if (IPSEC_IS_P2ALIGNED(sp)) {
865 sp_unaligned = NULL;
866 } else {
867 sp_unaligned = sp;
868 sp = sbuf;
869 memcpy(sp, sp_unaligned, blocklen);
870 }
871 // no need to check output pointer alignment
872 (*algo->blockdecrypt)(algo, sav, sp, mtod(d, u_int8_t *) + dn);
873
874 // update unaligned pointers
875 if (!IPSEC_IS_P2ALIGNED(sp_unaligned)) {
876 sp = sp_unaligned;
877 }
878
879 /* xor */
880 p = ivp ? ivp : iv;
881 q = mtod(d, u_int8_t *) + dn;
882 for (i = 0; i < blocklen; i++) {
883 q[i] ^= p[i];
884 }
885
886 /* next iv */
887 if (sp == sbuf) {
888 bcopy(sbuf, iv, blocklen);
889 ivp = NULL;
890 } else {
891 ivp = sp;
892 }
893
894 sn += blocklen;
895 dn += blocklen;
896
897 /* find the next source block */
898 while (s && sn >= s->m_len) {
899 sn -= s->m_len;
900 soff += s->m_len;
901 s = s->m_next;
902 }
903 }
904
905 m_freem(scut->m_next);
906 scut->m_len = scutoff;
907 scut->m_next = d0;
908
909 /* just in case */
910 bzero(iv, sizeof(iv));
911 bzero(sbuf, blocklen);
912 end:
913 if (sbuf != NULL) {
914 kfree_data(sbuf, blocklen);
915 }
916 return result;
917 }
918
919 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)920 esp_cbc_encrypt(
921 struct mbuf *m,
922 size_t off,
923 __unused size_t plen,
924 struct secasvar *sav,
925 const struct esp_algorithm *algo,
926 int ivlen)
927 {
928 struct mbuf *s;
929 struct mbuf *d, *d0, *dp;
930 int soff, doff; /* offset from the head of chain, to head of this mbuf */
931 int sn, dn; /* offset from the head of the mbuf, to meat */
932 size_t ivoff, bodyoff;
933 u_int8_t iv[MAXIVLEN] __attribute__((aligned(4))), *ivp;
934 u_int8_t *sbuf = NULL, *sp, *sp_unaligned;
935 u_int8_t *p, *q;
936 struct mbuf *scut;
937 int scutoff;
938 int i, result = 0;
939 int blocklen;
940 int derived;
941
942 if (ivlen != sav->ivlen || ivlen > sizeof(iv)) {
943 ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
944 "unsupported ivlen %d\n", algo->name, ivlen));
945 m_freem(m);
946 return EINVAL;
947 }
948
949 /* assumes blocklen == padbound */
950 blocklen = algo->padbound;
951
952 #if DIAGNOSTIC
953 if (blocklen > sizeof(iv)) {
954 ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
955 "unsupported blocklen %d\n", algo->name, blocklen));
956 m_freem(m);
957 return EINVAL;
958 }
959 #endif
960
961 if (sav->flags & SADB_X_EXT_OLD) {
962 /* RFC 1827 */
963 ivoff = off + sizeof(struct esp);
964 bodyoff = off + sizeof(struct esp) + ivlen;
965 derived = 0;
966 } else {
967 /* RFC 2406 */
968 if (sav->flags & SADB_X_EXT_DERIV) {
969 /*
970 * draft-ietf-ipsec-ciph-des-derived-00.txt
971 * uses sequence number field as IV field.
972 */
973 ivoff = off + sizeof(struct esp);
974 bodyoff = off + sizeof(struct esp) + sizeof(u_int32_t);
975 ivlen = sizeof(u_int32_t);
976 derived = 1;
977 } else {
978 ivoff = off + sizeof(struct newesp);
979 bodyoff = off + sizeof(struct newesp) + ivlen;
980 derived = 0;
981 }
982 }
983
984 VERIFY(ivoff <= INT_MAX);
985
986 /* put iv into the packet. if we are in derived mode, use seqno. */
987 if (derived) {
988 m_copydata(m, (int)ivoff, ivlen, (caddr_t) iv);
989 } else {
990 bcopy(sav->iv, iv, ivlen);
991 /* maybe it is better to overwrite dest, not source */
992 m_copyback(m, (int)ivoff, ivlen, (caddr_t) iv);
993 }
994
995 /* extend iv */
996 if (ivlen == blocklen) {
997 ;
998 } else if (ivlen == 4 && blocklen == 8) {
999 bcopy(&iv[0], &iv[4], 4);
1000 iv[4] ^= 0xff;
1001 iv[5] ^= 0xff;
1002 iv[6] ^= 0xff;
1003 iv[7] ^= 0xff;
1004 } else {
1005 ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
1006 "unsupported ivlen/blocklen: %d %d\n",
1007 algo->name, ivlen, blocklen));
1008 m_freem(m);
1009 return EINVAL;
1010 }
1011
1012 if (m->m_pkthdr.len < bodyoff) {
1013 ipseclog((LOG_ERR, "esp_cbc_encrypt %s: bad len %d/%u\n",
1014 algo->name, m->m_pkthdr.len, (u_int32_t)bodyoff));
1015 m_freem(m);
1016 return EINVAL;
1017 }
1018 if ((m->m_pkthdr.len - bodyoff) % blocklen) {
1019 ipseclog((LOG_ERR, "esp_cbc_encrypt %s: "
1020 "payload length must be multiple of %u\n",
1021 algo->name, (u_int32_t)algo->padbound));
1022 m_freem(m);
1023 return EINVAL;
1024 }
1025
1026 s = m;
1027 d = d0 = dp = NULL;
1028 soff = doff = sn = dn = 0;
1029 ivp = sp = NULL;
1030
1031 /* skip bodyoff */
1032 while (soff < bodyoff) {
1033 if (soff + s->m_len > bodyoff) {
1034 sn = (int)(bodyoff - soff);
1035 break;
1036 }
1037
1038 soff += s->m_len;
1039 s = s->m_next;
1040 }
1041 scut = s;
1042 scutoff = sn;
1043
1044 /* skip over empty mbuf */
1045 while (s && s->m_len == 0) {
1046 s = s->m_next;
1047 }
1048
1049 // Allocate blocksized buffer for unaligned or non-contiguous access
1050 sbuf = (u_int8_t *)kalloc_data(blocklen, Z_NOWAIT);
1051 if (sbuf == NULL) {
1052 return ENOBUFS;
1053 }
1054 while (soff < m->m_pkthdr.len) {
1055 /* source */
1056 if (sn + blocklen <= s->m_len) {
1057 /* body is continuous */
1058 sp = mtod(s, u_int8_t *) + sn;
1059 } else {
1060 /* body is non-continuous */
1061 m_copydata(s, sn, blocklen, (caddr_t) sbuf);
1062 sp = sbuf;
1063 }
1064
1065 /* destination */
1066 if (!d || dn + blocklen > d->m_len) {
1067 if (d) {
1068 dp = d;
1069 }
1070 MGET(d, M_DONTWAIT, MT_DATA);
1071 i = m->m_pkthdr.len - (soff + sn);
1072 if (d && i > MLEN) {
1073 MCLGET(d, M_DONTWAIT);
1074 if ((d->m_flags & M_EXT) == 0) {
1075 m_free(d);
1076 d = NULL;
1077 }
1078 }
1079 if (!d) {
1080 m_freem(m);
1081 if (d0) {
1082 m_freem(d0);
1083 }
1084 result = ENOBUFS;
1085 goto end;
1086 }
1087 if (!d0) {
1088 d0 = d;
1089 }
1090 if (dp) {
1091 dp->m_next = d;
1092 }
1093
1094 // try to make mbuf data aligned
1095 if (!IPSEC_IS_P2ALIGNED(d->m_data)) {
1096 m_adj(d, IPSEC_GET_P2UNALIGNED_OFS(d->m_data));
1097 }
1098
1099 d->m_len = 0;
1100 d->m_len = (int)((M_TRAILINGSPACE(d) / blocklen) * blocklen);
1101 if (d->m_len > i) {
1102 d->m_len = i;
1103 }
1104 dn = 0;
1105 }
1106
1107 /* xor */
1108 p = ivp ? ivp : iv;
1109 q = sp;
1110 for (i = 0; i < blocklen; i++) {
1111 q[i] ^= p[i];
1112 }
1113
1114 /* encrypt */
1115 // check input pointer alignment and use a separate aligned buffer (if sp is not aligned on 4-byte boundary).
1116 if (IPSEC_IS_P2ALIGNED(sp)) {
1117 sp_unaligned = NULL;
1118 } else {
1119 sp_unaligned = sp;
1120 sp = sbuf;
1121 memcpy(sp, sp_unaligned, blocklen);
1122 }
1123 // no need to check output pointer alignment
1124 (*algo->blockencrypt)(algo, sav, sp, mtod(d, u_int8_t *) + dn);
1125
1126 // update unaligned pointers
1127 if (!IPSEC_IS_P2ALIGNED(sp_unaligned)) {
1128 sp = sp_unaligned;
1129 }
1130
1131 /* next iv */
1132 ivp = mtod(d, u_int8_t *) + dn;
1133
1134 sn += blocklen;
1135 dn += blocklen;
1136
1137 /* find the next source block */
1138 while (s && sn >= s->m_len) {
1139 sn -= s->m_len;
1140 soff += s->m_len;
1141 s = s->m_next;
1142 }
1143 }
1144
1145 m_freem(scut->m_next);
1146 scut->m_len = scutoff;
1147 scut->m_next = d0;
1148
1149 /* just in case */
1150 bzero(iv, sizeof(iv));
1151 bzero(sbuf, blocklen);
1152
1153 key_sa_stir_iv(sav);
1154 end:
1155 if (sbuf != NULL) {
1156 kfree_data(sbuf, blocklen);
1157 }
1158 return result;
1159 }
1160
1161 /*------------------------------------------------------------*/
1162
1163 /* does not free m0 on error */
1164 int
esp_auth(struct mbuf * m0,size_t skip,size_t length,struct secasvar * sav,u_char * sum)1165 esp_auth(
1166 struct mbuf *m0,
1167 size_t skip, /* offset to ESP header */
1168 size_t length, /* payload length */
1169 struct secasvar *sav,
1170 u_char *sum)
1171 {
1172 struct mbuf *m;
1173 size_t off;
1174 struct ah_algorithm_state s;
1175 u_char sumbuf[AH_MAXSUMSIZE] __attribute__((aligned(4)));
1176 const struct ah_algorithm *algo;
1177 size_t siz;
1178 int error;
1179
1180 /* sanity checks */
1181 if (m0->m_pkthdr.len < skip) {
1182 ipseclog((LOG_DEBUG, "esp_auth: mbuf length < skip\n"));
1183 return EINVAL;
1184 }
1185 if (m0->m_pkthdr.len < skip + length) {
1186 ipseclog((LOG_DEBUG,
1187 "esp_auth: mbuf length < skip + length\n"));
1188 return EINVAL;
1189 }
1190
1191 KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_START, skip, length, 0, 0, 0);
1192 /*
1193 * length of esp part (excluding authentication data) must be 4n,
1194 * since nexthdr must be at offset 4n+3.
1195 */
1196 if (length % 4) {
1197 ipseclog((LOG_ERR, "esp_auth: length is not multiple of 4\n"));
1198 KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 1, 0, 0, 0, 0);
1199 return EINVAL;
1200 }
1201 if (!sav) {
1202 ipseclog((LOG_DEBUG, "esp_auth: NULL SA passed\n"));
1203 KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 2, 0, 0, 0, 0);
1204 return EINVAL;
1205 }
1206 algo = ah_algorithm_lookup(sav->alg_auth);
1207 if (!algo) {
1208 ipseclog((LOG_ERR,
1209 "esp_auth: bad ESP auth algorithm passed: %d\n",
1210 sav->alg_auth));
1211 KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 3, 0, 0, 0, 0);
1212 return EINVAL;
1213 }
1214
1215 m = m0;
1216 off = 0;
1217
1218 siz = (((*algo->sumsiz)(sav) + 3) & ~(4 - 1));
1219 if (sizeof(sumbuf) < siz) {
1220 ipseclog((LOG_DEBUG,
1221 "esp_auth: AH_MAXSUMSIZE is too small: siz=%u\n",
1222 (u_int32_t)siz));
1223 KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 4, 0, 0, 0, 0);
1224 return EINVAL;
1225 }
1226
1227 /* skip the header */
1228 while (skip) {
1229 if (!m) {
1230 panic("mbuf chain?");
1231 }
1232 if (m->m_len <= skip) {
1233 skip -= m->m_len;
1234 m = m->m_next;
1235 off = 0;
1236 } else {
1237 off = skip;
1238 skip = 0;
1239 }
1240 }
1241
1242 error = (*algo->init)(&s, sav);
1243 if (error) {
1244 KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 5, 0, 0, 0, 0);
1245 return error;
1246 }
1247 while (0 < length) {
1248 if (!m) {
1249 panic("mbuf chain?");
1250 }
1251
1252 if (m->m_len - off < length) {
1253 (*algo->update)(&s, (caddr_t)(mtod(m, u_char *) + off),
1254 m->m_len - off);
1255 length -= m->m_len - off;
1256 m = m->m_next;
1257 off = 0;
1258 } else {
1259 (*algo->update)(&s, (caddr_t)(mtod(m, u_char *) + off), length);
1260 break;
1261 }
1262 }
1263 (*algo->result)(&s, (caddr_t) sumbuf, sizeof(sumbuf));
1264 bcopy(sumbuf, sum, siz); /*XXX*/
1265 KERNEL_DEBUG(DBG_FNC_ESPAUTH | DBG_FUNC_END, 6, 0, 0, 0, 0);
1266 return 0;
1267 }
1268
1269 void
esp_init(void)1270 esp_init(void)
1271 {
1272 static int esp_initialized = 0;
1273
1274 if (esp_initialized) {
1275 return;
1276 }
1277
1278 esp_initialized = 1;
1279
1280 esp_mpkl_log_object = MPKL_CREATE_LOGOBJECT("com.apple.xnu.esp");
1281 if (esp_mpkl_log_object == NULL) {
1282 panic("MPKL_CREATE_LOGOBJECT for ESP failed");
1283 }
1284
1285 return;
1286 }
1287