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